Edit.vue 35 KB

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