index.vue 56 KB

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