index.vue 55 KB

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