project.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <template>
  2. <PageMain class="vh100">
  3. <div class="flex h-full">
  4. <div class="w-282px h-full relative flex-shrink-0 member-tree box-border">
  5. <el-input class="w-250px m-l-8px" placeholder="请输入保险公司名称" v-model="company" @keyup.enter="searchCompany">
  6. <template #append>
  7. <el-button icon="Search" link @click="searchCompany" />
  8. </template>
  9. </el-input>
  10. <div style="height: calc(100% - 80px); overflow: auto;" class="m-t-14px">
  11. <div v-for="item, index in filterList" :key="item.id" :class="companyIndex == index ? 'on' : 'role-item'"
  12. @click="companyChose(item, index)"
  13. class="h-64px w-266px p-[0_8px] flex flex-col items-start justify-center">
  14. <div class="text-16px color-[#333]">{{ item.nameSimple }}</div>
  15. </div>
  16. </div>
  17. </div>
  18. <div class="w-[calc(100%-282px)]">
  19. <div
  20. class="flex m-r--16px m-t-4px h-52px justify-between items-center p-b-20px p-l-24px p-r-24px b-b-(1px solid #EEEEEE)">
  21. <div class="">
  22. <div class="text-20px color-[#333] font-500">险种方案配置</div>
  23. <div class="text-14px color-[#999]">配置各家保险公司险种方案套餐,报价时根据规则信息匹配符合报价车辆的保司与保司内的方案</div>
  24. </div>
  25. <div>
  26. <ElButton type="primary" @click="addProject">添加新方案</ElButton>
  27. </div>
  28. </div>
  29. <el-form class="p-[20px_8px_0_24px]" :model="projectForm" ref="projectRefs">
  30. <el-row :gutter="20">
  31. <el-col :span="8">
  32. <el-form-item label="方案类型">
  33. <el-select clearable v-model="projectForm.schemeType" placeholder="请选择" @change="search">
  34. <el-option key="1" value="1" label="基础方案"></el-option>
  35. <el-option key="2" value="2" label="自选方案"></el-option>
  36. </el-select>
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="8">
  40. <el-form-item label="险种">
  41. <el-select clearable v-model="projectForm.productId" placeholder="请选择" @change="search">
  42. <el-option v-for="item in insuranceType" :key="item.value" :value="item.value"
  43. :label="item.label"></el-option>
  44. </el-select>
  45. </el-form-item>
  46. </el-col>
  47. <el-col :span="8">
  48. <el-form-item>
  49. <el-input clearable prefix-icon="search" placeholder="输入规则描述查找" @keyup.enter="search"
  50. v-model="projectForm.ruleDesc"></el-input>
  51. </el-form-item>
  52. </el-col>
  53. </el-row>
  54. </el-form>
  55. <el-table class="p-l-24px" :data="tableData" height="calc(100% - 182px)">
  56. <el-table-column label="方案名称" prop="schemeName"></el-table-column>
  57. <el-table-column label="方案描述" prop="description"></el-table-column>
  58. <el-table-column label="方案类型" prop="schemeType">
  59. <template #default="scope">
  60. {{ scope.row.schemeType == '1' ? '基础方案' : scope.row.schemeType == '2' ? '自选方案' : '' }}
  61. </template>
  62. </el-table-column>
  63. <el-table-column label="险种" prop="productName"></el-table-column>
  64. <el-table-column label="排序" prop="sort"></el-table-column>
  65. <el-table-column label="驾意险" prop="drivingIntentionNum"></el-table-column>
  66. <el-table-column label="规则描述" prop="ruleDesc"></el-table-column>
  67. <el-table-column label="操作">
  68. <template #default="scope">
  69. <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
  70. <el-button link type="primary" @click="handleCopy(scope.row)">复制</el-button>
  71. <el-button link type="primary" @click="handleDel(scope.row)">删除</el-button>
  72. </template>
  73. </el-table-column>
  74. </el-table>
  75. <div class="paginationBox p-r-8px">
  76. <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 30, 40]"
  77. layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
  78. @current-change="handleCurrentChange"></el-pagination>
  79. </div>
  80. </div>
  81. </div>
  82. <!-- <el-row :gutter="20" style="height: 100%; padding: 10px">
  83. <el-col :span="4">
  84. <el-input placeholder="请输入保险公司名称" v-model="company" prefix-icon="search"
  85. @keyup.enter="searchCompany"></el-input>
  86. <div class="companyList">
  87. <div class="companyItem" :class="{ 'active': companyIndex === index }" v-for="(item, index) in filterList"
  88. @click="companyChose(item, index)">{{ item.nameSimple }}</div>
  89. </div>
  90. </el-col>
  91. <el-col :span="20">
  92. <el-row :gutter="20" align="middle">
  93. <el-col :span="20">
  94. <h4>险种方案配置</h4>
  95. <p>配置各家保险公司险种方案套餐,报价时根据规则信息匹配符合报价车辆的保司与保司内的方案</p>
  96. </el-col>
  97. <el-col :span="4">
  98. <el-button icon="plus" type="primary" @click="addProject">添加新方案</el-button>
  99. </el-col>
  100. </el-row>
  101. <el-divider></el-divider>
  102. <el-form :model="projectForm" ref="projectRefs">
  103. <el-row :gutter="20">
  104. <el-col :span="4">
  105. <el-form-item label="方案类型">
  106. <el-select clearable v-model="projectForm.schemeType" placeholder="请选择" @change="search">
  107. <el-option key="1" value="1" label="基础方案"></el-option>
  108. <el-option key="2" value="2" label="自选方案"></el-option>
  109. </el-select>
  110. </el-form-item>
  111. </el-col>
  112. <el-col :span="4">
  113. <el-form-item label="险种">
  114. <el-select clearable v-model="projectForm.productId" placeholder="请选择" @change="search">
  115. <el-option v-for="item in insuranceType" :key="item.value" :value="item.value"
  116. :label="item.label"></el-option>
  117. </el-select>
  118. </el-form-item>
  119. </el-col>
  120. <el-col :span="4">
  121. <el-form-item>
  122. <el-input clearable prefix-icon="search" placeholder="输入规则描述查找" @keyup.enter="search"
  123. v-model="projectForm.ruleDesc"></el-input>
  124. </el-form-item>
  125. </el-col>
  126. </el-row>
  127. </el-form>
  128. <el-table :data="tableData" height="600">
  129. <el-table-column label="方案名称" prop="schemeName"></el-table-column>
  130. <el-table-column label="方案描述" prop="description"></el-table-column>
  131. <el-table-column label="方案类型" prop="schemeType">
  132. <template #default="scope">
  133. {{ scope.row.schemeType == '1' ? '基础方案' : scope.row.schemeType == '2' ? '自选方案' : '' }}
  134. </template>
  135. </el-table-column>
  136. <el-table-column label="险种" prop="productName"></el-table-column>
  137. <el-table-column label="驾意险" prop="drivingIntentionNum"></el-table-column>
  138. <el-table-column label="规则描述" prop="ruleDesc"></el-table-column>
  139. <el-table-column label="操作">
  140. <template #default="scope">
  141. <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
  142. <el-button link type="primary" @click="handleDel(scope.row)">删除</el-button>
  143. </template>
  144. </el-table-column>
  145. </el-table>
  146. <div class="paginationBox">
  147. <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 30, 40]"
  148. layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
  149. @current-change="handleCurrentChange"></el-pagination>
  150. </div>
  151. </el-col>
  152. </el-row> -->
  153. </PageMain>
  154. <el-dialog :close-on-click-modal="false" v-model="copyDialog" title="复制" width="600">
  155. <el-form>
  156. <el-form-item label="险种类型">
  157. <el-select v-model="insuranceTypeValue" placeholder="请选择险种类型">
  158. <el-option v-for="item in insuranceType" :key="item.value" :value="item.value"
  159. :label="item.label"></el-option>
  160. </el-select>
  161. </el-form-item>
  162. </el-form>
  163. <template #footer>
  164. <el-button size="small" type="primary" :loading="loading" @click="submitCopy">确定</el-button>
  165. </template>
  166. </el-dialog>
  167. </template>
  168. <script setup lang="ts">
  169. import api from '@/api'
  170. import { ElMessage, ElMessageBox } from "element-plus";
  171. import { useRouter, useRoute } from 'vue-router'
  172. const myRouter = useRouter()
  173. const muRoute = useRoute()
  174. const searchCompany = () => {
  175. currentPage.value = 1
  176. pageSize.value = 10
  177. initData()
  178. }
  179. let company = ref('')
  180. const filterList = computed(() => {
  181. return companyOption.value.filter(a => a.nameSimple.includes(company.value))
  182. })
  183. const search = () => {
  184. initData()
  185. }
  186. // 保险公司
  187. let companyOption = ref([])
  188. let companyIndex = ref(0)
  189. let companyId = ref('')
  190. const initCompany = () => {
  191. api.projectApi.getCompanyList().then(res => {
  192. if (res.code == 200) {
  193. companyOption.value = res.data
  194. if (muRoute.query.id) {
  195. companyIndex.value = companyOption.value.findIndex(a => a.id == muRoute.query.id)
  196. } else {
  197. companyIndex.value = 0
  198. }
  199. companyId.value = muRoute.query.id || companyOption.value[companyIndex.value].id
  200. initData()
  201. } else {
  202. ElMessage({
  203. message: res.msg,
  204. type: 'warning'
  205. })
  206. }
  207. })
  208. }
  209. const companyChose = (item, index) => {
  210. companyIndex.value = index
  211. companyId.value = item.id
  212. initData()
  213. }
  214. const addProject = () => {
  215. myRouter.push({
  216. path: '/quoteConfig/agreement/project/projectAdd',
  217. query: {
  218. companyId: companyId.value
  219. }
  220. })
  221. }
  222. let projectForm = ref({})
  223. let tableData = ref([])
  224. // 分页数据
  225. let currentPage = ref(0)
  226. let pageSize = ref(10)
  227. let total = ref(0)
  228. const initData = () => {
  229. api.projectApi.getSchemeList({
  230. pages: currentPage.value,
  231. size: pageSize.value,
  232. companyId: companyId.value,
  233. productId: projectForm.value.productId,
  234. schemeType: projectForm.value.schemeType,
  235. ruleDesc: projectForm.value.ruleDesc
  236. }).then(res => {
  237. if (res.code == 200) {
  238. tableData.value = res.data.records
  239. total.value = res.data.total
  240. } else {
  241. ElMessage({
  242. message: res.msg,
  243. type: 'warning'
  244. })
  245. }
  246. })
  247. }
  248. // 险种类型
  249. let insuranceType = ref([])
  250. const initType = () => {
  251. api.commonApi.personInfo('insurance_type').then(res => {
  252. if (res.code == 200) {
  253. insuranceType.value = res.data
  254. } else {
  255. ElMessage({
  256. message: res.msg,
  257. type: 'warning'
  258. })
  259. }
  260. })
  261. }
  262. const handleSizeChange = (size) => {
  263. pageSize.value = size
  264. initData()
  265. }
  266. const handleCurrentChange = (page) => {
  267. currentPage.value = page
  268. initData()
  269. }
  270. // 编辑
  271. const handleEdit = (row) => {
  272. myRouter.push({
  273. path: '/quoteConfig/agreement/project/projectAdd',
  274. query: {
  275. id: row.id,
  276. companyId: companyId.value,
  277. productId: row.productId
  278. }
  279. })
  280. }
  281. // 删除
  282. const handleDel = (row) => {
  283. ElMessageBox({
  284. title: '删除方案',
  285. message: '确定要删除该方案吗?',
  286. type: 'warning',
  287. showCancelButton: true,
  288. confirmButtonText: '确定',
  289. cancelButtonText: '取消',
  290. }).then((action) => {
  291. if (action === 'confirm') {
  292. api.projectApi.deleteScheme({
  293. id: row.id
  294. }).then(res => {
  295. if (res.code == 200) {
  296. ElMessage({
  297. message: res.msg,
  298. type: 'success'
  299. })
  300. initData()
  301. } else {
  302. ElMessage({
  303. message: res.msg,
  304. type: 'warning'
  305. })
  306. }
  307. })
  308. }
  309. }).catch((action) => {
  310. })
  311. }
  312. const copyDialog = ref(false)
  313. const copyId = ref('')
  314. const insuranceTypeValue = ref('')
  315. /** 复制操作处理:记录当前行的ID并打开复制确认对话框 */
  316. const handleCopy = (row) => {
  317. copyId.value = row.id
  318. copyDialog.value = true
  319. }
  320. const loading = ref(false)
  321. /** 提交复制操作,校验险种选择后触发保险公司查询 */
  322. const submitCopy = () => {
  323. if (insuranceTypeValue.value.length == 0) {
  324. ElMessage({
  325. message: '请选择险种',
  326. type: 'warning'
  327. })
  328. return
  329. }
  330. const params = {
  331. schemeId: copyId.value,
  332. productCode: insuranceTypeValue.value
  333. }
  334. loading.value = true
  335. api.projectApi.copyScheme(params).then(res => {
  336. if (res.code == 200) {
  337. ElMessage({
  338. message: res.msg,
  339. type: 'success'
  340. })
  341. copyDialog.value = false
  342. searchCompany()
  343. }
  344. }).finally(() => loading.value = false)
  345. }
  346. onMounted(() => {
  347. // initData()
  348. initCompany()
  349. initType()
  350. })
  351. </script>
  352. <style scoped lang="scss">
  353. :deep(.main-container) {
  354. padding: 16px;
  355. }
  356. :deep(.el-input-group__append) {
  357. color: #fff;
  358. background: linear-gradient(91deg, #4FCAFF 0%, #2B62FF 100%);
  359. }
  360. .member-tree {
  361. &::after {
  362. content: '';
  363. position: absolute;
  364. height: calc(100% + 32px);
  365. width: 1px;
  366. background-color: #EEEEEE;
  367. top: -16px;
  368. right: 0;
  369. bottom: -16px;
  370. }
  371. }
  372. .role-item {
  373. cursor: pointer;
  374. }
  375. .on {
  376. cursor: pointer;
  377. background: #F4FAFF;
  378. border-right: 1px solid #0083FF;
  379. }
  380. .paginationBox {
  381. display: flex;
  382. justify-content: end;
  383. margin-top: 10px;
  384. }
  385. </style>