Time-limit-edit.vue 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. <template>
  2. <div class="system-timeLimit-edit-container">
  3. <el-dialog v-model="state.dialogVisible" width="60%" draggable title="新增时限">
  4. <el-form :model="state.ruleForm" ref="ruleFormRef" label-width="100px" scroll-to-error>
  5. <el-row :gutter="5">
  6. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  7. <el-form-item label="配置名称" prop="timeLimitName" :rules="[{ required: true, message: '请填写配置名称', trigger: 'blur' }]">
  8. <el-input v-model="state.ruleForm.timeLimitName" placeholder="请填写配置名称" clearable max-length="50"></el-input>
  9. </el-form-item>
  10. </el-col>
  11. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  12. <el-form-item label="业务名称" prop="workflowObj" :rules="[{ required: true, message: '请选择业务名称', trigger: 'change' }]">
  13. <el-select
  14. v-model="state.ruleForm.workflowObj"
  15. placeholder="请选择业务名称"
  16. style="width: calc(100% - 60px)"
  17. value-key="key"
  18. @change="
  19. (val) => {
  20. state.ruleForm.workflowCode = val.key;
  21. state.ruleForm.workflowName = val.value;
  22. }
  23. "
  24. >
  25. <el-option v-for="item in state.moduleOptions" :key="item.key" :label="item.value" :value="item" />
  26. </el-select>
  27. <el-tooltip placement="top-start" v-if="state.ruleForm.workflowCode === 'Order'">
  28. <SvgIcon name="ele-InfoFilled" size="24px" color="var(--el-color-primary)" class="ml15" />
  29. <template #content>
  30. 说明:时限计算优先级依次为指定优先级、组合、时限最短。<br />
  31. 若已配置指定参数优先级的,则先按指定的优先级计算办理期限;
  32. <br />无指定优先级的,默认按组合最短时限计算办理期限;<br />
  33. 无组合配置的,则默认按已配置的参数最短时限计算办理期限;未配置时限的参数,默认为无时限要求。
  34. </template>
  35. </el-tooltip>
  36. </el-form-item>
  37. </el-col>
  38. </el-row>
  39. </el-form>
  40. <el-collapse
  41. v-model="state.collapseArr"
  42. class="collapse-box mt20"
  43. style="border-top: none"
  44. v-loading="state.loading"
  45. v-if="state.ruleForm.workflowCode === 'Order'"
  46. >
  47. <p class="border-title mb10">参数信息</p>
  48. <!-- 参数多选 -->
  49. <div class="pl20 pr20">
  50. <el-checkbox-group v-model="state.parameterList" class="pd20">
  51. <el-row>
  52. <el-col v-for="(item, index) in state.baseData" :key="index" :xs="24" :sm="8" :md="8" :lg="6" :xl="4">
  53. <el-checkbox :label="item" @change="(val) => parameterChange(val, item)">{{ item.name }}</el-checkbox>
  54. </el-col>
  55. </el-row>
  56. </el-checkbox-group>
  57. <el-collapse-item name="1">
  58. <template #title>
  59. <p class="pl10">
  60. <b class="font14">已选参数</b>
  61. </p>
  62. </template>
  63. <div class="parameter pl20 pr20">
  64. <!-- 已选列表 -->
  65. <div class="mt20 parameter-choose">
  66. <el-row>
  67. <el-col v-for="(item, index) in state.paramArr" :key="index" :xs="24" :sm="8" :md="8" :lg="6" :xl="4">
  68. <div class="parameter-choose-one text-no-wrap" :class="{ active: item.active }" @click="chooseParameter(item)">
  69. {{ item.name }}<span v-if="item.paramValue.length">({{ item.paramValue.length }})</span>
  70. </div>
  71. </el-col>
  72. </el-row>
  73. </div>
  74. <!-- 参数表格 -->
  75. <el-table :data="state.currentParam.paramValue" class="mt20" v-if="state.currentParam">
  76. <el-table-column :label="state.currentParam.name" prop="paramTypeValue">
  77. <template #default="{ row }">
  78. <template v-if="state.currentParam.typeCode === 'HotPots'">
  79. <el-tree-select
  80. class="w100"
  81. v-model="row.paramTypeValue"
  82. filterable
  83. placeholder="请选择热点分类"
  84. :props="HotspotProps"
  85. lazy
  86. :load="load"
  87. node-key="id"
  88. check-strictly
  89. :render-after-expand="false"
  90. @node-click="
  91. (val, e) => {
  92. state.hotspotExternal = [];
  93. state.external = [];
  94. row.paramTypeName = val.hotSpotFullName;
  95. state.hotspotExternal = getParentId(e, state.external);
  96. row.hotParamParent = getParentId(e, state.external).join(',');
  97. }
  98. "
  99. :default-expanded-keys="state.hotspotExternal"
  100. />
  101. </template>
  102. <template v-else>
  103. <el-select
  104. v-model="row.paramTypeObj"
  105. :placeholder="'请选择' + state.currentParam.name"
  106. value-key="key"
  107. class="w100"
  108. @change="
  109. (val) => {
  110. row.paramTypeValue = val.key;
  111. row.paramTypeName = val.value;
  112. getSelectedParams();
  113. getEnableAcceptType();
  114. }
  115. "
  116. >
  117. <el-option v-for="item in state.selectArray" :key="item.key" :label="item.value" :value="item" :disabled="item.disabled" />
  118. </el-select>
  119. </template>
  120. </template>
  121. </el-table-column>
  122. <el-table-column label="时限" prop="name">
  123. <template #default="{ row }">
  124. <el-input-number
  125. v-model="row.timeLimitValue"
  126. :min="1"
  127. @change="
  128. (val) => {
  129. getSelectedParams();
  130. getEnableAcceptType();
  131. if (row.timeLimitType !== 1) row.hour = val * 24;
  132. else row.hour = val;
  133. }
  134. "
  135. placeholder="请填写时限"
  136. class="w100"
  137. ></el-input-number>
  138. </template>
  139. </el-table-column>
  140. <el-table-column label="单位" prop="name">
  141. <template #default="{ row }">
  142. <el-select
  143. v-model="row.hourObj"
  144. placeholder="请选择单位"
  145. class="w100"
  146. value-key="key"
  147. @change="
  148. (val) => {
  149. row.timeLimitType = val.key;
  150. if (val.key !== 1) row.hour = row.timeLimitValue * 24;
  151. else row.hour = row.timeLimitValue;
  152. row.timeLimitTypeName = val.value;
  153. getSelectedParams();
  154. getEnableAcceptType();
  155. }
  156. "
  157. >
  158. <el-option v-for="item in state.timeType" :key="item.key" :label="item.value" :value="item" />
  159. </el-select>
  160. </template>
  161. </el-table-column>
  162. <el-table-column align="center" width="100">
  163. <template #header>
  164. <el-button type="primary" @click="handleAdd"> 新增 </el-button>
  165. </template>
  166. <template #default="scope">
  167. <el-button @click="handleDelete(scope.row, scope.$index)" type="danger" text>删除</el-button>
  168. </template>
  169. </el-table-column>
  170. </el-table>
  171. <div class="mt20"></div>
  172. </div>
  173. </el-collapse-item>
  174. <el-collapse-item name="2">
  175. <template #title>
  176. <p class="pl10">
  177. <b class="font14">已配置参数</b>
  178. </p>
  179. </template>
  180. <div class="parameter-stop pd20">
  181. <el-row>
  182. <el-col v-for="(item, index) in state.paramSelect" :key="index" :xs="24" :sm="8" :md="8" :lg="6" :xl="4" :title="item.name">
  183. <div class="parameter-stop-one mb10 text-no-wrap" :class="{ active: item.active }" @click="selectParameter(item)">
  184. {{ item.name }}
  185. </div>
  186. </el-col>
  187. </el-row>
  188. </div>
  189. </el-collapse-item>
  190. <el-collapse-item name="3">
  191. <template #title>
  192. <p class="flex-center-align pl10">
  193. <b class="font14">指定优先级</b>
  194. <el-tooltip placement="top-start" content="选中已配置参数,可自定义优先级,参数越靠前优先级越高。" trigger="hover">
  195. <SvgIcon name="ele-QuestionFilled" size="16px" color="var(--el-color-info)" class="ml5"></SvgIcon>
  196. </el-tooltip>
  197. </p>
  198. </template>
  199. <div class="pd20">
  200. <draggable-list :list="state.priority" :force-fallback="true" animation="300" @end="onEnd" itemKey="id" class="parameter-sort">
  201. <template #item="item">
  202. <div class="parameter-sort-one" :title="item.element.timeLimitValue">
  203. <el-tag class="mr20"> {{ item.index + 1 }}. {{ item.element.name }} </el-tag>
  204. </div>
  205. </template>
  206. </draggable-list>
  207. </div>
  208. </el-collapse-item>
  209. </div>
  210. </el-collapse>
  211. <p class="border-title mb10 mt20" v-if="state.ruleForm.workflowCode === 'Order'">参数组合</p>
  212. <!-- 组合参数表格 -->
  213. <div class="pd20" v-if="state.ruleForm.workflowCode === 'Order'">
  214. <el-table :data="state.combination">
  215. <el-table-column label="组合名称" prop="combinationName">
  216. <template #default="{ row }">
  217. <el-input v-model="row.combinationName" placeholder="请填写组合名称" class="w100" max-length="30"></el-input>
  218. </template>
  219. </el-table-column>
  220. <el-table-column label="参数" prop="combinationDisplayParam">
  221. <template #default="{ row }">
  222. <div class="flex-center-align">
  223. <span class="omit text-no-wrap" :title="row.combinationDisplayParam">{{ row.combinationDisplayParam }}</span>
  224. <el-button class="ml3" text title="配置参数" type="primary" @click="chooseCombination(row)">
  225. <SvgIcon name="ele-Edit" size="16px" />
  226. </el-button>
  227. </div>
  228. </template>
  229. </el-table-column>
  230. <el-table-column label="时限" prop="timeLimitValue">
  231. <template #default="{ row }">
  232. <el-input-number
  233. v-model="row.timeLimitValue"
  234. :min="1"
  235. placeholder="请填写时限"
  236. class="w100"
  237. @change="
  238. (val) => {
  239. if (row.timeLimit !== 1) row.hour = val * 24;
  240. else row.hour = val;
  241. }
  242. "
  243. ></el-input-number>
  244. </template>
  245. </el-table-column>
  246. <el-table-column label="单位" prop="hourObj">
  247. <template #default="{ row }">
  248. <el-select
  249. v-model="row.hourObj"
  250. value-key="key"
  251. placeholder="请选择单位"
  252. class="w100"
  253. @change="
  254. (val) => {
  255. row.timeLimit = val.key;
  256. if (val.key !== 1) row.hour = row.timeLimitValue * 24;
  257. else row.hour = row.timeLimitValue;
  258. row.timeLimitTypeName = val.value;
  259. }
  260. "
  261. >
  262. <el-option v-for="item in state.timeType" :key="item.key" :label="item.value" :value="item" />
  263. </el-select>
  264. </template>
  265. </el-table-column>
  266. <el-table-column align="center" width="100">
  267. <template #header>
  268. <el-button type="primary" @click="combinationAdd"> 新增 </el-button>
  269. </template>
  270. <template #default="scope">
  271. <el-button @click="combinationDelete(scope.row, scope.$index)" type="danger" text>删除</el-button>
  272. </template>
  273. </el-table-column>
  274. </el-table>
  275. </div>
  276. <template #footer>
  277. <span class="dialog-footer">
  278. <el-button @click="onSubmit(ruleFormRef)" class="default-button">暂 存</el-button>
  279. <el-button type="primary" @click="onConfirm(ruleFormRef)">确 定</el-button>
  280. </span>
  281. </template>
  282. </el-dialog>
  283. <el-dialog v-model="state.paramDialog" width="700" draggable title="参数选择">
  284. <el-form :model="state.paramForm" ref="paramFormRef" label-width="100px">
  285. <el-row :gutter="5">
  286. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  287. <el-form-item label="受理类型" prop="acceptType" :rules="[{ required: false, message: '请选择受理类型', trigger: 'change' }]">
  288. <el-select
  289. v-model="state.paramForm.acceptType"
  290. placeholder="请选择受理类型"
  291. class="w100"
  292. value-key="key"
  293. clearable
  294. @clear="clearCombinationParam('AcceptType')"
  295. >
  296. <el-option v-for="item in state.result.acceptType" :key="item.key" :label="item.value" :value="item" />
  297. </el-select>
  298. </el-form-item>
  299. </el-col>
  300. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  301. <el-form-item label="热点分类" prop="hotspot" :rules="[{ required: false, message: '请选择热点分类', trigger: 'change' }]">
  302. <el-tree-select
  303. class="w100"
  304. v-model="state.paramForm.hotspot"
  305. filterable
  306. placeholder="请选择热点分类"
  307. :props="HotspotProps"
  308. lazy
  309. :load="load"
  310. node-key="id"
  311. check-strictly
  312. :render-after-expand="false"
  313. @node-click="getComHotspot"
  314. ref="hotspotComRef"
  315. :default-expanded-keys="state.hotspotExternalCom"
  316. clearable
  317. @clear="clearCombinationParam('HotPots')"
  318. />
  319. </el-form-item>
  320. </el-col>
  321. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  322. <el-form-item label="来源渠道" prop="sourceChannel" :rules="[{ required: false, message: '请选择来源渠道', trigger: 'change' }]">
  323. <el-select
  324. v-model="state.paramForm.sourceChannel"
  325. placeholder="请选择来源渠道"
  326. class="w100"
  327. value-key="key"
  328. filterable
  329. clearable
  330. @clear="clearCombinationParam('SourceChannel')"
  331. >
  332. <el-option v-for="item in state.result.sourceChannel" :key="item.key" :label="item.value" :value="item" />
  333. </el-select>
  334. </el-form-item>
  335. </el-col>
  336. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  337. <el-form-item label="来电人身份" prop="identityType" :rules="[{ required: false, message: '请选择来电人身份', trigger: 'change' }]">
  338. <el-select
  339. v-model="state.paramForm.identityType"
  340. placeholder="请选择来电人身份"
  341. class="w100"
  342. value-key="key"
  343. filterable
  344. clearable
  345. @clear="clearCombinationParam('IdentityType')"
  346. >
  347. <el-option v-for="item in state.result.identityType" :key="item.key" :label="item.value" :value="item" />
  348. </el-select>
  349. </el-form-item>
  350. </el-col>
  351. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  352. <el-form-item label="工单类型" prop="orderType" :rules="[{ required: false, message: '请选择工单类型', trigger: 'change' }]">
  353. <el-select
  354. v-model="state.paramForm.orderType"
  355. placeholder="请选择工单类型"
  356. class="w100"
  357. value-key="key"
  358. filterable
  359. clearable
  360. @clear="clearCombinationParam('OrderType')"
  361. >
  362. <el-option v-for="item in state.result.orderType" :key="item.key" :label="item.value" :value="item" />
  363. </el-select>
  364. </el-form-item>
  365. </el-col>
  366. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  367. <el-form-item label="证件类型" prop="certType" :rules="[{ required: false, message: '请选择证件类型类', trigger: 'change' }]">
  368. <el-select
  369. v-model="state.paramForm.certType"
  370. placeholder="请选择证件类型"
  371. class="w100"
  372. value-key="dicDataValue"
  373. filterable
  374. clearable
  375. @clear="clearCombinationParam('LicenceType')"
  376. >
  377. <el-option v-for="item in state.result.certType" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
  378. </el-select>
  379. </el-form-item>
  380. </el-col>
  381. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  382. <el-form-item label="紧急程度" prop="emergencyLevel" :rules="[{ required: false, message: '请选择紧急程度', trigger: 'change' }]">
  383. <el-select
  384. v-model="state.paramForm.emergencyLevel"
  385. placeholder="请选择紧急程度"
  386. class="w100"
  387. value-key="key"
  388. filterable
  389. clearable
  390. @clear="clearCombinationParam('EmergencyLevel')"
  391. >
  392. <el-option v-for="item in state.result.emergencyLevel" :key="item.key" :label="item.value" :value="item" />
  393. </el-select>
  394. </el-form-item>
  395. </el-col>
  396. <!-- <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  397. <el-form-item label="默认参数" prop="emergencyLevel" :rules="[{ required: false, message: '请选择默认参数', trigger: 'change' }]">
  398. <el-select v-model="state.paramForm.emergencyLevel" placeholder="请选择默认参数" class="w100" value-key="key" filterable>
  399. <el-option v-for="item in state.result.emergencyLevel" :key="item.key" :label="item.value" :value="item" />
  400. </el-select>
  401. </el-form-item>
  402. </el-col> -->
  403. </el-row>
  404. </el-form>
  405. <template #footer>
  406. <span class="dialog-footer">
  407. <el-button class="default-button" @click="state.paramDialog = false">取 消</el-button>
  408. <el-button type="primary" @click="onConfirmCom">确 定</el-button>
  409. </span>
  410. </template>
  411. </el-dialog>
  412. </div>
  413. </template>
  414. <script lang="ts" setup name="EditTimeLimit">
  415. import { ref, reactive } from 'vue';
  416. import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
  417. import { guid } from '@/utils/tools';
  418. import { removeDuplicate } from '@/utils/arrayOperation';
  419. import DraggableList from 'vuedraggable';
  420. import { hotSpotType } from '@/api/business/order';
  421. import { timeLimitDetail, timeLimitUpdate } from '@/api/system/timeLimit';
  422. import other from '@/utils/other';
  423. // 定义子组件向父组件传值/事件
  424. const emit = defineEmits(['updateList', 'openDialog', 'closeDialog']);
  425. const paramTypeNameType: any = {
  426. AcceptType: '受理类型',
  427. HotPots: '热点分类',
  428. SourceChannel: '来源渠道',
  429. IdentityType: '来电人身份',
  430. OrderType: '工单类型',
  431. LicenceType: '证件类型',
  432. EmergencyLevel: '紧急程度',
  433. DefaultTime: '默认参数',
  434. };
  435. // 定义变量内容
  436. const ruleFormRef = ref<RefType>();
  437. const state = reactive<any>({
  438. ruleForm: {},
  439. paramForm: {},
  440. paramDialog: false,
  441. dialogVisible: false,
  442. baseData: [], // 基础数据
  443. parameterList: [], //选择基础数据
  444. paramArr: [], //参数列表信息
  445. currentParam: null as any, // 当前参数
  446. collapseArr: ['1', '2', '3', '4'], //展开列表
  447. result: {}, //所有基础数据
  448. timeType: [], // 单位
  449. moduleOptions: [], // 业务名称
  450. selectArray: [], // 可选数据
  451. paramSelect: [], // 已配置的数据 (可选择)
  452. priority: [], // 排序参数
  453. combination: [], // 组合
  454. hotspotExternal: [], // 热点分类展开
  455. external: [],
  456. hotspotExternalCom: [], // 组合热点分类展开
  457. externalCom: [],
  458. loading: false,
  459. timeLimitId: null as any,
  460. });
  461. // 热点分类远程搜索
  462. const HotspotProps = {
  463. label: 'hotSpotFullName',
  464. children: 'children',
  465. isLeaf: 'isLeaf',
  466. };
  467. // 热点分类懒加载
  468. const load = async (node: any, resolve: any) => {
  469. if (node.isLeaf) return resolve([]);
  470. const res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
  471. resolve(res.result);
  472. };
  473. // 递归查找父级Id
  474. const getParentId = (val: any, arr: string[]) => {
  475. if (val.data.parentId) {
  476. arr.push(val.data.parentId);
  477. getParentId(val.parent, arr);
  478. }
  479. return arr;
  480. };
  481. const resetState = () => {
  482. state.parameterList = [];
  483. state.paramArr = [];
  484. state.currentParam = null;
  485. state.selectArray = [];
  486. state.paramSelect = [];
  487. state.priority = [];
  488. state.combination = [];
  489. state.hotspotExternal = [];
  490. state.external = [];
  491. state.hotspotExternalCom = [];
  492. state.externalCom = [];
  493. };
  494. // 打开弹窗
  495. const openDialog = (val: any, baseData: any) => {
  496. state.dialogVisible = true;
  497. state.loading = true;
  498. resetState();
  499. ruleFormRef.value?.resetFields();
  500. const { baseData: stateBaseData = [], timeType = [], moduleOptions = [] } = baseData;
  501. state.result = baseData;
  502. state.baseData = stateBaseData; //基础数据
  503. state.timeType = timeType; //单位
  504. state.moduleOptions = moduleOptions; //业务名称
  505. state.timeLimitId = val.id;
  506. timeLimitDetail(val.id)
  507. .then((res: any) => {
  508. // 表单数据
  509. const { timeLimitName, workflowCode, workflowName } = res.result;
  510. state.ruleForm.timeLimitName = timeLimitName;
  511. state.ruleForm.workflowObj = {
  512. key: workflowCode,
  513. value: workflowName,
  514. };
  515. state.ruleForm.workflowCode = workflowCode;
  516. state.ruleForm.workflowName = workflowName;
  517. // 参数
  518. for (const i of res.result.paramArr) {
  519. for (const j of state.baseData) {
  520. if (i.paramType === j.typeCode) {
  521. state.parameterList.push({
  522. ...j,
  523. });
  524. state.parameterList = removeDuplicate(state.parameterList, 'typeCode');
  525. parameterChange(true, j);
  526. }
  527. }
  528. for (const k of state.paramArr) {
  529. if (i.paramType === k.paramType) {
  530. k.paramValue.push({
  531. paramTypeObj: {
  532. key: i.paramTypeValue,
  533. value: i.paramTypeName,
  534. },
  535. hourObj: {
  536. key: i.timeLimitType,
  537. },
  538. ...i,
  539. });
  540. if (i.hotParamParent) state.hotspotExternal = i.hotParamParent.split(',');
  541. }
  542. }
  543. }
  544. // 配置参数
  545. getSelectedParams();
  546. for (let i of state.paramSelect) {
  547. for (let j of res.result.priority) {
  548. if (i.id === j.code) {
  549. i.active = true;
  550. }
  551. }
  552. }
  553. state.priority = res.result.priority;
  554. state.priority = state.priority.map((v: any) => {
  555. return {
  556. ...v,
  557. name: paramTypeNameType[v.paramType] + '-' + v.paramTypeName,
  558. };
  559. });
  560. // 组合
  561. state.combination = res.result.combination;
  562. state.combination = state.combination.map((v: any) => {
  563. return {
  564. ...v,
  565. hourObj: {
  566. key: v.timeLimit,
  567. },
  568. };
  569. });
  570. state.loading = false;
  571. })
  572. .catch(() => {
  573. state.loading = false;
  574. state.dialogVisible = false;
  575. });
  576. };
  577. // 关闭弹窗
  578. const closeDialog = () => {
  579. state.dialogVisible = false;
  580. emit('closeDialog');
  581. };
  582. // 选择参数
  583. const parameterChange = (value: string | number | boolean, item: any) => {
  584. let arr: any = other.deepClone(state.parameterList);
  585. state.paramArr = arr.map((v: any) => {
  586. let j = state.paramArr.find((j: any) => j.paramType === v.typeCode);
  587. if (j) {
  588. v.paramValue = j.paramValue;
  589. }
  590. return {
  591. ...v,
  592. paramType: v.typeCode,
  593. paramValue: v.paramValue ?? [],
  594. };
  595. });
  596. if (value) {
  597. //新增选中新增的
  598. chooseParameter(item);
  599. } else {
  600. // 取消选中最后一个
  601. chooseParameter(state.paramArr[state.paramArr.length - 1]);
  602. }
  603. };
  604. // 选择参数 切换当前
  605. const chooseParameter = (item: any) => {
  606. switch (item?.typeCode) {
  607. case 'AcceptType':
  608. state.selectArray = state.result.acceptType;
  609. break;
  610. case 'HotPots': // 热点
  611. state.selectArray = [];
  612. break;
  613. case 'SourceChannel':
  614. state.selectArray = state.result.sourceChannel;
  615. break;
  616. case 'IdentityType':
  617. state.selectArray = state.result.identityType;
  618. break;
  619. case 'OrderType':
  620. state.selectArray = state.result.orderType;
  621. break;
  622. case 'LicenceType': //证件类型
  623. state.selectArray = state.result.certType.map((item: any) => {
  624. return {
  625. key: item.dicDataValue,
  626. value: item.dicDataName,
  627. };
  628. });
  629. break;
  630. case 'EmergencyLevel':
  631. state.selectArray = state.result.emergencyLevel;
  632. break;
  633. case 'DefaultTime': //默认参数
  634. state.selectArray = [];
  635. break;
  636. default:
  637. break;
  638. }
  639. // state.selectArray = state.result[state.currentParam.typeCode];
  640. state.paramArr.forEach((v: any) => {
  641. if (item.typeCode === v.paramType) {
  642. v.active = true;
  643. state.currentParam = v;
  644. } else {
  645. v.active = false;
  646. }
  647. });
  648. getEnableAcceptType();
  649. getSelectedParams();
  650. };
  651. // 新增
  652. const handleAdd = () => {
  653. state.currentParam.paramValue.push({
  654. id: guid(),
  655. paramType: state.currentParam.paramType,
  656. paramTypeName: '',
  657. paramTypeValue: '',
  658. timeLimitValue: 1,
  659. hour: '',
  660. });
  661. getEnableAcceptType();
  662. getSelectedParams();
  663. };
  664. // 删除
  665. const handleDelete = (row: any, index: number) => {
  666. ElMessageBox.confirm(`确定要删除?`, '提示', {
  667. confirmButtonText: '确定',
  668. cancelButtonText: '取消',
  669. type: 'warning',
  670. draggable: true,
  671. cancelButtonClass: 'default-button',
  672. })
  673. .then(() => {
  674. state.currentParam.paramValue.splice(index, 1);
  675. getEnableAcceptType();
  676. getSelectedParams();
  677. })
  678. .catch(() => {});
  679. };
  680. // 获取可用的数组
  681. const getEnableAcceptType = () => {
  682. if (state.currentParam?.paramValue.length) {
  683. const array = state.currentParam.paramValue.map((v: any) => v.paramTypeValue);
  684. state.selectArray.forEach((v: any) => {
  685. v.disabled = array.includes(v.key);
  686. });
  687. }
  688. };
  689. // 获取已经配置的列表
  690. const getSelectedParams = () => {
  691. const arr = state.paramArr.flatMap((i: any) => i.paramValue).filter((j: any) => j.paramTypeName && j.id && j.timeLimitType);
  692. state.paramSelect = arr.map((v: any) => {
  693. const { id, active } = v;
  694. const selected = state.paramSelect.find((j: any) => j.id === id);
  695. return {
  696. ...v,
  697. active: selected?.active ?? false,
  698. name: paramTypeNameType[v.paramType] + '-' + v.paramTypeName,
  699. };
  700. });
  701. };
  702. // 选择已配置的
  703. const selectParameter = (item: any) => {
  704. state.paramSelect.forEach((v: any) => {
  705. if (item.id === v.id) {
  706. v.active = !v.active;
  707. }
  708. });
  709. // 排序数组
  710. state.priority = state.paramSelect.filter((v: any) => {
  711. return v.active;
  712. });
  713. state.priority = state.priority.map((item: any, index: number) => {
  714. return {
  715. ...item,
  716. sort: index,
  717. code: item.id,
  718. };
  719. });
  720. };
  721. //结束拖拽事件
  722. const onEnd = () => {
  723. state.priority = state.priority.map((item: any, index: number) => {
  724. return {
  725. ...item,
  726. sort: index,
  727. code: item.id,
  728. };
  729. });
  730. };
  731. // 新增组合
  732. const combinationAdd = () => {
  733. state.combination.push({
  734. id: guid(),
  735. combinationName: '',
  736. combinationDisplayParam: '',
  737. combinationParam: [],
  738. timeLimitValue: 1,
  739. hour: '',
  740. });
  741. };
  742. // 删除组合
  743. const combinationDelete = (row: any, index: number) => {
  744. ElMessageBox.confirm(`确定要删除?`, '提示', {
  745. confirmButtonText: '确定',
  746. cancelButtonText: '取消',
  747. type: 'warning',
  748. draggable: true,
  749. cancelButtonClass: 'default-button',
  750. })
  751. .then(() => {
  752. state.combination.splice(index, 1);
  753. getEnableAcceptType();
  754. getSelectedParams();
  755. })
  756. .catch(() => {});
  757. };
  758. // 选择组合参数
  759. const chooseCombination = (row: any) => {
  760. state.paramForm = row;
  761. for (let i of state.combination) {
  762. for (let j of i.combinationParam) {
  763. switch (j.paramType) {
  764. case 'AcceptType':
  765. state.paramForm.acceptType = {
  766. key: j.paramValue,
  767. value: j.paramName,
  768. };
  769. break;
  770. case 'HotPots':
  771. state.paramForm.hotspot = j.paramValue;
  772. state.paramForm.hotspotSpliceName = j.paramName;
  773. if (j.hotParamParent) state.hotspotExternalCom = j.hotParamParent.split(',');
  774. break;
  775. case 'SourceChannel':
  776. state.paramForm.sourceChannel = {
  777. key: j.paramValue,
  778. value: j.paramName,
  779. };
  780. break;
  781. case 'IdentityType':
  782. state.paramForm.identityType = {
  783. key: j.paramValue,
  784. value: j.paramName,
  785. };
  786. break;
  787. case 'OrderType':
  788. state.paramForm.orderType = {
  789. key: j.paramValue,
  790. value: j.paramName,
  791. };
  792. break;
  793. case 'LicenceType':
  794. state.paramForm.certType = {
  795. dicDataValue: j.paramValue,
  796. dicDataName: j.paramName,
  797. };
  798. break;
  799. case 'EmergencyLevel':
  800. state.paramForm.emergencyLevel = {
  801. key: j.paramValue,
  802. value: j.paramName,
  803. };
  804. break;
  805. default:
  806. break;
  807. }
  808. }
  809. }
  810. state.paramDialog = true;
  811. };
  812. // 选择组合热点
  813. const getComHotspot = (val: any, e: any) => {
  814. state.hotspotExternalCom = [];
  815. state.externalCom = [];
  816. state.hotspotExternalCom = getParentId(e, state.externalCom);
  817. state.paramForm.hotspotSpliceName = val.hotSpotFullName;
  818. };
  819. // 删除组合参数
  820. const clearCombinationParam = (val: any) => {
  821. let item = state.combination.find((item: any) => item.id === state.paramForm.id);
  822. item.combinationParam = item.combinationParam.filter((v: any) => v.paramType !== val);
  823. };
  824. // 参数组合确定
  825. const onConfirmCom = () => {
  826. let comName: string[] = [];
  827. let item = state.combination.find((item: any) => item.id === state.paramForm.id);
  828. if (item) {
  829. if (item.acceptType?.value) {
  830. item.combinationParam.push({
  831. paramName: item.acceptType.value,
  832. paramValue: item.acceptType.key,
  833. hotParamParent: '',
  834. paramType: 'AcceptType',
  835. });
  836. comName.push(`受理类型-${item.acceptType.value}`);
  837. }
  838. if (item?.hotspot) {
  839. item.combinationParam.push({
  840. paramName: item.hotspotSpliceName,
  841. paramValue: item.hotspot,
  842. hotParamParent: state.hotspotExternalCom.join(','),
  843. paramType: 'HotPots',
  844. });
  845. comName.push(`热点分类-${item.hotspotSpliceName}`);
  846. }
  847. if (item.identityType?.value) {
  848. item.combinationParam.push({
  849. paramName: item.identityType.value,
  850. paramValue: item.identityType.key,
  851. hotParamParent: '',
  852. paramType: 'IdentityType',
  853. });
  854. comName.push(`来电人身份-${item.identityType.value}`);
  855. }
  856. if (item.sourceChannel?.value) {
  857. item.combinationParam.push({
  858. paramName: item.sourceChannel.value,
  859. paramValue: item.sourceChannel.key,
  860. hotParamParent: '',
  861. paramType: 'SourceChannel',
  862. });
  863. comName.push(`来源渠道-${item.sourceChannel.value}`);
  864. }
  865. if (item.orderType?.value) {
  866. item.combinationParam.push({
  867. paramName: item.orderType.value,
  868. paramValue: item.orderType.key,
  869. hotParamParent: '',
  870. paramType: 'OrderType',
  871. });
  872. comName.push(`工单类型-${item.orderType.value}`);
  873. }
  874. if (item.certType?.dicDataName) {
  875. item.combinationParam.push({
  876. paramName: item.certType.dicDataName,
  877. paramValue: item.certType.dicDataValue,
  878. hotParamParent: '',
  879. paramType: 'LicenceType',
  880. });
  881. comName.push(`证件类型-${item.certType.dicDataName}`);
  882. }
  883. if (item.emergencyLevel?.value) {
  884. item.combinationParam.push({
  885. paramName: item.emergencyLevel.value,
  886. paramValue: item.emergencyLevel.key,
  887. hotParamParent: '',
  888. paramType: 'EmergencyLevel',
  889. });
  890. comName.push(`紧急程度-${item.emergencyLevel.value}`);
  891. }
  892. // if(state.paramForm.emergencyLevel.value){
  893. // state.paramForm.push({
  894. // paramName:state.paramForm.emergencyLevel.value,
  895. // paramValue:state.paramForm.emergencyLevel.key,
  896. // hotParamParent:'',
  897. // paramType:'EmergencyLevel'
  898. // })
  899. // comName+=`默认参数-${state.paramForm.emergencyLevel.value}&`;
  900. // }
  901. }
  902. item.combinationParam = removeDuplicate(item.combinationParam, 'paramType');
  903. state.paramForm.hotParamParent = state.hotspotExternalCom.join(',');
  904. if (item.combinationParam.length < 2) {
  905. ElMessageBox.alert('一个组合中至少包含两个参数', '提示', {
  906. confirmButtonText: '确定',
  907. });
  908. return;
  909. }
  910. item.combinationDisplayParam = comName.join('&');
  911. state.paramDialog = false;
  912. };
  913. // 定义一个函数来检查某个属性是否存在,如果不存在就给出提示信息,并返回false
  914. const checkProperty = (obj: any, property: string, message: string) => {
  915. if (!obj[property]) {
  916. ElMessage.warning(message);
  917. return false;
  918. }
  919. return true;
  920. };
  921. // 暂存
  922. const onSubmit = async (formEl: FormInstance | undefined) => {
  923. if (!formEl) return;
  924. await formEl.validate((valid: boolean) => {
  925. if (!valid) return;
  926. let arr: any = [];
  927. for (let i of state.paramArr) {
  928. if (i.paramValue.length) {
  929. for (let j of i.paramValue) {
  930. // 检查paramTypeName是否存在
  931. if (!checkProperty(j, 'paramTypeName', `请选择${i.name}`)) return;
  932. // 检查timeLimitValue是否存在
  933. if (!checkProperty(j, 'timeLimitValue', `请填写${i.name}的时限`)) return;
  934. // 检查timeLimitType是否存在
  935. if (!checkProperty(j, 'timeLimitType', `请选择${i.name}的单位`)) return;
  936. arr.push(j);
  937. }
  938. }
  939. }
  940. if (!arr.length) {
  941. ElMessage.warning(`请选择参数`);
  942. return;
  943. }
  944. for (let i of state.combination) {
  945. // 检查combinationName是否存在
  946. if (!checkProperty(i, 'combinationName', `请填写组合名称`)) return;
  947. // 检查combinationDisplayParam是否存在
  948. if (!checkProperty(i, 'combinationDisplayParam', `请选择组合参数`)) return;
  949. if (i.combinationParam.length.length < 2) {
  950. ElMessageBox.alert('一个组合中至少包含两个参数', '提示', {
  951. confirmButtonText: '确定',
  952. });
  953. return;
  954. }
  955. // 检查timeLimitValue是否存在
  956. if (!checkProperty(i, 'timeLimitValue', `请填写时限`)) return;
  957. // 检查timeLimit是否存在或者为0
  958. if (!checkProperty(i, 'timeLimit', `请选择组合单位`)) return;
  959. }
  960. let req = {
  961. ...state.ruleForm,
  962. paramArr: arr,
  963. priority: state.priority,
  964. combination: state.combination,
  965. id: state.timeLimitId,
  966. };
  967. timeLimitUpdate(req).then(() => {
  968. ElMessage.success('操作成功');
  969. emit('updateList');
  970. state.dialogVisible = false;
  971. });
  972. });
  973. };
  974. // 确定
  975. const onConfirm = async (formEl: FormInstance | undefined) => {
  976. if (!formEl) return;
  977. await formEl.validate((valid: boolean) => {
  978. if (!valid) return;
  979. let arr: any = [];
  980. for (let i of state.paramArr) {
  981. if (i.paramValue.length) {
  982. for (let j of i.paramValue) {
  983. // 检查paramTypeName是否存在
  984. if (!checkProperty(j, 'paramTypeName', `请选择${i.name}`)) return;
  985. // 检查timeLimitValue是否存在
  986. if (!checkProperty(j, 'timeLimitValue', `请填写${i.name}的时限`)) return;
  987. // 检查timeLimitType是否存在
  988. if (!checkProperty(j, 'timeLimitType', `请选择${i.name}的单位`)) return;
  989. arr.push(j);
  990. }
  991. }
  992. }
  993. if (!arr.length) {
  994. ElMessage.warning(`请选择参数`);
  995. return;
  996. }
  997. for (let i of state.combination) {
  998. // 检查combinationName是否存在
  999. if (!checkProperty(i, 'combinationName', `请填写组合名称`)) return;
  1000. // 检查combinationDisplayParam是否存在
  1001. if (!checkProperty(i, 'combinationDisplayParam', `请选择组合参数`)) return;
  1002. if (i.combinationParam.length.length < 2) {
  1003. ElMessageBox.alert('一个组合中至少包含两个参数', '提示', {
  1004. confirmButtonText: '确定',
  1005. });
  1006. return;
  1007. }
  1008. // 检查timeLimitValue是否存在
  1009. if (!checkProperty(i, 'timeLimitValue', `请填写时限`)) return;
  1010. // 检查timeLimit或者timeLimit(这里可能是拼写错误)是否存在或者为0
  1011. if (!checkProperty(i, 'timeLimit', `请选择组合单位`)) return;
  1012. }
  1013. // timeLimitAdd(state.ruleForm).then(() => {
  1014. // ElMessage.success('操作成功');
  1015. // emit('updateList');
  1016. // state.dialogVisible = false;
  1017. // });
  1018. });
  1019. };
  1020. //暴漏变量和方法
  1021. defineExpose({ closeDialog, openDialog });
  1022. </script>
  1023. <style lang="scss" scoped>
  1024. .system-timeLimit-edit-container {
  1025. .collapse-box {
  1026. :deep(.el-collapse-item__header) {
  1027. background-color: var(--hotline-bg-main-color);
  1028. height: 40px;
  1029. border-radius: var(--el-border-radius-base);
  1030. }
  1031. :deep(.el-collapse-item__content) {
  1032. padding-bottom: 0 !important;
  1033. .el-form-item {
  1034. margin-bottom: 5px;
  1035. .el-form-item__content {
  1036. line-height: 24px;
  1037. }
  1038. }
  1039. }
  1040. .collapse-container {
  1041. padding: 10px;
  1042. .plug-container {
  1043. border: var(--el-border);
  1044. border-radius: var(--el-border-radius-base);
  1045. margin-bottom: 15px;
  1046. &:last-child {
  1047. margin-bottom: 0;
  1048. }
  1049. .plug-container-title {
  1050. padding: 10px 15px;
  1051. font-weight: bold;
  1052. border-bottom: var(--el-border);
  1053. font-size: var(--el-font-size-medium);
  1054. }
  1055. }
  1056. }
  1057. }
  1058. :deep(.el-collapse-item__wrap) {
  1059. border-bottom: 0;
  1060. }
  1061. :deep(.el-collapse) {
  1062. border-bottom: 0;
  1063. }
  1064. :deep(.el-tabs__nav-wrap::after) {
  1065. height: 100% !important;
  1066. }
  1067. .parameter-choose {
  1068. &-one {
  1069. cursor: pointer;
  1070. text-align: center;
  1071. height: 34px;
  1072. line-height: 34px;
  1073. color: var(--el-color-primary);
  1074. width: calc(100% - 10px);
  1075. padding: 0 5px;
  1076. border: 1px solid transparent;
  1077. }
  1078. .active {
  1079. border: 1px solid var(--el-color-primary);
  1080. border-radius: var(--el-border-radius-base);
  1081. }
  1082. }
  1083. .parameter-stop {
  1084. &-one {
  1085. cursor: pointer;
  1086. text-align: center;
  1087. height: 34px;
  1088. line-height: 34px;
  1089. width: calc(100% - 10px);
  1090. padding: 0 5px;
  1091. }
  1092. .active {
  1093. border: 1px solid var(--el-color-primary);
  1094. border-radius: var(--el-border-radius-base);
  1095. color: var(--el-color-primary);
  1096. }
  1097. }
  1098. .parameter-sort {
  1099. display: flex;
  1100. flex-wrap: wrap;
  1101. &-one {
  1102. cursor: pointer;
  1103. text-align: center;
  1104. height: 34px;
  1105. line-height: 34px;
  1106. }
  1107. }
  1108. .omit {
  1109. display: inline-block;
  1110. }
  1111. }
  1112. </style>