agreementIndex.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. <template>
  2. <div>
  3. <PageMain class="vh100">
  4. <SearchForm :fields="fields" :formInline="formInline" :onSearch="agreementQuery" :onReset="resetForm" />
  5. <ComplexTable :tableData="tableData" :columns="columns" :showIndex="false" :columnwidth="200" :showSelect="true"
  6. :pageInfo="pageInfo" @getList="getList" @selectionChange="selectionChange">
  7. <template v-slot:table-title-btn>
  8. <RouterLink :to="{ name: 'AgreementAdd' }">
  9. <el-button type="primary">
  10. 添加协议
  11. <template #icon>
  12. <el-icon>
  13. <Plus />
  14. </el-icon>
  15. </template>
  16. </el-button>
  17. </RouterLink>
  18. <el-dropdown placement="bottom-start">
  19. <el-button> 批量管理<el-icon>
  20. <arrow-down />
  21. </el-icon>
  22. </el-button>
  23. <template #dropdown>
  24. <el-dropdown-menu>
  25. <el-dropdown-item :disabled="!sysUpAndDownList.length" @click="batchDel">删除</el-dropdown-item>
  26. <el-dropdown-item :disabled="!sysUpAndDownList.length" @click="batchdisable">禁用</el-dropdown-item>
  27. <el-dropdown-item :disabled="!sysUpAndDownList.length" @click="batchenable">启用</el-dropdown-item>
  28. </el-dropdown-menu>
  29. </template>
  30. </el-dropdown>
  31. </template>
  32. <template v-slot:operation="scope">
  33. <el-button type="primary" link @click="agreemenUpdate(scope.operationData)"> 详情
  34. </el-button>
  35. <el-dropdown placement="bottom-start" trigger="click">
  36. <span class="el-dropdown-link">
  37. 更 多
  38. </span>
  39. <template #dropdown>
  40. <el-dropdown-menu>
  41. <el-dropdown-item @click="enable(scope.operationData.id)">启用</el-dropdown-item>
  42. <el-dropdown-item @click="disable(scope.operationData.id)">禁用</el-dropdown-item>
  43. <el-dropdown-item @click="del(scope.operationData.id)">删除</el-dropdown-item>
  44. <el-dropdown-item @click="agreemenCopy">复制协议</el-dropdown-item>
  45. <el-dropdown-item @click="batchAuthorization(scope.operationData.id)">协议授权</el-dropdown-item>
  46. <el-dropdown-item @click="agreemenUpdate(scope.operationData)">费用管理</el-dropdown-item>
  47. </el-dropdown-menu>
  48. </template>
  49. </el-dropdown>
  50. </template>
  51. <template v-slot:search="scope">
  52. {{ scope.slotData.label }}
  53. </template>
  54. </ComplexTable>
  55. </PageMain>
  56. <auth-Drawer :Drawer="agreementAuthDrawer" @cancel=" agreementAuthDrawer = false" @save="DrawerSave"
  57. @query="Drawerquery" :deptlist="deptauthList" :checkedKeys="checkedKeys" :checkedIds="checkedIds"></auth-Drawer>
  58. </div>
  59. </template>
  60. <script lang="ts" setup>
  61. import { ref, reactive } from 'vue'
  62. import { RouterLink, useRouter } from "vue-router";
  63. import { ElMessage, ElMessageBox } from 'element-plus'
  64. import { loadDicts, getDict } from '@/utils/composables/dictService';//字典组件
  65. import authDrawer from "./components/agreementAuth.vue";
  66. import api from '@/api';
  67. interface PageInfo {
  68. pageNum: number;
  69. pageSize: number;
  70. sizes: number[];
  71. total: number;
  72. }
  73. onBeforeMount(async () => {
  74. await loadDicts(['agreement_type', 'valid_status', 'is_enable', 'with_tax']);//获取多个字典
  75. findpage();//列表数据
  76. getDeptTree();
  77. agreement_type.value = getDict('agreement_type');//协议类型
  78. valid_status.value = getDict('valid_status');//生效状态
  79. is_enable.value = getDict('is_enable');//协议状态
  80. with_tax.value = getDict('with_tax')//是否含税
  81. });
  82. const parentIdprops = {
  83. expandTrigger: 'hover' as const,
  84. value: 'id',
  85. label: 'name',
  86. checkStrictly: true,
  87. }
  88. const tableData = ref([
  89. ]);
  90. const sysUpAndDownList = ref<string[]>([])//选中id
  91. const provinceoptions = ref<string[]>([])//省市区回显数据
  92. const deptOptions = ref()//机构数据
  93. const agreement_type = ref();
  94. const valid_status = ref();
  95. const is_enable = ref();
  96. const with_tax = ref();
  97. const router = useRouter();
  98. const pageInfo = ref({
  99. pageNum: 1,
  100. pageSize: 20,
  101. sizes: [10, 20, 30, 40, 50],
  102. total: 100,
  103. });
  104. const formInline = reactive({
  105. searchValue: '',//协议信息
  106. deptId: "",//归属
  107. companyId: '',//保险公司id
  108. agreementType: '',//协议类型
  109. validStatus: "",//有效状态
  110. isEnable: "",//协议状态
  111. withTax: "",
  112. dockingPerson: "",
  113. attributionName: "",
  114. takeStartDate: "",
  115. takeEndDate: "",
  116. loseStartDate: "",
  117. loseEndDate: "",
  118. })
  119. //表格字段数据
  120. const fields = ref([
  121. { label: "协议信息", model: "searchValue", type: "input", placeholder: "输入代码,名称,简称查找" },
  122. {
  123. label: "协议归属", model: "deptId", type: "cascader", options: deptOptions, props: parentIdprops, onChange: (value: any) => {
  124. formInline.deptId = value[value.length - 1];
  125. }
  126. },
  127. {
  128. label: "保险公司", model: "companyId", type: "select", placeholder: "选择保险公司",
  129. },
  130. {
  131. label: "协议类型", model: "agreementType", type: "select", placeholder: "选择保险公司", options: agreement_type,
  132. },
  133. {
  134. label: "生效状态", model: "validStatus", type: "select", placeholder: "选择生效状态", options: valid_status,
  135. },
  136. {
  137. label: "协议状态", model: "isEnable", type: "select", placeholder: "选择协议状态", options: is_enable,
  138. },
  139. {
  140. label: "是否含税结算", model: "withTax", type: "select", placeholder: "请选择", options: with_tax,
  141. },
  142. {
  143. label: "对接人", model: "dockingPerson", type: "input", placeholder: "输入姓名,手机号查找"
  144. },
  145. {
  146. label: "出单账号", model: "attributionName", type: "input", placeholder: "选择出单账号"
  147. },
  148. {
  149. label: "生效时间", model: "takeStartDate", type: "date", dateType: "datetimerange", startplaceholder: "开始时间", endplaceholder: "结束时间",
  150. onChange: (value: any) => {
  151. formInline.takeStartDate = value[0];
  152. formInline.takeEndDate = value[1];
  153. }
  154. },
  155. {
  156. label: "失效时间", model: "loseStartDate", type: "date", dateType: "datetimerange", startplaceholder: "开始时间", endplaceholder: "结束时间",
  157. onChange: (value: any) => {
  158. formInline.loseStartDate = value[0];
  159. formInline.loseEndDate = value[1];
  160. }
  161. },
  162. ]);
  163. //数据查询
  164. function findpage() {
  165. api.agreementApi.agreementList({ pages: pageInfo.value.pageNum, size: pageInfo.value.pageSize, ...formInline }).then((res: any) => {
  166. if (res.code == '200') {
  167. tableData.value = res.data.records;
  168. pageInfo.value.pageNum = res.data.current;
  169. pageInfo.value.pageSize = res.data.size;
  170. pageInfo.value.total = res.data.total;
  171. } else {
  172. }
  173. });
  174. }
  175. const columns = [
  176. { prop: "agreementCode", label: "协议编号", width: '200', },
  177. {
  178. prop: "agreementTitle", label: "协议名称", width: '200',
  179. },
  180. { prop: "agreementAbbreviation", label: "协议简称", width: '120', },
  181. {
  182. prop: "deptName", label: "归属", width: '120',
  183. },
  184. {
  185. prop: "agreementType", label: "协议类型", width: '200', formatter: (row: any) => {
  186. let name = getDict('agreement_type').find(val => val.value == row.agreementType).label
  187. return name
  188. }
  189. },
  190. {
  191. prop: "isEnable", label: "协议状态", width: '100',
  192. component: "Tag",
  193. formatter: (row: any) => {
  194. let name = getDict('is_enable').find(val => val.value == row.isEnable).label
  195. if (name) {
  196. return { type: 'primary', text: name };
  197. } else {
  198. return { type: 'primary', text: name };
  199. }
  200. }
  201. },
  202. {
  203. prop: "validStatus", label: "生效状态", width: '120', component: "Tag",
  204. formatter: (row: any) => {
  205. let name = getDict('valid_status').find(val => val.value == row.validStatus).label
  206. if (name) {
  207. return { type: 'danger', text: name };
  208. } else {
  209. return { type: 'danger', text: name };
  210. }
  211. }
  212. },
  213. {
  214. prop: "withTax", label: "是否含税结算", width: '180',
  215. formatter: (row: any) => {
  216. let name = getDict('with_tax').find(val => val.value == row.withTax).label
  217. return name
  218. }
  219. },
  220. {
  221. prop: "moneyTime", label: "结算周期", width: '120',
  222. formatter: (row: any) => {
  223. return 'T' + row.moneyTime
  224. }
  225. },
  226. { prop: "attributionId", label: "出单账号", width: '120', },
  227. { prop: "company", label: "保险公司", width: '200' },
  228. { prop: "dockingPerson", label: "对接人", width: '200' },
  229. { prop: "custodianId", label: "管理人", width: '200' },
  230. { prop: "startDate", label: "生效时间", width: '200' },
  231. { prop: "endDate", label: "失效时间", width: '200' },
  232. { prop: "createTime", label: "添加时间", width: '200' },
  233. { prop: "createBy", label: "添加人", width: '200' },
  234. { prop: "fileName", label: "协议文件", width: '200' },
  235. ];
  236. //分页事件
  237. function getList(item: PageInfo) {
  238. pageInfo.value.pageNum = item.pageNum;
  239. pageInfo.value.pageSize = item.pageSize;
  240. findpage();
  241. };
  242. //机构授权
  243. const agreementAuthDrawer = ref(false)//授权弹窗
  244. const deptauthList = ref([]);//授权机构列表
  245. const checkedKeys = ref<string[]>([])//授权机构回显数据
  246. const checkedIds = ref<string[]>([])//授权机构回显id
  247. //授权机构检索
  248. const Drawerquery = (name: any) => {
  249. agreementAuth(name)
  250. }
  251. //授权保存
  252. const DrawerSave = (list: any) => {
  253. api.agreementApi.authSave({ deptIds: list, id: agreementId.value }).then((res: any) => {
  254. if (res.code == '200') {
  255. ElMessage({
  256. type: 'success',
  257. message: res.msg,
  258. plain: true,
  259. })
  260. agreementAuthDrawer.value = false;
  261. } else {
  262. }
  263. });
  264. }
  265. //协议授权
  266. const agreementAuth = (deptName: any) => {
  267. let name = typeof deptName === 'string' ? deptName : '';
  268. api.agreementApi.agreementdeptTree(agreementId.value, name).then((res: any) => {
  269. if (res.code == '200') {
  270. agreementAuthDrawer.value = true;
  271. deptauthList.value = res.data;
  272. checkedKeys.value = getUncheckedIds(res.data);
  273. checkedIds.value = getUncheckedIds(res.data);
  274. } else {
  275. }
  276. });
  277. }
  278. // 定义递归函数
  279. function getUncheckedIds(data: any[]): string[] {
  280. let ids: string[] = [];
  281. data.forEach((item) => {
  282. if (item.isCheck === 1) {
  283. ids.push(item.id); // 如果 isCheck 为 0,添加 id
  284. }
  285. if (item.children && item.children.length > 0) {
  286. // 如果有子项,递归调用
  287. ids = ids.concat(getUncheckedIds(item.children));
  288. }
  289. });
  290. return ids;
  291. }
  292. function agreemenUpdate(item: any) {
  293. router.push({
  294. name: 'AgreementDetails',
  295. query: {
  296. id: item.id
  297. }
  298. })
  299. }
  300. //多选事件
  301. const selectionChange = (val: any) => {
  302. sysUpAndDownList.value = val;
  303. }
  304. //协议授权
  305. const agreementId = ref()
  306. const batchAuthorization = (value: string) => {
  307. agreementId.value = value;
  308. api.agreementApi.agreementdeptTree(value, '').then((res: any) => {
  309. if (res.code == '200') {
  310. agreementAuthDrawer.value = true;
  311. deptauthList.value = res.data;
  312. checkedKeys.value = getUncheckedIds(res.data);
  313. checkedIds.value = getUncheckedIds(res.data);
  314. } else {
  315. }
  316. });
  317. }
  318. //复制协议
  319. const agreemenCopy = () => {
  320. }
  321. //禁用
  322. const disable = (value: string) => {
  323. ElMessageBox.confirm(
  324. '确定要禁用该协议吗,禁用后,该协议不在支持报价出单,并且已核保待缴费,待支付的订单,都将失效,请确认是否禁用?',
  325. '禁用协议',
  326. {
  327. confirmButtonText: '确定禁用',
  328. type: 'error',
  329. center: true,
  330. confirmButtonClass: 'el-button--danger',
  331. }
  332. )
  333. .then(() => {
  334. sysUpAndDown('1', [value]);
  335. })
  336. }
  337. //启用
  338. const enable = (value: string) => {
  339. sysUpAndDown('0', [value]);
  340. }
  341. const del = (value: string) => {
  342. ElMessageBox.confirm(
  343. '确定要删除该协议吗,删除后,该协议不在支持报价出单,并且已核保待缴费,待支付的订单,都将失效,请确认是否删除?',
  344. '删除协议',
  345. {
  346. confirmButtonText: '确定删除',
  347. type: 'error',
  348. center: true,
  349. confirmButtonClass: 'el-button--danger',
  350. }
  351. )
  352. .then(() => {
  353. api.agreementApi.agreementDelete([value]).then((res: any) => {
  354. if (res.code == '200') {
  355. ElMessage({
  356. type: 'success',
  357. message: res.msg,
  358. plain: true,
  359. })
  360. router.push({
  361. name: 'reload',
  362. })
  363. }
  364. });
  365. })
  366. }
  367. //批量删除
  368. const batchDel = () => {
  369. ElMessageBox.confirm(
  370. '确定要删除该协议吗,删除后,该协议不在支持报价出单,并且已核保待缴费,待支付的订单,都将失效,请确认是否删除?',
  371. '删除协议',
  372. {
  373. confirmButtonText: '确定删除',
  374. type: 'error',
  375. center: true,
  376. confirmButtonClass: 'el-button--danger',
  377. }
  378. )
  379. .then(() => {
  380. api.agreementApi.agreementDelete(sysUpAndDownList.value).then((res: any) => {
  381. if (res.code == '200') {
  382. ElMessage({
  383. type: 'success',
  384. message: res.msg,
  385. plain: true,
  386. })
  387. router.push({
  388. name: 'reload',
  389. })
  390. }
  391. });
  392. })
  393. }
  394. //批量禁用
  395. const batchdisable = () => {
  396. ElMessageBox.confirm(
  397. '确定要禁用该协议吗,禁用后,该协议不在支持报价出单,并且已核保待缴费,待支付的订单,都将失效,请确认是否禁用?',
  398. '禁用协议',
  399. {
  400. confirmButtonText: '确定禁用',
  401. type: 'error',
  402. center: true,
  403. confirmButtonClass: 'el-button--danger',
  404. }
  405. )
  406. .then(async () => {
  407. await sysUpAndDown('1', undefined);
  408. })
  409. .catch(() => {
  410. })
  411. }
  412. //批量启用
  413. const batchenable = async () => {
  414. await sysUpAndDown('0', undefined);
  415. }
  416. const agreementQuery = () => {
  417. findpage();
  418. }
  419. const sysUpAndDown = async (type: string, list?: string[]) => {
  420. await api.agreementApi.sysUpAndDown({ ids: list ? list : sysUpAndDownList.value, opType: type }).then((res: any) => {
  421. if (res.code == '200') {
  422. findpage();
  423. ElMessage({
  424. type: 'success',
  425. message: res.msg,
  426. plain: true,
  427. })
  428. }
  429. });
  430. }
  431. //添加子机构
  432. const subOrganizationAdd = (code: string) => {
  433. router.push({
  434. name: 'OrganizationDeptAdd',
  435. query: {
  436. code: code
  437. }
  438. })
  439. }
  440. const resetForm = () => {
  441. formInline.searchValue = '';
  442. provinceoptions.value = [];
  443. findpage();
  444. }
  445. const getDeptTree = () => {
  446. api.institutionApi.institutionList({}).then((res: any) => {
  447. if (res.code == '200') {
  448. deptOptions.value = res.data;
  449. } else {
  450. }
  451. });
  452. }
  453. </script>
  454. <style lang="scss" scoped>
  455. .demo-form-inline .el-input {
  456. --el-input-width: 220px;
  457. }
  458. .demo-form-inline .el-select {
  459. --el-select-width: 220px;
  460. }
  461. :deep(.el-dropdown-link) {
  462. display: flex;
  463. align-items: center;
  464. margin-left: 15px;
  465. color: var(--el-color-primary);
  466. cursor: pointer;
  467. }
  468. .el-inputs {
  469. width: 100% !important;
  470. }
  471. </style>