toDoTask.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport"
  7. content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />
  8. <title>待办任务</title>
  9. <!-- 引入样式文件 -->
  10. <link rel="stylesheet"
  11. href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
  12. <link rel="stylesheet" href="../css/page-return.css">
  13. <!-- 必须先引入vue, 后使用vant-ui -->
  14. <script
  15. src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
  16. <!-- 引入vant的组件库-->
  17. <!-- 引入 Vant 的 JS 文件 -->
  18. <script
  19. src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
  20. <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
  21. <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
  22. <script src="../js/page-return.js"></script>
  23. <script src="../js/vconsole.min.js"></script>
  24. <script>
  25. var vConsole = new window.VConsole();
  26. </script>
  27. </head>
  28. <style>
  29. body {
  30. margin: 0;
  31. padding: 0;
  32. }
  33. .box {
  34. width: 100vw;
  35. height: 100vh;
  36. box-sizing: border-box;
  37. background: #F7F9FC;
  38. }
  39. .page5 {
  40. width: 100vw;
  41. box-sizing: border-box;
  42. padding: 15px;
  43. padding-bottom: 39px;
  44. }
  45. .task_list {
  46. }
  47. .task_item {
  48. width: 100%;
  49. background: linear-gradient( 180deg, rgba(255,255,255,0.8) 0%, #FFFFFF 100%);
  50. border-radius: 15px ;
  51. border: 1px solid #FFFFFF;
  52. box-sizing: border-box;
  53. margin-bottom: 15px;
  54. }
  55. .task_item:last-child {
  56. margin-bottom: 0;
  57. }
  58. .task_item_title {
  59. display: flex;
  60. align-items: center;
  61. padding: 15px 15px 0;
  62. position: relative;
  63. }
  64. .created_time {
  65. font-size: 12px;
  66. color: #999999;
  67. line-height: 17px;
  68. position: absolute;
  69. top: 10px;
  70. right: 10px;
  71. }
  72. .task_item_title img {
  73. width: 48px;
  74. height: 48px;
  75. border-radius: 8px;
  76. margin-right: 10px;
  77. }
  78. .task_item_text {
  79. font-weight: 500;
  80. font-size: 14px;
  81. color: #222222;
  82. display: flex;
  83. flex-direction: column;
  84. gap: 9px;
  85. }
  86. .client_tag {
  87. display: flex;
  88. align-items: center;
  89. gap: 8px;
  90. height: 21px;
  91. }
  92. .client_tag span {
  93. height: 21px;
  94. font-size: 12px;
  95. color: #FF4141;
  96. line-height: 17px;
  97. border-radius: 5px;
  98. padding: 2px 8px;
  99. background: rgba(255, 65, 65, 0.05);
  100. box-sizing: border-box;
  101. }
  102. .task_item_line {
  103. width: 100%;
  104. height: 1px;
  105. margin: 14px 0 10px;
  106. background: linear-gradient( 180deg, rgba(217,219,227,0) 0%, #D9DBE3 49%, rgba(217,219,227,0) 100%);
  107. }
  108. .task_item_des {
  109. display: flex;
  110. align-items: flex-start;
  111. padding: 0 15px 20px;
  112. }
  113. .task_des_title {
  114. font-size: 12px;
  115. color: #222222;
  116. line-height: 17px;
  117. white-space: nowrap;
  118. }
  119. .task_des {
  120. font-size: 12px;
  121. color: #999999;
  122. line-height: 18px;
  123. display: -webkit-box;
  124. -webkit-line-clamp: 2;
  125. -webkit-box-orient: vertical;
  126. overflow: hidden;
  127. text-overflow: ellipsis;
  128. }
  129. .notask {
  130. display: flex;
  131. flex-direction: column;
  132. align-items: center;
  133. padding-top: 198px;
  134. }
  135. .notask img {
  136. width: 102px;
  137. height: 90px;
  138. }
  139. .notask_text {
  140. font-size: 14px;
  141. color: #CCCCCC;
  142. line-height: 20px;
  143. padding-top: 20px;
  144. }
  145. .task_btn_box {
  146. padding: 0 20px 15px;
  147. }
  148. .task_btn {
  149. width: 100%;
  150. height: 50px;
  151. color: #136DFB;
  152. border-radius: 20px;
  153. font-weight: 500;
  154. font-size: 14px;
  155. background: rgba(22, 119, 255, 0.1);
  156. line-height: 50px;
  157. text-align: center;
  158. }
  159. .task_btn_read {
  160. width: 100%;
  161. height: 50px;
  162. border-radius: 20px;
  163. font-weight: 500;
  164. font-size: 14px;
  165. color: #7D97BF;
  166. background: rgba(125, 151, 191, 0.1);
  167. line-height: 50px;
  168. text-align: center;
  169. }
  170. </style>
  171. <body>
  172. <div id="box" class="box">
  173. <div class="page5">
  174. <div class="task_list" v-if="taskList.length > 0">
  175. <div class="task_item" v-for="item in taskList" :key="item.id">
  176. <div class="task_item_title">
  177. <img :src="item.clientAvatar ? item.clientAvatar : '../img/qw/mem_icon.png'" alt="">
  178. <div class="task_item_text">
  179. <div>{{ item.clientName }}</div>
  180. <div class="client_tag">
  181. <span v-for="(tag, tagIndex) in item.businessTags" :key="tagIndex">{{ tag }}</span>
  182. </div>
  183. </div>
  184. <div class="created_time">{{ item.createdTime }}</div>
  185. </div>
  186. <div class="task_item_line"></div>
  187. <div class="task_item_des">
  188. <div class="task_des_title">任务描述:</div>
  189. <div class="task_des" v-if="taskType === 'CLIENT_LOG'" v-html="item.taskDesc"></div>
  190. <div class="task_des" v-else>{{item.taskDesc}}</div>
  191. </div>
  192. <div class="task_btn_box" @click="handleTaskDetail(item)">
  193. <div :class="item.isRead ? 'task_btn_read' : 'task_btn'" v-if="taskType === 'MONITORED_MESSAGE'">{{item.isRead ? '已读' : '去回复'}}</div>
  194. <div :class="item.isRead ? 'task_btn_read' : 'task_btn'" v-else>{{item.isRead ? '已读' : '查看详情'}}</div>
  195. </div>
  196. </div>
  197. </div>
  198. <div class="notask" v-else>
  199. <img src="../img/qw/no_task.png" alt="">
  200. <div class="notask_text">暂无待办任务</div>
  201. </div>
  202. </div>
  203. <!-- 底部返回栏 -->
  204. <page-return></page-return>
  205. </div>
  206. </body>
  207. <script>
  208. new Vue({
  209. el: '#box',
  210. data() {
  211. return {
  212. httpUrl: '',
  213. bId: null,
  214. env: '',
  215. memberId: null,
  216. taskType: null,
  217. taskList: [],
  218. }
  219. },
  220. created() {
  221. this.bId = this.getQueryParam('bId')
  222. this.env = this.getQueryParam('env')
  223. if (!this.env || this.env === 'prod') {
  224. this.httpUrl = 'https://wlapi.wefanbot.com'
  225. } else {
  226. this.httpUrl = 'http://test.wefanbot.com:18993'
  227. }
  228. if (this.getQueryParam('memberId')) {
  229. this.memberId = this.getQueryParam('memberId')
  230. this.taskType = this.getQueryParam('type')
  231. this.getTaskList()
  232. }
  233. this.getQyWxSign()
  234. },
  235. methods: {
  236. getTaskList() {
  237. fetch(this.httpUrl + `/scrm/v1/wxcp-member-todo-task/p/page?memberId=${this.memberId}&taskType=${this.taskType}&page=1&pageCount=1000`)
  238. .then(res => {
  239. return res.json()
  240. }).then(result => {
  241. let { data, code, msg } = result
  242. if (code === 1) {
  243. this.taskList = data.records || []
  244. } else {
  245. vant.Toast.fail(msg)
  246. }
  247. })
  248. },
  249. handleTaskDetail(item) {
  250. if (this.taskType === 'MONITORED_MESSAGE') {
  251. if (!item.clientExternalUserId) {
  252. vant.Toast.fail('无效')
  253. return
  254. }
  255. wx.openEnterpriseChat({
  256. externalUserIds: item.clientExternalUserId, // 参与会话的外部联系人列表,格式为userId1;userId2;…,用分号隔开。
  257. groupName: "", // 会话名称。单聊时该参数传入空字符串""即可。
  258. chatId: "",
  259. success: function (res) {
  260. var chatId = res.chatId; //返回当前群聊ID,仅当使用agentConfig注入该接口权限时才返回chatId
  261. // 回调
  262. console.log('成功', res);
  263. },
  264. fail: function (res) {
  265. // 回调
  266. if (res.errMsg.indexOf('function not exist') > -1) {
  267. alert('版本过低请升级');
  268. }
  269. console.log('失败', res);
  270. },
  271. complete: function (res) {
  272. // 回调
  273. console.log('完成', res);
  274. }
  275. });
  276. } else if (this.taskType === 'CLIENT_SOP') {
  277. window.location.href = `taskDetail.html?taskId=${item.businessId}&type=${item.type}&env=${this.env}&bId=${this.bId}`
  278. } else {
  279. window.location.href = `taskDetail.html?taskId=${item.todoTaskId}&type=${item.type}&env=${this.env}&bId=${this.bId}`
  280. }
  281. },
  282. getQyWxSign() {
  283. fetch(this.httpUrl + '/scrm/v1/wxcp-corp/p/getAgentConfig', {
  284. method: 'post',
  285. body: JSON.stringify({
  286. bid: this.bId,
  287. url: window.location.href,
  288. }),
  289. headers: {
  290. 'Content-Type': 'application/json'
  291. }
  292. }).then(res => {
  293. return res.json()
  294. }).then(result => {
  295. let { data, code, msg } = result
  296. if (code === 1) {
  297. wx.config({
  298. beta: true,
  299. debug: false,
  300. appId: data.corpid, // 必填,企业号的唯一标识,此处填写企业号corpid
  301. timestamp: data.timestamp, // 必填,生成签名的时间戳
  302. nonceStr: data.nonceStr, // 必填,生成签名的随机串
  303. signature: data.agentSignature, // 必填,签名,见附录1
  304. jsApiList: ['checkJsApi', 'openEnterpriseChat'] // 必填,需要使用的JS接口列表
  305. })
  306. wx.agentConfig({
  307. corpid: data.corpid,
  308. agentid: data.agentId,
  309. timestamp: data.timestamp, // 必填,生成签名的时间戳
  310. nonceStr: data.nonceStr, // 必填,生成签名的随机串
  311. signature: data.agentSignature, // 必填,签名,见附录1
  312. jsApiList: ['openEnterpriseChat'], // 必填,需要使用的JS接口列表
  313. success: function (res) {
  314. // 回调
  315. console.log('agentConfig成功', res);
  316. },
  317. fail: function (res) {
  318. if (res.errMsg.indexOf('function not exist') > -1) {
  319. alert('版本过低请升级');
  320. }
  321. },
  322. complete: function (res) {
  323. // 回调
  324. console.log('complete', res);
  325. }
  326. });
  327. } else {
  328. vant.Toast.fail(msg)
  329. }
  330. })
  331. },
  332. // 截取url中的数据
  333. getQueryParam(paramName) {
  334. // 获取当前URL的查询字符串部分
  335. const queryString = window.location.search;
  336. // 创建一个URLSearchParams对象
  337. const urlParams = new URLSearchParams(queryString);
  338. // 返回指定参数的值,如果不存在则返回null
  339. return urlParams.get(paramName);
  340. },
  341. }
  342. })
  343. </script>
  344. </html>