Message.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. <?php
  2. namespace addons\qingdongams\model;
  3. use addons\qingdongams\library\Wechat;
  4. use addons\qingdongams\library\WechatEnterprise;
  5. use fast\Http;
  6. use think\Exception;
  7. use think\Model;
  8. use traits\model\SoftDelete;
  9. /**
  10. *提醒消息
  11. */
  12. class Message extends Model
  13. {
  14. use SoftDelete;
  15. // 表名,不含前缀
  16. const EXAMINE_TYPE = 'examine';//审批
  17. const CONSUME_TYPE = 'consume';//费用
  18. const RECORD_TYPE = 'record';//
  19. const COMMENT_TYPE = 'comment';//评论
  20. const CONTRACT_TYPE = 'contract';//合同
  21. const PLAN_TYPE = 'plan';//回款计划
  22. const RECEIVABLES_TYPE = 'receivables';//回款
  23. const CUSTOMER_TYPE = 'customer';//客户
  24. const SIGN_TYPE = 'sign';//签到
  25. const DAILY_TYPE = 'daily';//报告
  26. const ACHIEVEMENT_TYPE = 'achievement';//业绩
  27. const EXAMINE_ADOPT_TYPE = 'examine_adopt';//审核通过
  28. const EXAMINE_REFUSE_TYPE = 'examine_refuse';//审批通过
  29. const CONTRACT_EXPIRE_TYPE = 'contract_expire';//合同到期
  30. const PLAN_EXPIRE_TYPE = 'plan_expire';//计划到期
  31. const SEAS_TYPE = 'seas';//公海
  32. const EVENT_TYPE = 'event';//日程
  33. const NOTICE_TYPE = 'notice';//公告
  34. const WORKORDER_TYPE = 'workorder';//工单
  35. const APPROVAL_TYPE = 'approval';//
  36. const BUSINESS_TYPE = 'business';//商机
  37. const CARD_TYPE = 'card';//补卡
  38. const LEAVE_TYPE = 'leave';//请假
  39. const DISCUSS_TYPE = 'discuss';//讨论
  40. const ARTICLE_TYPE = 'article';// 文章评论
  41. const PROOF_TYPE = 'proofing';//打样
  42. const QUOTE_TYPE = 'quote';//报价单
  43. const PARTS_STOCK_RELOAD_TYPE = 'parts_stock_reload';//审核
  44. const WORKREPORT_TYPE = 'work_report';//工作报告
  45. const CUSTOMER_TYPE_MESSAGE = 'customer_type';// 客户类型转变 给员工
  46. const CUSTOMER_NODEAL = 'customer_nodeal';// 到期未成交提醒 给员工
  47. const ASSIST_EVENT_TYPE = 'assist_event';//协助任务
  48. const PARTS_TYPE = 'parts';//零件
  49. const WORKORDER_RECEIVABLES = 'workorder_receivables';// 工单收款
  50. const INVOICE_TYPE = 'invoice';//零件
  51. protected $name = 'qingdongams_message';//
  52. // 开启自动写入时间戳字段
  53. protected $autoWriteTimestamp = 'int';
  54. // 定义时间戳字段名
  55. protected $createTime = 'createtime';
  56. protected $updateTime = 'updatetime';
  57. protected $deleteTime = 'deletetime';
  58. public static function setRead($relation_type, $relation_id = 0, $to_staff_id = 0)
  59. {
  60. $where = [
  61. 'relation_type' => $relation_type,
  62. 'status' => 0
  63. ];
  64. if (!empty($relation_id)) {
  65. $where['relation_id'] = $relation_id;
  66. }
  67. if (!empty($to_staff_id)) {
  68. $where['to_staff_id'] = $to_staff_id;
  69. }
  70. return Message::where($where)->update(['read_time' => time(), 'status' => 1]);
  71. }
  72. //发送人
  73. /**
  74. * 添加通知消息
  75. * @param $relation_type string 类型
  76. * @param $relation_id int 类型id
  77. * @param $to_staff_id int 接收人
  78. * @param $from_staff_id int 发送人
  79. * @return bool
  80. * @throws Exception
  81. */
  82. public static function addMessage($relation_type, $relation_id, $to_staff_id, $from_staff_id,$content='')
  83. {
  84. $addMessage = [
  85. 'to_staff_id' => $to_staff_id,
  86. 'from_staff_id' => $from_staff_id,
  87. 'send_time' => time(),
  88. 'status' => 0,
  89. ];
  90. $contents = '';
  91. switch ($relation_type) {//不同类型打开不同页面
  92. case self::EXAMINE_ADOPT_TYPE:
  93. $examine = ExamineRecord::get($relation_id);
  94. $addMessage['relation_type'] = $examine['relation_type'];
  95. $addMessage['relation_id'] = $examine['relation_id'];
  96. break;
  97. case self::EXAMINE_REFUSE_TYPE:
  98. $examine = ExamineRecord::get($relation_id);
  99. $addMessage['relation_type'] = $examine['relation_type'];
  100. $addMessage['relation_id'] = $examine['relation_id'];
  101. break;
  102. case self::COMMENT_TYPE:
  103. $addMessage['relation_type'] = Message::RECORD_TYPE;
  104. $addMessage['relation_id'] = $relation_id;
  105. break;
  106. case self::CONTRACT_EXPIRE_TYPE:
  107. $addMessage['relation_type'] = Message::CONTRACT_TYPE;
  108. $addMessage['relation_id'] = $relation_id;
  109. break;
  110. case self::PLAN_EXPIRE_TYPE:
  111. $addMessage['relation_type'] = Message::PLAN_TYPE;
  112. $addMessage['relation_id'] = $relation_id;
  113. break;
  114. case self::APPROVAL_TYPE:
  115. $addMessage['relation_type'] = Message::APPROVAL_TYPE;
  116. $addMessage['relation_id'] = $relation_id;
  117. $contents ='您有新的办公申请提醒';
  118. break;
  119. case self::CUSTOMER_TYPE:
  120. $addMessage['relation_type'] = Message::CUSTOMER_TYPE;
  121. $addMessage['relation_id'] = $relation_id;
  122. $contents =Customer::where(array('id'=>$relation_id))->value('name');
  123. break;
  124. case self::SEAS_TYPE:
  125. $addMessage['relation_type'] = Message::SEAS_TYPE;
  126. $addMessage['relation_id'] = $relation_id;
  127. $contents =Customer::where(array('id'=>$relation_id))->value('name');
  128. break;
  129. case self::BUSINESS_TYPE:
  130. $addMessage['relation_type'] = Message::BUSINESS_TYPE;
  131. $addMessage['relation_id'] = $relation_id;
  132. $contents =Business::where(array('id'=>$relation_id))->value('name');
  133. break;
  134. default:
  135. $addMessage['relation_type'] = $relation_type;
  136. $addMessage['relation_id'] = $relation_id;
  137. $contents = '您有新的消息!';
  138. }
  139. $data = NoticeTemplate::getTypeForData($relation_type);
  140. $data = NoticeTemplate::replaceTemplateContent($data,$relation_type,$relation_id);
  141. $addMessage['content'] = $content ? : ($data['first'] ?? $contents);
  142. $Model = new self;
  143. $result = $Model->save($addMessage);
  144. if (false === $result) {
  145. // 验证失败 输出错误信息
  146. throw new Exception($Model->getError());
  147. }
  148. $fromStaff = Staff::get($to_staff_id);
  149. $corpid = AdminConfig::getConfigValue('corpid', 'wechat');
  150. $corpsecret = AdminConfig::getConfigValue('corpsecret', 'wechat');
  151. //企业微信通知
  152. if($corpid && $corpsecret){
  153. $enterpriseData = NoticeTemplate::getTypeForEnterpriseData($relation_type);
  154. if($enterpriseData){
  155. $enterpriseData=NoticeTemplate::replaceTemplateContent($enterpriseData,$relation_type,$relation_id);
  156. $enterpriseMessageData = [
  157. 'title' => $enterpriseData['first'],
  158. 'description' => $enterpriseData['remark'],
  159. 'content_item'=>[]
  160. ];
  161. for ($i = 1; $i <= 5; $i++) {
  162. if ($enterpriseData['keyword' . $i]) {
  163. $enterpriseMessageData['content_item'][] = [
  164. 'key' => $enterpriseData['keyword' . $i . '_title'],
  165. 'value' => $enterpriseData['keyword' . $i],
  166. ];
  167. }
  168. }
  169. $wechatEnterprise= new WechatEnterprise();
  170. $touser=$fromStaff['touser'];
  171. if(empty($touser)){
  172. $touser=$wechatEnterprise->userid($fromStaff['mobile']);
  173. }
  174. if($touser){
  175. $result=$wechatEnterprise->sendTemplate($touser,$enterpriseMessageData);
  176. }
  177. }
  178. }
  179. $templateId = $data['template_id'] ?? '';
  180. //微信小程序通知
  181. if ($templateId) {
  182. $messageData = [
  183. 'first' => [
  184. 'value' => $data['first'],
  185. ],
  186. ];
  187. for ($i = 1; $i <= 5; $i++) {
  188. if ($data['keyword' . $i]) {
  189. $messageData['keyword' . $i] = [
  190. 'value' => $data['keyword' . $i],
  191. 'color' => $data['keyword' . $i . '_color']
  192. ];
  193. }
  194. }
  195. if ($data['remark']) {
  196. $messageData['remark'] = [
  197. 'value' => $data['remark'],
  198. 'color' => $data['remark' . '_color']
  199. ];
  200. }
  201. $result=self::sendWechat($fromStaff['openid'] ?? $fromStaff['wx_openid'], $templateId, $messageData, 'pagesB/news/theReminder');
  202. }
  203. return true;
  204. }
  205. /**
  206. * 提交给微信
  207. * @param $openid
  208. * @param $templateId
  209. * @param $data
  210. * @param $pagepath
  211. * @return bool
  212. */
  213. public static function sendWechat($openid, $templateId, $data, $pagepath)
  214. {
  215. if (empty($openid)) {
  216. return false;
  217. }
  218. $miniAppid = AdminConfig::getConfigValue('mini_appid', 'wechat');
  219. $app_id = AdminConfig::getConfigValue('appid', 'wechat');
  220. $web_url = AdminConfig::getConfigValue('web_url', 'wechat');
  221. if (!empty($miniAppid)) {//打开小程序页面
  222. $mini_wechat = new Wechat('wxMiniProgram');
  223. $token = $mini_wechat->getAccessToken();
  224. $params = [
  225. 'touser' => $openid,
  226. 'mp_template_msg' => [
  227. 'appid' => $app_id,//
  228. 'template_id' => $templateId,//模板ID
  229. 'url' => $web_url . $pagepath,//
  230. 'data' => $data,
  231. 'miniprogram' => [
  232. 'appid' => $mini_wechat->config['app_id'],
  233. 'pagepath' => $pagepath,
  234. ],
  235. ]
  236. ];
  237. $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=' . $token['access_token'];
  238. } else {
  239. $mini_wechat = new Wechat('wxOfficialAccount');
  240. $token = $mini_wechat->getAccessToken();
  241. $params = [
  242. 'touser' => $openid,
  243. 'template_id' => $templateId,
  244. 'url' => $web_url . $pagepath,
  245. 'data' => $data
  246. ];
  247. $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $token['access_token'];
  248. }
  249. $json = json_encode($params, JSON_UNESCAPED_UNICODE);
  250. $result = Http::post($url, $json);
  251. $arr_result = json_decode($result, true);
  252. //添加日志
  253. PushReload::create([
  254. 'openid' => $openid,
  255. 'template_id' => $templateId,
  256. 'data' => json_encode($data, JSON_UNESCAPED_UNICODE),
  257. 'pagepath' => $pagepath,
  258. 'errcode' => $arr_result['errcode'],
  259. 'result' => $result
  260. ]);
  261. if ($arr_result['errcode'] === 0) {
  262. return true;
  263. }
  264. return false;
  265. }
  266. public function getSendTimeAttr($value)
  267. {
  268. return date('Y-m-d H:i:s', $value);
  269. }
  270. public function fromStaff()
  271. {
  272. return $this->hasOne(Staff::class, 'id', 'from_staff_id')->field('id,name');
  273. }
  274. public function examine()
  275. {
  276. return $this->hasOne(ExamineRecord::class, 'id', 'relation_id')->field('id,relation_type,relation_id');
  277. }
  278. //消息类型
  279. public static function messageType($relation_type='',$relation_id=''){
  280. switch($relation_type){
  281. case self::CONTRACT_TYPE:
  282. $relation_name = '合同';
  283. if($relation_id){
  284. $relation_name = Contract::where(['id'=>$relation_id])->value('name');
  285. }
  286. break;
  287. case self::WORKORDER_RECEIVABLES:
  288. $relation_name = '上门维修';
  289. if($relation_id){
  290. $relation_name = Workorder::where(['id'=>$relation_id])->value('title');
  291. }
  292. break;
  293. case self::ASSIST_EVENT_TYPE:
  294. $relation_name = '任务协作';
  295. break;
  296. case self::DAILY_TYPE:
  297. $relation_name = '工作报告';
  298. break;
  299. case self::PARTS_STOCK_RELOAD_TYPE:
  300. $relation_name = '传阅信息';
  301. break;
  302. case self::CUSTOMER_TYPE:
  303. $relation_name = '客户';
  304. if($relation_id){
  305. $relation_name = Customer::where(['id'=>$relation_id])->value('name');
  306. }
  307. break;
  308. case self::RECORD_TYPE:
  309. $relation_name = '跟进记录';
  310. break;
  311. case self::SIGN_TYPE:
  312. $relation_name = '工作动态';
  313. break;
  314. case self::WORKORDER_TYPE:
  315. $relation_name = '工单';
  316. if($relation_id){
  317. $relation_name = Workorder::where(['id'=>$relation_id])->value('title');
  318. }
  319. break;
  320. case self::EXAMINE_TYPE:
  321. $relation_name = '审批';
  322. break;
  323. case self::CONSUME_TYPE:
  324. $relation_name = '费用';
  325. break;
  326. case self::COMMENT_TYPE:
  327. $relation_name = '评论';
  328. break;
  329. case self::PLAN_TYPE:
  330. $relation_name = '回款计划';
  331. break;
  332. case self::RECEIVABLES_TYPE:
  333. $relation_name = '回款';
  334. break;
  335. case self::ACHIEVEMENT_TYPE:
  336. $relation_name = '业绩';
  337. break;
  338. case self::EXAMINE_ADOPT_TYPE:
  339. $relation_name = '审批通过';
  340. break;
  341. case self::EXAMINE_REFUSE_TYPE:
  342. $relation_name = '审批拒绝';
  343. break;
  344. case self::CONTRACT_EXPIRE_TYPE:
  345. $relation_name = '合同到期';
  346. break;
  347. case self::PLAN_EXPIRE_TYPE:
  348. $relation_name = '计划周期';
  349. break;
  350. case self::SEAS_TYPE:
  351. $relation_name = '公海';
  352. if($relation_id){
  353. $relation_name = Customer::where(['id'=>$relation_id])->value('name');
  354. }
  355. break;
  356. case self::EVENT_TYPE:
  357. $relation_name = '日程';
  358. if($relation_id){
  359. $relation_name = Event::where(['id'=>$relation_id])->value('title');
  360. }
  361. break;
  362. case self::NOTICE_TYPE:
  363. $relation_name = '公告';
  364. if($relation_id){
  365. $relation_name = Notice::where(['id'=>$relation_id])->value('name');
  366. }
  367. break;
  368. case self::APPROVAL_TYPE:
  369. $relation_name = '办公';
  370. break;
  371. case self::BUSINESS_TYPE:
  372. $relation_name = '商机';
  373. if($relation_id){
  374. $relation_name = Business::where(['id'=>$relation_id])->value('name');
  375. }
  376. break;
  377. case self::CARD_TYPE:
  378. $relation_name = '补卡';
  379. break;
  380. case self::LEAVE_TYPE:
  381. $relation_name = '请假';
  382. break;
  383. case self::DISCUSS_TYPE:
  384. $relation_name = '讨论';
  385. break;
  386. case self::ARTICLE_TYPE:
  387. $relation_name = '文章评论';
  388. break;
  389. case self::PROOF_TYPE:
  390. $relation_name = '打样';
  391. break;
  392. case self::QUOTE_TYPE:
  393. $relation_name = '报价';
  394. break;
  395. case self::WORKREPORT_TYPE:
  396. $relation_name = '工作报告';
  397. break;
  398. case self::CUSTOMER_NODEAL:
  399. $relation_name = '到期提醒';
  400. break;
  401. case self::PARTS_TYPE:
  402. $relation_name = '零件';
  403. break;
  404. default:
  405. $relation_name = '消息';
  406. break;
  407. }
  408. return $relation_name;
  409. }
  410. }