Email.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. <?php
  2. namespace app\api\controller\v1;
  3. use app\api\controller\Base;
  4. use app\hander\HelpHander;
  5. use PHPMailer\PHPMailer\Exception;
  6. use PHPMailer\PHPMailer\PHPMailer;
  7. use think\Db;
  8. use tools\Oaimap;
  9. class Email extends Base
  10. {
  11. // 新增
  12. public function save(){
  13. model('Email')->add();
  14. HelpHander::success([],'操作成功');
  15. }
  16. // 编辑
  17. public function update(){
  18. model('Email')->edit();
  19. HelpHander::success([],'操作成功');
  20. }
  21. // 列表
  22. public function list(){
  23. $page = input('page/d',1);
  24. $size = input('size/d',10);
  25. $title = input('title','','trim');
  26. $status = input('status/d',0);
  27. $ret = model('Email')->lists($page,$size,$title,$status,$this->orgId);
  28. HelpHander::success($ret);
  29. }
  30. public function login(){
  31. $email = Db::name('user_email')->where('active',1)->where('user_id',$this->userId)->value('email');
  32. if(!$email){
  33. HelpHander::error('未设置邮箱账号或邮箱账号被禁用,请联系管理员');
  34. }
  35. $res = model('Email')->login($email);
  36. HelpHander::success(['url'=>$res]);
  37. }
  38. public function loginIpmc(){
  39. $email = 'ipmc@dr-ipmc.org.cn';
  40. $res = model('Email')->login($email);
  41. HelpHander::success(['url'=>$res]);
  42. }
  43. // 新消息数量
  44. public function newMessage(){
  45. $email = Db::name('user_email')->where('active',1)->where('user_id',$this->userId)->value('email');
  46. if(!$email){
  47. HelpHander::success([
  48. "count" => 0,
  49. "unseenCount" => 0,
  50. "uidNext" => 0,
  51. "newMessage" => []
  52. ]);
  53. }
  54. $res = model('Email')->newMessage($email);
  55. HelpHander::success($res);
  56. }
  57. // 删除
  58. public function del(){
  59. $id = input('id/d',0);
  60. model('Email')->del($id);
  61. HelpHander::success([],'操作成功');
  62. }
  63. // 批量更新通讯录
  64. public function batchTel(){
  65. set_time_limit(0);
  66. ini_set("memory_limit","2048M");
  67. model('Email')->batchTel();
  68. HelpHander::success([],'操作成功');
  69. }
  70. // 获取文件夹列表
  71. public function getFolders(){
  72. $uemail = $this->checkEmail();
  73. $config = config('app.email');
  74. $url = $config['host2'].'Email/getFolders';
  75. $ret = curl_post($url,['token' => $uemail['token']]);
  76. if(!$ret){
  77. HelpHander::error('数据获取失败');
  78. }
  79. $ret = json_decode($ret,true);
  80. if($ret['code'] != 0){
  81. HelpHander::error($ret['message']);
  82. }
  83. HelpHander::success($ret['data']);
  84. }
  85. // 获取邮件列表
  86. public function getMessages(){
  87. $uemail = $this->checkEmail();
  88. $data = [
  89. 'token' => $uemail['token'],
  90. 'page' => input('page/d',1),
  91. 'size' => input('size/d',10),
  92. 'keyword' => input('keyword','','trim'),
  93. 'folder' => input('folder','INBOX','trim') // 默认是收件箱
  94. ];
  95. $config = config('app.email');
  96. $url = $config['host2'].'Email/getMessages';
  97. $ret = curl_post($url,$data);
  98. if(!$ret){
  99. HelpHander::error('数据获取失败');
  100. }
  101. $ret = json_decode($ret,true);
  102. if($ret['code'] != 0){
  103. HelpHander::error($ret['message']);
  104. }
  105. HelpHander::success($ret['data']);
  106. }
  107. private function checkEmail(){
  108. $uemail = Db::name('user_email')->where('user_id',$this->userId)->find();
  109. if(!$uemail){
  110. HelpHander::error('改用户未设置邮箱');
  111. }
  112. $uemail['password'] = think_decrypt($uemail['password']);
  113. $uemail['name'] = Db::name('user_info')->where('user_id',$this->userId)->value('name');
  114. $token = think_encrypt(json_encode(['email'=>$uemail['email'],'password'=>$uemail['password']]),'',20);
  115. $uemail['token'] = $token;
  116. return $uemail;
  117. }
  118. // 发送邮件
  119. public function send(){
  120. $uemail = $this->checkEmail();
  121. $data = [
  122. 'token' => $uemail['token'],
  123. 'subject' => input('subject','','trim'),
  124. 'body' => input('body','','trim'),
  125. 'to' => input('to','','trim'), // [{"email":"hzd@dr-ipmc.org.cn","name":"hzd"}]
  126. 'cc' => input('cc','','trim'), // [{"email":"hzd@dr-ipmc.org.cn","name":"hzd"}]
  127. 'bcc' => input('bcc','','trim'), // [{"email":"hzd@dr-ipmc.org.cn","name":"hzd"}]
  128. 'attachment' => input('attachment','','trim'),
  129. 'bookTime' => input('bookTime','','trim'),
  130. 'priority' => input('priority/d',0),
  131. 'dnt' => input('dnt/d',0), // 0=不回复 1=回复
  132. 'messageFolder' => input('messageFolder','','trim'),// 编辑草稿箱时填写
  133. 'messageUid' => input('messageUid','','trim'), // 编辑草稿箱uid
  134. 'draftInfo' => input('draftInfo','','trim'), // draftInfo,有值时传,回复、转发 {"type":"reply","uid":1,"folder":"INBOX"}
  135. 'inReplyTo' => input('inReplyTo','','trim'), // 回复、转发,messageId
  136. 'references' => input('references','','trim'),// 回复、转发,messageId
  137. 'dsn' => input('dsn/d',0),// 0=发送成功不回复 1=发送成功回复
  138. ];
  139. $data['fromName'] = $uemail['name'];
  140. $data['fromEmail'] = $uemail['email'];
  141. if($data['bookTime'] && strtotime($data['bookTime']) <= time()){
  142. HelpHander::error('定时时间不能小于当前时间');
  143. }
  144. if(!$data['subject']){
  145. HelpHander::error('未填写主题');
  146. }
  147. if(!$data['to']){
  148. HelpHander::error('未填写收件人');
  149. }
  150. $config = config('app.email');
  151. $url = $config['host2'].'Email/sendMessage';
  152. $ret = curl_post($url,$data);
  153. if(!$ret){
  154. HelpHander::error('数据获取失败');
  155. }
  156. $ret = json_decode($ret,true);
  157. if($ret['code'] != 0){
  158. HelpHander::error($ret['message']);
  159. }
  160. HelpHander::success([],'发送成功');
  161. }
  162. // 保存草稿箱
  163. public function saveMessage(){
  164. $uemail = $this->checkEmail();
  165. $data = [
  166. 'token' => $uemail['token'],
  167. 'subject' => input('subject','','trim'),
  168. 'plain' => input('plain','','trim'),
  169. 'body' => input('body','','trim'),
  170. 'to' => input('to','','trim'), // [{"email":"hzd@dr-ipmc.org.cn","name":"hzd"}]
  171. 'cc' => input('cc','','trim'), // [{"email":"hzd@dr-ipmc.org.cn","name":"hzd"}]
  172. 'bcc' => input('bcc','','trim'), // [{"email":"hzd@dr-ipmc.org.cn","name":"hzd"}]
  173. 'attachment' => input('attachment','','trim'),
  174. 'bookTime' => input('bookTime','','trim'),
  175. 'priority' => input('priority/d',0),
  176. 'dnt' => input('dnt/d',0), // 0=不回复 1=回复
  177. 'messageFolder' => input('messageFolder','','trim'),// 编辑草稿箱时填写
  178. 'messageUid' => input('messageUid','','trim'), // 编辑草稿箱uid
  179. 'draftInfo' => input('draftInfo','','trim'), // draftInfo,有值时传,回复、转发 (type-uid-folder reply-1-INBOX)
  180. 'inReplyTo' => input('inReplyTo','','trim'), // 回复、转发,messageId
  181. 'references' => input('references','','trim'),// 回复、转发,messageId
  182. 'dsn' => input('dsn/d',0),// 0=发送成功不回复 1=发送成功回复
  183. ];
  184. $data['fromName'] = $uemail['name'];
  185. $data['fromEmail'] = $uemail['email'];
  186. $config = config('app.email');
  187. $url = $config['host2'].'Email/saveMessage';
  188. $ret = curl_post($url,$data);
  189. if(!$ret){
  190. HelpHander::error('数据获取失败');
  191. }
  192. $ret = json_decode($ret,true);
  193. if($ret['code'] != 0){
  194. HelpHander::error($ret['message']);
  195. }
  196. HelpHander::success($ret['data']);
  197. }
  198. public function messageSetSeen(){
  199. $uemail = $this->checkEmail();
  200. $data = [
  201. 'token' => $uemail['token'],
  202. 'setAction' => input('setAction/d',0),
  203. 'uids' => input('uids','','trim'),
  204. 'folder' => input('folder','INBOX','trim') // 默认是收件箱
  205. ];
  206. $config = config('app.email');
  207. $url = $config['host2'].'Email/messageSetSeen';
  208. $ret = curl_post($url,$data);
  209. if(!$ret){
  210. HelpHander::error('数据获取失败');
  211. }
  212. $ret = json_decode($ret,true);
  213. if($ret['code'] != 0){
  214. HelpHander::error($ret['message']);
  215. }
  216. HelpHander::success([],'操作成功');
  217. }
  218. public function messageSetSeenToAll(){
  219. $uemail = $this->checkEmail();
  220. $data = [
  221. 'token' => $uemail['token'],
  222. 'setAction' => input('setAction/d',0),
  223. 'folder' => input('folder','INBOX','trim') // 默认是收件箱
  224. ];
  225. $config = config('app.email');
  226. $url = $config['host2'].'Email/messageSetSeenToAll';
  227. $ret = curl_post($url,$data);
  228. if(!$ret){
  229. HelpHander::error('数据获取失败');
  230. }
  231. $ret = json_decode($ret,true);
  232. if($ret['code'] != 0){
  233. HelpHander::error($ret['message']);
  234. }
  235. HelpHander::success([],'操作成功');
  236. }
  237. public function messageSetFlagged(){
  238. $uemail = $this->checkEmail();
  239. $data = [
  240. 'token' => $uemail['token'],
  241. 'setAction' => input('setAction/d',0),
  242. 'uids' => input('uids','','trim'),
  243. 'folder' => input('folder','INBOX','trim') // 默认是收件箱
  244. ];
  245. $config = config('app.email');
  246. $url = $config['host2'].'Email/messageSetFlagged';
  247. $ret = curl_post($url,$data);
  248. if(!$ret){
  249. HelpHander::error('数据获取失败');
  250. }
  251. $ret = json_decode($ret,true);
  252. if($ret['code'] != 0){
  253. HelpHander::error($ret['message']);
  254. }
  255. HelpHander::success([],'操作成功');
  256. }
  257. public function messageDelete(){
  258. $uemail = $this->checkEmail();
  259. $data = [
  260. 'token' => $uemail['token'],
  261. 'uids' => input('uids','','trim'),
  262. 'folder' => input('folder','INBOX','trim') // 默认是收件箱
  263. ];
  264. $config = config('app.email');
  265. $url = $config['host2'].'Email/messageDelete';
  266. $ret = curl_post($url,$data);
  267. if(!$ret){
  268. HelpHander::error('数据获取失败');
  269. }
  270. $ret = json_decode($ret,true);
  271. if($ret['code'] != 0){
  272. HelpHander::error($ret['message']);
  273. }
  274. HelpHander::success([],'操作成功');
  275. }
  276. public function messageMove(){
  277. $uemail = $this->checkEmail();
  278. $data = [
  279. 'token' => $uemail['token'],
  280. 'uids' => input('uids','','trim'),
  281. 'fromFolder' => input('fromFolder','INBOX','trim'), // 默认是收件箱
  282. 'toFolder' => input('toFolder','INBOX','trim') // 默认是收件箱
  283. ];
  284. $config = config('app.email');
  285. $url = $config['host2'].'Email/messageMove';
  286. $ret = curl_post($url,$data);
  287. if(!$ret){
  288. HelpHander::error('数据获取失败');
  289. }
  290. $ret = json_decode($ret,true);
  291. if($ret['code'] != 0){
  292. HelpHander::error($ret['message']);
  293. }
  294. HelpHander::success([],'操作成功');
  295. }
  296. public function folderClear(){
  297. $uemail = $this->checkEmail();
  298. $data = [
  299. 'token' => $uemail['token'],
  300. 'folder' => input('folder','INBOX','trim'), // 默认是收件箱
  301. ];
  302. $config = config('app.email');
  303. $url = $config['host2'].'Email/folderClear';
  304. $ret = curl_post($url,$data);
  305. if(!$ret){
  306. HelpHander::error('数据获取失败');
  307. }
  308. $ret = json_decode($ret,true);
  309. if($ret['code'] != 0){
  310. HelpHander::error($ret['message']);
  311. }
  312. HelpHander::success([],'操作成功');
  313. }
  314. //最近联系人
  315. public function recent(){
  316. $uemail = $this->checkEmail();
  317. $data = [
  318. 'token' => $uemail['token'],
  319. ];
  320. $config = config('app.email');
  321. $url = $config['host2'].'Email/recent';
  322. $ret = curl_post($url,$data);
  323. if(!$ret){
  324. HelpHander::error('数据获取失败');
  325. }
  326. $ret = json_decode($ret,true);
  327. if($ret['code'] != 0){
  328. HelpHander::error($ret['message']);
  329. }
  330. HelpHander::success($ret['data'],'操作成功');
  331. }
  332. //企业通讯录
  333. public function addressBook(){
  334. $uemail = $this->checkEmail();
  335. $data = [
  336. 'token' => $uemail['token'],
  337. ];
  338. $config = config('app.email');
  339. $url = $config['host2'].'Email/addressBook';
  340. $ret = curl_post($url,$data);
  341. if(!$ret){
  342. HelpHander::error('数据获取失败');
  343. }
  344. $ret = json_decode($ret,true);
  345. if($ret['code'] != 0){
  346. HelpHander::error($ret['message']);
  347. }
  348. HelpHander::success($ret['data'],'操作成功');
  349. }
  350. public function createEml($data,$from){
  351. $date = date('D, d M Y H:i:s');
  352. $data['date'] = $date;
  353. $altbody = strip_tags($data['body']);
  354. $messageId = md5(json_encode($data));
  355. $partend = get_rand_num().'.'.time();
  356. $part1 = '1_'.$partend;
  357. $emlstr = "Mime-Version: 1.0".PHP_EOL;
  358. $emlstr .= "Date: ".$date.' +0800'.PHP_EOL;
  359. $emlstr .= "Content-Type: multipart/mixed;".PHP_EOL;
  360. $emlstr .= " boundary=\"--=_Part_{$part1}\"".PHP_EOL;
  361. $emlstr .= "Message-ID: <{$messageId}@localhost>".PHP_EOL;
  362. $emlstr .= "X-Mailer: Postfix".PHP_EOL;
  363. if($data['book_time']){
  364. $emlstr .= "TimedSendDate: 1".PHP_EOL;
  365. }
  366. $emlstr .= 'From: "=?utf-8?B?'.base64_encode($from['name']).'?=" <'.$from['email'].'>'.PHP_EOL;
  367. $tos = json_decode($data['to'],true);
  368. $tostr = [];
  369. foreach ($tos as $k=>$v){
  370. $str = '';
  371. if($v['name']){
  372. $str .= '"=?utf-8?B?'.base64_encode($v['name']).'?=" <'.$v['email'].'>';
  373. }else{
  374. $str .= '<'.$v['email'].'>';
  375. }
  376. $tostr[] = $str;
  377. }
  378. $emlstr .= 'To: '.implode(',',$tostr).PHP_EOL;
  379. $ccs = json_decode($data['cc'],true);
  380. if($ccs){
  381. $ccstr = [];
  382. foreach ($ccs as $k=>$v){
  383. $str = '';
  384. if($v['name']){
  385. $str .= '"=?utf-8?B?'.base64_encode($v['name']).'?=" <'.$v['email'].'>';
  386. }else{
  387. $str .= '<'.$v['email'].'>';
  388. }
  389. $ccstr[] = $str;
  390. }
  391. $emlstr .= 'Cc: '.implode(',',$ccstr).PHP_EOL;
  392. }
  393. $bccs = json_decode($data['bcc'],true);
  394. if($bccs){
  395. $bccstr = [];
  396. foreach ($bccs as $k=>$v){
  397. $str = '';
  398. if($v['name']){
  399. $str .= '"=?utf-8?B?'.base64_encode($v['name']).'?=" <'.$v['email'].'>';
  400. }else{
  401. $str .= '<'.$v['email'].'>';
  402. }
  403. $bccstr[] = $str;
  404. }
  405. $emlstr .= 'Bcc: '.implode(',',$bccstr).PHP_EOL;
  406. }
  407. if($data['dnt'] == 1){
  408. $emlstr .= 'Disposition-Notification-To: '.$from['name'].PHP_EOL;
  409. $emlstr .= 'X-Confirm-Reading-To: '.$from['name'].PHP_EOL;
  410. }
  411. if($data['priority'] == 1){
  412. $emlstr .= 'X-Priority: 1 (Highest)'.PHP_EOL;
  413. }
  414. $emlstr .= 'Subject: =?utf-8?B?'.base64_encode($data['subject']).'?='.PHP_EOL;
  415. $emlstr .= PHP_EOL.'----=_Part_'.$part1.PHP_EOL;
  416. $part2 = '2_'.$partend;
  417. $emlstr .= "Content-Type: multipart/alternative;".PHP_EOL;
  418. $emlstr .= " boundary=\"--=_Part_{$part2}".PHP_EOL;
  419. $emlstr .= PHP_EOL.'----=_Part_'.$part2.PHP_EOL;
  420. $emlstr .= 'Content-Type: text/plain; charset="utf-8"'.PHP_EOL;
  421. $emlstr .= 'Content-Transfer-Encoding: quoted-printable'.PHP_EOL;
  422. $emlstr .= PHP_EOL.quoted_printable_encode($altbody).PHP_EOL;
  423. $emlstr .= PHP_EOL.'----=_Part_'.$part2.PHP_EOL;
  424. $emlstr .= 'Content-Type: text/html; charset="utf-8"'.PHP_EOL;
  425. $emlstr .= 'Content-Transfer-Encoding: quoted-printable'.PHP_EOL;
  426. $emlstr .= PHP_EOL.quoted_printable_encode($data['body']).PHP_EOL;
  427. $emlstr .= PHP_EOL.'----=_Part_'.$part2.'--'.PHP_EOL;
  428. // 附件
  429. // $emlstr .= PHP_EOL.'----=_Part_'.$part1.PHP_EOL;
  430. // $emlstr .= 'Content-Type: image/png; name="favicon.png"'.PHP_EOL;
  431. // $emlstr .= 'Content-Disposition: attachment; filename="favicon.png"'.PHP_EOL;
  432. // $emlstr .= 'Content-Transfer-Encoding: base64'.PHP_EOL;
  433. // $emlstr .= PHP_EOL.base64_encode(file_get_contents('./favicon.png')).PHP_EOL;
  434. // $emlstr .= PHP_EOL.'----=_Part_'.$part1.'--'.PHP_EOL;
  435. file_put_contents('./email/'.date('Ymd_').$messageId.'.eml', $emlstr);
  436. }
  437. // 获取邮件
  438. public function getMessageByUid(){
  439. $uemail = $this->checkEmail();
  440. $data = [
  441. 'token' => $uemail['token'],
  442. 'uid' => input('uid','','trim'),
  443. 'folder' => input('folder','INBOX','trim') // 默认是收件箱
  444. ];
  445. $config = config('app.email');
  446. $url = $config['host2'].'Email/getMessageByUid';
  447. $ret = curl_post($url,$data);
  448. if(!$ret){
  449. HelpHander::error('数据获取失败');
  450. }
  451. $ret = json_decode($ret,true);
  452. if($ret['code'] != 0){
  453. HelpHander::error($ret['message']);
  454. }
  455. HelpHander::success($ret['data']);
  456. }
  457. }