bcf82db06db70174f58b1b463f219d7e8f8bed42.svn-base 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. <template>
  2. <div class="container">
  3. <div class="left-section">
  4. <div style="height: 50%;display: flex;flex-direction: column;">
  5. <div style="display: flex;align-items: center;padding-top: 1%;height: 20px;">
  6. <div style="height: 100%;background-color:#4FAFCB;width: 2px;"></div>
  7. <div style="margin-left: 10px;">保险公司承保数量</div>
  8. </div>
  9. <div style="display: flex;align-items: center;height: 20px;margin-top: 5%;">
  10. <el-select @change="initBingChart" v-model="valueQunian" placeholder="请选择年份" style="width: 30%;">
  11. <el-option
  12. v-for="item in optionsYear"
  13. :key="item.value"
  14. :label="item.label"
  15. :value="item.value">
  16. </el-option>
  17. </el-select>
  18. <el-button @click="showAxde" type="primary" style="margin-left: auto;">详情</el-button>
  19. </div>
  20. <div id="bing1" style="flex: 1;width: 90%;margin: 0 auto;"></div>
  21. </div>
  22. <div style="margin-top: 1%;height: 50%;display: flex;flex-direction: column;">
  23. <div style="display: flex;align-items: center;padding-top: 1%;height: 20px;">
  24. <div style="height: 100%;background-color:#4FAFCB;width: 2px;"></div>
  25. <div style="margin-left: 10px;">保险公司承保趋势统计</div>
  26. </div>
  27. <el-select @change="initZhu1Chart" v-model="valueZhu1nian" placeholder="请选择年份" style="margin-top: 5%;width: 30%;">
  28. <el-option
  29. v-for="item in optionsYear"
  30. :key="item.value"
  31. :label="item.label"
  32. :value="item.value">
  33. </el-option>
  34. </el-select>
  35. <div id="zhu1" style="flex: 1;width: 90%;margin: 0 auto;"></div>
  36. </div>
  37. </div>
  38. <div class="middle-section" style='margin-left: 1%;display: flex;flex-direction: column;height: 100%;'>
  39. <div style="height: 50%;display: flex;flex-direction: column;">
  40. <div style="display: flex;align-items: center;padding-top: 1%;height: 20px;">
  41. <div style="height: 100%;background-color:#4FAFCB;width: 2px;"></div>
  42. <div style="margin-left: 10px;">安责险完成情况</div>
  43. </div>
  44. <div style="display: flex;align-items: center;height: 20px;margin-top: 5%;">
  45. <el-select @change="initZhu2Chart" v-model="valueZhu2nian" placeholder="请选择年份" style="width: 30%;">
  46. <el-option
  47. v-for="item in optionsYear"
  48. :key="item.value"
  49. :label="item.label"
  50. :value="item.value">
  51. </el-option>
  52. </el-select>
  53. <el-button @click="showAxCom" type="primary" style="margin-left: auto;">详情</el-button>
  54. </div>
  55. <el-table
  56. :data="tableDataAnCom"
  57. :height="tableHeight"
  58. style="flex: 1;width: 100%;margin-top:2%;"
  59. >
  60. <el-table-column
  61. prop="AD_NAME"
  62. label="地区"
  63. ></el-table-column>
  64. <el-table-column
  65. prop="PROJECT_CNT"
  66. label="项目个数"
  67. ></el-table-column>
  68. <el-table-column
  69. prop="UNDERWRITING_CNT"
  70. label="保险承保个数"
  71. ></el-table-column>
  72. <el-table-column
  73. prop="COMPLETION_CNT"
  74. label="完成情况"
  75. ></el-table-column>
  76. </el-table>
  77. </div>
  78. <div id="zhu2" style="height: 50%;border-top: 1px solid #e0e0e0;box-sizing: border-box;">
  79. </div>
  80. </div>
  81. <!-- 弹窗展示安全保险详情 -->
  82. <el-dialog
  83. title="安全保险详情"
  84. :visible.sync="showAxDialog"
  85. width="90%"
  86. height="90%"
  87. :fullscreen="false"
  88. >
  89. <DuChaTianBaoIndexAx />
  90. </el-dialog>
  91. <el-dialog
  92. title="六项机制详情"
  93. :visible.sync="showLxDialog"
  94. width="90%"
  95. height="90%"
  96. :fullscreen="false"
  97. >
  98. <DuChaTianBaoIndexLx />
  99. </el-dialog>
  100. <div class="right-section" style='margin-left: 1%;'>
  101. <div style="height: 50%;display: flex;flex-direction: column;">
  102. <div style="display: flex;align-items: center;padding-top: 1%;height: 20px;">
  103. <div style="height: 100%;background-color:#4FAFCB;width: 2px;"></div>
  104. <div style="margin-left: 10px;">六项机制完成情况</div>
  105. </div>
  106. <div style="display: flex;align-items: center;height: 20px;margin-top: 5%;">
  107. <el-select @change="initZhu3Chart" v-model="valueZhu3nian" placeholder="请选择年份" style="width: 30%;">
  108. <el-option
  109. v-for="item in optionsYear"
  110. :key="item.value"
  111. :label="item.label"
  112. :value="item.value">
  113. </el-option>
  114. </el-select>
  115. <el-button @click="showLxCom" type="primary" style="margin-left: auto;">详情</el-button>
  116. </div>
  117. <el-table
  118. :data="tableDataLiuCom"
  119. :height="tableHeight"
  120. style="flex: 1;width: 100%;margin-top: 2%;"
  121. >
  122. <el-table-column
  123. prop="AD_NAME"
  124. label="地区"
  125. ></el-table-column>
  126. <el-table-column
  127. prop="PROJECT_CNT"
  128. label="项目个数"
  129. ></el-table-column>
  130. <el-table-column
  131. prop="COMPLETION_CNT"
  132. label="完成个数"
  133. ></el-table-column>
  134. </el-table>
  135. </div>
  136. <div id="zhu3" style="height: 50%;border-top: 1px solid #e0e0e0;box-sizing: border-box;">
  137. </div>
  138. </div>
  139. <el-dialog
  140. title="安险详情"
  141. :visible.sync="dialogVisible"
  142. width="80%">
  143. <!-- 搜索条件 -->
  144. <div style="display: flex; gap: 15px; margin-bottom: 20px; flex-wrap: wrap;">
  145. <el-input
  146. v-model="searchForm.name"
  147. placeholder="工程名称"
  148. style="width: 200px;">
  149. </el-input>
  150. <addvSearch
  151. v-model="searchForm.adName"
  152. :maxHeight='300'
  153. :maxWidth='250'
  154. :rootAddCode='curAdcode_long'
  155. :level='"3"'
  156. placeholder="地区"
  157. :nameOrCode="'name'"
  158. ></addvSearch>
  159. <el-input
  160. v-model="searchForm.insuranceCompany"
  161. placeholder="保险名称"
  162. style="width: 200px;">
  163. </el-input>
  164. <el-button
  165. type="primary"
  166. @click="showAxde"
  167. size="mini"
  168. style="height: 32px; align-self: center;">
  169. 搜索
  170. </el-button>
  171. <!-- <el-button
  172. @click="resetSearch"
  173. style="height: 32px; align-self: center;">
  174. 重置
  175. </el-button> -->
  176. </div>
  177. <el-table
  178. ref="table"
  179. border
  180. :data="tableDataAn"
  181. style="width: 100%"
  182. v-loading="expLoading">
  183. <el-table-column
  184. prop="name"
  185. label="工程名称">
  186. </el-table-column>
  187. <el-table-column
  188. prop="adName"
  189. label="地区">
  190. </el-table-column>
  191. <el-table-column
  192. prop="insuranceCompany"
  193. label="保险名称">
  194. </el-table-column>
  195. <el-table-column
  196. prop="insuranceContactPerson"
  197. label="保险机构联系人">
  198. </el-table-column>
  199. <el-table-column
  200. prop="insuranceContactPhone"
  201. label="保险机构联系电话"
  202. show-overflow-tooltip>
  203. </el-table-column>
  204. <el-table-column
  205. prop="policyholder"
  206. label="投保人">
  207. </el-table-column>
  208. <el-table-column
  209. prop="policyholderPhone"
  210. label="投保人联系电话">
  211. </el-table-column>
  212. <el-table-column
  213. prop="serviceUnitContactPerson"
  214. label="服务单位">
  215. </el-table-column>
  216. <el-table-column
  217. prop="serviceUnitContactPhone"
  218. label="服务单位联系电话">
  219. </el-table-column>
  220. </el-table>
  221. <div style="text-align: center; margin-top: 20px;">
  222. <el-pagination
  223. layout="prev, pager, next"
  224. :current-page="currentPageAx"
  225. @current-change="handleCurrentChangeAx"
  226. :total="totalAx">
  227. </el-pagination>
  228. </div>
  229. <span slot="footer" class="dialog-footer">
  230. <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  231. </span>
  232. </el-dialog>
  233. </div>
  234. </template>
  235. <script>
  236. import * as echarts from 'echarts'
  237. import request from '../../utils/gw_ajax_request.js'
  238. import DuChaTianBaoIndexAx from './duChaTianBaoIndex_ax.vue'
  239. import DuChaTianBaoIndexLx from './duChaTianBaoIndex_lx.vue'
  240. import addvSearch from "@widget/addvSearch.vue"
  241. import {curAdcode_short,curAdcode_long} from '@util/global_variable.js'
  242. export default {
  243. name: 'DuChaTianBaoIndexLxShouye',
  244. components: {
  245. DuChaTianBaoIndexAx,
  246. DuChaTianBaoIndexLx,
  247. addvSearch
  248. },
  249. data() {
  250. return {
  251. tableDataAn:[],
  252. tableDataLiuCom:[],
  253. tableHeight: window.innerHeight - 304,
  254. dialogVisible: false,
  255. totalAx: 0,
  256. currentPageAx: 1,
  257. showLxDialog: false,
  258. showAxDialog: false,
  259. searchForm: {
  260. name: '',
  261. adName: '',
  262. insuranceCompany: ''
  263. },
  264. valueZhu1nian: '2026',
  265. tableDataAnCom:[],
  266. valueZhu2nian: '2026',
  267. valueZhu3nian: '2026',
  268. valueQunian: '2026',
  269. optionsYear: [
  270. { value: '2026', label: '2026' },
  271. { value: '2025', label: '2025' },
  272. { value: '2024', label: '2024' },
  273. { value: '2023', label: '2023' },
  274. { value: '2022', label: '2022' },
  275. { value: '2021', label: '2021' }
  276. ],
  277. // 表格数据
  278. tableData: [
  279. { name: '数据1', value: 1234, status: '正常' },
  280. { name: '数据2', value: 5678, status: '正常' },
  281. { name: '数据3', value: 9012, status: '异常' },
  282. { name: '数据4', value: 3456, status: '正常' },
  283. { name: '数据5', value: 7890, status: '正常' }
  284. ]
  285. }
  286. },
  287. computed: {
  288. curAdcode_long(){
  289. return curAdcode_long
  290. },
  291. },
  292. mounted() {
  293. // 初始化图表
  294. this.initBingChart()
  295. this.initZhu1Chart()
  296. this.initZhu2Chart()
  297. this.initZhu3Chart()
  298. // 响应窗口大小变化
  299. window.addEventListener('resize', () => {
  300. this.bingChart && this.bingChart.resize()
  301. this.zhu1Chart && this.zhu1Chart.resize()
  302. this.zhu2Chart && this.zhu2Chart.resize()
  303. this.zhu3Chart && this.zhu3Chart.resize()
  304. })
  305. },
  306. beforeDestroy() {
  307. // 销毁图表
  308. this.bingChart && this.bingChart.dispose()
  309. this.zhu1Chart && this.zhu1Chart.dispose()
  310. this.zhu2Chart && this.zhu2Chart.dispose()
  311. this.zhu3Chart && this.zhu3Chart.dispose()
  312. window.removeEventListener('resize', this.handleResize)
  313. },
  314. methods: {
  315. showLxCom(){
  316. this.showLxDialog = true
  317. },
  318. showAxCom(){
  319. this.showAxDialog = true
  320. },
  321. handleCurrentChangeAx(val) {
  322. this.currentPageAx = val
  323. this.showAxde()
  324. },
  325. showAxde(){
  326. request.get('/att/project/insurance/anze/underwriting/list',{
  327. params: {
  328. 'year': this.valueQunian,
  329. pageNum: this.currentPageAx,
  330. pageSize: 10,
  331. name: this.searchForm.name,
  332. adName: this.searchForm.adName,
  333. insuranceCompany: this.searchForm.insuranceCompany
  334. }
  335. }).then(response => {
  336. this.tableDataAn = response.data.list
  337. this.totalAx = response.data.total
  338. this.dialogVisible = true
  339. })
  340. },
  341. resetSearch(){
  342. this.searchForm = {
  343. name: '',
  344. adName: '',
  345. insuranceCompany: ''
  346. }
  347. this.currentPageAx = 1
  348. this.showAxde()
  349. },
  350. async initBingChart() {
  351. let chartData
  352. await request.get('/bis/insp/anze/statistics/insurer/underwritingCount',{params:{'year':this.valueQunian}}).then(response => {
  353. // 处理响应数据,更新图表数据
  354. const data = response.data
  355. // 假设返回的数据格式为 { company: '中国平安', value: 335 }
  356. chartData = data.map(item => ({
  357. value: item.CNT,
  358. name: item.INSURANCE_COMPANY
  359. }))
  360. console.log('获取保险数据成功:', chartData)
  361. }).catch(error => {
  362. console.error('获取保险数据失败:', error)
  363. })
  364. this.bingChart = echarts.init(document.getElementById('bing1'))
  365. const option = {
  366. tooltip: {
  367. trigger: 'item',
  368. formatter: '{b}: {c} ({d}%)'
  369. },
  370. grid: {
  371. left: '3%',
  372. right: '4%',
  373. bottom: '3%',
  374. containLabel: true
  375. },
  376. legend: {
  377. orient: 'horizontal',
  378. bottom: '2%',
  379. left: 'center',
  380. itemWidth: 8,
  381. itemHeight: 8,
  382. textStyle: {
  383. fontSize: 8
  384. }
  385. },
  386. series: [
  387. {
  388. name: '承保数量',
  389. type: 'pie',
  390. radius: ['30%', '55%'],
  391. center: ['50%', '45%'],
  392. avoidLabelOverlap: false,
  393. itemStyle: {
  394. borderRadius: 6,
  395. borderColor: '#fff',
  396. borderWidth: 1
  397. },
  398. label: {
  399. show: true,
  400. formatter: '{b}: {d}%',
  401. fontSize: 8
  402. },
  403. emphasis: {
  404. label: {
  405. show: true,
  406. fontSize: 10,
  407. fontWeight: 'bold'
  408. }
  409. },
  410. data: chartData
  411. }
  412. ]
  413. }
  414. this.bingChart.setOption(option)
  415. },
  416. // 初始化zhu1柱状图
  417. async initZhu1Chart() {
  418. let chartDataX
  419. let chartDataY
  420. await request.get('/bis/insp/anze/statistics/insurer/underwritingCount',{params:{'year':this.valueZhu1nian}}).then(response => {
  421. // 处理响应数据,更新图表数据
  422. const data = response.data
  423. // 假设返回的数据格式为 { company: '中国平安', value: 335 }
  424. chartDataX = data.map(item => ( item.INSURANCE_COMPANY
  425. ))
  426. chartDataY = data.map(item => ( item.CNT
  427. ))
  428. console.log('获取保险数据成功:', chartDataY)
  429. }).catch(error => {
  430. console.error('获取保险数据失败:', error)
  431. })
  432. this.zhu1Chart = echarts.init(document.getElementById('zhu1'))
  433. const option = {
  434. tooltip: {
  435. trigger: 'axis',
  436. axisPointer: {
  437. type: 'shadow'
  438. }
  439. },
  440. grid: {
  441. left: '3%',
  442. right: '4%',
  443. bottom: '8%',
  444. containLabel: true
  445. },
  446. xAxis: {
  447. type: 'category',
  448. data: chartDataX
  449. },
  450. yAxis: {
  451. type: 'value'
  452. },
  453. series: [
  454. {
  455. name: '承保数量',
  456. type: 'bar',
  457. data: chartDataY,
  458. itemStyle: {
  459. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  460. { offset: 0, color: '#83bff6' },
  461. { offset: 0.5, color: '#188df0' },
  462. { offset: 1, color: '#188df0' }
  463. ])
  464. }
  465. }
  466. ]
  467. }
  468. this.zhu1Chart.setOption(option)
  469. },
  470. // 初始化zhu2柱状图
  471. async initZhu2Chart() {
  472. var chartDataX
  473. var chartDataY
  474. await request.get('/bis/insp/anze/statistics/completion',{params:{'year':this.valueZhu2nian}}).then(response => {
  475. this.tableDataAnCom = response.data
  476. chartDataX = response.data.map(item => ( item.AD_NAME
  477. ))
  478. chartDataY = response.data.map(item => ( item.COMPLETION_CNT
  479. ))
  480. })
  481. this.zhu2Chart = echarts.init(document.getElementById('zhu2'))
  482. const option = {
  483. tooltip: {
  484. trigger: 'axis',
  485. axisPointer: {
  486. type: 'shadow'
  487. }
  488. },
  489. // 取消图例
  490. grid: {
  491. left: '3%',
  492. right: '4%',
  493. bottom: '8%',
  494. containLabel: true
  495. },
  496. xAxis:{
  497. type: 'category',
  498. data: chartDataX
  499. },
  500. yAxis: {
  501. type: 'value'
  502. },
  503. series: [
  504. {
  505. name: '未承保',
  506. type: 'bar',
  507. data: chartDataY,
  508. itemStyle: {
  509. color: '#ff4d4f'
  510. }
  511. }
  512. ]
  513. }
  514. this.zhu2Chart.setOption(option)
  515. },
  516. // 初始化zhu3柱状图
  517. async initZhu3Chart() {
  518. var chartDataX
  519. var chartDataY
  520. await request.get('/bis/insp/sixme/statistics/completion',{params:{'year':this.valueZhu3nian}}).then(response => {
  521. this.tableDataLiuCom = response.data
  522. chartDataX = response.data.map(item => ( item.AD_NAME
  523. ))
  524. chartDataY = response.data.map(item => ( item.COMPLETION_CNT
  525. ))
  526. })
  527. this.zhu3Chart = echarts.init(document.getElementById('zhu3'))
  528. const option = {
  529. tooltip: {
  530. trigger: 'axis',
  531. axisPointer: {
  532. type: 'shadow'
  533. }
  534. },
  535. grid: {
  536. left: '3%',
  537. right: '4%',
  538. bottom: '8%',
  539. containLabel: true
  540. },
  541. xAxis: {
  542. type: 'category',
  543. data: chartDataX
  544. },
  545. yAxis: {
  546. type: 'value'
  547. },
  548. series: [
  549. {
  550. name: '保费收入',
  551. type: 'bar',
  552. data: chartDataY,
  553. itemStyle: {
  554. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  555. { offset: 0, color: '#ff7a45' },
  556. { offset: 1, color: '#ff4757' }
  557. ]),
  558. borderRadius: [4, 4, 0, 0]
  559. }
  560. }
  561. ]
  562. }
  563. this.zhu3Chart.setOption(option)
  564. }
  565. }
  566. }
  567. </script>
  568. <style scoped>
  569. .container {
  570. width: 100vw;
  571. height: 95vh;
  572. display: flex;
  573. flex-direction: row;
  574. }
  575. .left-section {
  576. width: 20%;
  577. height: 100%;
  578. padding: 20px;
  579. box-sizing: border-box;
  580. }
  581. .middle-section {
  582. width: 39%;
  583. height: 100%;
  584. padding: 20px;
  585. box-sizing: border-box;
  586. }
  587. .right-section {
  588. width: 39%;
  589. height: 100%;
  590. padding: 20px;
  591. box-sizing: border-box;
  592. }
  593. h2 {
  594. margin-top: 0;
  595. color: #333;
  596. }
  597. p {
  598. color: #666;
  599. }
  600. </style>