clientMassList.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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. min-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. .client_top {
  46. width: 100%;
  47. height: 70px;
  48. position: absolute;
  49. top: 0;
  50. left: 0;
  51. z-index: 1;
  52. background: #FFFFFF;
  53. }
  54. .client_top_box {
  55. padding: 15px 15px 0px;
  56. }
  57. .search_icon {
  58. width: 24px;
  59. height: 24px;
  60. }
  61. .search_input {
  62. padding: 0;
  63. }
  64. .search_input .van-search__content {
  65. padding: 0;
  66. border-radius: 19px;
  67. }
  68. .search_input .van-cell {
  69. padding: 0;
  70. }
  71. .search_input .van-field__body {
  72. display: flex;
  73. align-items: center;
  74. position: relative;
  75. }
  76. .search_input .van-field__body input{
  77. border: none;
  78. width: 100%;
  79. height: 40px;
  80. background: #FAFAFA;
  81. padding: 10px 36px 10px 15px;
  82. border-radius: 19px;
  83. }
  84. .search_input .van-field__body input:focus {
  85. outline: none;
  86. }
  87. .search_input .van-field__body .van-field__right-icon{
  88. position: absolute;
  89. right: 12px;
  90. }
  91. .task_list {
  92. width: 100%;
  93. height: calc(100vh - 109px);
  94. position: absolute;
  95. top: 70px;
  96. left: 0;
  97. z-index: 1;
  98. background: #F7F9FC;
  99. overflow: auto;
  100. padding-bottom: 60px;
  101. box-sizing: border-box;
  102. }
  103. .task_content {
  104. padding: 15px;
  105. }
  106. .task_item {
  107. width: 100%;
  108. background: #FFFFFF;
  109. border-radius: 15px;
  110. border: 1px solid #FFFFFF;
  111. box-sizing: border-box;
  112. margin-bottom: 10px;
  113. padding: 15px;
  114. }
  115. .task_item:last-child {
  116. margin-bottom: 0;
  117. }
  118. .task_item_title {
  119. display: flex;
  120. justify-content: space-between;
  121. font-weight: 500;
  122. font-size: 16px;
  123. color: #222222;
  124. line-height: 20px;
  125. }
  126. .task_item_name {
  127. width: 160px;
  128. /* 必须设置宽度 */
  129. overflow: hidden;
  130. white-space: nowrap;
  131. text-overflow: ellipsis;
  132. }
  133. .client_tag {
  134. font-size: 12px;
  135. line-height: 17px;
  136. }
  137. .task_item_time {
  138. font-size: 12px;
  139. color: #999999;
  140. line-height: 17px;
  141. padding-top: 8px;
  142. }
  143. .notask {
  144. display: flex;
  145. flex-direction: column;
  146. align-items: center;
  147. padding-top: 198px;
  148. }
  149. .notask img {
  150. width: 102px;
  151. height: 90px;
  152. }
  153. .notask_text {
  154. font-size: 14px;
  155. color: #CCCCCC;
  156. line-height: 20px;
  157. padding-top: 20px;
  158. }
  159. .send_foot {
  160. position: absolute;
  161. bottom: 39px;
  162. left: 0;
  163. width: 100%;
  164. z-index: 2;
  165. }
  166. .send_btn {
  167. font-weight: 500;
  168. font-size: 14px;
  169. color: #FFFFFF;
  170. line-height: 20px;
  171. padding: 15px 0;
  172. border-radius: 20px;
  173. background: #1677FF;
  174. margin: 0 35px;
  175. text-align: center;
  176. }
  177. .status1 {
  178. color: #136DFB;
  179. }
  180. .status2 {
  181. color: #FFA041;
  182. }
  183. .status3 {
  184. color: #FF4141;
  185. }
  186. </style>
  187. <body>
  188. <div id="box" class="box">
  189. <div class="page5">
  190. <div v-if="tableData.length">
  191. <div class="client_top">
  192. <div class="client_top_box">
  193. <van-search class="search_input" placeholder="搜索客户昵称/客户群昵称" v-model="keyword" :clearable="false" left-icon="" @search="initData">
  194. <!-- 自定义右侧图标 -->
  195. <template v-slot:right-icon>
  196. <img class="search_icon" src="../img/qw/search_icon.png" alt="" @click="initData" />
  197. </template>
  198. </van-search>
  199. </div>
  200. </div>
  201. <div class="task_list">
  202. <div class="task_content">
  203. <div class="task_item" v-for="item in tableData" :key="item.id" @click="handleClientMassDetail(item)">
  204. <div class="task_item_title">
  205. <div class="task_item_name">{{item.name}}</div>
  206. <div v-if="item.isNotify === -2" class="client_tag status3">无符合条件客户</div>
  207. <div v-else-if="item.isNotify === -1" class="client_tag status3">创建失败</div>
  208. <div v-else-if="item.isNotify === 0" class="client_tag status2">待通知</div>
  209. <div v-else-if="item.isNotify === 1" class="client_tag status1">已通知</div>
  210. <div v-else-if="item.isNotify === 3" class="client_tag status2">创建中</div>
  211. </div>
  212. <div class="task_item_time">创建时间:{{item.createdTime}}</div>
  213. </div>
  214. </div>
  215. </div>
  216. <div class="send_foot">
  217. <div class="send_btn" @click="handleClientMass">创建客户群发</div>
  218. </div>
  219. </div>
  220. <div class="notask" v-else>
  221. <img src="../img/qw/no_task.png" alt="">
  222. <div class="notask_text">暂无数据</div>
  223. </div>
  224. </div>
  225. <!-- 底部返回栏 -->
  226. <page-return></page-return>
  227. </div>
  228. </body>
  229. <script>
  230. new Vue({
  231. el: '#box',
  232. data() {
  233. return {
  234. httpUrl: '',
  235. bId: null,
  236. env: '',
  237. token: null,
  238. tenancyId: null,
  239. userId: null,
  240. memberId: null,
  241. keyword: '',
  242. tableData: [],
  243. }
  244. },
  245. created() {
  246. this.bId = this.getQueryParam('bId')
  247. this.env = this.getQueryParam('env')
  248. this.memberId = this.getQueryParam('memberId')
  249. if (!this.env || this.env === 'prod') {
  250. this.httpUrl = 'https://wlapi.wefanbot.com'
  251. } else {
  252. this.httpUrl = 'http://test.wefanbot.com:18993'
  253. }
  254. this.token = localStorage.getItem('tokenValue')
  255. this.tenancyId = localStorage.getItem('tenancyIdValue')
  256. this.userId = localStorage.getItem('userId')
  257. this.initData()
  258. },
  259. methods: {
  260. initData() {
  261. const headers = new Headers()
  262. headers.append('token', this.token)
  263. headers.append('tenancyId', this.tenancyId)
  264. headers.append('userId', this.userId)
  265. fetch(this.httpUrl + '/scrm/v1/wxcp-send/m/findListByPage', {
  266. method: 'post',
  267. body: JSON.stringify({
  268. keyword: this.keyword,
  269. page: 1,
  270. pageCount: 1000,
  271. }),
  272. headers: {
  273. 'Content-Type': 'application/json',
  274. 'token': this.token,
  275. 'tenancyId': this.tenancyId,
  276. 'userId': this.userId,
  277. }
  278. }).then(res => {
  279. return res.json()
  280. }).then(result => {
  281. let { data, code, msg } = result
  282. if (code === 1) {
  283. this.tableData = data.records || []
  284. this.tableData.forEach(item => {
  285. item.createdTime = this.timeFormat(item.createdTime)
  286. })
  287. } else {
  288. vant.Toast.fail(msg)
  289. }
  290. })
  291. },
  292. onSearch() {
  293. this.initData()
  294. },
  295. handleClientMassDetail(item) {
  296. window.location.href = `clientMassDetail.html?bId=${this.bId}&env=${this.env}&id=${item.id}`
  297. },
  298. handleClientMass() {
  299. window.location.href = `clientMass.html?bId=${this.bId}&env=${this.env}&memberId=${this.memberId}`
  300. },
  301. timeFormat(time, format = 'yyyy-MM-dd hh:mm:ss') {
  302. if (time === undefined || time === '' || time === null) {
  303. return '/';
  304. }
  305. const date = new Date(time);
  306. const o = {
  307. 'M+': date.getMonth() + 1, // 月份
  308. 'd+': date.getDate(), // 日
  309. 'h+': date.getHours(), // 小时
  310. 'm+': date.getMinutes(), // 分钟
  311. 's+': date.getSeconds(), // 秒
  312. 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
  313. 'S': date.getMilliseconds() // 毫秒
  314. };
  315. // 处理年份
  316. if (/(y+)/.test(format)) {
  317. format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  318. }
  319. // 处理日期和时间部分
  320. for (let k in o) {
  321. if (new RegExp('(' + k + ')').test(format)) {
  322. let value = o[k];
  323. let padding = RegExp.$1.length === 1 ? '' : '00'; // 根据格式字符串中的长度决定是否补零
  324. format = format.replace(RegExp.$1, ('' + value).padStart(padding.length + value.toString().length - value.toString().length, '0'));
  325. }
  326. }
  327. // 如果格式只包含时间部分,移除日期部分可能的占位符
  328. if (!/(M+|d+)/.test(format)) {
  329. // 移除任何可能存在的日期占位符(如:'yyyy-MM-dd ')
  330. format = format.replace(/(\s*-\s*){2}/g, ''); // 移除两个'-'之间的任何内容
  331. format = format.replace(/^\s*yyyy-\s*/, ''); // 移除开头的'yyyy-'
  332. }
  333. // 如果格式只包含日期部分,移除时间部分可能的占位符
  334. if (!/(h+|m+|s+)/.test(format)) {
  335. // 移除任何可能存在的时间占位符(如:' hh:mm:ss')
  336. format = format.replace(/(\s*:\s*){2}/g, ''); // 移除两个':'之间的任何内容
  337. format = format.replace(/\s*hh:\s*$/, ''); // 移除结尾的' hh:'
  338. }
  339. return format;
  340. },
  341. // 截取url中的数据
  342. getQueryParam(paramName) {
  343. // 获取当前URL的查询字符串部分
  344. const queryString = window.location.search;
  345. // 创建一个URLSearchParams对象
  346. const urlParams = new URLSearchParams(queryString);
  347. // 返回指定参数的值,如果不存在则返回null
  348. return urlParams.get(paramName);
  349. },
  350. }
  351. })
  352. </script>
  353. </html>