QuoteCountManagement.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <template>
  2. <div class="QuoteCountManagement">
  3. <el-row style="height: 100%">
  4. <el-col :span="4" style="height: 100%; overflow-y: auto; background: rgba(244, 246, 248, 1);">
  5. <div class="menu-item" :class="{'active': menuIndex === index}" v-for="(item, index) in leftTree" :key="item.id" @click="handleSelect(item, index)">{{ item.namesimple }}</div>
  6. </el-col>
  7. <el-col :span="20">
  8. <el-row :gutter="20" align="middle" style="display: flex; align-items: center; width: 100%; overflow: hidden; margin: 0">
  9. <el-col :span="18" style="padding-left: 20px">报价限制</el-col>
  10. <el-col :span="6">
  11. <el-button type="primary" @click="handleSync" :disabled="!isEdit">同步配置到其他保司</el-button>
  12. <el-button type="primary" @click="handleEdit" v-if="!isEdit">编辑</el-button>
  13. <el-button type="primary" @click="handleSave" v-else>保存</el-button>
  14. </el-col>
  15. </el-row>
  16. <el-divider></el-divider>
  17. <el-form :model="quoteForm" ref="QuoteFormRef" :rules="quoteRules" style="padding-left: 30px;" label-width="120px">
  18. <el-form-item prop="isEnabled" label="报价次数限制">
  19. <el-switch v-model="quoteForm.isEnabled" :disabled="!isEdit"></el-switch>
  20. <p class="tips">开启后,代理人的报价次数将受到限制,超出设置的报价次数后将停止代理人的报价功能</p>
  21. </el-form-item>
  22. <el-form-item prop="authorize" label="代理人限制">
  23. <div>
  24. <el-radio-group v-model="quoteForm.authorize" :disabled="!isEdit">
  25. <el-radio :label="0">限制全部代理人</el-radio>
  26. <el-radio :label="1">限制部分代理人</el-radio>
  27. </el-radio-group>
  28. <kt-button v-if="quoteForm.authorize" type="text" label="选择代理人" :disabled="!isEdit" icon="el-icon-plus" style="color: #2D4D89; margin-left: 30px" @click="selectAgent" />
  29. </div>
  30. <el-table
  31. :data="selectList"
  32. >
  33. <el-table-column prop="deptId" label="部门编码"></el-table-column>
  34. <!-- <el-table-column prop="organization" label="机构名称"></el-table-column>-->
  35. <el-table-column prop="deptName" label="部门名称"></el-table-column>
  36. <el-table-column prop="id" label="工号"></el-table-column>
  37. <el-table-column prop="name" label="姓名"></el-table-column>
  38. <el-table-column prop="mobile" label="联系电话"></el-table-column>
  39. <el-table-column label="操作">
  40. <template slot-scope="scope">
  41. <el-popconfirm
  42. confirm-button-text='确定'
  43. cancel-button-text='取消'
  44. icon="el-icon-info"
  45. icon-color="red"
  46. :ref="`popconfirm-${scope.row.id}`"
  47. title="确定删除吗?"
  48. @confirm="handleDelete(scope.row)"
  49. >
  50. <kt-button slot="reference" :disabled="!isEdit" type="text" label="删除" style="color: #2D4D89;" />
  51. </el-popconfirm>
  52. </template>
  53. </el-table-column>
  54. </el-table>
  55. </el-form-item>
  56. <el-form-item prop="quoteLimit" label="报价限制">
  57. <el-checkbox-group v-model="quoteForm.quoteLimit" @change="checkChange">
  58. <div>
  59. <el-checkbox label="1" :disabled="!isEdit">
  60. <div style="display: flex; align-items: center">
  61. 单日报价,出单比不满<el-input size="small" maxlength="2" v-model="quoteForm.orderRatio" :disabled="!isEdit" style="width: 150px; margin: 0 20px;">
  62. <template slot="append">%</template>
  63. </el-input>后,锁定代理人报价次数
  64. </div>
  65. </el-checkbox>
  66. </div>
  67. <p style="font-size: 12px; color: #999; margin: 0">报价出单比=承保单数/报价单数*100% (四舍五入到小数点后两位)</p>
  68. <div>
  69. <el-checkbox label="2" :disabled="!isEdit">
  70. <div>单日最大报价次数</div>
  71. <div style="display: flex; align-items: center">
  72. 单日代理人报价满<el-input size="small" maxlength="4" v-model="quoteForm.dayMaxQuoteNum" :disabled="!isEdit" style="width: 150px; margin: 0 20px;">
  73. <template slot="append">次</template>
  74. </el-input>后,锁定代理人报价次数
  75. </div>
  76. </el-checkbox>
  77. </div>
  78. <div>
  79. <el-checkbox label="3" :disabled="!isEdit">
  80. <div>单日单车限制</div>
  81. <div style="display: flex; align-items: center">
  82. 单日代理人单车最多报价<el-input size="small" maxlength="4" :disabled="!isEdit" v-model="quoteForm.carMaxQuoteNum" style="width: 150px; margin: 0 20px;">
  83. <template slot="append">次</template>
  84. </el-input>后,锁定代理人报价次数
  85. </div>
  86. </el-checkbox>
  87. </div>
  88. </el-checkbox-group>
  89. </el-form-item>
  90. </el-form>
  91. </el-col>
  92. </el-row>
  93. <el-dialog
  94. :visible.sync="syncShow"
  95. width="30%"
  96. >
  97. <template slot="title">
  98. <i class="el-icon-warning" style="color: red"></i><span>是否同步配置到其它保险公司</span>
  99. </template>
  100. <span>同步后,所有保险公司的报价限制配置都将变为该保险公司相同配置,是否确认同步</span>
  101. <template slot="footer">
  102. <el-button @click="syncShow = false">取消</el-button>
  103. <el-button type="primary" @click="handleSubmit">确定</el-button>
  104. </template>
  105. </el-dialog>
  106. <el-dialog
  107. title="选择代理人"
  108. :visible.sync="agentTableShow"
  109. width="80%"
  110. >
  111. <el-form ref="CountDetailForm" v-model="countDetailForm" :inline="true" label-width="130px">
  112. <el-form-item style="width: 30%;" label="代理人">
  113. <el-input size="small" v-model="countDetailForm.orderNumber" placeholder="请输入工号、姓名查找" @change="() => {
  114. pageNum = 1
  115. }"></el-input>
  116. </el-form-item>
  117. <el-form-item style="width: 30%;" label="所属机构">
  118. <el-cascader size="small" v-model="countDetailForm.organization" :options="areaOptions" style="width: 100%;"
  119. :props="{ label: 'name', value: 'id', children: 'children', checkStrictly: true, expandTrigger: 'hover' }" clearable
  120. ref="area" @change="() => {
  121. pageNum = 1
  122. }"></el-cascader>
  123. </el-form-item>
  124. <el-form-item style="width: 30%;">
  125. <el-button type="primary" size="small" @click="initAgentUser" style="margin-left: 150px;">查询</el-button>
  126. <el-button size="small" @click="reset">重置</el-button>
  127. </el-form-item>
  128. </el-form>
  129. <div>
  130. <el-select class="select-box" size="small" v-model="checkType" placeholder="全选" style="width: 130px; border: none;" @change="selectTypeChange">
  131. <el-option label="选中所有数据" value="all"></el-option>
  132. <el-option label="选中本页数据" value="cur"></el-option>
  133. </el-select>
  134. <el-divider direction="vertical"></el-divider>
  135. <span>已经选择了{{ selectedLength }}条</span>
  136. </div>
  137. <el-table
  138. :data="agentDataList"
  139. ref="multipleTable"
  140. row-key="id"
  141. :reserve-selection="true"
  142. style="width: 100%"
  143. @select-all="handleSelectAll"
  144. @select="handleSelectChange"
  145. >
  146. <el-table-column type="selection"></el-table-column>
  147. <el-table-column prop="deptId" label="部门编码"></el-table-column>
  148. <!-- <el-table-column prop="organization" label="机构名称"></el-table-column>-->
  149. <el-table-column prop="deptName" label="部门名称"></el-table-column>
  150. <el-table-column prop="id" label="工号"></el-table-column>
  151. <el-table-column prop="name" label="姓名"></el-table-column>
  152. <el-table-column prop="mobile" label="联系电话"></el-table-column>
  153. </el-table>
  154. <div class="pagination-box">
  155. <el-pagination
  156. @current-change="handlePageNumChange"
  157. background
  158. :page-size="5"
  159. :current-page="pageNum"
  160. layout="prev, pager, next"
  161. :total="total">
  162. </el-pagination>
  163. </div>
  164. <template slot="footer">
  165. <kt-button label="取消" size="small" type="text" @click="handleCancel" />
  166. <kt-button label="确认" size="small" type="primary" @click="handleOk" />
  167. </template>
  168. </el-dialog>
  169. </div>
  170. </template>
  171. <script>
  172. import KtButton from "../../Core/KtButton.vue";
  173. import {getAgentUser, getQuoteConfigInfo, setQuoteInfo, syncQuoteInfo} from "../../../http/moudules/quote";
  174. import {findTree} from "../../../http/moudules/insCompany";
  175. export default {
  176. components: {
  177. KtButton
  178. },
  179. data() {
  180. return {
  181. leftTree: [], // 保险公司list
  182. menuIndex: 0, // 保险公司item下标
  183. syncShow: false, // 同步设置弹框
  184. quoteForm: {
  185. id: '',
  186. isEnabled: false,
  187. authorize: '',
  188. quoteLimit: []
  189. }, // 报价form
  190. quoteRules: {
  191. isEnabled: [
  192. {
  193. required: true, message: '', trigger: 'change'
  194. }
  195. ],
  196. authorize: [
  197. {
  198. required: true, message: '请选择代理人限制', trigger: 'change'
  199. }
  200. ],
  201. quoteLimit: [
  202. {
  203. type: 'array',required: true, message: '请选择报价限制', trigger: 'change'
  204. }
  205. ]
  206. }, // 报价form规则
  207. isEdit: false, // 是否可编辑
  208. checkType: '', // 全选类型
  209. agentTableShow: false, // 控制选择代理人弹框
  210. agentDataList: [],
  211. myList: [], // 记录每个保险公司接口返回的已经选好的代理人
  212. selectList: [], // 勾选的数据
  213. selectedList: [], // 勾选的数据(格式为平铺后)
  214. pageList: [1], // 记录点击了的页码
  215. selectedLength: 0, // 选择(包括全选后)的数据数量
  216. total: 0,
  217. countDetailForm: {},
  218. pageNum: 1,
  219. areaOptions: [], // 机构树
  220. }
  221. },
  222. methods: {
  223. checkChange() {
  224. if(!this.quoteForm.quoteLimit.includes('1')) {
  225. this.$set(this.quoteForm, 'orderRatio', '')
  226. }
  227. if(!this.quoteForm.quoteLimit.includes('2')) {
  228. this.$set(this.quoteForm, 'dayMaxQuoteNum', '')
  229. }
  230. if(!this.quoteForm.quoteLimit.includes('3')) {
  231. this.$set(this.quoteForm, 'carMaxQuoteNum', '')
  232. }
  233. },
  234. // 获取保险公司
  235. initCompany() {
  236. this.$api.quote.getCompany().then(res => {
  237. if(res.code == 200) {
  238. this.leftTree = res.data
  239. this.initQuoteDetails(res.data[0].id)
  240. } else {
  241. this.$message.error(res.msg)
  242. }
  243. })
  244. },
  245. // 获取机构
  246. initOrganization() {
  247. this.$api.dept.findTree().then(res => {
  248. this.areaOptions = res.data
  249. })
  250. },
  251. // 获取代理人
  252. initAgentUser() {
  253. let that = this
  254. that.$api.quote.getAgentUser({
  255. pageNum: this.pageNum,
  256. pageSize: 5,
  257. columnFilters: {
  258. name: {
  259. value: that.countDetailForm.orderNumber?that.countDetailForm.orderNumber: ''
  260. },
  261. deptId: {
  262. value: that.countDetailForm.organization?that.countDetailForm.organization[that.countDetailForm.organization.length-1]: ''
  263. }
  264. }
  265. }).then(res => {
  266. if(res.code == 200) {
  267. that.agentDataList = res.data.content
  268. that.total = res.data.totalSize
  269. that.$nextTick(() => {
  270. if(that.checkType === 'all') {
  271. that.selectedLength = res.data.totalSize
  272. if(that.agentDataList.length>0) {
  273. that.agentDataList.forEach(item => {
  274. that.$refs.multipleTable.toggleRowSelection(item, true)
  275. })
  276. }
  277. } else {
  278. let list = [...that.selectedList]
  279. if(list&&list.length>0) {
  280. list.forEach(item => {
  281. let arrayItem = that.agentDataList.find(sub => sub.id === item.id)
  282. if(arrayItem) {
  283. that.$refs.multipleTable.toggleRowSelection(arrayItem, true)
  284. }
  285. })
  286. }
  287. }
  288. })
  289. }
  290. })
  291. },
  292. // 代理人搜索条件重置
  293. reset() {
  294. this.countDetailForm = {}
  295. this.pageNum = 1
  296. this.initAgentUser()
  297. },
  298. // 代理人分页页数变化函数
  299. handlePageNumChange(page) {
  300. this.pageNum = page
  301. if(this.checkType === 'cur') {
  302. this.checkType = ''
  303. }
  304. this.initAgentUser()
  305. },
  306. // 选择代理人确认
  307. handleOk() {
  308. if(this.checkType === 'all') {
  309. this.quoteForm.authorize = 0
  310. this.selectList = []
  311. } else {
  312. this.selectList = [...this.selectedList]
  313. }
  314. this.agentTableShow = false
  315. },
  316. // 选择代理人取消
  317. handleCancel() {
  318. // this.selectList = [...this.myList]
  319. this.selectedList = [...this.selectList]
  320. this.selectedLength = this.selectedList.length
  321. this.agentTableShow = false
  322. },
  323. // 代理选择
  324. handleSelectChange(rows) {
  325. if(this.checkType === 'all') {
  326. this.selectedLength = this.total
  327. return;
  328. }
  329. let list = [...this.selectedList]
  330. if(list.length>0){
  331. if(rows.length>0) {
  332. let arr = list.filter(item1 => !this.agentDataList.some(item2 => item1.id === item2.id))
  333. this.selectedList = this.uniqueItems([...arr, ...rows])
  334. } else {
  335. this.selectedList = this.uniqueItems([...list])
  336. }
  337. this.selectedLength = this.selectedList.length
  338. } else {
  339. if(rows.length>0) {
  340. this.selectedList = [...rows]
  341. } else {
  342. this.selectedList = []
  343. }
  344. this.selectedLength = this.selectedList.length
  345. }
  346. },
  347. // 手动点击全选
  348. handleSelectAll(rows) {
  349. let list = [...this.selectedList]
  350. if(rows.length===0) {
  351. if(list.length>0){
  352. let arr = list.filter(item1 => !this.agentDataList.some(item2 => item1.id === item2.id))
  353. this.selectedList = this.uniqueItems([...arr])
  354. this.selectedLength = this.selectedList.length
  355. } else {
  356. this.selectedList = [...rows]
  357. }
  358. } else {
  359. let arr = [...rows], brr = [...list], crr = brr.concat(arr)
  360. this.selectedList = this.uniqueItems([...crr])
  361. this.selectedLength = this.selectedList.length
  362. }
  363. },
  364. // 数组去重
  365. uniqueItems(arr) {
  366. const unique = [];
  367. arr.forEach(item => {
  368. const exists = unique.some(el => el.id === item.id);
  369. if (!exists) {
  370. unique.push(item);
  371. }
  372. });
  373. return unique;
  374. },
  375. // 保险公司切换
  376. handleSelect(item, index) {
  377. this.menuIndex = index
  378. this.quoteForm = {
  379. id: '',
  380. isEnabled: false,
  381. authorize: '',
  382. quoteLimit: []
  383. }
  384. this.isEdit = false
  385. this.initQuoteDetails(item.id)
  386. },
  387. // 获取详情
  388. initQuoteDetails(id) {
  389. this.selectList = []
  390. this.selectedList = []
  391. this.myList = []
  392. this.$api.quote.getQuoteConfigInfo(id).then(res => {
  393. if(res.code === 200) {
  394. this.quoteForm = {...res.data}
  395. this.quoteForm.isEnabled = res.data.isEnabled?true:false
  396. let list = []
  397. if(res.data.orderRatio){
  398. list.push('1')
  399. }
  400. if(res.data.dayMaxQuoteNum){
  401. list.push('2')
  402. }
  403. if(res.data.carMaxQuoteNum){
  404. list.push('3')
  405. }
  406. this.$set(this.quoteForm, 'quoteLimit', list)
  407. this.selectedList = [...res.data.proxyList]
  408. this.selectedLength = res.data.proxyList.length
  409. this.selectList = [...res.data.proxyList]
  410. this.myList = [...res.data.proxyList]
  411. } else {
  412. this.$message.error(res.msg)
  413. }
  414. })
  415. },
  416. // 同步到其他
  417. handleSync() {
  418. this.syncShow = true
  419. },
  420. // 编辑
  421. handleEdit() {
  422. this.isEdit = true
  423. },
  424. // 保存
  425. handleSave() {
  426. this.$refs["QuoteFormRef"].validate((valid) => {
  427. if(valid) {
  428. this.$api.quote.setQuoteInfo({
  429. companyId: this.leftTree[this.menuIndex].id,
  430. isEnabled: this.quoteForm.isEnabled?1:0,
  431. id: this.quoteForm.id,
  432. authorize: this.quoteForm.authorize,
  433. proxyList: this.selectedList,
  434. orderRatio: this.quoteForm.orderRatio,
  435. dayMaxQuoteNum: this.quoteForm.dayMaxQuoteNum,
  436. carMaxQuoteNum: this.quoteForm.carMaxQuoteNum
  437. }).then(res => {
  438. if(res.code == 200) {
  439. this.$message.success(res.msg)
  440. this.initQuoteDetails(this.leftTree[this.menuIndex].id)
  441. this.quoteForm = {}
  442. } else {
  443. this.$message.error(res.msg)
  444. }
  445. })
  446. } else {
  447. this.$message.error('请填写或选择必要数据!')
  448. }
  449. this.isEdit = false
  450. })
  451. },
  452. // 同步到其他确定
  453. handleSubmit() {
  454. this.$api.quote.syncQuoteInfo({
  455. companyId: this.leftTree[this.menuIndex].id,
  456. isEnabled: this.quoteForm.isEnabled?1:0,
  457. id: this.quoteForm.id,
  458. authorize: this.quoteForm.authorize,
  459. proxyList: this.selectedList,
  460. orderRatio: this.quoteForm.orderRatio,
  461. dayMaxQuoteNum: this.quoteForm.dayMaxQuoteNum,
  462. carMaxQuoteNum: this.quoteForm.carMaxQuoteNum
  463. }).then(res => {
  464. if(res.code === 200) {
  465. this.$message.success(res.msg)
  466. } else {
  467. this.$message.error(res.msg)
  468. }
  469. this.syncShow = false
  470. })
  471. },
  472. // 选择代理人
  473. selectAgent() {
  474. this.agentTableShow = true
  475. this.countDetailForm = {}
  476. this.pageNum = 1
  477. this.checkType = ''
  478. this.selectedLength = 0
  479. this.initAgentUser()
  480. this.initOrganization()
  481. },
  482. // 全选类型切换
  483. selectTypeChange() {
  484. if(this.agentDataList.length>0) {
  485. this.agentDataList.forEach(item => {
  486. this.$refs.multipleTable.toggleRowSelection(item, true)
  487. })
  488. }
  489. if(this.checkType === 'all') {
  490. this.selectedLength = this.total
  491. this.selectedList = []
  492. }
  493. if(this.checkType === 'cur') {
  494. let list = [...this.selectedList], arr = [...this.agentDataList]
  495. this.selectedList = this.uniqueItems(list.concat(arr))
  496. this.selectedLength = this.selectedList.length
  497. }
  498. },
  499. // 监听浏览器刷新
  500. handleBeforeUnload(event) {
  501. if(this.isEdit) {
  502. event.preventDefault();
  503. event.returnValue = '';
  504. }
  505. },
  506. // 删除选择的代理人
  507. handleDelete(row) {
  508. let list = []
  509. list = this.selectList.filter((item) => {
  510. return item.id != row.id
  511. })
  512. this.selectList = [...list]
  513. this.selectedList = [...list]
  514. this.selectedLength = this.selectedList.length
  515. this.myList = [...list]
  516. }
  517. },
  518. mounted() {
  519. this.initCompany();
  520. window.addEventListener('beforeunload', this.handleBeforeUnload);
  521. },
  522. beforeDestroy() {
  523. window.removeEventListener('beforeunload', this.handleBeforeUnload)
  524. }
  525. }
  526. </script>
  527. <style scoped>
  528. .QuoteCountManagement{
  529. width: 100%;
  530. height: 100%;
  531. overflow-y: auto;
  532. .tips{
  533. font-size: 12px;
  534. color: #999;
  535. }
  536. }
  537. .menu-item{
  538. line-height: 38px;
  539. padding: 8px 0 8px 10px;
  540. color: #333333;
  541. cursor: pointer;
  542. }
  543. .active{
  544. background: rgba(24, 144, 255, 0.2);
  545. color: #1890FF;
  546. font-weight: 700;
  547. }
  548. .pagination-box{
  549. display: flex;
  550. align-items: center;
  551. justify-content: flex-end;
  552. margin-top: 10px;
  553. }
  554. /deep/.el-divider--horizontal{
  555. margin: 12px 0;
  556. }
  557. /deep/.el-input__inner{
  558. padding-left: 34px !important;
  559. }
  560. /deep/.select-box .el-input__inner{
  561. border: none !important;
  562. }
  563. </style>