externalCostApproval.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <template>
  2. <div>
  3. <PageMain class="vh100">
  4. <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
  5. <el-tab-pane :label="`待审核(${pendingReviewlength})`" name="pendingReview">
  6. </el-tab-pane>
  7. <el-tab-pane :label="`审核通过(${passlength})`" name="pass">
  8. </el-tab-pane>
  9. <el-tab-pane :label="`审核不通过(${reviewRejectedlength})`" name="reviewRejected">
  10. </el-tab-pane>
  11. </el-tabs>
  12. <SearchForm :fields="fields" :formInline="formInline" :onSearch="agreementQuery" :onReset="resetForm" />
  13. <ComplexTable :tableData="tableData" :columns="columns" :showIndex="false" :columnwidth="200" :showSelect="true"
  14. :pageInfo="pageInfo" @getList="getList" @selectionChange="selectionChange">
  15. <template v-slot:table-title-btn>
  16. <el-dropdown placement="bottom-start">
  17. <el-button> 批量管理<el-icon>
  18. <arrow-down />
  19. </el-icon>
  20. </el-button>
  21. <template #dropdown>
  22. <el-dropdown-menu>
  23. <el-dropdown-item :disabled="!sysUpAndDownList.length" @click="batchaudit">批量审核</el-dropdown-item>
  24. <el-dropdown-item :disabled="!sysUpAndDownList.length" @click="batchrejected">批量驳回</el-dropdown-item>
  25. </el-dropdown-menu>
  26. </template>
  27. </el-dropdown>
  28. <span class="col-108 ">
  29. 已选: <span class="text-red">{{ sysUpAndDownList.length }}</span> 条
  30. </span>
  31. </template>
  32. <template #costDescribe="{ data, bodyCell }">
  33. <div class="whitespace-normal">{{ data.costDescribe }}</div>
  34. </template>
  35. <template v-slot:operation="scope">
  36. <el-button v-if="scope.operationData.auditStatus == '0'" type="primary" link
  37. @click="agreemenUpdate(scope.operationData.id)"> 审核
  38. </el-button>
  39. <el-button v-if="scope.operationData.auditStatus == '2' || scope.operationData.auditStatus == '1'"
  40. type="primary" link @click="agreemenUpdate(scope.operationData.id)"> 详情
  41. </el-button>
  42. </template>
  43. </ComplexTable>
  44. </PageMain>
  45. <!-- 费用编辑组件 -->
  46. <contactPersonFeeDialogEdit :ruleFeeVisible="ruleFeeEditVisible" :headerTitle="ruleFeeHeaderTitle"
  47. :costitemEditInfo="costitemEditInfo" @save="ruleFeeEditSave" @cancel="ruleFeeEditVisible = false"
  48. operationType="audit" @rejectOperation="rejectOperation" @auditOperation="auditOperation" />
  49. </div>
  50. </template>
  51. <script lang="ts" setup>
  52. import { ref, reactive } from 'vue'
  53. import { useRoute } from 'vue-router';
  54. import { ElMessage, ElMessageBox } from 'element-plus'
  55. import { loadDicts, getDict } from '@/utils/composables/dictService';//字典组件
  56. import contactPersonFeeDialogEdit from "../externalAgreement/agreement/components/contactPersonFeeDialogEdit.vue";
  57. import api from '@/api';
  58. interface PageInfo {
  59. pageNum: number;
  60. pageSize: number;
  61. sizes: number[];
  62. total: number;
  63. }
  64. onBeforeMount(async () => {
  65. await loadDicts(['valid_status', 'is_enable', 'audit_status', 'insurance_type']);//获取多个字典
  66. if (id.value) {
  67. formInline.agreement = id.value;
  68. }
  69. findpage(0);//列表数据
  70. findpage(1);//列表数据
  71. findpage(2);//列表数据
  72. valid_status.value = getDict('valid_status');//生效状态
  73. is_enable.value = getDict('is_enable');//协议状态
  74. insurance_type.value = getDict('insurance_type')
  75. audit_status.value = getDict('audit_status')
  76. });
  77. const activeName = ref('pendingReview')
  78. const pendingReviewlength = ref(0);
  79. const passlength = ref(0);//审核通过
  80. const reviewRejectedlength = ref(0);
  81. // 两个选项卡各自的数据和分页
  82. const tableData1 = ref([]);//待审核
  83. const tableData2 = ref([]);//审核通过
  84. const tableData3 = ref([]);//审核不通过
  85. const pageInfoPending = ref({
  86. pageNum: 1,
  87. pageSize: 20,
  88. sizes: [10, 20, 30, 40, 50],
  89. total: 0,
  90. });
  91. const pageInfoPass = ref({
  92. pageNum: 1,
  93. pageSize: 20,
  94. sizes: [10, 20, 30, 40, 50],
  95. total: 0,
  96. });
  97. const pageInfoRejected = ref({
  98. pageNum: 1,
  99. pageSize: 20,
  100. sizes: [10, 20, 30, 40, 50],
  101. total: 0,
  102. });
  103. // 当前激活选项卡的数据和分页
  104. const tableData = computed(() => {
  105. return activeName.value === 'pendingReview' ? tableData1.value : activeName.value === 'pass' ? tableData2.value : tableData3.value;
  106. });
  107. const pageInfo = computed(() => {
  108. return activeName.value === 'pendingReview' ? pageInfoPending.value : activeName.value === 'pass' ? pageInfoPass.value : pageInfoRejected.value;
  109. });
  110. const sysUpAndDownList = ref<string[]>([])//选中id
  111. const insurance_type = ref();
  112. const valid_status = ref();
  113. const audit_status = ref();
  114. const is_enable = ref();
  115. const route = useRoute();
  116. const id = ref(route.query.id as string);//id参数
  117. const formInline = reactive({
  118. agreement: '',//协议信息
  119. productId: "",//归属
  120. rulesName: '',//保险公司id
  121. costRules: '',//协议类型
  122. agreementStatus: "",//有效状态
  123. auditStatus: "0",//协议状态
  124. validState: "",
  125. effectiveTime: [],
  126. failureTime: [],
  127. })
  128. //表格字段数据
  129. const fields = ref([
  130. { label: "所属协议", model: "agreement", type: "input", placeholder: "输入代码,名称,简称查找" },
  131. {
  132. label: "险种", model: "productId", type: "select", options: insurance_type,
  133. },
  134. {
  135. label: "承保规则", model: "rulesName", type: "input", placeholder: "输入业务规则查找",
  136. },
  137. {
  138. label: "费用规则", model: "costRules", type: "input", placeholder: "输入费用规则关键字查找",
  139. },
  140. {
  141. label: "费用状态", model: "agreementStatus", type: "select", placeholder: "选择状态", options: is_enable,
  142. },
  143. {
  144. label: "有效状态", model: "validState", type: "select", placeholder: "请选择状态", options: valid_status,
  145. },
  146. {
  147. label: "生效时间", model: "effectiveTime", type: "date", dateType: "datetimerange", startplaceholder: "开始时间", endplaceholder: "结束时间",
  148. format: "YYYY-MM-DD HH:mm:ss", valueFormat: "YYYY-MM-DD HH:mm:ss", timeFormat: "HH:mm:ss",
  149. onChange: (value: any) => {
  150. console.log(value)
  151. formInline.effectiveTime = value;
  152. }
  153. },
  154. {
  155. label: "失效时间", model: "failureTime", type: "date", dateType: "datetimerange", startplaceholder: "开始时间", endplaceholder: "结束时间",
  156. format: "YYYY-MM-DD HH:mm:ss", valueFormat: "YYYY-MM-DD HH:mm:ss", timeFormat: "HH:mm:ss",
  157. onChange: (value: any) => {
  158. formInline.failureTime = value;
  159. }
  160. },
  161. ]);
  162. //费用数据查询
  163. function findpage(status: any) {
  164. formInline.auditStatus = status;
  165. // 根据状态使用对应的分页数据
  166. let currentPageInfo = status == '0' ? pageInfoPending.value : status == '1' ? pageInfoPass.value : pageInfoRejected.value;
  167. api.agreementApi.CostExternalFeePageList({ pages: currentPageInfo.pageNum, size: currentPageInfo.pageSize, ...formInline, auditStatus: status }).then((res: any) => {
  168. if (res.code == '200') {
  169. currentPageInfo.pageNum = res.data.current;
  170. currentPageInfo.pageSize = res.data.size;
  171. currentPageInfo.total = res.data.total;
  172. if (status == 0) {
  173. tableData1.value = res.data.records;
  174. pendingReviewlength.value = res.data.total;
  175. } else if (status == '1') {
  176. tableData2.value = res.data.records;
  177. passlength.value = res.data.total;
  178. }
  179. else {
  180. tableData3.value = res.data.records;
  181. reviewRejectedlength.value = res.data.total;
  182. }
  183. } else {
  184. }
  185. });
  186. }
  187. const columns = [
  188. {
  189. prop: "agreementAbbreviation", label: "协议信息", width: '300',
  190. formatter: (row: any) => {
  191. return `${row.agreementCode}\n${row.agreementAbbreviation}`
  192. }
  193. },
  194. { prop: "productName", label: "险种", width: '120', },
  195. {
  196. prop: "contactPerson", label: "对接人", width: '200', formatter: (row: any) => {
  197. return `${row.contactPerson} ${row.contactMobile}`
  198. }
  199. },
  200. {
  201. prop: "isInquiry", label: "是否现询", width: '120', formatter: (row: any) => {
  202. if (row.isInquiry == '0') {
  203. return '是'
  204. } else {
  205. return "否"
  206. }
  207. }
  208. },
  209. {
  210. prop: "auditMethod", label: "审核方式", width: '120', formatter: (row: any) => {
  211. if (row.auditMethod == '0') {
  212. return '自动审核'
  213. } else {
  214. return "手动审核"
  215. }
  216. }
  217. },
  218. { prop: "costDescribe", label: "费用描述", width: '500',component: 'customSlot', },
  219. { prop: "priorityLevel", label: "优先级", width: '120', },
  220. {
  221. prop: "isEnabled", label: "费用状态", width: '100', component: "Tag",
  222. formatter: (row: any) => {
  223. let name = getDict('is_enable').find(val => val.value == row.isEnabled).label
  224. if (name) {
  225. return { type: 'primary', text: name };
  226. }
  227. }
  228. },
  229. {
  230. prop: "auditStatus", label: "审核状态", width: '120', component: "Tag",
  231. formatter: (row: any) => {
  232. let name = getDict('audit_status').find(val => val.value == row.auditStatus).label
  233. if (name) {
  234. return { type: 'warning', text: name };
  235. }
  236. }
  237. },
  238. { prop: "effectiveTime", label: "生效时间", width: '200' },
  239. { prop: "failureTime", label: "失效时间", width: '200' },
  240. {
  241. prop: "costExternalTypeAdds", label: "交强险费用", width: '300', formatter: (row: any) => {
  242. let info = row.costExternalTypeAdds.find((val: any) => val.costType == '交强险');
  243. if (info) {
  244. return `入口:${info.inlet?.toFixed(2)}% 出口:${info.export?.toFixed(2)}%\n加投:${info.addThrow?.toFixed(2)}% 出口留点:${info.keepPointRatio?.toFixed(2)}%`
  245. } else {
  246. return '-'
  247. }
  248. }
  249. },
  250. {
  251. prop: "costExternalTypeAdds", label: "商业险费用", width: '300', formatter: (row: any) => {
  252. let info = row.costExternalTypeAdds.find((val: any) => val.costType == '商业险');
  253. if (info) {
  254. return `入口:${info.inlet?.toFixed(2)}% 出口:${info.export?.toFixed(2)}%\n加投:${info.addThrow?.toFixed(2)}% 出口留点:${info.keepPointRatio?.toFixed(2)}%`
  255. } else {
  256. return '-'
  257. }
  258. }
  259. },
  260. {
  261. prop: "costExternalTypeAdds", label: "驾意险费用", width: '300', formatter: (row: any) => {
  262. let info = row.costExternalTypeAdds.find((val: any) => val.costType == '驾意险');
  263. if (info) {
  264. return `入口:${info.inlet?.toFixed(2)}% 出口:${info.export?.toFixed(2)}%\n加投:${info.addThrow?.toFixed(2)}% 出口留点:${info.keepPointRatio?.toFixed(2)}%`
  265. } else {
  266. return '-'
  267. }
  268. }
  269. },
  270. ];
  271. //分页事件
  272. function getList(item: PageInfo) {
  273. // 根据当前选项卡更新对应的分页数据
  274. if (activeName.value == 'pendingReview') {
  275. pageInfoPending.value.pageNum = item.pageNum;
  276. pageInfoPending.value.pageSize = item.pageSize;
  277. findpage(0);
  278. } else if (activeName.value == 'pass') {
  279. pageInfoPass.value.pageNum = item.pageNum;
  280. pageInfoPass.value.pageSize = item.pageSize;
  281. findpage(1);
  282. } else {
  283. pageInfoRejected.value.pageNum = item.pageNum;
  284. pageInfoRejected.value.pageSize = item.pageSize;
  285. findpage(2);
  286. }
  287. };
  288. // 费用编辑
  289. const ruleFeeEditVisible = ref(false);
  290. const ruleFeeHeaderTitle = ref();//编辑弹窗title
  291. const costitemEditInfo = ref();
  292. const agreemenUpdate = async (id: any) => {
  293. api.agreementApi.FeegetById(id).then((res: any) => {
  294. if (res.code == '200') {
  295. ruleFeeHeaderTitle.value = res.data.productName;
  296. costitemEditInfo.value = res.data;
  297. ruleFeeEditVisible.value = true;
  298. } else {
  299. }
  300. });
  301. }
  302. //费用编辑
  303. const ruleFeeEditSave = (data: object) => {
  304. api.agreementApi.FeeupdateById(data).then((res: any) => {
  305. if (res.code == '200') {
  306. ElMessage({
  307. type: 'success',
  308. message: res.msg,
  309. plain: true,
  310. })
  311. ruleFeeEditVisible.value = false;
  312. if (activeName.value == 'pendingReview') {
  313. findpage(0);
  314. } else if (activeName.value == 'pass') {
  315. findpage(1);
  316. } else {
  317. findpage(2);
  318. }
  319. } else {
  320. }
  321. });
  322. }
  323. //多选事件
  324. const selectionChange = (val: any) => {
  325. sysUpAndDownList.value = val;
  326. }
  327. //批量删除
  328. const batchaudit = () => {
  329. ElMessageBox.confirm(
  330. '确定审核通过该费用吗?',
  331. '审核通过',
  332. {
  333. confirmButtonText: '确定',
  334. type: 'info',
  335. center: true,
  336. confirmButtonClass: 'el-button--primary',
  337. }
  338. )
  339. .then(() => {
  340. ExternalauditSuccess(sysUpAndDownList.value)
  341. })
  342. }
  343. //批量驳回
  344. const batchrejected = () => {
  345. ElMessageBox.prompt('', '审核不通过', {
  346. confirmButtonText: '确定',
  347. type: 'warning',
  348. center: true,
  349. inputType: "textarea",
  350. inputPlaceholder: "请输入不通过原因",
  351. inputPattern: /^[\u4e00-\u9fa5,。!?、;:“”‘’《》【】()——]+$/,
  352. inputErrorMessage: '请输入中文',
  353. })
  354. .then(({ value }) => {
  355. ExternalauditFailed(sysUpAndDownList.value, value)
  356. })
  357. }
  358. //单一审核回调
  359. const auditOperation = (automatic: any, id: any) => {
  360. ExternalauditSuccess([id], automatic)
  361. }
  362. //单一驳回回调
  363. const rejectOperation = (automatic: any, id: any, value: any) => {
  364. ExternalauditFailed([id], value, automatic)
  365. }
  366. const agreementQuery = () => {
  367. if (activeName.value == 'pendingReview') {
  368. findpage(0);
  369. } else if (activeName.value == 'pass') {
  370. findpage(1);
  371. } else {
  372. findpage(2);
  373. }
  374. }
  375. const ExternalauditSuccess = async (list: string[], automatic?: boolean) => {
  376. await api.agreementApi.ExternalauditSuccess({ ids: list, automatic: automatic }).then((res: any) => {
  377. if (res.code == '200') {
  378. findpage(0);
  379. findpage(1);
  380. findpage(2);
  381. ElMessage({
  382. type: 'success',
  383. message: res.msg,
  384. plain: true,
  385. })
  386. ruleFeeEditVisible.value = false;
  387. if (res.data) {
  388. let info: any = tableData1.value.find((val: any) => val.id == res.data);
  389. if (info) {
  390. agreemenUpdate(info.id)
  391. }
  392. }
  393. }
  394. });
  395. }
  396. const ExternalauditFailed = async (list: string[], value: string, automatic?: boolean) => {
  397. await api.agreementApi.ExternalauditFailed({ ids: list, reason: value, automatic: automatic }).then((res: any) => {
  398. if (res.code == '200') {
  399. findpage(0);
  400. findpage(1);
  401. findpage(2);
  402. ElMessage({
  403. type: 'success',
  404. message: res.msg,
  405. plain: true,
  406. })
  407. ruleFeeEditVisible.value = false;
  408. if (res.data) {
  409. let info: any = tableData1.value.find((val: any) => val.id == res.data);
  410. if (info) {
  411. agreemenUpdate(info.id)
  412. }
  413. }
  414. }
  415. });
  416. }
  417. const resetForm = () => {
  418. formInline.agreement = '';//协议信息
  419. formInline.productId = "";//归属
  420. formInline.rulesName = '';//保险公司id
  421. formInline.costRules = '';//协议类型
  422. formInline.agreementStatus = "";//有效状态
  423. formInline.auditStatus = "";//协议状态
  424. formInline.validState = "";
  425. formInline.effectiveTime = [];
  426. formInline.failureTime = [];
  427. if (activeName.value == 'pendingReview') {
  428. findpage(0);
  429. } else if (activeName.value == 'pass') {
  430. findpage(1);
  431. } else {
  432. findpage(2);
  433. }
  434. }
  435. // 批量编辑
  436. const handleClick = (pane: any) => {
  437. activeName.value = pane.props.name;
  438. if (pane.props.name == 'pendingReview') {
  439. findpage(0);
  440. } else if (pane.props.name == 'pass') {
  441. findpage(1);
  442. } else {
  443. findpage(2);
  444. }
  445. }
  446. </script>
  447. <style lang="scss" scoped>
  448. .demo-form-inline .el-input {
  449. --el-input-width: 220px;
  450. }
  451. .demo-form-inline .el-select {
  452. --el-select-width: 220px;
  453. }
  454. :deep(.el-dropdown-link) {
  455. display: flex;
  456. align-items: center;
  457. margin-left: 15px;
  458. color: var(--el-color-primary);
  459. cursor: pointer;
  460. }
  461. .el-inputs {
  462. width: 100% !important;
  463. }
  464. </style>