index.vue 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  1. <template>
  2. <div >
  3. <div style="padding: 10px">
  4. <div style="border-bottom: 1px solid #e6e6e6;background-color: white; display: flex;justify-content: left;padding-top: 20px;">
  5. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
  6. <el-form-item label="企微公司" prop="corpId">
  7. <el-select v-model="queryParams.corpId" placeholder="企微账号" size="small" @change="updateCorpId()">
  8. <el-option
  9. v-for="dict in myQwCompanyList"
  10. :key="dict.dictValue"
  11. :label="dict.dictLabel"
  12. :value="dict.dictValue"
  13. />
  14. </el-select>
  15. </el-form-item>
  16. <el-form-item label="名称" prop="name">
  17. <el-input
  18. v-model="queryParams.name"
  19. placeholder="请输入名称"
  20. clearable
  21. size="small"
  22. @keyup.enter.native="handleQuery"
  23. />
  24. </el-form-item>
  25. <el-form-item label="类型" prop="type">
  26. <el-select v-model="queryParams.type" placeholder="请选择联系方式类型" clearable size="small">
  27. <el-option
  28. v-for="dict in typeOptions"
  29. :key="dict.dictValue"
  30. :label="dict.dictLabel"
  31. :value="dict.dictValue"
  32. />
  33. </el-select>
  34. </el-form-item>
  35. <el-form-item label="是否免验证" prop="skipVerify">
  36. <el-select v-model="queryParams.skipVerify" placeholder="是否无需验证" clearable size="small">
  37. <el-option
  38. v-for="dict in isOptions"
  39. :key="dict.dictValue"
  40. :label="dict.dictLabel"
  41. :value="dict.dictValue"
  42. />
  43. </el-select>
  44. </el-form-item>
  45. <!-- <el-form-item label="用户" prop="userIds">
  46. <el-select v-model="queryParams.userIds" filterable placeholder="公司员工" >
  47. <el-option style="width: 300px;"
  48. v-for="dict in companyUserList"
  49. :key="dict.userId"
  50. :label="dict.nickName"
  51. :value="dict.userId">
  52. </el-option>
  53. </el-select>
  54. </el-form-item> -->
  55. <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
  56. <el-form-item>
  57. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  58. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  59. </el-form-item>
  60. </el-form>
  61. </div>
  62. <div style="height: 700px;width: auto; display: flex;margin-top: 10px;">
  63. <div style="background-color: white;height: 100%;width: 15%; border: 1px solid #e6e6e6; ">
  64. <div >
  65. <contactWayGroup ref="contactWayGroup" @selectGroupScreen="selectGroupScreen" @getGroupList="getGroupList" ></contactWayGroup>
  66. </div>
  67. </div>
  68. <div style="height: 100%;width: 1%">
  69. </div>
  70. <div style="background-color: white;height: 100%;width: 85%;border: 1px solid #e6e6e6; ">
  71. <el-row :gutter="10" class="mb8" style="margin-top: 10px;margin: 15px;">
  72. <el-col :span="1.5">
  73. <el-button
  74. type="primary"
  75. plain
  76. icon="el-icon-plus"
  77. size="mini"
  78. @click="handleAdd"
  79. v-hasPermi="['qw:contactWay:add']"
  80. >新增</el-button>
  81. </el-col>
  82. <el-col :span="1.5">
  83. <el-button
  84. type="warning"
  85. plain
  86. icon="el-icon-download"
  87. size="mini"
  88. :loading="exportLoading"
  89. @click="handleExport"
  90. v-hasPermi="['qw:contactWay:export']"
  91. >导出</el-button>
  92. </el-col>
  93. <el-col :span="1.5">
  94. <el-button
  95. type="primary"
  96. plain
  97. size="mini"
  98. @click="sync"
  99. v-hasPermi="['qw:contactWay:add']"
  100. >同步</el-button>
  101. </el-col>
  102. </el-row>
  103. <div style=" height: calc(100% - 40px); overflow-y: auto;">
  104. <el-table v-loading="loading" :data="contactWayList" @selection-change="handleSelectionChange" border>
  105. <el-table-column label="名称" align="center" prop="name" />
  106. <el-table-column label="二维码" align="center" prop="qrCode" width="150px" >
  107. <template slot-scope="scope">
  108. <el-popover
  109. placement="right"
  110. title=""
  111. trigger="hover">
  112. <img slot="reference" :src="scope.row.qrCode" width="100px">
  113. <img :src="scope.row.qrCode" style="max-width: 350px;">
  114. </el-popover>
  115. </template>
  116. </el-table-column>
  117. <el-table-column label="类型" align="center" prop="type">
  118. <template slot-scope="scope">
  119. <dict-tag :options="typeOptions" :value="scope.row.type"/>
  120. </template>
  121. </el-table-column>
  122. <el-table-column label="备注" align="center" prop="remark" />
  123. <el-table-column label="是否免验证" align="center" prop="skipVerify">
  124. <template slot-scope="scope">
  125. <dict-tag :options="isOptions" :value="scope.row.skipVerify"/>
  126. </template>
  127. </el-table-column>
  128. <el-table-column label="state参数" align="center" prop="state" />
  129. <el-table-column label="用户" align="center" prop="userIds" width="200px">
  130. <template slot-scope="scope">
  131. <div v-for="i in JSON.parse(scope.row.userIds)" :key="i" style="display: inline;">
  132. <el-tag type="success" v-for="ii in companyUserList" :key="ii.id" style="margin: 3px;" v-if="ii.qwUserId==i">{{ii.qwUserName}}</el-tag>
  133. </div>
  134. </template>
  135. </el-table-column>
  136. <el-table-column label="添加人数" align="center" prop="addNum" />
  137. <el-table-column label="删除人数" align="center" prop="deleteNum" />
  138. <el-table-column label="净人数" align="center" prop="num" />
  139. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="170px">
  140. <template slot-scope="scope">
  141. <el-button
  142. size="mini"
  143. type="text"
  144. icon="el-icon-edit"
  145. @click="handleUpdate(scope.row)"
  146. v-hasPermi="['qw:contactWay:edit']"
  147. >修改</el-button>
  148. <el-button
  149. size="mini"
  150. type="text"
  151. @click="handledetails(scope.row)"
  152. >数据统计
  153. </el-button>
  154. <el-button
  155. size="mini"
  156. type="text"
  157. icon="el-icon-delete"
  158. @click="handleDelete(scope.row)"
  159. v-hasPermi="['qw:contactWay:remove']"
  160. >删除</el-button>
  161. </template>
  162. </el-table-column>
  163. </el-table>
  164. <pagination style="margin: 10px;"
  165. v-show="total>0"
  166. :total="total"
  167. :page.sync="queryParams.pageNum"
  168. :limit.sync="queryParams.pageSize"
  169. @pagination="getList"
  170. />
  171. </div>
  172. </div>
  173. </div>
  174. <!-- 添加或修改企微活码对话框 -->
  175. <el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>
  176. <el-form ref="form" :model="form" :rules="rules" label-width="120px">
  177. <el-form-item label="名称" prop="name">
  178. <el-input v-model="form.name" placeholder="请输入名称" />
  179. </el-form-item>
  180. <el-form-item label="客服类型" prop="userType" >
  181. <el-radio-group v-model="form.userType">
  182. <el-radio :key="1":label="1" >全天在线</el-radio>
  183. <el-radio :key="2":label="2" >自动上下线</el-radio>
  184. </el-radio-group>
  185. </el-form-item>
  186. <el-form-item label="" prop="userTimeJson" v-if="form.userType==2">
  187. <div v-for="(item, index) in userTimeJson" >
  188. <el-row>
  189. <el-col :span="22">
  190. <div style="background-color: #fbfbfb;padding: 15px; border: 1px solid #e6e6e6; margin-bottom: 20px;">
  191. <el-form :model="item" label-width="80px">
  192. <el-form-item label="员工选择" style="height: 50px;">
  193. <el-select v-model="item.userIds" remote multiple placeholder="请选择" filterable style="width: 100%;">
  194. <el-option
  195. v-for="dict in companyUserList"
  196. :key="dict.qwUserId"
  197. :label="dict.qwUserName"
  198. :value="dict.qwUserId">
  199. </el-option>
  200. </el-select>
  201. </el-form-item>
  202. <el-form-item label="工作周期" prop="week" style="height: 50px;" >
  203. <el-select v-model="item.week" remote multiple placeholder="请选择" filterable style="width: 100%;">
  204. <el-option
  205. v-for="dict in weekOptions"
  206. :key="dict.value"
  207. :label="dict.label"
  208. :value="dict.value">
  209. </el-option>
  210. </el-select>
  211. </el-form-item>
  212. <el-form-item label="上线时间" style="height: 50px;">
  213. <el-time-select style="margin-right: 20px; width: 150px;"
  214. placeholder="起始时间"
  215. v-model="item.startTime"
  216. :picker-options="{
  217. start: '00:00',
  218. step: '00:15',
  219. end: '24:00'
  220. }">
  221. </el-time-select>
  222. <el-time-select style="width: 150px;"
  223. placeholder="结束时间"
  224. v-model="item.endTime"
  225. :picker-options="{
  226. start: '00:00',
  227. step: '00:15',
  228. end: '24:00',
  229. minTime: item.startTime
  230. }">
  231. </el-time-select>
  232. </el-form-item>
  233. </el-form>
  234. </div>
  235. </el-col>
  236. <el-col :span="1" :offset="1">
  237. <i class="el-icon-delete-solid" @click="delUserTime(index)" style="margin-top: 165px;" v-if="userTimeJson.length>1"></i>
  238. </el-col>
  239. </el-row>
  240. </div>
  241. <el-link type="primary" class="el-icon-plus" :underline="false" @click='addUserTime()'>添加其他工作周期</el-link>
  242. </el-form-item>
  243. <el-form-item label="" v-if="form.userType==1">
  244. <el-select v-model="userIds" remote multiple placeholder="选择全天在线员工" filterable style="width: 800px;" :change="userChange()">
  245. <el-option
  246. v-for="dict in companyUserList"
  247. :label="dict.qwUserName"
  248. :value="dict.qwUserId">
  249. </el-option>
  250. </el-select>
  251. </el-form-item>
  252. <el-form-item label="员工添加上限"v-if="form.userType==1" prop="isUserLimit">
  253. <el-switch
  254. v-model="form.isUserLimit"
  255. :active-value="1"
  256. :inactive-value="0"
  257. >
  258. </el-switch>
  259. </el-form-item>
  260. <el-form-item label="" v-if="form.isUserLimit==1&&form.userType==1">
  261. <el-table :data="userLimitJson" style="border: 1px solid #e6e6e6;width: 50%;">
  262. <el-table-column label="名称" align="center" prop="userId" >
  263. <template slot-scope="scope">
  264. <div v-for="(companyUser, index) in companyUserList" :key="index">
  265. <span v-if="companyUser.qwUserId==scope.row.userId">{{companyUser.qwUserName}}</span>
  266. </div>
  267. </template>
  268. </el-table-column>
  269. <el-table-column label="数量" align="center" prop="limitCount" >
  270. <template slot-scope="scope">
  271. <div>
  272. <el-input-number v-model="scope.row.limitCount" size="mini" :min="0" ></el-input-number>
  273. </div>
  274. </template>
  275. </el-table-column>
  276. </el-table>
  277. </el-form-item>
  278. <el-form-item label="备用员工" prop="spareUserIds" >
  279. <el-select v-model="spareUserIds" remote multiple placeholder="员工" filterable style="width: 800px;">
  280. <el-option
  281. v-for="dict in companyUserList"
  282. :key="dict.qwUserId"
  283. :label="dict.qwUserName"
  284. :value="dict.qwUserId">
  285. </el-option>
  286. </el-select>
  287. </el-form-item>
  288. <el-form-item label="分组" prop="groupId">
  289. <el-select v-model="form.groupId" placeholder="分组">
  290. <el-option
  291. v-for="dict in groupList"
  292. :label="dict.groupName"
  293. :value="parseInt(dict.id)"
  294. ></el-option>
  295. </el-select>
  296. </el-form-item>
  297. <el-form-item label="信息流" prop="informationId">
  298. <el-select v-model="form.informationId" placeholder="分组">
  299. <el-option
  300. v-for="dict in informationList"
  301. :label="dict.dictLabel"
  302. :value="parseInt(dict.dictValue)"
  303. ></el-option>
  304. </el-select>
  305. </el-form-item>
  306. <el-form-item label="免验证" prop="skipVerify">
  307. <el-switch
  308. v-model="form.skipVerify"
  309. :active-value="1"
  310. :inactive-value="0"
  311. >
  312. </el-switch>
  313. </el-form-item>
  314. <el-form-item label="备注" prop="isRemark">
  315. <el-radio-group v-model="form.isRemark">
  316. <el-switch
  317. v-model="form.isRemark"
  318. :active-value="1"
  319. :inactive-value="0"
  320. >
  321. </el-switch>
  322. </el-radio-group>
  323. </el-form-item>
  324. <el-form-item label="" v-if="form.isRemark==1" prop="remarkStatus">
  325. <el-radio-group v-model="form.remarkStatus" >
  326. <el-radio :label="1">昵称后</el-radio>
  327. <el-radio :label="2">昵称前</el-radio>
  328. </el-radio-group>
  329. </el-form-item>
  330. <el-form-item label="" prop="remark" v-if="form.isRemark==1">
  331. <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
  332. </el-form-item>
  333. <el-form-item label="添加描述" prop="isDescription">
  334. <el-switch
  335. v-model="form.isDescription"
  336. :active-value="1"
  337. :inactive-value="0"
  338. >
  339. </el-switch>
  340. </el-form-item>
  341. <el-form-item label="" prop="description" v-if="form.isDescription==1">
  342. <el-input v-model="form.description" type="textarea" placeholder="请输入描述" />
  343. </el-form-item>
  344. <el-form-item label="开启欢迎语屏蔽" prop="isCloseWelcome">
  345. <el-switch
  346. v-model="form.isCloseWelcome"
  347. :active-value="1"
  348. :inactive-value="0"
  349. >
  350. </el-switch>
  351. </el-form-item>
  352. <el-form-item label="欢迎语屏蔽" prop="closeWelcomeWord" v-if="form.isCloseWelcome==1">
  353. <el-tag
  354. v-for="tag in closeWelcomeWord"
  355. closable
  356. :disable-transitions="false"
  357. @close="handleCloseWord(tag)">
  358. {{tag}}
  359. </el-tag>
  360. <el-input
  361. style="width:110px"
  362. class="input-new-tag"
  363. v-if="inputVisible"
  364. v-model="inputValue"
  365. ref="saveTagInput"
  366. size="small"
  367. @keyup.enter.native="handleInputConfirm"
  368. @blur="handleInputConfirm"
  369. >
  370. </el-input>
  371. <el-button v-else class="button-new-tag" size="small" style="width: 110px" @click="showInput">新增屏蔽关键词</el-button>
  372. </el-form-item>
  373. <el-form-item label="添加标签" prop="isTag">
  374. <el-switch
  375. v-model="form.isTag"
  376. :active-value="1"
  377. :inactive-value="0"
  378. >
  379. </el-switch>
  380. </el-form-item>
  381. <el-form-item label="" v-if="form.isTag==1">
  382. <div>
  383. <div>
  384. <el-button size="medium" icon="el-icon-circle-plus-outline" plain @click="handleTags()">请选择标签</el-button>
  385. </div>
  386. <div>
  387. <div v-for="i in tagListForm" :key="i" style="display: inline;">
  388. <el-tag type="success" closable :disable-transitions="false" @close="handleCloseTag(i)" v-for="ii in tagList" :key="ii.id" style="margin: 3px;" v-if="ii.tagId==i">{{ii.name}}</el-tag>
  389. </div>
  390. </div>
  391. </div>
  392. </el-form-item>
  393. <el-form-item label="发送欢迎语" prop="isWelcome">
  394. <el-switch
  395. v-model="form.isWelcome"
  396. :active-value="1"
  397. :inactive-value="0"
  398. >
  399. </el-switch>
  400. </el-form-item>
  401. <el-form-item label="消息文本内容" prop="textContent" v-if="form.isWelcome==1">
  402. <el-input type="textarea" cols="1000" v-model="form.textContent" placeholder="请输入消息文本内容" />
  403. </el-form-item>
  404. <el-form-item label="图片的链接" prop="imagePicUrl" v-if="form.isWelcome==1">
  405. <el-upload
  406. v-model="form.imgUrl"
  407. class="avatar-uploader"
  408. :action="uploadUrl"
  409. :show-file-list="false"
  410. :on-success="handleAvatarSuccess"
  411. :before-upload="beforeAvatarUpload">
  412. <img v-if="form.imagePicUrl" :src="form.imagePicUrl" class="avatar" width="300px">
  413. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  414. </el-upload>
  415. </el-form-item>
  416. <el-form-item label="分时段欢迎语" prop="isSpanWelcome">
  417. <el-switch
  418. v-model="form.isSpanWelcome"
  419. :active-value="1"
  420. :inactive-value="0"
  421. >
  422. </el-switch>
  423. </el-form-item>
  424. <div v-if="form.isSpanWelcome == '1'" v-for="(item, index) in welcomeJson" :key="index" >
  425. <el-form-item :label="`时段 ${index + 1}:`">
  426. <el-row>
  427. <el-col :span="22">
  428. <div style="background-color: #fbfbfb;padding: 10px; border: 1px solid #e6e6e6; margin-bottom: 20px;">
  429. <el-form ref="friendWelcomeItemForm" :rules="itemRules" :model="item">
  430. <div style="display: flex; ">
  431. <el-form-item label="时间:" prop="week" style="flex: 6;">
  432. <el-select v-model="item.week" remote multiple placeholder="请选择" filterable style="width: 580px;">
  433. <el-option
  434. v-for="dict in weekOptions"
  435. :key="dict.value"
  436. :label="dict.label"
  437. :value="dict.value">
  438. </el-option>
  439. </el-select>
  440. </el-form-item>
  441. <el-form-item prop="startTime" style="flex: 1;">
  442. <el-time-picker
  443. v-model="item.startTime"
  444. value-format="HH:mm"
  445. format="HH:mm"
  446. :picker-options="{ selectableRange: '00:00:00 - 23:59:59' }"
  447. placeholder="开始"
  448. style="width: 100px">
  449. </el-time-picker>
  450. </el-form-item>
  451. <el-form-item prop="endTime" style="flex: 1;">
  452. <el-time-picker
  453. v-model="item.endTime"
  454. value-format="HH:mm"
  455. format="HH:mm"
  456. :picker-options="{ selectableRange: '00:00:00 - 23:59:59' }"
  457. placeholder="结束"
  458. style="width: 100px">
  459. </el-time-picker>
  460. </el-form-item>
  461. </div>
  462. <el-form-item style="margin-top: 20px" prop="text">
  463. <el-input v-model="item.text.content" type="textarea" :rows="12" maxlength="1300" show-word-limit placeholder="请输入消息内容"/>
  464. <!-- 附件和链接列表 -->
  465. <el-row>
  466. <el-col>
  467. <div v-for="(attachment, attachIndex) in item.attachments" :key="attachIndex" style="background-color: #f5f7fa;padding: 5px;border: 1px solid #d9d9d9;">
  468. <div slot="header" style=" display: flex;justify-content: space-between;align-items: center; ">
  469. <div style="flex: 1;">
  470. <span v-if="attachment.msgtype === 'image'">【图片】: {{ attachment.image.pic_url }}</span>
  471. <span v-if="attachment.msgtype === 'link'">【链接】: {{ attachment.link.title }}-{{attachment.link.desc}}</span>
  472. </div>
  473. <div style=" display: flex;gap: 10px;">
  474. <el-button
  475. size="mini"
  476. type="text"
  477. icon="el-icon-edit"
  478. style="float: left;"
  479. @click="editFileItem(attachment,attachIndex,index)"
  480. >修改</el-button>
  481. <el-button
  482. size="mini"
  483. type="text"
  484. icon="el-icon-delete"
  485. style="float: right;"
  486. @click="removeFileItem(attachment,attachIndex,index)"
  487. >删除</el-button>
  488. </div>
  489. </div>
  490. </div>
  491. </el-col>
  492. </el-row>
  493. <el-dropdown @command="(command) => handleCommand(command, index)" trigger="click" placement="top-start">
  494. <el-dropdown-menu slot="dropdown" style="width: 100px;">
  495. <el-dropdown-item command="image">
  496. <i class="el-icon-picture" style="margin-right: 10px;"></i>图片
  497. </el-dropdown-item>
  498. <el-dropdown-item command="link">
  499. <i class="el-icon-link" style="margin-right: 10px;"></i>链接
  500. </el-dropdown-item>
  501. </el-dropdown-menu>
  502. <span class="el-dropdown-link">
  503. <el-link icon="el-icon-paperclip" type="text" style="color: rgb(24, 144, 255)">
  504. 添加附件(最多9个)
  505. </el-link>
  506. </span>
  507. </el-dropdown>
  508. </el-form-item>
  509. </el-form>
  510. </div>
  511. </el-col>
  512. <el-col :span="1" :offset="1">
  513. <el-link v-if="welcomeJson.length>1" icon="el-icon-delete-solid" @click="delItemList(index)" type="text" style="margin-top: 400px" ></el-link>
  514. </el-col>
  515. </el-row>
  516. </el-form-item>
  517. </div>
  518. <div v-if="form.isSpanWelcome == '1'" style="margin-left: 10%">
  519. <el-link type="primary" class="el-icon-plus" :underline="false" @click='addItemList()'>添加其他分时段欢迎语</el-link>
  520. </div>
  521. </el-form>
  522. <div slot="footer" class="dialog-footer">
  523. <el-button type="primary" @click="submitForm">确 定</el-button>
  524. <el-button @click="cancel">取 消</el-button>
  525. </div>
  526. </el-dialog>
  527. <el-dialog :title="welcomeItem.title" :visible.sync="welcomeItem.open" style="width: 1300px;height: 100%" append-to-body>
  528. <el-form ref="fileFrom" :model="fileFrom" :rules="fuleRules" label-width="100px">
  529. <div v-if="welcomeItem.type==='image'">
  530. <el-form-item label="图片:" prop="imagePicUrl">
  531. <ImageUpload v-model="fileFrom.imagePicUrl" type="image" :num="10" :width="150" :height="150" disabled/>
  532. </el-form-item>
  533. </div>
  534. <div v-if="welcomeItem.type==='link'">
  535. <el-form-item label="选择课程">
  536. <el-select v-model="fileFrom.courseId" placeholder="请选择课程" style=" margin-right: 10px;" size="mini" @change="courseChange(fileFrom,welcomeItem.index,welcomeItem.itemIndex)">
  537. <el-option
  538. v-for="dict in courseList"
  539. :key="dict.dictValue"
  540. :label="dict.dictLabel"
  541. :value="parseInt(dict.dictValue)"
  542. />
  543. </el-select>
  544. <el-select v-model="fileFrom.videoId" placeholder="请选择小节" size="mini" style=" margin-right: 10px;" @change="videoIdChange(fileFrom, welcomeItem.index, welcomeItem.itemIndex)" >
  545. <el-option
  546. v-for="dict in videoList"
  547. :key="dict.dictValue"
  548. :label="dict.dictLabel"
  549. :value="parseInt(dict.dictValue)"
  550. />
  551. </el-select>
  552. </el-form-item>
  553. <el-form-item label="图文标题:" prop="linkTitle">
  554. <el-input v-model="fileFrom.linkTitle" :rows="2" maxlength="42" show-word-limit placeholder="请输入图文消息标题,最长为42字" />
  555. </el-form-item>
  556. <el-form-item label="图文封面:" prop="linkPicUrl">
  557. <ImageUpload v-model="fileFrom.linkPicUrl" type="image" :num="10" :width="150" :height="150" />
  558. </el-form-item>
  559. <el-form-item label="图文的描述:" prop="linkDesc">
  560. <el-input v-model="fileFrom.linkDesc" :rows="4" maxlength="170" show-word-limit type="textarea" placeholder="请输入内容,,最长为170字" />
  561. </el-form-item>
  562. <div v-if="fileFrom.videoId==null" style="margin-top: 1%">
  563. <el-form-item label="图文链接:" label-width="100px" >
  564. <el-input v-model="fileFrom.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>
  565. </el-form-item>
  566. </div>
  567. <div v-if="fileFrom.videoId!=null">
  568. <el-form-item label="图文链接:" label-width="100px" >
  569. <el-tag type="warning" v-model="fileFrom.linkUrl='待生成'">选择的课程小节 即为卡片链接地址</el-tag>
  570. </el-form-item>
  571. </div>
  572. <div v-if="fileFrom.videoId!=null">
  573. <el-form-item label="课节过期时间" style="margin-top: 1%" required label-width="110px">
  574. <el-row>
  575. <el-input-number v-model="fileFrom.expiresDays" :min="1" :max="9999" ></el-input-number>
  576. (天)
  577. </el-row>
  578. <el-row>
  579. <span class="tip">默认为30天</span>
  580. </el-row>
  581. </el-form-item>
  582. </div>
  583. </div>
  584. </el-form>
  585. <div slot="footer" class="dialog-footer" style="text-align: center">
  586. <el-button type="primary" @click="confirmUpload">确定</el-button>
  587. <el-button type="primary" @click="cancelUpload">取消</el-button>
  588. </div>
  589. </el-dialog>
  590. <el-dialog title="添加标签" :visible.sync="tagOpen" width="800px" append-to-body>
  591. <div>搜索标签:
  592. <el-input v-model="tagChange.tagName" placeholder="请输入标签名称" clearable size="small" style="width: 200px;margin-right: 10px" />
  593. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearchTags(tagChange.tagName)">搜索</el-button>
  594. <el-button type="primary" icon="el-icon-plus" size="mini" @click="cancelSearchTags">重置</el-button>
  595. </div>
  596. <div v-for="item in tagGroupList" :key="item.id" >
  597. <div style="font-size: 20px;margin-top: 20px;margin-bottom: 20px;">
  598. <span class="name-background">{{ item.name }}</span>
  599. </div>
  600. <!-- 添加外层滚动容器 -->
  601. <div class="scroll-wrapper">
  602. <div class="tag-container">
  603. <a
  604. v-for="tagItem in item.tag"
  605. class="tag-box"
  606. @click="tagSelection(tagItem)"
  607. :class="{ 'tag-selected': tagItem.isSelected }"
  608. >
  609. {{ tagItem.name }}
  610. </a>
  611. </div>
  612. </div>
  613. </div>
  614. <div slot="footer" class="dialog-footer">
  615. <el-button type="primary" @click="addTagSubmitForm()">确 定</el-button>
  616. <el-button @click="addTagCancel">取 消</el-button>
  617. </div>
  618. </el-dialog>
  619. </div>
  620. <el-drawer
  621. :with-header="false"
  622. size="75%"
  623. :title="show.title" :visible.sync="show.open">
  624. <statisDetails ref="Details" />
  625. </el-drawer>
  626. </div>
  627. </template>
  628. <script>
  629. import { informationList,sync,listContactWay, getContactWay, delContactWay, addContactWay, updateContactWay, exportContactWay } from "@/api/qw/contactWay";
  630. import {getQwAllUserList } from "@/api/company/companyUser";
  631. import contactWayGroup from '@/views/qw/contactWay/group';
  632. import {listTag, getTag, searchTags,} from "@/api/qw/tag";
  633. import { allListTagGroup} from "@/api/qw/tagGroup";
  634. import ImageUpload from '@/views/qw/material/ImageUpload.vue'
  635. import statisDetails from '@/views/qw/contactWay/statisDetails';
  636. import { getMyQwUserList,getMyQwCompanyList } from "@/api/qw/user";
  637. import {courseList, videoList} from "@/api/qw/sop";
  638. export default {
  639. name: "ContactWay",
  640. components: { contactWayGroup,ImageUpload,statisDetails},
  641. data() {
  642. return {
  643. // 遮罩层
  644. loading: true,
  645. informationList:[],
  646. // 导出遮罩层
  647. exportLoading: false,
  648. // 选中数组
  649. ids: [],
  650. userTimeJson:[{userIds:null,week:[1,2,3,4,5,6,7],startTime:null,endTime:null}],
  651. userIds:[],
  652. show:{
  653. title:"医院详情",
  654. open:false,
  655. },
  656. userLimitJson:[],
  657. welcomeJson:[{text:{content:null},attachments:[],week:[1,2,3,4,5,6,7],startTime:null,endTime:null}],
  658. closeWelcomeWord: [],
  659. inputVisible: false,
  660. inputValue: '',
  661. myQwCompanyList:[],
  662. tagOpen:false,
  663. spareUserIds:[],
  664. welcomeItem:{
  665. open: false,
  666. title: '',
  667. type: '',
  668. index: -1,
  669. itemIndex: -1
  670. },
  671. courseList:[],
  672. videoList:[],
  673. //标签弹窗选择
  674. tagChange:{
  675. open:false,
  676. index:null,
  677. },
  678. // 非单个禁用
  679. single: true,
  680. // 非多个禁用
  681. multiple: true,
  682. // 显示搜索条件
  683. showSearch: true,
  684. // 总条数
  685. total: 0,
  686. groupList:[],
  687. // 企微活码表格数据
  688. contactWayList: [],
  689. // 弹出层标题
  690. title: "",
  691. itemRules: {
  692. week: [
  693. { required: true, message: '请选择发起时间的星期', trigger: 'submit' }
  694. ],
  695. startTime: [
  696. { required: true, message: '请选择开始时间', trigger: 'submit' },
  697. ],
  698. endTime: [
  699. { required: true, message: '请选择结束时间', trigger: 'submit' },
  700. ],
  701. text: [
  702. { required: true, message: '消息内容不能为空噢', trigger: 'submit' }
  703. ],
  704. },
  705. fuleRules:{
  706. imagePicUrl:[ { required: true, message: "图片不能为空", trigger: "submit" }],
  707. linkTitle:[ { required: true, message: "图文标题不能为空", trigger: "submit" }],
  708. linkUrl:[ { required: true, message: "图文链接不能为空", trigger: "submit" }],
  709. },
  710. // 是否显示弹出层
  711. open: false,
  712. // 联系方式类型,1-单人, 2-多人字典
  713. typeOptions: [],
  714. weekOptions: [{
  715. value: 1,
  716. label: '星期一'
  717. }, {
  718. value: 2,
  719. label: '星期二'
  720. }, {
  721. value: 3,
  722. label: '星期三'
  723. }, {
  724. value: 4,
  725. label: '星期四'
  726. }, {
  727. value: 5,
  728. label: '星期五'
  729. }
  730. , {
  731. value: 6,
  732. label: '星期六'
  733. }
  734. , {
  735. value: 7,
  736. label: '星期天'
  737. }],
  738. // 外部客户添加时是否无需验证字典
  739. isOptions: [],
  740. // 查询参数
  741. queryParams: {
  742. pageNum: 1,
  743. pageSize: 10,
  744. name: null,
  745. type: null,
  746. skipVerify: null,
  747. state: null,
  748. userIds: null,
  749. addNum: null,
  750. deleteNum: null,
  751. num: null,
  752. qrCode: null,
  753. configId: null,
  754. isDel: 0,
  755. companyId: null,
  756. groupId: null,
  757. },
  758. uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
  759. baseUrl: process.env.VUE_APP_BASE_API,
  760. // 表单参数
  761. form: {
  762. },
  763. fileFrom:{
  764. imagePicUrl:null,
  765. linkTitle:null,
  766. linkPicUrl:null,
  767. linkDesc:null,
  768. linkUrl:null,
  769. videoId:null,
  770. courseId:null,
  771. expiresDays:30,
  772. },
  773. // 是否发送欢迎语字典
  774. companyUserList:[],
  775. // 表单校验
  776. rules: {
  777. name:[{required:true,message:"名称不能为空",trigger:"blur"}],
  778. userIds:[{required:true,message:"用户不能为空",trigger:"blur"}],
  779. skipVerify:[{required:true,message:"是否跳过验证不能为空",trigger:"change"}],
  780. isWelcome:[{required:true,message:"是否发送欢迎语不能为空",trigger:"change"}],
  781. textContent:[{required:true,message:"不能为空",trigger:"change"}],
  782. isUserLimit:[{required:true,message:"不能为空",trigger:"change"}],
  783. isSpanWelcome:[{required:true,message:"不能为空",trigger:"change"}],
  784. isCloseWelcome:[{required:true,message:"不能为空",trigger:"change"}],
  785. isTag:[{required:true,message:"不能为空",trigger:"change"}],
  786. tags:[{required:true,message:"不能为空",trigger:"change"}],
  787. isRemark:[{required:true,message:"不能为空",trigger:"change"}],
  788. remarkStatus:[{required:true,message:"不能为空",trigger:"change"}],
  789. description:[{required:true,message:"不能为空",trigger:"change"}],
  790. isDescription:[{required:true,message:"不能为空",trigger:"change"}],
  791. groupId:[{required:true,message:"不能为空",trigger:"change"}],
  792. userType:[{required:true,message:"不能为空",trigger:"change"}],
  793. },
  794. tagGroupList:[],
  795. tagList:[],
  796. tagListForm:[],
  797. };
  798. },
  799. created() {
  800. informationList().then(response => {
  801. this.informationList = response.data;
  802. });
  803. courseList().then(response => {
  804. this.courseList = response.list;
  805. });
  806. this.getDicts("sys_qw_contact_way_type").then(response => {
  807. this.typeOptions = response.data;
  808. });
  809. this.getDicts("sys_company_or").then(response => {
  810. this.isOptions = response.data;
  811. });
  812. getMyQwCompanyList().then(response => {
  813. this.myQwCompanyList = response.data;
  814. if(this.myQwCompanyList!=null){
  815. this.queryParams.corpId=this.myQwCompanyList[0].dictValue;
  816. setTimeout(() => {
  817. this.$refs.contactWayGroup.getDetails(this.queryParams.corpId);
  818. }, 100);
  819. getQwAllUserList(this.queryParams.corpId).then(response => {
  820. this.companyUserList = response.data;
  821. });
  822. listTag({corpId:this.queryParams.corpId}).then(response => {
  823. this.tagList = response.rows;
  824. });
  825. allListTagGroup({corpId:this.queryParams.corpId}).then(response => {
  826. this.tagGroupList = response.rows;
  827. });
  828. this.getList();
  829. }
  830. });
  831. },
  832. methods: {
  833. updateCorpId(){
  834. setTimeout(() => {
  835. this.$refs.contactWayGroup.getDetails(this.queryParams.corpId);
  836. }, 1);
  837. getQwAllUserList(this.queryParams.corpId).then(response => {
  838. this.companyUserList = response.data;
  839. });
  840. listTag({corpId:this.queryParams.corpId}).then(response => {
  841. this.tagList = response.rows;
  842. });
  843. allListTagGroup({corpId:this.queryParams.corpId}).then(response => {
  844. this.tagGroupList = response.rows;
  845. });
  846. this.getList();
  847. },
  848. handleSearchTags(name){
  849. if (!name){
  850. return this.$message.error("请输入要搜索的标签")
  851. }
  852. this.queryTagParams.name=name;
  853. this.queryTagParams.corpId=this.queryParams.corpId;
  854. searchTags(this.queryTagParams).then(response => {
  855. this.tagGroupList = response.rows;
  856. });
  857. // searchTags({name:name,corpId:this.queryParams.corpId}).then(response => {
  858. // this.tagGroupList = response.rows;
  859. // });
  860. },
  861. cancelSearchTags(){
  862. this.afreshData(this.queryParams.corpId)
  863. },
  864. /**
  865. * 重新获取 部分数据
  866. */
  867. afreshData(value){
  868. //所有的标签组
  869. allListTagGroup({corpId:value}).then(response => {
  870. this.tagGroupList = response.rows;
  871. });
  872. //所有的标签
  873. listTag({corpId:value}).then(response => {
  874. this.tagList = response.rows;
  875. });
  876. },
  877. /** 查询企微活码列表 */
  878. getList() {
  879. this.loading = true;
  880. listContactWay(this.queryParams).then(response => {
  881. this.contactWayList = response.rows;
  882. this.total = response.total;
  883. this.loading = false;
  884. });
  885. },
  886. handledetails(row){
  887. this.show.open=true;
  888. setTimeout(() => {
  889. this.$refs.Details.getDetails(row.id);
  890. }, 1);
  891. },
  892. courseChange(fileFrom,index,itemIndex){
  893. // 清空 videoId 选择
  894. this.$set(fileFrom, 'videoId', null);
  895. // 清空 videoList
  896. this.videoList = [];
  897. if (fileFrom.courseId != null) {
  898. // 查找选中的课程对应的 label 和 dictImgUrl
  899. const selectedCourse = this.courseList.find(course => parseInt(course.dictValue) === fileFrom.courseId);
  900. if (selectedCourse) {
  901. // 设置 linkTitle 和 linkImageUrl
  902. this.$set(fileFrom, 'linkTitle', selectedCourse.dictLabel);
  903. this.$set(fileFrom, 'linkPicUrl', selectedCourse.dictImgUrl);
  904. }
  905. // 获取新的 videoList
  906. videoList(fileFrom.courseId).then(response => {
  907. this.videoList = response.list;
  908. });
  909. }
  910. //
  911. // // 更新对应的数据层级
  912. // if (itemIndex === -1) {
  913. // // 更新 form.attachments
  914. // this.$set(this.form.attachments, index, {
  915. // ...this.form.attachments[index],
  916. // courseId: fileFrom.courseId,
  917. // videoId: null, // 因为已清空
  918. // title: fileFrom.linkTitle,
  919. // picurl: fileFrom.linkPicUrl
  920. // });
  921. // } else {
  922. //
  923. // this.$set(this.form.daypartingItemlist[itemIndex].attachments, index, {
  924. // ...this.form.daypartingItemlist[itemIndex].attachments[index],
  925. // courseId: fileFrom.courseId,
  926. // videoId: null, // 因为已清空
  927. // title: fileFrom.linkTitle,
  928. // picurl: fileFrom.linkPicUrl
  929. // });
  930. // }
  931. },
  932. videoIdChange(fileFrom,index, itemIndex){
  933. //选择了课程小节则 默认绑上
  934. if (fileFrom.videoId != null) {
  935. // 根据 videoId 获取相关信息(假设有相关的 API 调用)
  936. let selectedVideo = this.videoList.find(course => parseInt(course.dictValue) === fileFrom.videoId);
  937. if (selectedVideo) {
  938. this.$set(fileFrom, 'linkDesc', selectedVideo.dictLabel);
  939. this.$set(fileFrom, 'expiresDays', 30);
  940. }
  941. }
  942. // // 更新对应的数据层级
  943. // if (itemIndex === -1) {
  944. // // 更新 form.attachments
  945. // this.$set(this.form.attachments, index, {
  946. // ...this.form.attachments[index],
  947. // videoId: fileFrom.videoId,
  948. // desc: fileFrom.linkDesc,
  949. // });
  950. // } else {
  951. // // 更新 form.daypartingItemlist[itemIndex].attachments
  952. // this.$set(this.form.daypartingItemlist[itemIndex].attachments, index, {
  953. // ...this.form.daypartingItemlist[itemIndex].attachments[index],
  954. // videoId: fileFrom.videoId,
  955. // desc: fileFrom.linkDesc,
  956. // });
  957. //
  958. // }
  959. },
  960. //附件选择
  961. handleCommand(command,itemIndex){
  962. if (this.welcomeJson[itemIndex].attachments.length>=9){
  963. return this.$message.error('附件数量已达上限,无法添加更多附件');
  964. }
  965. this.welcomeItem = {
  966. open: true,
  967. title: command === 'image' ? '添加图片' : '添加链接',
  968. type: command,
  969. index: itemIndex === -1 ? this.form.attachments.length : this.welcomeJson[itemIndex].attachments.length,
  970. itemIndex
  971. };
  972. },
  973. //重置附件表单
  974. resetFileFrom() {
  975. this.fileFrom = {
  976. imagePicUrl: null,
  977. linkTitle: null,
  978. linkPicUrl: null,
  979. linkDesc: null,
  980. linkUrl: null,
  981. videoId:null,
  982. courseId:null,
  983. };
  984. this.welcomeItem={
  985. open: false,
  986. title: '',
  987. type: '',
  988. index: -1,
  989. itemIndex: -1
  990. } // 重置编辑索引
  991. },
  992. //修改附件
  993. editFileItem(item, index, itemIndex){
  994. this.welcomeItem = {
  995. open: true,
  996. title: item.msgtype === 'image' ? '编辑图片' : '编辑链接',
  997. type: item.msgtype,
  998. index,
  999. itemIndex
  1000. };
  1001. if (item.msgtype === 'image') {
  1002. this.fileFrom.imagePicUrl = item.image.pic_url;
  1003. } else if (item.msgtype === 'link') {
  1004. this.fileFrom.linkTitle = item.link.title;
  1005. this.fileFrom.linkPicUrl = item.link.picurl;
  1006. this.fileFrom.linkDesc = item.link.desc;
  1007. this.fileFrom.linkUrl = item.link.url;
  1008. this.fileFrom.videoId = item.link.videoId;
  1009. this.fileFrom.courseId = item.link.courseId;
  1010. this.fileFrom.expiresDays = item.link.expiresDays;
  1011. }
  1012. videoList(item.link.courseId).then(response => {
  1013. this.videoList = response.list;
  1014. });
  1015. },
  1016. //删除附件
  1017. removeFileItem(data,index, itemIndex) {
  1018. if (itemIndex === -1) {
  1019. this.form.attachments.splice(index, 1);
  1020. } else {
  1021. this.welcomeJson[itemIndex].attachments.splice(index, 1);
  1022. }
  1023. },
  1024. //添加分时段欢迎语
  1025. addItemList(){
  1026. this.welcomeJson.push({text:{content:null},attachments:[],week:[1,2,3,4,5,6,7],startTime:null,endTime:null})
  1027. },
  1028. //删除某一个分时段欢迎语
  1029. delItemList(index){
  1030. this.welcomeJson.splice(index,1)
  1031. },
  1032. //提交附件
  1033. confirmUpload() {
  1034. const { type, index, itemIndex } = this.welcomeItem;
  1035. let attachment = {};
  1036. if (type === 'image') {
  1037. attachment = {
  1038. msgtype: 'image',
  1039. image: {
  1040. pic_url: this.fileFrom.imagePicUrl
  1041. }
  1042. };
  1043. } else if (type === 'link') {
  1044. attachment = {
  1045. msgtype: 'link',
  1046. link: {
  1047. title: this.fileFrom.linkTitle,
  1048. picurl: this.fileFrom.linkPicUrl,
  1049. desc: this.fileFrom.linkDesc,
  1050. url: this.fileFrom.linkUrl,
  1051. courseId:this.fileFrom.courseId,
  1052. videoId:this.fileFrom.videoId,
  1053. expiresDays:this.fileFrom.expiresDays,
  1054. }
  1055. };
  1056. }
  1057. if (itemIndex === -1) {
  1058. // 默认欢迎语附件处理
  1059. if (index < this.form.attachments.length) {
  1060. // 存在附件则更新
  1061. this.form.attachments.splice(index, 1, attachment);
  1062. } else {
  1063. // 不存在附件则插入
  1064. this.form.attachments.push(attachment);
  1065. }
  1066. } else {
  1067. // 分时段欢迎语附件处理
  1068. if (index < this.welcomeJson[itemIndex].attachments.length) {
  1069. // 存在附件则更新
  1070. this.welcomeJson[itemIndex].attachments.splice(index, 1, attachment);
  1071. } else {
  1072. // 不存在附件则插入
  1073. this.welcomeJson[itemIndex].attachments.push(attachment);
  1074. }
  1075. }
  1076. this.resetFileFrom();
  1077. },
  1078. //取消附件
  1079. cancelUpload() {
  1080. this.resetFileFrom();
  1081. this.welcomeItem.open = false;
  1082. },
  1083. userChange(){
  1084. for (let i = 0; i < this.userIds.length; i++) {
  1085. if(!this.userLimitJson.find(item => item.userId == this.userIds[i])){
  1086. this.userLimitJson.push({userId:this.userIds[i],limitCount:100})
  1087. console.log(this.userLimitJson)
  1088. }
  1089. }
  1090. for (let i = 0; i < this.userLimitJson.length; i++) {
  1091. if(!this.userIds.find(item => item== this.userLimitJson[i].userId)){
  1092. this.userLimitJson.splice(i,1)
  1093. }
  1094. }
  1095. },
  1096. showInput() {
  1097. this.inputVisible = true;
  1098. this.$nextTick(_ => {
  1099. this.$refs.saveTagInput.$refs.input.focus();
  1100. });
  1101. },
  1102. addUserTime(){
  1103. this.userTimeJson.push({userIds:null,week:[1,2,3,4,5,6,7],startTime:null,endTime:null})
  1104. },
  1105. delUserTime(index){
  1106. this.userTimeJson.splice(index,1)
  1107. },
  1108. handleInputConfirm() {
  1109. let inputValue = this.inputValue;
  1110. if (inputValue) {
  1111. this.closeWelcomeWord.push(inputValue);
  1112. }
  1113. this.inputVisible = false;
  1114. this.inputValue = '';
  1115. },
  1116. handleCloseTag(row) {
  1117. console.log(row)
  1118. this.tagListForm.splice(this.tagListForm.indexOf(row), 1);
  1119. },
  1120. handleTags(){
  1121. for (let i = 0; i < this.tagGroupList.length; i++) {
  1122. for (let x = 0; x < this.tagGroupList[i].tag.length; x++) {
  1123. this.tagGroupList[i].tag[x].isSelected=false;
  1124. }
  1125. }
  1126. this.tagOpen = true;
  1127. },
  1128. addTagSubmitForm(){
  1129. this.tagListForm=[];
  1130. for (let i = 0; i < this.tagGroupList.length; i++) {
  1131. for (let x = 0; x < this.tagGroupList[i].tag.length; x++) {
  1132. if(this.tagGroupList[i].tag[x].isSelected==true){
  1133. this.tagListForm.push(this.tagGroupList[i].tag[x].tagId)
  1134. }
  1135. }
  1136. }
  1137. if(this.tagListForm==[]||this.tagListForm==null||this.tagListForm==""){
  1138. return this.$message('请选择标签');
  1139. }
  1140. this.tagOpen = false;
  1141. },
  1142. addTagCancel() {
  1143. this.tagOpen = false;
  1144. this.tagListForm=null;
  1145. },
  1146. tagSelection(row){
  1147. row.isSelected= !row.isSelected;
  1148. this.$forceUpdate();
  1149. },
  1150. selectGroupScreen(row){
  1151. this.queryParams.groupId=row
  1152. this.getList();
  1153. },
  1154. getGroupList(row){
  1155. this.groupList=row;
  1156. },
  1157. // 取消按钮
  1158. cancel() {
  1159. this.open = false;
  1160. this.reset();
  1161. },
  1162. // 表单重置
  1163. reset() {
  1164. this.form = {
  1165. id: null,
  1166. type: null,
  1167. name: null,
  1168. remark: null,
  1169. skipVerify: null,
  1170. state: null,
  1171. userIds: null,
  1172. addNum: null,
  1173. deleteNum: null,
  1174. num: null,
  1175. qrCode: null,
  1176. configId: null,
  1177. isDel: null,
  1178. createTime: null,
  1179. companyId: null,
  1180. isWelcome: 0,
  1181. textContent: null,
  1182. imagePicUrl: null,
  1183. isUserLimit: 0,
  1184. isSpanWelcome: 1,
  1185. isCloseWelcome: 1,
  1186. closeWelcomeWord: null,
  1187. isTag: 0,
  1188. tags: null,
  1189. isRemark: 0,
  1190. remarkStatus: 1,
  1191. description: null,
  1192. isDescription: 0,
  1193. spareUserIds: null,
  1194. groupId: null,
  1195. userLimitJson: null,
  1196. userTimeJson: null,
  1197. userType: 2
  1198. };
  1199. this.userTimeJson=[{userIds:null,week:[1,2,3,4,5,6,7],startTime:null,endTime:null}];
  1200. this.userLimitJson=[];
  1201. this.userIds=[];
  1202. this.spareUserIds=[];
  1203. this.tagListForm=[];
  1204. this.closeWelcomeWord=[];
  1205. this.welcomeJson=[{text:{content:null},attachments:[],week:[1,2,3,4,5,6,7],startTime:null,endTime:null}];
  1206. },
  1207. /** 搜索按钮操作 */
  1208. handleQuery() {
  1209. this.queryParams.pageNum = 1;
  1210. this.getList();
  1211. },
  1212. sync(){
  1213. sync(this.queryParams.corpId).then(response => {
  1214. this.msgSuccess("同步");
  1215. this.getList();
  1216. });
  1217. },
  1218. /** 重置按钮操作 */
  1219. resetQuery() {
  1220. this.resetForm("queryForm");
  1221. this.queryParams.groupId=null
  1222. this.handleQuery();
  1223. },
  1224. // 多选框选中数据
  1225. handleSelectionChange(selection) {
  1226. this.ids = selection.map(item => item.id)
  1227. this.single = selection.length!==1
  1228. this.multiple = !selection.length
  1229. },
  1230. /** 新增按钮操作 */
  1231. handleAdd() {
  1232. this.reset();
  1233. this.open = true;
  1234. this.title = "添加企微活码";
  1235. this.form.groupId=this.queryParams.groupId
  1236. },
  1237. handleAvatarSuccess(res, file) {
  1238. if(res.code==200){
  1239. this.form.imagePicUrl=res.url;
  1240. }
  1241. else{
  1242. this.msgError(res.msg);
  1243. }
  1244. },
  1245. beforeAvatarUpload(file) {
  1246. const isLt1M = file.size / 1024 / 1024 < 1;
  1247. if (!isLt1M) {
  1248. this.$message.error('上传图片大小不能超过 1MB!');
  1249. }
  1250. return isLt1M;
  1251. },
  1252. /** 修改按钮操作 */
  1253. handleUpdate(row) {
  1254. this.reset();
  1255. const id = row.id || this.ids
  1256. getContactWay(id).then(response => {
  1257. this.form = response.data;
  1258. this.open = true;
  1259. if(this.form.userTimeJson!=null){
  1260. this.userTimeJson=JSON.parse(this.form.userTimeJson)
  1261. }else{ this.userTimeJson=[{userIds:null,week:[1,2,3,4,5,6,7],startTime:null,endTime:null}]}
  1262. if(this.form.userLimitJson!=null){
  1263. this.userLimitJson=JSON.parse(this.form.userLimitJson)
  1264. }else{ this.userLimitJson=[]}
  1265. if(this.form.userIds!=null){
  1266. this.userIds=JSON.parse(this.form.userIds)
  1267. }else{ this.userIds=[]}
  1268. if(this.form.spareUserIds!=null){
  1269. this.spareUserIds=JSON.parse(this.form.spareUserIds)
  1270. }else{ this.spareUserIds=[]}
  1271. if(this.form.tags!=null){
  1272. this.tagListForm=JSON.parse(this.form.tags)
  1273. }else{ this.tagListForm=[]}
  1274. if(this.form.closeWelcomeWord!=null){
  1275. this.closeWelcomeWord=JSON.parse(this.form.closeWelcomeWord)
  1276. }else{ this.closeWelcomeWord=[]}
  1277. if(this.form.welcomeJson!=null){
  1278. this.welcomeJson=JSON.parse(this.form.welcomeJson)
  1279. }else{ this.welcomeJson=[{text:{content:null},attachments:[],week:[1,2,3,4,5,6,7],startTime:null,endTime:null}] }
  1280. this.title = "修改企微活码";
  1281. });
  1282. },
  1283. /** 提交按钮 */
  1284. submitForm() {
  1285. this.$refs["form"].validate(valid => {
  1286. if (valid) {
  1287. this.form.corpId=this.queryParams.corpId
  1288. if(this.form.userType==2){
  1289. var jsonUserIds=[];
  1290. for (let i = 0; i < this.userTimeJson.length; i++) {
  1291. if(this.userTimeJson[i].userIds==null||this.userTimeJson[i].userIds==""){
  1292. return this.$message('人员不能为空');
  1293. }
  1294. if(this.userTimeJson[i].week==null||this.userTimeJson[i].week==""){
  1295. return this.$message('日期不能为空');
  1296. }
  1297. if(this.userTimeJson[i].startTime==null||this.userTimeJson[i].startTime==""){
  1298. return this.$message('时间不能为空');
  1299. }
  1300. if(this.userTimeJson[i].endTime==null||this.userTimeJson[i].endTime==""){
  1301. return this.$message('时间不能为空');
  1302. }
  1303. for (let j = 0; j < this.userTimeJson[i].userIds.length; j++) {
  1304. console.log("!jsonUserIds.find(item=>item==this.userTimeJson[i].userIds[j])")
  1305. if(!jsonUserIds.find(item=>item==this.userTimeJson[i].userIds[j])){
  1306. jsonUserIds.push(this.userTimeJson[i].userIds[j]);
  1307. }
  1308. }
  1309. }
  1310. this.userIds=jsonUserIds;
  1311. }
  1312. this.form.closeWelcomeWord=JSON.stringify(this.closeWelcomeWord)
  1313. this.form.userIds=JSON.stringify(this.userIds)
  1314. this.form.userTimeJson=JSON.stringify(this.userTimeJson)
  1315. this.form.userLimitJson=JSON.stringify(this.userLimitJson)
  1316. this.form.spareUserIds=JSON.stringify(this.spareUserIds)
  1317. this.form.tags=JSON.stringify(this.tagListForm)
  1318. this.form.welcomeJson=JSON.stringify(this.welcomeJson)
  1319. if (this.form.id != null) {
  1320. updateContactWay(this.form).then(response => {
  1321. this.msgSuccess("修改成功");
  1322. this.open = false;
  1323. this.getList();
  1324. });
  1325. } else {
  1326. addContactWay(this.form).then(response => {
  1327. this.msgSuccess("新增成功");
  1328. this.open = false;
  1329. this.getList();
  1330. });
  1331. }
  1332. }
  1333. });
  1334. },
  1335. /** 删除按钮操作 */
  1336. handleDelete(row) {
  1337. const ids = row.id || this.ids;
  1338. this.$confirm('是否确认删除企微活码编号为"' + ids + '"的数据项?', "警告", {
  1339. confirmButtonText: "确定",
  1340. cancelButtonText: "取消",
  1341. type: "warning"
  1342. }).then(function() {
  1343. return delContactWay(ids);
  1344. }).then(() => {
  1345. this.getList();
  1346. this.msgSuccess("删除成功");
  1347. }).catch(() => {});
  1348. },
  1349. /** 导出按钮操作 */
  1350. handleExport() {
  1351. const queryParams = this.queryParams;
  1352. this.$confirm('是否确认导出所有企微活码数据项?', "警告", {
  1353. confirmButtonText: "确定",
  1354. cancelButtonText: "取消",
  1355. type: "warning"
  1356. }).then(() => {
  1357. this.exportLoading = true;
  1358. return exportContactWay(queryParams);
  1359. }).then(response => {
  1360. this.download(response.msg);
  1361. this.exportLoading = false;
  1362. }).catch(() => {});
  1363. }
  1364. }
  1365. };
  1366. </script>
  1367. <style scoped>
  1368. .avatar-uploader .el-upload {
  1369. border: 1px dashed #d9d9d9;
  1370. border-radius: 6px;
  1371. cursor: pointer;
  1372. position: relative;
  1373. overflow: hidden;
  1374. }
  1375. .avatar-uploader .el-upload:hover {
  1376. border-color: #409EFF;
  1377. }
  1378. .avatar-uploader-icon {
  1379. font-size: 28px;
  1380. color: #8c939d;
  1381. width: 150px;
  1382. height: 150px;
  1383. line-height: 150px;
  1384. text-align: center;
  1385. }
  1386. </style>
  1387. <style scoped>
  1388. /* CSS 样式 */
  1389. .tag-container {
  1390. display: flex;
  1391. flex-wrap: wrap; /* 超出宽度时自动换行 */
  1392. gap: 8px; /* 设置标签之间的间距 */
  1393. }
  1394. .name-background {
  1395. display: inline-block;
  1396. background-color: #abece6; /* 背景颜色 */
  1397. padding: 4px 8px; /* 调整内边距,让背景包裹文字 */
  1398. border-radius: 4px; /* 可选:设置圆角 */
  1399. }
  1400. .tag-box {
  1401. padding: 8px 12px;
  1402. border: 1px solid #989797;
  1403. border-radius: 4px;
  1404. cursor: pointer;
  1405. display: inline-block;
  1406. }
  1407. .tag-selected {
  1408. background-color: #00bc98;
  1409. color: #fff;
  1410. border-color: #00bc98;
  1411. }
  1412. .el-tag + .el-tag {
  1413. margin-left: 10px;
  1414. }
  1415. .button-new-tag {
  1416. margin-left: 10px;
  1417. height: 32px;
  1418. line-height: 30px;
  1419. padding-top: 0;
  1420. padding-bottom: 0;
  1421. }
  1422. .input-new-tag {
  1423. width: 90px;
  1424. margin-left: 10px;
  1425. vertical-align: bottom;
  1426. }
  1427. /* 新增的滚动容器样式(不影响原有样式) */
  1428. .scroll-wrapper {
  1429. max-height: 130px; /* 大约三行的高度 */
  1430. overflow-y: auto; /* 垂直滚动 */
  1431. padding-right: 5px; /* 为滚动条留出空间 */
  1432. }
  1433. /* 美化滚动条(可选) */
  1434. .scroll-wrapper::-webkit-scrollbar {
  1435. width: 6px;
  1436. }
  1437. .scroll-wrapper::-webkit-scrollbar-thumb {
  1438. background: rgba(0, 0, 0, 0.2);
  1439. border-radius: 3px;
  1440. }
  1441. </style>