clientMass.html 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965
  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/select-tag.css">
  13. <link rel="stylesheet" href="../css/page-return.css">
  14. <!-- 必须先引入vue, 后使用vant-ui -->
  15. <script
  16. src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
  17. <!-- 引入vant的组件库-->
  18. <!-- 引入 Vant 的 JS 文件 -->
  19. <script
  20. src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
  21. <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
  22. <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
  23. <script src="../js/select-tag.js"></script>
  24. <script src="../js/page-return.js"></script>
  25. <!-- <script src="js/vconsole.min.js"></script>
  26. <script>
  27. var vConsole = new window.VConsole();
  28. </script> -->
  29. </head>
  30. <style>
  31. body {
  32. margin: 0;
  33. padding: 0;
  34. }
  35. .box {
  36. width: 100vw;
  37. min-height: 100vh;
  38. box-sizing: border-box;
  39. background: #F7F9FC;
  40. }
  41. .page5 {
  42. width: 100vw;
  43. box-sizing: border-box;
  44. padding-bottom: 39px;
  45. }
  46. .task_content {
  47. padding: 15px 10px;
  48. }
  49. .send_item {
  50. width: 100%;
  51. background: #FFFFFF;
  52. border-radius: 15px;
  53. box-sizing: border-box;
  54. padding: 15px 10px;
  55. margin-bottom: 15px;
  56. }
  57. .client_tag {
  58. font-size: 12px;
  59. line-height: 17px;
  60. }
  61. .status1 {
  62. color: #136DFB;
  63. }
  64. .status2 {
  65. color: #FFA041;
  66. }
  67. .status3 {
  68. color: #FF4141;
  69. }
  70. .mem_title {
  71. display: flex;
  72. justify-content: space-between;
  73. align-items: center;
  74. }
  75. .mem_title_left {
  76. font-size: 14px;
  77. color: #222222;
  78. line-height: 20px;
  79. padding-left: 5px;
  80. position: relative;
  81. display: flex;
  82. align-items: center;
  83. }
  84. .mem_title_left::after {
  85. position: absolute;
  86. left: 0;
  87. content: '';
  88. width: 2px;
  89. height: 12px;
  90. background: #136DFB;
  91. border-radius: 1px;
  92. }
  93. .mem_title_right {
  94. display: flex;
  95. align-items: center;
  96. font-size: 12px;
  97. color: #136DFB;
  98. line-height: 17px;
  99. }
  100. .mem_title_right img {
  101. width: 16px;
  102. height: 16px;
  103. }
  104. .mem_tag_list {
  105. display: flex;
  106. flex-wrap: wrap;
  107. align-items: center;
  108. gap: 10px;
  109. max-height: 52px;
  110. overflow: hidden;
  111. }
  112. .mem_tag {
  113. margin-top: 15px;
  114. }
  115. .mem_tag span {
  116. padding: 2px 8px;
  117. background: rgba(19, 109, 251, 0.05);
  118. border-radius: 5px;
  119. font-size: 12px;
  120. line-height: 17px;
  121. color: #136DFB;
  122. }
  123. .condition_mem_tag1 {
  124. margin-top: 10px;
  125. }
  126. .condition_mem_tag2 {
  127. margin-top: 10px;
  128. }
  129. .condition_mem_tag3 {
  130. margin-top: 18px;
  131. }
  132. .condition_mem_tag1 span {
  133. padding: 2px 8px;
  134. background: #F2F6FC;
  135. border-radius: 5px;
  136. font-size: 12px;
  137. line-height: 17px;
  138. color: #7D97BF;
  139. }
  140. .condition_mem_tag2 span {
  141. padding: 2px 8px;
  142. background: #FCF7F2;
  143. border-radius: 5px;
  144. font-size: 12px;
  145. line-height: 17px;
  146. color: #BFA17D;
  147. }
  148. .condition_mem_tag3 span {
  149. padding: 2px 8px;
  150. background: #FCF2F2;
  151. border-radius: 5px;
  152. font-size: 12px;
  153. line-height: 17px;
  154. color: #BF7D7D;
  155. }
  156. .send_centent {
  157. padding: 20px 15px;
  158. }
  159. .send_text {
  160. font-size: 14px;
  161. color: #222222;
  162. line-height: 20px;
  163. padding-bottom: 10px;
  164. }
  165. .send_contentText {
  166. font-size: 14px;
  167. line-height: 23px;
  168. color: #666666;
  169. padding-bottom: 20px;
  170. }
  171. .img_list {
  172. display: flex;
  173. flex-wrap: nowrap;
  174. overflow-x: auto;
  175. gap: 10px;
  176. padding: 10px 5px 10px;
  177. }
  178. .img_box {
  179. position: relative;
  180. width: 105px;
  181. height: 140px;
  182. }
  183. .close_imgMater {
  184. width: 24px;
  185. height: 24px;
  186. position: absolute;
  187. top: -8px;
  188. right: -8px;
  189. }
  190. .img_url {
  191. width: 105px;
  192. height: 140px;
  193. border-radius: 10px;
  194. object-fit: cover;
  195. }
  196. .video_container {
  197. position: relative;
  198. width: 105px;
  199. height: 140px;
  200. }
  201. .play_button {
  202. width: 24px;
  203. height: 24px;
  204. position: absolute;
  205. top: 50%;
  206. left: 50%;
  207. transform: translate(-50%, -50%);
  208. }
  209. .matters_item {
  210. width: 163px;
  211. height: 60px;
  212. border-radius: 10px;
  213. display: flex;
  214. align-items: center;
  215. padding: 10px;
  216. box-sizing: border-box;
  217. border: 1px solid #EFEFEF;
  218. position: relative;
  219. }
  220. .matters_item_img {
  221. width: 40px;
  222. height: 40px;
  223. margin-right: 8px;
  224. }
  225. .close_mater {
  226. width: 24px;
  227. height: 24px;
  228. position: absolute;
  229. top: -8px;
  230. right: -8px;
  231. }
  232. .matters_item_info {
  233. display: flex;
  234. flex-direction: column;
  235. font-size: 12px;
  236. color: #999999;
  237. line-height: 17px;
  238. }
  239. .matters_item_title {
  240. font-size: 12px;
  241. color: #222222;
  242. line-height: 17px;
  243. width: 96px;
  244. /* 必须设置宽度 */
  245. overflow: hidden;
  246. white-space: nowrap;
  247. text-overflow: ellipsis;
  248. padding-bottom: 4px;
  249. }
  250. .matters_list {
  251. display: flex;
  252. flex-wrap: wrap;
  253. gap: 10px;
  254. }
  255. .mem_centent {
  256. padding: 10px 15px;
  257. }
  258. .filter_list {
  259. display: flex;
  260. flex-wrap: nowrap;
  261. white-space: nowrap;
  262. width: 100%;
  263. overflow-x: auto;
  264. gap: 10px;
  265. }
  266. .filter_span {
  267. height: 25px;
  268. box-sizing: border-box;
  269. font-size: 12px;
  270. color: #999999;
  271. padding: 4px 12px;
  272. background: #FAFAFA;
  273. border-radius: 10px;
  274. }
  275. .active {
  276. height: 25px;
  277. box-sizing: border-box;
  278. font-size: 12px;
  279. color: #1677FF;
  280. background: rgba(22, 119, 255, 0.1);
  281. padding: 4px 12px;
  282. border-radius: 10px;
  283. }
  284. .send_num_data {
  285. display: flex;
  286. align-items: center;
  287. padding: 15px 5px 10px;
  288. font-size: 12px;
  289. color: #222222;
  290. line-height: 17px;
  291. }
  292. .color1 {
  293. color: #1677FF;
  294. padding-right: 20px;
  295. }
  296. .color2 {
  297. color: #FFA041;
  298. padding-right: 20px;
  299. }
  300. .color3 {
  301. color: #FF4E4E;
  302. padding-right: 20px;
  303. }
  304. .color4 {
  305. color: #7D97BF;
  306. padding-right: 20px;
  307. }
  308. .send_mem_item {
  309. height: 100px;
  310. display: flex;
  311. flex-direction: column;
  312. justify-content: space-between;
  313. padding: 15px;
  314. background: #FAFAFA;
  315. border-radius: 15px;
  316. box-sizing: border-box;
  317. margin-bottom: 10px;
  318. }
  319. .send_mem_name {
  320. font-weight: 500;
  321. font-size: 14px;
  322. color: #222222;
  323. line-height: 20px;
  324. }
  325. .send_mem_data {
  326. display: flex;
  327. align-items: center;
  328. font-size: 12px;
  329. color: #999999;
  330. line-height: 17px;
  331. }
  332. .send_mem_time {
  333. font-size: 12px;
  334. color: #999999;
  335. line-height: 17px;
  336. }
  337. .van-cell {
  338. padding: 15px 5px 0;
  339. }
  340. .matter_btn_box {
  341. padding: 20px 0 10px;
  342. }
  343. .cond_btn_box {
  344. padding-top: 15px;
  345. }
  346. .matter_btn {
  347. height: 50px;
  348. padding: 15px 0;
  349. background: rgba(19, 109, 251, 0.1);
  350. border-radius: 20px;
  351. font-weight: 500;
  352. font-size: 14px;
  353. color: #136DFB;
  354. text-align: center;
  355. box-sizing: border-box;
  356. }
  357. .send_btn_box {
  358. padding: 15px 25px 10px;
  359. }
  360. .send_btn {
  361. height: 50px;
  362. padding: 15px 0;
  363. background: #1677FF;
  364. border-radius: 20px;
  365. font-weight: 500;
  366. font-size: 14px;
  367. color: #FFFFFF;
  368. text-align: center;
  369. box-sizing: border-box;
  370. }
  371. textarea {
  372. height: 68px !important;
  373. line-height: 23px;
  374. }
  375. .van-radio__icon {
  376. width: 16px;
  377. height: 16px;
  378. }
  379. .van-radio__label {
  380. font-size: 14px;
  381. line-height: 20px;
  382. color: #222222;
  383. }
  384. .van-radio--horizontal {
  385. margin-right: 40px;
  386. }
  387. .van-radio-group {
  388. margin-top: 15px;
  389. }
  390. .check_div {
  391. width: 16px;
  392. height: 16px;
  393. border-radius: 50%;
  394. border: 1px solid #CCCCCC;
  395. box-sizing: border-box;
  396. margin-right: 8px;
  397. }
  398. .check_div_active {
  399. width: 16px;
  400. height: 16px;
  401. border-radius: 50%;
  402. border: 1px solid #136DFB;
  403. box-sizing: border-box;
  404. margin-right: 8px;
  405. }
  406. .check_div_active:after{
  407. content: "";
  408. display: block;
  409. width: 10px;
  410. height: 10px;
  411. border-radius: 50%;
  412. background: #136DFB;
  413. position: relative;
  414. top: 2px;
  415. left: 2px;
  416. }
  417. .send_item_name {
  418. font-size: 14px;
  419. line-height: 20px;
  420. color: #666666;
  421. padding-top: 20px;
  422. }
  423. .data_item {
  424. display: flex;
  425. align-items: center;
  426. justify-content: space-between;
  427. padding: 20px 20px 10px;
  428. }
  429. .data_title {
  430. font-size: 14px;
  431. color: #222222;
  432. line-height: 20px;
  433. display: -webkit-box;
  434. -webkit-line-clamp: 2;
  435. -webkit-box-orient: vertical;
  436. overflow: hidden;
  437. text-overflow: ellipsis;
  438. }
  439. .condition_box1 {
  440. padding: 15px;
  441. background: rgba(245,249,255,0.5);
  442. border-radius: 10px;
  443. border: 1px solid #E2EAFF;
  444. box-sizing: border-box;
  445. margin-bottom: 10px;
  446. }
  447. .condition_box2 {
  448. padding: 15px;
  449. background: rgba(255,252,245,0.5);
  450. border-radius: 10px;
  451. border: 1px solid #FFF5E2;
  452. box-sizing: border-box;
  453. margin-bottom: 10px;
  454. }
  455. .condition_box3 {
  456. padding: 15px;
  457. background: rgba(255,245,245,0.5);
  458. border-radius: 10px;
  459. border: 1px solid #FFE2E2;
  460. box-sizing: border-box;
  461. }
  462. .con_data {
  463. display: flex;
  464. align-items: center;
  465. }
  466. .con_data_title {
  467. font-weight: 500;
  468. font-size: 12px;
  469. color: #222222;
  470. padding-right: 24px;
  471. }
  472. .con_data_edit {
  473. font-size: 12px;
  474. color: #136DFB;
  475. padding-right: 15px;
  476. }
  477. .con_data_del {
  478. font-size: 12px;
  479. color: #FF4141;
  480. }
  481. .tag_radio {
  482. margin-top: 10px;
  483. }
  484. .tag_radio_item {
  485. margin-right: 32px;
  486. }
  487. .condition_list {
  488. margin-top: 15px;
  489. }
  490. .exc_title {
  491. padding-right: 24px;
  492. }
  493. .filter_list {
  494. height: 146px;
  495. display: flex;
  496. align-items: center;
  497. gap: 15px;
  498. }
  499. .filter_or {
  500. font-weight: 500;
  501. font-size: 16px;
  502. color: #FFA041;
  503. width: 100%;
  504. text-align: center;
  505. background: rgba(255, 160, 65, 0.05);
  506. padding: 49px 0 48px;
  507. border-radius: 15px;
  508. }
  509. .filter_exc_active {
  510. font-weight: 500;
  511. font-size: 16px;
  512. color: #FF4141;
  513. width: 100%;
  514. text-align: center;
  515. padding: 49px 0 48px;
  516. background: rgba(255, 65, 65, 0.05);
  517. border-radius: 15px;
  518. }
  519. .filter_exc {
  520. font-weight: 500;
  521. font-size: 16px;
  522. color: #999999;
  523. width: 100%;
  524. text-align: center;
  525. padding: 49px 0 48px;
  526. background: #FAFAFA;
  527. border-radius: 15px;
  528. }
  529. .dev_left {
  530. margin-left: 15px;
  531. }
  532. .dev_right {
  533. margin-right: 15px;
  534. }
  535. .page_box {
  536. padding: 15px 15px 0;
  537. height: 446px;
  538. box-sizing: border-box;
  539. }
  540. .path_list {
  541. display: flex;
  542. align-items: center;
  543. flex-wrap: nowrap;
  544. white-space: nowrap;
  545. width: 100%;
  546. overflow-x: auto;
  547. margin-bottom: 25px;
  548. height: 17px;
  549. }
  550. .path_span {
  551. font-size: 12px;
  552. color: #999999;
  553. line-height: 17px;
  554. }
  555. .path_line {
  556. font-size: 12px;
  557. color: #999999;
  558. line-height: 17px;
  559. padding: 0 10px;
  560. }
  561. .path_item:last-child {
  562. color: #222222;
  563. }
  564. .data_list {
  565. height: 404px;
  566. gap: 25px;
  567. overflow-y: auto;
  568. }
  569. .mem_item {
  570. display: flex;
  571. align-items: center;
  572. justify-content: space-between;
  573. margin-bottom: 20px;
  574. }
  575. .mem_item img {
  576. width: 40px;
  577. height: 40px;
  578. margin-right: 10px;
  579. }
  580. .mem_title {
  581. width: 224px;
  582. font-size: 14px;
  583. color: #222222;
  584. line-height: 20px;
  585. width:238px;
  586. white-space: nowrap;
  587. overflow: hidden;
  588. text-overflow: ellipsis;
  589. }
  590. .dept_item {
  591. display: flex;
  592. align-items: center;
  593. }
  594. .time_list {
  595. overflow-y: auto;
  596. padding: 10px 20px 29px;
  597. box-sizing: border-box;
  598. }
  599. .time_box {
  600. height: 50px;
  601. box-sizing: border-box;
  602. display: flex;
  603. align-items: center;
  604. justify-content: space-between;
  605. padding: 15px;
  606. border-radius: 15px;
  607. border: 1px solid #F1F1F1;
  608. }
  609. .time_box img {
  610. width: 16px;
  611. height: 16px;
  612. }
  613. .date_box {
  614. height: 210px;
  615. box-sizing: border-box;
  616. display: flex;
  617. align-items: center;
  618. justify-content: space-between;
  619. border-radius: 15px;
  620. border: 1px solid #F1F1F1;
  621. }
  622. .date_box .van-ellipsis {
  623. /* width: 100px; */
  624. width: 102px;
  625. text-align: center;
  626. font-size: 14px;
  627. color: #222222;
  628. white-space: wrap;
  629. }
  630. .time_date {
  631. display: flex;
  632. align-items: center;
  633. font-size: 14px;
  634. color: #222222;
  635. line-height: 20px;
  636. }
  637. .time_date_center {
  638. padding: 0 10px;
  639. }
  640. .date_select {
  641. display: flex;
  642. align-items: center;
  643. justify-content: space-between;
  644. margin-top: 20px;
  645. }
  646. .select_time {
  647. width: 76px;
  648. height: 37px;
  649. line-height: 37px;
  650. background: #FAFAFA;
  651. border-radius: 10px;
  652. font-size: 12px;
  653. color: #222222;
  654. text-align: center;
  655. }
  656. .select_time_ac {
  657. width: 76px;
  658. height: 37px;
  659. line-height: 37px;
  660. background: rgba(19,109,251,0.05);
  661. border-radius: 10px;
  662. border: 1px solid #136DFB;
  663. font-size: 12px;
  664. color: #136DFB;
  665. text-align: center;
  666. box-sizing: border-box;
  667. }
  668. .now_date {
  669. display: flex;
  670. align-items: center;
  671. font-weight: 500;
  672. font-size: 16px;
  673. color: #222222;
  674. padding: 12px 20px;
  675. background: #FAFAFA;
  676. border-radius: 15px;
  677. justify-content: space-between;
  678. margin-top: 20px;
  679. }
  680. </style>
  681. <body>
  682. <div id="box" class="box">
  683. <div class="page5">
  684. <van-dialog v-model="showReturn" title="提示" show-cancel-button :before-close="beforeClose" confirm-button-text="确定"
  685. cancel-button-text="取消">
  686. <div style="padding: 20px; text-align: center;">确认返回吗?</div>
  687. </van-dialog>
  688. <!-- 标签筛选组件 -->
  689. <select-tag :show-Client-Tag.sync="showClientTag" :show-Label-Filter="showLabelFilter" :label-Filter.sync="selectLabelFilter" :select-Tag-List.sync="SelectWach" @add="handleAdd"></select-tag>
  690. <!-- 选择群发时间 -->
  691. <van-popup v-model="showTime" duration="0.2" round position="bottom" :close-on-click-overlay="false"
  692. :style="{ width: '100%', height: showDateColumns ? '426px' : '266px' }">
  693. <div class="clientTag_title">
  694. <div class="close_icon"></div>
  695. <div>选择时间</div>
  696. <img class="close_icon" src="../img/qw/close_icon.png" alt="" @click="showTime = false"/>
  697. </div>
  698. <div class="time_list" :style="{ height: showDateColumns ? '306px' : '146px' }">
  699. <div class="date_box" v-if="showDateColumns">
  700. <van-picker ref = "vanPicker" :columns="dateColumns" @change="handleChangeDate" visible-item-count="4" />
  701. </div>
  702. <div class="time_box" @click="handleShowDateColumns" v-else>
  703. <div class="close_icon"></div>
  704. <div class="time_date">
  705. <span>{{nowDate[0]}}</span>
  706. <span class="time_date_center">{{nowDate[1]}}</span>
  707. <span>{{nowDate[2]}}</span>
  708. </div>
  709. <img src="../img/qw/select_icon.png" alt="" @click="showTime = false">
  710. </div>
  711. <div class="date_select">
  712. <span :class="dateIndex === 'hour' ? 'select_time_ac' : 'select_time'" @click="getTimeInfo('hour')">一小时后</span>
  713. <span :class="dateIndex === 'day' ? 'select_time_ac' : 'select_time'" @click="getTimeInfo('day')">一天后</span>
  714. <span :class="dateIndex === 'week' ? 'select_time_ac' : 'select_time'" @click="getTimeInfo('week')">一周后</span>
  715. <span :class="dateIndex === 'month' ? 'select_time_ac' : 'select_time'" @click="getTimeInfo('month')">一个月后</span>
  716. </div>
  717. </div>
  718. <div class="tag_footers">
  719. <div class="tag_re_btn" @click="showTime = false">取消</div>
  720. <div class="tag_ok_btn" @click="handleTime">保存</div>
  721. </div>
  722. </van-popup>
  723. <!-- 筛选条件(或、排除) -->
  724. <van-popup v-model="showFilter" duration="0.2" round position="bottom" :close-on-click-overlay="false"
  725. :style="{ width: '100%', height: '266px' }">
  726. <div class="clientTag_title">
  727. <div class="close_icon"></div>
  728. <div>筛选条件</div>
  729. <img class="close_icon" src="../img/qw/close_icon.png" alt="" @click="showFilter = false">
  730. </div>
  731. <div class="filter_list">
  732. <div class="dev_left" :class="filterIndex ? 'filter_or' : 'filter_exc'" @click="filterIndex = 1">或</div>
  733. <div class="dev_right" :class="(formValidate.tagReq.excludeTags.length || filterIndex) ? 'filter_exc' : 'filter_exc_active'" @click="handleExclude">排除</div>
  734. </div>
  735. <div class="tag_footers">
  736. <div class="tag_re_btn" @click="showFilter = false">取消</div>
  737. <div class="tag_ok_btn" @click="handleFilter">保存</div>
  738. </div>
  739. </van-popup>
  740. <!-- 顾问数据 -->
  741. <van-popup v-model="showMem" duration="0.2" round position="bottom" :close-on-click-overlay="false"
  742. :style="{ width: '100%', height: '566px' }">
  743. <div class="clientTag_title">
  744. <div class="close_icon"></div>
  745. <div>添加顾问</div>
  746. <img class="close_icon" src="../img/qw/close_icon.png" alt="" @click="handleCancelMem">
  747. </div>
  748. <div class="page_box">
  749. <div class="path_list">
  750. <div class="path_span">
  751. <span @click="getTreeData(0)">全部</span>
  752. <span class="path_item" v-for="(item, index) in pathList" :key="index" @click="handlePathClick(item)">
  753. <span class="path_line">/</span>{{item.text}}</span>
  754. </div>
  755. </div>
  756. <div class="data_list">
  757. <!-- 部门 -->
  758. <div class="mem_item" v-for="item in treeData" :key="item.id">
  759. <div class="dept_item" @click="handleDeptClick(item)">
  760. <img src="../img/qw/dept_icon.png" alt="" />
  761. <div class="mem_title">{{item.text}}</div>
  762. </div>
  763. </div>
  764. <!-- 成员 -->
  765. <van-checkbox-group v-model="checkedMemIds" @change="onChangeMem">
  766. <div class="mem_item" v-for="item in itemList" :key="item.memberId">
  767. <div class="dept_item">
  768. <img src="../img/qw/mem_icon.png" alt="" />
  769. <div class="mem_title">{{item.name}}</div>
  770. </div>
  771. <van-checkbox :name="item.memberId">
  772. <template #icon="props">
  773. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  774. </template>
  775. </van-checkbox>
  776. </div>
  777. </van-checkbox-group>
  778. </div>
  779. </div>
  780. <div class="tag_footer">
  781. <div class="tag_re_btn" @click="handleCancelMem">取消</div>
  782. <div class="tag_ok_btn" @click="handleMem">保存</div>
  783. </div>
  784. </van-popup>
  785. <!-- 客群包数据 -->
  786. <van-popup v-model="showClientBag" duration="0.2" round position="bottom" :close-on-click-overlay="false"
  787. :style="{ width: '100%', height: '566px' }">
  788. <div class="clientTag_title">
  789. <div class="close_icon"></div>
  790. <div>选择客群包</div>
  791. <img class="close_icon" src="../img/qw/close_icon.png" alt="" @click="showClientBag = false">
  792. </div>
  793. <div class="search_box">
  794. <van-search class="search_input" placeholder="搜索客户昵称/客户群昵称" v-model="clientBagKeyword" :clearable="false" left-icon=""
  795. @search="handleAddClientBag">
  796. <!-- 自定义右侧图标 -->
  797. <template v-slot:right-icon>
  798. <img class="search_icon" src="../img/qw/search_icon.png" alt="" @click="handleAddClientBag" />
  799. </template>
  800. </van-search>
  801. </div>
  802. <div class="tag_list">
  803. <van-checkbox-group v-model="checkedCbIds" @change="onChangeChecked">
  804. <div class="data_item" v-for="item in clientBagList" :key="item.id">
  805. <div class="data_title">{{item.name}}</div>
  806. <van-checkbox :name="item.id">
  807. <template #icon="props">
  808. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  809. </template>
  810. </van-checkbox>
  811. </div>
  812. </van-checkbox-group>
  813. </div>
  814. <div class="tag_footer">
  815. <div class="tag_re_btn" @click="showClientBag = false">取消</div>
  816. <div class="tag_ok_btn" @click="handleCb">保存</div>
  817. </div>
  818. </van-popup>
  819. <div class="task_content">
  820. <div class="send_item">
  821. <div class="mem_title_left">群发任务名称</div>
  822. <van-field v-model="formValidate.name" maxlength="20" show-word-limit placeholder="请输入群发任务名称" />
  823. </div>
  824. <div class="send_item">
  825. <div class="mem_title_left">发送顾问账号</div>
  826. <div class="mem_tag mem_tag_list">
  827. <span v-for="(item, index) in SelectWachAuthor" :key="index">{{item.name}}</span>
  828. </div>
  829. <div class="matter_btn_box">
  830. <div class="matter_btn" @click="handleAddMem">{{SelectWachAuthor.length ? '编辑' : '添加'}}顾问</div>
  831. </div>
  832. </div>
  833. <div class="send_item">
  834. <div class="mem_title_left">发送对象</div>
  835. <van-radio-group v-model="formValidate.isAll" direction="horizontal">
  836. <van-radio :name="1">
  837. 全部客户
  838. <template #icon="props">
  839. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  840. </template>
  841. </van-radio>
  842. <van-radio :name="0">
  843. 筛选客户
  844. <template #icon="props">
  845. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  846. </template>
  847. </van-radio>
  848. </van-radio-group>
  849. <div v-if="!formValidate.isAll">
  850. <div class="send_item_name">客群包</div>
  851. <div class="mem_tag mem_tag_list">
  852. <span v-for="(item, index) in SelectPackage" :key="index">{{item.name}}</span>
  853. </div>
  854. <div class="cond_btn_box">
  855. <div class="matter_btn" @click="handleAddClientBag">{{SelectPackage.length ? '编辑' : '添加'}}客群包</div>
  856. </div>
  857. <div class="send_item_name">筛选条件</div>
  858. <div class="mem_tag" :class="index > 0 ? 'condition_box2' : 'condition_box1'" v-for="(item, index) in formValidate.tagReq.tagPackageList" :key="index">
  859. <div class="mem_title">
  860. <div class="mem_title_left">{{index > 0 ? '或' : '初始条件'}}</div>
  861. <div class="mem_title_right" @click="handleCond(index)">
  862. <img src="../img/qw/con_add.png" alt="">
  863. <div>添加</div>
  864. </div>
  865. </div>
  866. <div class="condition_list" v-for="(cond, condIndex) in formValidate.tagReq.tagPackageList[index].tagCondList" :key="condIndex">
  867. <div class="con_data">
  868. <div class="con_data_title">条件{{ condIndex + 1 }}</div>
  869. <div class="con_data_edit" @click="handleSelectWach(index, condIndex, 'package')">修改</div>
  870. <div class="con_data_del"@click="handleDelCond(index, condIndex)">删除</div>
  871. </div>
  872. <van-radio-group class="tag_radio" v-model="cond.labelFilter" direction="horizontal">
  873. <van-radio :name="1" class="tag_radio_item">
  874. 标签满足其一
  875. <template #icon="props">
  876. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  877. </template>
  878. </van-radio>
  879. <van-radio :name="0">
  880. 标签同时满足
  881. <template #icon="props">
  882. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  883. </template>
  884. </van-radio>
  885. </van-radio-group>
  886. <div class="mem_tag_list" :class="index > 0 ? 'condition_mem_tag2' : 'condition_mem_tag1'">
  887. <span v-for="(tag, tagIndex) in cond.tags" :key="tagIndex">{{tag.name}}</span>
  888. </div>
  889. </div>
  890. </div>
  891. <div class="condition_box3" v-if="formValidate.tagReq.excludeTags.length">
  892. <div>
  893. <div class="con_data">
  894. <div class="mem_title_left exc_title">排除</div>
  895. <div class="con_data_edit" @click="handleExcludeTags('exclude')">修改</div>
  896. <div class="con_data_del" @click="handleDelExclude">删除</div>
  897. </div>
  898. <div class="condition_mem_tag3 mem_tag_list">
  899. <span v-for="(tag, tagIndex) in formValidate.tagReq.excludeTags" :key="tagIndex">{{tag.name}}</span>
  900. </div>
  901. </div>
  902. </div>
  903. <div class="cond_btn_box">
  904. <div class="matter_btn" @click="handleAddFilter">添加筛选条件</div>
  905. </div>
  906. </div>
  907. </div>
  908. <div class="send_item">
  909. <div class="mem_title_left">发送内容</div>
  910. <van-field v-model="formValidate.contentText" maxlength="500" show-word-limit type="textarea" placeholder="请输入要发送给客户的文本" />
  911. </div>
  912. <div class="send_item">
  913. <div class="mem_title_left">素材</div>
  914. <van-radio-group class="tag_radio" v-model="materialType" direction="horizontal">
  915. <van-radio :name="1">
  916. 素材库选择
  917. <template #icon="props">
  918. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  919. </template>
  920. </van-radio>
  921. <!-- <van-radio :name="2">
  922. 自定义上传
  923. <template #icon="props">
  924. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  925. </template>
  926. </van-radio> -->
  927. </van-radio-group>
  928. <template v-if="formValidate.ctOthers && formValidate.ctOthers.length > 0">
  929. <div class="img_list" v-if="formValidate.ctOthers[0].matterType === 1">
  930. <div class="img_box" v-for="(item, index) in formValidate.ctOthers" :key="index">
  931. <img class="img_url" :src="item.url" alt="">
  932. <img class="close_imgMater" src="../img/qw/close_img.png" alt="" @click="handleCloseMatter(item)">
  933. </div>
  934. </div>
  935. <div class="video_container" v-if="formValidate.ctOthers[0].matterType === 2">
  936. <video id="myVideo" style="width: 105px; height: 140px;"
  937. :src="formValidate.ctOthers[0].videoPath"></video>
  938. <img id="playButton" class="play_button" src="../img/qw/play_icon.png" alt="" @click="playPause">
  939. </div>
  940. <div class="matters_item" v-if="formValidate.ctOthers[0].matterType === 5">
  941. <img class="matters_item_img" src="../img/qw/link.png" alt="">
  942. <div class="matters_item_info">
  943. <div class="matters_item_title">{{formValidate.ctOthers[0].linkTitle}}</div>
  944. <div>自定义链接</div>
  945. </div>
  946. <img class="close_mater" src="../img/qw/close_mater.png" alt="" @click="handleCloseMatter(item)">
  947. </div>
  948. </template>
  949. <template v-if="formValidate.matters && formValidate.matters.length > 0">
  950. <div class="img_list" v-if="matterImgList.length > 0">
  951. <div class="img_box" v-for="(item, index) in matterImgList" :key="index">
  952. <img class="img_url" :src="item.url" alt="">
  953. <img class="close_imgMater" src="../img/qw/close_img.png" alt="" @click="handleCloseMatter(item)">
  954. </div>
  955. </div>
  956. <div class="matters_list">
  957. <div class="matters_item" v-for="(item, index) in matterOthersList" :key="index">
  958. <img class="matters_item_img" v-if="item.contentType === 0" src="../img/qw/article.png" alt="">
  959. <img class="matters_item_img" v-else-if="item.contentType === 2" src="../img/qw/form.png" alt="">
  960. <img class="matters_item_img" v-else-if="item.contentType === 3" src="../img/qw/file.png" alt="">
  961. <img class="matters_item_img" v-else src="../img/qw/link.png" alt="">
  962. <div class="matters_item_info">
  963. <div class="matters_item_title">{{item.title}}</div>
  964. <div>{{matterTypeList.find(type => type.contentType === item.contentType)?.name || '未知类型'}}</div>
  965. </div>
  966. <img class="close_mater" src="../img/qw/close_mater.png" alt="" @click="handleCloseMatter(item)">
  967. </div>
  968. </div>
  969. </template>
  970. <div class="matter_btn_box">
  971. <div class="matter_btn" @click="handleAddMatter">添加素材</div>
  972. </div>
  973. </div>
  974. <div class="send_item">
  975. <div class="mem_title_left">群发时间</div>
  976. <van-radio-group class="tag_radio" v-model="formValidate.type" direction="horizontal" @change="handleRadioType">
  977. <van-radio :name="1">
  978. 立即群发
  979. <template #icon="props">
  980. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  981. </template>
  982. </van-radio>
  983. <van-radio :name="2">
  984. 定时转发
  985. <template #icon="props">
  986. <div :class="props.checked ? 'check_div_active' : 'check_div'"></div>
  987. </template>
  988. </van-radio>
  989. </van-radio-group>
  990. <div class="now_date" v-if="showDateTime.length > 0" @click="showTime = true">
  991. <span>{{showDateTime[0]}}</span>
  992. <span>{{showDateTime[1]}}</span>
  993. <span>{{showDateTime[2]}}</span>
  994. </div>
  995. </div>
  996. <div class="send_btn_box">
  997. <div class="send_btn" @click="sendMass">一键群发</div>
  998. </div>
  999. </div>
  1000. </div>
  1001. <!-- 底部返回栏 -->
  1002. <page-return></page-return>
  1003. </div>
  1004. </body>
  1005. <script>
  1006. new Vue({
  1007. el: '#box',
  1008. data() {
  1009. return {
  1010. httpUrl: '',
  1011. bId: null,
  1012. env: '',
  1013. memberId: null,
  1014. tenancyId: null,
  1015. token: null,
  1016. userId: null,
  1017. showReturn: false,
  1018. isConfirmingBack: false, // 标记是否已确认返回
  1019. pushStateCount: 0, // 记录 pushState 的次数
  1020. initialHistoryLength: 0, // 记录初始历史记录长度
  1021. clientBagKeyword: '',
  1022. showClientBag: false,
  1023. checkedCbIds: [], // 选中的客群包id
  1024. clientBagList: [], // 客群包列表
  1025. SelectPackage: [], // 选中的客群包
  1026. showClientTag: false,
  1027. selectLabelFilter: 0,
  1028. showLabelFilter: true,
  1029. pageIndex: 0,
  1030. condIndex: 0,
  1031. tagType: 'package',
  1032. SelectWach: [],
  1033. showFilter: false,
  1034. filterIndex: 1,
  1035. materialType: 1,
  1036. formValidate: {
  1037. name: '',
  1038. contentText: '',
  1039. memberIds: [],
  1040. ctOthers: [],
  1041. matters: [],
  1042. isAll: 1,
  1043. type: 1,
  1044. tagReq: {
  1045. excludeTags: [],
  1046. packageList: [],
  1047. tagPackageList: []
  1048. }
  1049. },
  1050. matterImgList: [],
  1051. matterOthersList: [],
  1052. matterTypeList: [
  1053. { contentType: 0, name: '文章' },
  1054. { contentType: 2, name: '表单' },
  1055. { contentType: 3, name: '文件' },
  1056. { contentType: 4, name: '外部链接' },
  1057. { contentType: 15, name: '视频' },
  1058. { contentType: 17, name: '图集链接' },
  1059. ],
  1060. showMem: false,
  1061. checkedMemIds: [], // 选中的顾问id
  1062. memList: [], // 顾问列表
  1063. SelectMem: [], // 选中的顾问
  1064. treeData: [], // 总部门树数据
  1065. selectedMems: [], // 选中的所有顾问数据
  1066. itemList: [], // 当前树下的数据
  1067. pathList: [], // 当前路径
  1068. SelectWachAuthor: [], // 选好的微信成员
  1069. showTime: false,
  1070. dateIndex: 'hour',
  1071. showDateColumns: false,
  1072. dateColumns: [],
  1073. nowDate: [], // 当前选中的日期
  1074. NewDate: '', // 最终的日期
  1075. showDateTime: [], // 外面展示的日期格式
  1076. }
  1077. },
  1078. mounted() {
  1079. // 监听浏览器返回按钮
  1080. if (window.history && window.history.pushState) {
  1081. // 记录初始历史记录长度
  1082. this.initialHistoryLength = window.history.length;
  1083. history.pushState(null, null, document.URL);
  1084. this.pushStateCount = 1; // 记录初始 pushState
  1085. window.addEventListener('popstate', this.handleBack, false);
  1086. }
  1087. // 监听微信/企业微信返回按钮
  1088. if (typeof wx !== 'undefined' && wx.ready) {
  1089. wx.ready(() => {
  1090. wx.hideOptionMenu();
  1091. });
  1092. }
  1093. if (typeof ww !== 'undefined' && ww.ready) {
  1094. ww.ready(() => {
  1095. ww.hideOptionMenu();
  1096. });
  1097. }
  1098. },
  1099. beforeDestroy() {
  1100. // 移除事件监听
  1101. window.removeEventListener('popstate', this.handleBack, false);
  1102. },
  1103. created() {
  1104. this.bId = this.getQueryParam('bId')
  1105. this.env = this.getQueryParam('env')
  1106. if (!this.env || this.env === 'prod') {
  1107. this.httpUrl = 'https://wlapi.wefanbot.com'
  1108. } else {
  1109. this.httpUrl = 'http://test.wefanbot.com:18993'
  1110. }
  1111. this.memberId = this.getQueryParam('memberId')
  1112. this.token = localStorage.getItem('tokenValue')
  1113. this.tenancyId = localStorage.getItem('tenancyIdValue')
  1114. this.userId = localStorage.getItem('userId')
  1115. this.formValidate = localStorage.getItem('clientMassData') ? JSON.parse(localStorage.getItem('clientMassData')) : {
  1116. name: '',
  1117. contentText: '',
  1118. memberIds: [],
  1119. ctOthers: [],
  1120. matters: [],
  1121. isAll: 1,
  1122. type: 1,
  1123. tagReq: {
  1124. excludeTags: [],
  1125. packageList: [],
  1126. tagPackageList: []
  1127. }
  1128. }
  1129. this.SelectWachAuthor = localStorage.getItem('selectedMems') ? JSON.parse(localStorage.getItem('selectedMems')) : []
  1130. this.formValidate.matters = JSON.parse(localStorage.getItem('selectedMaters')) || []
  1131. if (this.formValidate.matters && this.formValidate.matters.length > 0) {
  1132. this.formValidate.matters.forEach(item => {
  1133. if (item.contentType === 19) {
  1134. this.matterImgList.push(item)
  1135. } else {
  1136. this.matterOthersList.push(item)
  1137. }
  1138. })
  1139. }
  1140. // 客群包
  1141. if (this.formValidate.tagReq && this.formValidate.tagReq.packageList && this.formValidate.tagReq.packageList.length > 0) {
  1142. this.SelectPackage = this.formValidate.tagReq.packageList || []
  1143. this.checkedCbIds = this.SelectPackage.map(item => item.id)
  1144. }
  1145. },
  1146. methods: {
  1147. handleBack(e) {
  1148. // 如果已经确认返回,直接返回,不显示弹框
  1149. if (this.isConfirmingBack) {
  1150. return;
  1151. }
  1152. // 如果弹框已经显示,阻止默认返回行为,但不重复显示弹框
  1153. if (this.showReturn) {
  1154. // 阻止返回,重新添加历史记录
  1155. if (window.history && window.history.pushState) {
  1156. history.pushState(null, null, document.URL);
  1157. this.pushStateCount++;
  1158. }
  1159. return;
  1160. }
  1161. // 阻止默认返回行为
  1162. if (window.history && window.history.pushState) {
  1163. history.pushState(null, null, document.URL);
  1164. this.pushStateCount++;
  1165. }
  1166. // 显示确认弹框
  1167. this.showReturn = true;
  1168. },
  1169. beforeClose(action, done) {
  1170. if (action === 'confirm') {
  1171. // 点击确定,设置确认返回标志
  1172. this.isConfirmingBack = true;
  1173. // 清理数据
  1174. localStorage.removeItem('selectedMaters');
  1175. localStorage.removeItem('selectedMems');
  1176. localStorage.removeItem('clientMassData');
  1177. // 移除事件监听,避免触发弹框
  1178. window.removeEventListener('popstate', this.handleBack, false);
  1179. // 关闭弹框
  1180. done();
  1181. // 直接跳转到 WeCom.html 页面
  1182. setTimeout(() => {
  1183. // 获取当前 URL 的查询参数,保留必要的参数
  1184. const params = new URLSearchParams(window.location.search);
  1185. const memberId = params.get('memberId') || this.memberId;
  1186. const bId = params.get('bId') || this.bId;
  1187. const env = params.get('env') || this.env;
  1188. // 构建跳转 URL
  1189. let targetUrl = 'clientMassList.html';
  1190. if (memberId || bId || env) {
  1191. const queryParams = [];
  1192. if (memberId) queryParams.push(`memberId=${memberId}`);
  1193. if (bId) queryParams.push(`bId=${bId}`);
  1194. if (env) queryParams.push(`env=${env}`);
  1195. if (queryParams.length > 0) {
  1196. targetUrl += '?' + queryParams.join('&');
  1197. }
  1198. }
  1199. window.location.href = targetUrl;
  1200. }, 150);
  1201. } else {
  1202. // 点击取消,关闭弹框,重新添加历史记录防止返回
  1203. done();
  1204. if (window.history && window.history.pushState) {
  1205. history.pushState(null, null, document.URL);
  1206. this.pushStateCount++;
  1207. }
  1208. }
  1209. },
  1210. // 打开顾问选择
  1211. handleAddMem() {
  1212. this.showMem = true
  1213. this.getTreeData(0)
  1214. },
  1215. // 获取树数据
  1216. getTreeData(id) {
  1217. this.treeData = []
  1218. if (id === 0) {
  1219. this.pathList = []
  1220. this.itemList = []
  1221. }
  1222. const headers = new Headers()
  1223. headers.append('tenancyId', this.tenancyId)
  1224. headers.append('token', this.token)
  1225. headers.append('userId', this.userId)
  1226. fetch(this.httpUrl + `/scrm/v1/wxcp-dept/m/findByParentId?parentId=${id}`, {
  1227. method: 'GET',
  1228. headers: headers
  1229. }).then(res => {
  1230. return res.json()
  1231. }).then(result => {
  1232. let { data, code, msg } = result
  1233. if (code === 1) {
  1234. this.treeData = data || []
  1235. } else {
  1236. vant.Toast.fail(msg)
  1237. }
  1238. })
  1239. },
  1240. // 点击树路径
  1241. handlePathClick(item) {
  1242. // 找到目标元素的索引
  1243. const index = this.pathList.findIndex(arr => arr.id === item.id)
  1244. // 如果找到了该元素
  1245. if (index !== -1) {
  1246. // 从该索引位置开始删除到数组末尾
  1247. this.pathList.splice(index)
  1248. this.handleDeptClick(item)
  1249. }
  1250. },
  1251. //点击部门
  1252. handleDeptClick(item) {
  1253. this.pathList.push(item)
  1254. this.treeData = []
  1255. this.itemList = []
  1256. this.getTreeData(item.id)
  1257. fetch(this.httpUrl + '/scrm/v1/wxcp-dept/m/findActiveDeptMemberListByPage', {
  1258. method: 'post',
  1259. body: JSON.stringify({
  1260. deptId: item.id,
  1261. page: 1,
  1262. pageCount: 1000,
  1263. }),
  1264. headers: {
  1265. 'Content-Type': 'application/json',
  1266. 'tenancyId': this.tenancyId,
  1267. 'token': this.token,
  1268. 'userId': this.userId,
  1269. }
  1270. }).then(res => {
  1271. return res.json()
  1272. }).then(result => {
  1273. let { data, code, msg } = result
  1274. if (code === 1) {
  1275. this.itemList = data.records || []
  1276. if (this.itemList.length > 0) {
  1277. // 回显已选择的数据
  1278. this.checkedMemIds = this.extractSameIds(this.itemList, this.selectedMems)
  1279. }
  1280. } else {
  1281. vant.Toast.fail(msg)
  1282. }
  1283. })
  1284. },
  1285. extractSameIds(itemList, selectedMems) {
  1286. const arr2Ids = new Set(selectedMems.map(item => item.memberId))
  1287. return itemList.filter(item => arr2Ids.has(item.memberId))
  1288. .map(item => item.memberId)
  1289. },
  1290. // 顾问选择改变
  1291. onChangeMem(item) {
  1292. const currentSelected = this.itemList
  1293. .filter(item => this.checkedMemIds.includes(item.memberId))
  1294. .map(item => ({
  1295. ...item,
  1296. }))
  1297. // 先删除当前页面未选中的数据
  1298. const currentPageIds = new Set(this.itemList.map(item => item.memberId))
  1299. this.selectedMems = this.selectedMems.filter(item => {
  1300. // 如果是当前页面的数据,但未选中,则删除
  1301. if (currentPageIds.has(item.memberId)) {
  1302. return this.checkedMemIds.includes(item.memberId)
  1303. }
  1304. // 如果不是当前页面的数据,保留
  1305. return true
  1306. })
  1307. // 合并当前选中的和之前选中的,基于 id 去重(当前选中的优先,使用最新的类型)
  1308. const existingIdsMap = new Map()
  1309. this.selectedMems.forEach(item => {
  1310. existingIdsMap.set(item.memberId, item)
  1311. })
  1312. // 更新或添加当前选中的数据(优先使用当前页面的数据和类型)
  1313. currentSelected.forEach(item => {
  1314. existingIdsMap.set(item.memberId, item)
  1315. })
  1316. this.selectedMems = Array.from(existingIdsMap.values())
  1317. console.log('当前选中的所有顾问数据: ', this.selectedMems)
  1318. localStorage.setItem('selectedMems', JSON.stringify(this.selectedMems))
  1319. },
  1320. // 取消顾问选择
  1321. handleCancelMem() {
  1322. this.showMem = false
  1323. this.selectedMems = this.SelectWachAuthor
  1324. localStorage.setItem('selectedMems', JSON.stringify(this.selectedMems))
  1325. },
  1326. // 确定顾问选择
  1327. handleMem() {
  1328. let selectData = this.selectedMems.map((item) => {
  1329. return {
  1330. name: item.name,
  1331. memberId: item.memberId,
  1332. }
  1333. })
  1334. const strings = selectData.map((item) => JSON.stringify(item))
  1335. this.SelectWachAuthor = [...new Set(strings)].map((item) => JSON.parse(item))
  1336. this.formValidate.memberIds = [...new Set(this.selectedMems)].map((item) => item.memberId)
  1337. this.formValidate.memberIds = Array.from(new Set(this.formValidate.memberIds))
  1338. console.log('最终顾问选择: ', this.formValidate.memberIds)
  1339. this.showMem = false
  1340. },
  1341. // 打开客群包
  1342. handleAddClientBag() {
  1343. this.showClientBag = true
  1344. fetch(this.httpUrl + '/scrm/v1/wxcp-package/m/findListByPage', {
  1345. method: 'post',
  1346. body: JSON.stringify({
  1347. keyword: this.clientBagKeyword,
  1348. page: 1,
  1349. pageCount: 1000,
  1350. }),
  1351. headers: {
  1352. 'Content-Type': 'application/json',
  1353. 'token': this.token,
  1354. 'tenancyId': this.tenancyId,
  1355. 'userId': this.userId,
  1356. }
  1357. }).then(res => {
  1358. return res.json()
  1359. }).then(result => {
  1360. let { data, code, msg } = result
  1361. if (code === 1) {
  1362. this.clientBagList = data.records || []
  1363. } else {
  1364. vant.Toast.fail(msg)
  1365. }
  1366. })
  1367. },
  1368. onChangeChecked (val) {
  1369. this.checkedCbIds = val
  1370. },
  1371. // 选择客群包
  1372. handleCb() {
  1373. this.SelectPackage = this.clientBagList.filter(item => this.checkedCbIds.includes(item.id))
  1374. this.formValidate.tagReq.packageList = this.SelectPackage.length ? this.SelectPackage.map(item => {
  1375. return {
  1376. id: item.id,
  1377. name: item.name
  1378. }
  1379. }) : []
  1380. this.showClientBag = false
  1381. },
  1382. // 添加或
  1383. handleAddFilter() {
  1384. if (this.formValidate.tagReq.tagPackageList && this.formValidate.tagReq.tagPackageList.length > 0) {
  1385. this.showFilter = true
  1386. this.filterIndex = 1
  1387. } else {
  1388. this.showClientTag = true
  1389. }
  1390. },
  1391. handleFilter () {
  1392. if (this.filterIndex === 1) {
  1393. this.formValidate.tagReq.tagPackageList.push({
  1394. tagCondList: [
  1395. {
  1396. tags: [],
  1397. labelFilter: 0
  1398. }
  1399. ]
  1400. })
  1401. } else {
  1402. // 打开排除标签选择
  1403. this.tagType = 'exclude'
  1404. this.SelectWach = this.formValidate.tagReq.excludeTags
  1405. this.showLabelFilter = false
  1406. this.showFilter = false
  1407. this.showClientTag = true
  1408. }
  1409. this.showFilter = false
  1410. },
  1411. // 点击排除标签
  1412. handleExclude() {
  1413. if (this.formValidate.tagReq.excludeTags && this.formValidate.tagReq.excludeTags.length > 0) {
  1414. this.filterIndex = 1
  1415. } else {
  1416. this.filterIndex = 0
  1417. }
  1418. },
  1419. // 添加且
  1420. handleCond(index) {
  1421. this.formValidate.tagReq.tagPackageList[index].tagCondList.push({
  1422. tags: [],
  1423. labelFilter: 0
  1424. })
  1425. },
  1426. // 修改标签选择
  1427. handleSelectWach(index, condIndex, tagType) {
  1428. this.pageIndex = index
  1429. this.condIndex = condIndex
  1430. this.tagType = tagType
  1431. this.SelectWach = this.formValidate.tagReq.tagPackageList[index].tagCondList[condIndex].tags
  1432. this.selectLabelFilter = this.formValidate.tagReq.tagPackageList[index].tagCondList[condIndex].labelFilter
  1433. this.showLabelFilter = true
  1434. this.showClientTag = true
  1435. },
  1436. // 删除条件
  1437. handleDelCond(index, condIndex) {
  1438. this.formValidate.tagReq.tagPackageList[index].tagCondList.splice(condIndex, 1)
  1439. if (this.formValidate.tagReq.tagPackageList[index].tagCondList.length === 0) {
  1440. this.formValidate.tagReq.tagPackageList.splice(index, 1)
  1441. }
  1442. },
  1443. // 修改排除
  1444. handleExcludeTags(tagType) {
  1445. this.tagType = tagType
  1446. this.SelectWach = this.formValidate.tagReq.excludeTags
  1447. this.showLabelFilter = false
  1448. this.showClientTag = true
  1449. },
  1450. // 删除排除
  1451. handleDelExclude() {
  1452. this.formValidate.tagReq.excludeTags = []
  1453. },
  1454. // 接收标签数据
  1455. handleAdd(labelFilter, tagList) {
  1456. if (this.tagType === 'exclude') {
  1457. this.formValidate.tagReq.excludeTags = tagList
  1458. } else {
  1459. this.SelectWach = tagList
  1460. this.selectLabelFilter = labelFilter
  1461. if (this.formValidate.tagReq.tagPackageList.length === 0) {
  1462. this.formValidate.tagReq.tagPackageList.push({
  1463. tagCondList: [
  1464. {
  1465. tags: tagList,
  1466. labelFilter: labelFilter
  1467. }
  1468. ]
  1469. })
  1470. } else {
  1471. this.formValidate.tagReq.tagPackageList[this.pageIndex].tagCondList[this.condIndex].tags = tagList
  1472. this.formValidate.tagReq.tagPackageList[this.pageIndex].tagCondList[this.condIndex].labelFilter = labelFilter
  1473. }
  1474. }
  1475. this.showClientTag = false
  1476. },
  1477. handleRadioType(val) {
  1478. if (val === 2) {
  1479. this.showTime = true
  1480. if (!this.nowDate.length) {
  1481. this.getTimeInfo('hour')
  1482. }
  1483. this.dateColumns = [
  1484. {
  1485. values: this.generateDateArray(),
  1486. },
  1487. {
  1488. values: this.generateHourArrayEnhanced(),
  1489. },
  1490. {
  1491. values: this.generateMinuteArrayWithLoop(),
  1492. }
  1493. ]
  1494. } else {
  1495. }
  1496. },
  1497. // 生成日期数组第一组数据
  1498. generateDateArray() {
  1499. const result = [];
  1500. const today = new Date();
  1501. // 星期映射
  1502. const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
  1503. // 前三天特殊处理
  1504. const dayNames = ['今天', '明天', '后天'];
  1505. for (let i = 0; i < 365; i++) {
  1506. const currentDate = new Date(today);
  1507. currentDate.setDate(today.getDate() + i);
  1508. const year = currentDate.getFullYear();
  1509. const month = currentDate.getMonth() + 1;
  1510. const date = currentDate.getDate();
  1511. const day = currentDate.getDay();
  1512. // 获取星期几的中文
  1513. const weekDay = `周${weekDays[day]}`;
  1514. if (i < 3) {
  1515. // 前三天用特殊格式
  1516. result.push(`${dayNames[i]} ${weekDay}`);
  1517. } else {
  1518. // 从第四天开始用正常日期格式
  1519. // 年份只显示后两位
  1520. const shortYear = year.toString().slice(-2);
  1521. result.push(`${shortYear}年${month}月${date}日 ${weekDay}`);
  1522. }
  1523. }
  1524. return result;
  1525. },
  1526. // 生成小时数组
  1527. generateHourArrayEnhanced() {
  1528. const now = new Date();
  1529. const currentHour = now.getHours(); // 获取当前小时(0-23)
  1530. const currentMinute = now.getMinutes(); // 获取当前分钟(0-59)
  1531. const result = [];
  1532. // 计算开始小时:如果当前分钟≥55,从下一小时开始
  1533. let startHour = currentHour;
  1534. if (currentMinute >= 55) {
  1535. startHour = currentHour + 1;
  1536. }
  1537. // 如果开始小时大于23,返回空数组(因为已经超过今天的小时范围)
  1538. if (startHour > 23) {
  1539. return [];
  1540. }
  1541. // 从开始小时到23时
  1542. for (let hour = startHour; hour <= 23; hour++) {
  1543. result.push(`${hour}时`);
  1544. }
  1545. return result;
  1546. },
  1547. // 生成分钟数组,从当前分钟开始,循环到59分
  1548. generateMinuteArrayWithLoop() {
  1549. const now = new Date();
  1550. const currentMinute = now.getMinutes(); // 获取当前分钟(0-59)
  1551. const startMinute = (currentMinute + 5) % 60; // 计算开始分钟,如果超过59则从0开始
  1552. const result = [];
  1553. // 从开始分钟到59分
  1554. for (let minute = startMinute; minute <= 59; minute++) {
  1555. result.push(`${minute}分`);
  1556. }
  1557. return result;
  1558. },
  1559. handleChangeDate(values, index) {
  1560. if (index[0].substring(0, 2) === '今天') {
  1561. this.dateColumns[1].values = this.generateHourArrayEnhanced()
  1562. index[1] = this.dateColumns[1].values[0]
  1563. this.dateColumns[2].values = this.generateMinuteArrayWithLoop()
  1564. index[2] = this.dateColumns[2].values[0]
  1565. } else {
  1566. this.dateColumns[1].values = Array.from({ length: 24 }, (_, i) => `${i}时`)
  1567. this.dateColumns[2].values = Array.from({ length: 60 }, (_, i) => `${i}分`)
  1568. }
  1569. this.dateIndex = ''
  1570. this.NewDate = this.convertArrayToDateTime(index)
  1571. },
  1572. // 将那4个选项转为相应的数据
  1573. getTimeInfo(interval) {
  1574. const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
  1575. const now = new Date();
  1576. const result = new Date(now);
  1577. // 时间间隔映射
  1578. const intervals = {
  1579. 'hour': () => result.setHours(result.getHours() + 1, result.getMinutes() + 5),
  1580. 'day': () => result.setDate(result.getDate() + 1),
  1581. 'week': () => result.setDate(result.getDate() + 7),
  1582. 'month': () => result.setMonth(result.getMonth() + 1)
  1583. };
  1584. // 应用时间间隔
  1585. intervals[interval]?.();
  1586. if (interval !== 'hour') result.setMinutes(result.getMinutes() + 5);
  1587. // 将秒数设置为0(确保格式化为 "00" 秒)
  1588. result.setSeconds(0, 0);
  1589. // 格式化为 "2026-01-01 00:00:00" 格式
  1590. const year = result.getFullYear();
  1591. const month = String(result.getMonth() + 1).padStart(2, '0');
  1592. const day = String(result.getDate()).padStart(2, '0');
  1593. const hours = String(result.getHours()).padStart(2, '0');
  1594. const minutes = String(result.getMinutes()).padStart(2, '0');
  1595. // 赋值给 NewDate 变量
  1596. this.NewDate = `${year}-${month}-${day} ${hours}:${minutes}:00`;
  1597. // 格式化(原有逻辑保持不变)
  1598. const dayOfWeek = weekDays[result.getDay()];
  1599. const time = `${hours}:${minutes}`;
  1600. // 日期描述
  1601. let dateDesc = '';
  1602. if (interval === 'hour') {
  1603. const isSameDay = now.toDateString() === result.toDateString();
  1604. dateDesc = isSameDay ? '今天' : '明天';
  1605. } else if (interval === 'day') {
  1606. dateDesc = '明天';
  1607. } else {
  1608. dateDesc = `${result.getMonth() + 1}月${result.getDate()}日`;
  1609. }
  1610. this.dateIndex = interval;
  1611. this.nowDate = [dateDesc, `周${dayOfWeek}`, time];
  1612. this.showDateColumns = false;
  1613. },
  1614. // 将选择的日期时间数组转换为标准格式
  1615. convertArrayToDateTime(arr) {
  1616. // 获取当前日期和时间
  1617. const now = new Date();
  1618. const currentYear = now.getFullYear();
  1619. const currentMonth = now.getMonth() + 1;
  1620. const currentDate = now.getDate();
  1621. let targetDate;
  1622. const firstPart = arr[0];
  1623. // 解析小时和分钟
  1624. const hourStr = arr[1].replace('时', '');
  1625. const minuteStr = arr[2].replace('分', '');
  1626. const hour = parseInt(hourStr);
  1627. const minute = parseInt(minuteStr);
  1628. // 判断是哪种情况
  1629. if (firstPart.includes('今天')) {
  1630. // 今天的情况
  1631. targetDate = new Date(currentYear, currentMonth - 1, currentDate, hour, minute, 0);
  1632. } else if (firstPart.includes('明天')) {
  1633. // 明天的情况
  1634. const tomorrow = new Date(now);
  1635. tomorrow.setDate(currentDate + 1);
  1636. targetDate = new Date(tomorrow.getFullYear(), tomorrow.getMonth(), tomorrow.getDate(), hour, minute, 0);
  1637. } else if (firstPart.includes('后天')) {
  1638. // 后天的情况
  1639. const dayAfterTomorrow = new Date(now);
  1640. dayAfterTomorrow.setDate(currentDate + 2);
  1641. targetDate = new Date(dayAfterTomorrow.getFullYear(), dayAfterTomorrow.getMonth(), dayAfterTomorrow.getDate(), hour, minute, 0);
  1642. } else {
  1643. // 具体日期的情况,如 '26年1月1日 周四'
  1644. // 提取日期部分(去掉星期几)
  1645. const dateStr = firstPart.split(' ')[0];
  1646. // 解析日期字符串,如 "26年1月1日"
  1647. const dateMatch = dateStr.match(/(\d+)年(\d+)月(\d+)日/);
  1648. if (dateMatch) {
  1649. let year = parseInt(dateMatch[1]);
  1650. const month = parseInt(dateMatch[2]);
  1651. const day = parseInt(dateMatch[3]);
  1652. // 处理两位数年份:假设20xx年
  1653. if (year < 100) {
  1654. year += 2000;
  1655. }
  1656. targetDate = new Date(year, month - 1, day, hour, minute, 0);
  1657. } else {
  1658. throw new Error('日期格式解析错误');
  1659. }
  1660. }
  1661. // 格式化为 "YYYY-MM-DD HH:mm:00"
  1662. const year = targetDate.getFullYear();
  1663. const month = String(targetDate.getMonth() + 1).padStart(2, '0');
  1664. const day = String(targetDate.getDate()).padStart(2, '0');
  1665. const hours = String(targetDate.getHours()).padStart(2, '0');
  1666. const minutes = String(targetDate.getMinutes()).padStart(2, '0');
  1667. return `${year}-${month}-${day} ${hours}:${minutes}:00`;
  1668. },
  1669. // 将"2026-01-01 00:00:00"这种格式的数据转为['2026年1月1日',‘周四’,‘0时0分’]这种格式
  1670. formatDateTimeToArray(dateTimeStr) {
  1671. // 解析输入的时间字符串
  1672. let date;
  1673. try {
  1674. // 处理 "YYYY-MM-DD HH:mm:ss" 格式
  1675. date = new Date(dateTimeStr.replace(' ', 'T'));
  1676. // 验证日期是否有效
  1677. if (isNaN(date.getTime())) {
  1678. throw new Error('无效的日期时间格式');
  1679. }
  1680. } catch (error) {
  1681. throw new Error(`日期解析失败: ${error.message}`);
  1682. }
  1683. // 获取年、月、日
  1684. const year = date.getFullYear();
  1685. const month = date.getMonth() + 1; // getMonth() 返回 0-11
  1686. const day = date.getDate();
  1687. // 获取小时和分钟(24小时制)
  1688. const hour = date.getHours(); // 0-23
  1689. const minute = date.getMinutes(); // 0-59
  1690. // 获取星期几
  1691. const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
  1692. const weekDay = weekDays[date.getDay()];
  1693. // 构建数组
  1694. this.showDateTime = [
  1695. `${year}年${month}月${day}日`,
  1696. weekDay,
  1697. `${hour}时${minute}分`
  1698. ];
  1699. },
  1700. handleShowDateColumns() {
  1701. this.showDateColumns = true
  1702. },
  1703. handleTime () {
  1704. this.formatDateTimeToArray(this.NewDate)
  1705. this.formValidate.sendTime = this.NewDate
  1706. this.showTime = false
  1707. },
  1708. handleCloseMatter(item) {
  1709. this.formValidate.matters = this.formValidate.matters.filter(matter => matter.id !== item.id)
  1710. this.matterOthersList = this.matterOthersList.filter(matter => matter.id !== item.id)
  1711. this.matterImgList = this.matterImgList.filter(img => img.id !== item.id)
  1712. this.deleteItemFromLocalStorage('selectedMaters', item.id)
  1713. },
  1714. // 从localStorage中删除指定id的对象项
  1715. deleteItemFromLocalStorage(storageKey, idToDelete) {
  1716. try {
  1717. // 1. 从localStorage获取数据
  1718. const storedData = localStorage.getItem(storageKey);
  1719. if (!storedData) {
  1720. console.warn(`未找到键为 "${storageKey}" 的数据`);
  1721. return false;
  1722. }
  1723. // 2. 解析JSON数据
  1724. const dataArray = JSON.parse(storedData);
  1725. if (!Array.isArray(dataArray)) {
  1726. console.error(`"${storageKey}" 中存储的不是数组`);
  1727. return false;
  1728. }
  1729. // 3. 过滤掉要删除的项
  1730. const filteredArray = dataArray.filter(item => item.id !== idToDelete);
  1731. // 4. 检查是否有删除
  1732. if (filteredArray.length === dataArray.length) {
  1733. console.warn(`未找到id为 "${idToDelete}" 的项`);
  1734. return false;
  1735. }
  1736. // 5. 将过滤后的数组存回localStorage
  1737. localStorage.setItem(storageKey, JSON.stringify(filteredArray));
  1738. console.log(`成功删除id为 "${idToDelete}" 的项`);
  1739. return true;
  1740. } catch (error) {
  1741. console.error('删除localStorage项时出错:', error);
  1742. return false;
  1743. }
  1744. },
  1745. // 播放暂停视频
  1746. playPause() {
  1747. const video = document.getElementById('myVideo')
  1748. const playButton = document.getElementById("playButton")
  1749. if (video.paused) {
  1750. video.play()
  1751. } else {
  1752. video.pause()
  1753. }
  1754. },
  1755. // 一键群发
  1756. sendMass() {
  1757. if (!this.formValidate.name) {
  1758. vant.Toast.fail('请填写任务名称')
  1759. return
  1760. }
  1761. if (this.formValidate.memberIds && this.formValidate.memberIds.length === 0) {
  1762. vant.Toast.fail('请选择成员')
  1763. return
  1764. }
  1765. if (!this.formValidate.contentText && this.formValidate.ctOthers.length === 0 && this.formValidate.matters.length === 0) {
  1766. vant.Toast.fail('请添加要发送的内容')
  1767. return
  1768. }
  1769. if (this.formValidate.matters && this.formValidate.matters.length > 9) {
  1770. vant.Toast.fail('发送素材最多9个')
  1771. return
  1772. }
  1773. if (this.formValidate.type === 2 && !this.formValidate.sendTime) {
  1774. vant.Toast.fail('请设置群发时间再提交')
  1775. return
  1776. }
  1777. if (this.formValidate.type === 1) {
  1778. this.formValidate.sendTime = ''
  1779. }
  1780. this.formValidate.tagReq.tagPackageList = this.processData(this.formValidate.tagReq.tagPackageList)
  1781. fetch(this.httpUrl + '/scrm/v1/wxcp-send/m/add2', {
  1782. method: 'post',
  1783. body: JSON.stringify({
  1784. ...this.formValidate,
  1785. }),
  1786. headers: {
  1787. 'Content-Type': 'application/json',
  1788. 'token': this.token,
  1789. 'tenancyId': this.tenancyId,
  1790. 'userId': this.userId,
  1791. }
  1792. }).then(res => {
  1793. return res.json()
  1794. }).then(result => {
  1795. let { data, code, msg } = result
  1796. if (code === 1) {
  1797. vant.Toast.success('发送成功')
  1798. localStorage.removeItem('selectedMems')
  1799. localStorage.removeItem('clientMassData')
  1800. localStorage.removeItem('selectedMaters')
  1801. this.beforeClose('confirm', () => { })
  1802. } else {
  1803. vant.Toast.fail(msg)
  1804. }
  1805. })
  1806. },
  1807. processData(data) {
  1808. return data.map(obj => {
  1809. // 过滤掉tags为空的条件项
  1810. const filteredTagCondList = obj.tagCondList.filter(cond => cond.tags.length > 0)
  1811. // 如果过滤后tagCondList不为空则保留该对象
  1812. return filteredTagCondList.length > 0
  1813. ? { ...obj, tagCondList: filteredTagCondList }
  1814. : null
  1815. }).filter(obj => obj !== null) // 剔除空对象
  1816. },
  1817. // 添加素材
  1818. handleAddMatter() {
  1819. if (this.materialType === 1) {
  1820. localStorage.setItem('clientMassData', JSON.stringify(this.formValidate))
  1821. window.location.href = `material.html?memberId=${this.memberId}&bId=${this.bId}&env=${this.env}`
  1822. } else {
  1823. // 创建一个input元素,用于选择相册中的图片
  1824. const input = document.createElement('input');
  1825. input.type = 'file';
  1826. input.accept = 'image/*';
  1827. // 添加change事件监听,当选择图片后触发回调函数
  1828. input.addEventListener('change', this.handleFileSelect);
  1829. // 触发input的点击事件,打开相册
  1830. input.click();
  1831. }
  1832. },
  1833. handleFileSelect(event) {
  1834. // 获取选择的图片
  1835. const file = event.target.files[0];
  1836. // 使用FileReader读取图片数据
  1837. const reader = new FileReader();
  1838. reader.onload = (e) => {
  1839. // 将读取的图片数据赋值给selectedImage,用于展示选择的图片
  1840. // this.selectedImage = e.target.result;
  1841. console.log('等待', e.target.result);
  1842. };
  1843. reader.readAsDataURL(file);
  1844. },
  1845. // 截取url中的数据
  1846. getQueryParam(paramName) {
  1847. // 获取当前URL的查询字符串部分
  1848. const queryString = window.location.search;
  1849. // 创建一个URLSearchParams对象
  1850. const urlParams = new URLSearchParams(queryString);
  1851. // 返回指定参数的值,如果不存在则返回null
  1852. return urlParams.get(paramName);
  1853. },
  1854. }
  1855. })
  1856. </script>
  1857. </html>