audit-contrast-view.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. <template>
  2. <a-card>
  3. <a-form-model ref="search" v-bind="formItemLayout" :class="$style.form">
  4. <a-row>
  5. <a-col :span="6">
  6. <a-form-model-item label="查询公司选择">
  7. <audit-unit-select
  8. ref="cRelSelect"
  9. v-model="orgList"
  10. :read-only="false"
  11. :single="false"
  12. @change="changecompany"
  13. />
  14. </a-form-model-item>
  15. </a-col>
  16. <a-col :span="6">
  17. <a-form-model-item label="年份">
  18. <AuditYearTime v-model="year" />
  19. </a-form-model-item>
  20. </a-col>
  21. <!-- 搜索重置 -->
  22. <a-col :span="6">
  23. <a-form-model-item>
  24. <a-button style="margin-left: 15px" type="primary" @click="handlerSearch">
  25. 搜索
  26. </a-button>
  27. </a-form-model-item>
  28. </a-col>
  29. </a-row>
  30. </a-form-model>
  31. <div :class="$style.zbType">
  32. <a-button type="link" size="large">所选指标值:{{ zbName }}</a-button>
  33. <a-button type="primary" @click="goBack">返回重选</a-button>
  34. </div>
  35. <a-card>
  36. <!-- <sd-table
  37. :columns="columns"
  38. :scroll="{ x: '100%' }"
  39. :data-source="tableData"
  40. :row-key="(record, i) => record.key"
  41. :pagination="false"
  42. >
  43. </sd-table> -->
  44. <vxe-table
  45. ref="xTable"
  46. :key="tableKey"
  47. border
  48. :column-config="{ resizable: true }"
  49. :data="tableData"
  50. align="center"
  51. :tree-config="{}"
  52. >
  53. <template v-for="(item, i) in columns">
  54. <!-- 如果有children 则显示colgroup -->
  55. <vxe-colgroup
  56. v-if="item?.children?.length > 0"
  57. :key="i"
  58. :title="item.title"
  59. :field="item.dataIndex"
  60. align="center"
  61. :fixed="fixedType(i)"
  62. >
  63. <template v-for="(item1, i1) in item.children">
  64. <vxe-column
  65. :key="i1"
  66. :field="item1.dataIndex"
  67. :title="item1.title"
  68. align="center"
  69. min-width="240"
  70. >
  71. </vxe-column>
  72. </template>
  73. </vxe-colgroup>
  74. <vxe-column
  75. v-else
  76. :key="i"
  77. :title="item.title"
  78. :field="item.dataIndex"
  79. align="center"
  80. :fixed="fixedType(i)"
  81. ></vxe-column>
  82. </template>
  83. </vxe-table>
  84. </a-card>
  85. <a-card>
  86. <div :class="$style.barLineType">
  87. <span
  88. :style="{
  89. fontSize: '18px',
  90. color: action === 1 ? '#1890ff' : '#333',
  91. marginRight: '10px',
  92. }"
  93. @click="onTypeChange(1)"
  94. >柱状图</span
  95. >
  96. <span
  97. :style="{ fontSize: '18px', color: action === 2 ? '#1890ff' : '#333' }"
  98. @click="onTypeChange(2)"
  99. >折线图</span
  100. >
  101. </div>
  102. <div id="barLine" :class="$style.barLine"></div>
  103. </a-card>
  104. </a-card>
  105. </template>
  106. <script>
  107. import components from './_import-components/audit-contrast-view-import'
  108. import echarts from 'echarts'
  109. import AuditYearTime from './audit-year-time.vue'
  110. import auditUnitSelect from './audit-unit-select'
  111. import auditPortraitService from './audit-portrait-service'
  112. import { message } from 'ant-design-vue'
  113. import VXETable from 'vxe-table'
  114. import 'vxe-table/lib/style.css'
  115. import Vue from 'vue'
  116. Vue.use(VXETable)
  117. export default {
  118. name: 'AuditContrastView',
  119. metaInfo: {
  120. title: '对比',
  121. },
  122. components: {
  123. ...components,
  124. AuditYearTime,
  125. auditUnitSelect,
  126. },
  127. data() {
  128. return {
  129. formItemLayout: {
  130. labelCol: { span: 6 },
  131. wrapperCol: { span: 18 },
  132. },
  133. zbName: '',
  134. orgList: [],
  135. year: [],
  136. columns: [],
  137. tableData: [],
  138. action: 1,
  139. myChart: null,
  140. queryParams: null,
  141. tableKey: 1,
  142. }
  143. },
  144. created() {
  145. // this.initEcharts()
  146. this.initSearchData()
  147. },
  148. methods: {
  149. fixedType(i) {
  150. if (i === 0) return 'left'
  151. },
  152. // 初始化search数据
  153. initSearchData() {
  154. // 获取当前公司信息
  155. this.queryParams = JSON.parse(this.$route.query.params || '{}')
  156. this.orgList = this.queryParams.orgList || []
  157. this.year = this.queryParams.year || []
  158. this.zbName = this.queryParams.zbName || ''
  159. this.initTableData()
  160. },
  161. initTableData() {
  162. /**
  163. * mdg_orgCode
  164. */
  165. // private List<String> mdgOrgCodes;
  166. // /**
  167. // * 年
  168. // */
  169. // private List<Integer> year;
  170. // /**
  171. // *指标
  172. // */
  173. // private String metricName;
  174. // 获取表格数据
  175. const params = {
  176. mdgOrgCodes: this.orgList.map((res) => res.orgCode),
  177. year: this.year,
  178. metricName: this.queryParams.zbCode,
  179. }
  180. auditPortraitService.listMetricCompare(params).then((res) => {
  181. this.columns = [
  182. {
  183. fixed: 'left',
  184. children: [
  185. {
  186. // 公司名称
  187. title: '公司名称',
  188. dataIndex: 'orgName',
  189. fixed: 'left',
  190. width: '280px',
  191. // 自定义渲染 如果超长则显示tooltip
  192. customRender: (text) => {
  193. return {
  194. children: (
  195. <a-tooltip title={text}>
  196. <div style='width:100%;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;'>
  197. {text}
  198. </div>
  199. </a-tooltip>
  200. ),
  201. }
  202. },
  203. },
  204. ],
  205. },
  206. ]
  207. this.tableData = res.data.data.map((val, i) => {
  208. const obj = {}
  209. obj.key = i
  210. obj.orgName = val.org_name
  211. obj.orgCode = val.org_code
  212. val.values.map((item1) => {
  213. const isValue = this.zbName.includes('率')
  214. if (isValue) {
  215. obj[`zbz${item1.year}`] = (item1.value * 100).toFixed(2) || ''
  216. } else {
  217. obj[`zbz${item1.year}`] = item1.value
  218. }
  219. // 如果是NaN则显示原本的值
  220. if (isNaN(obj[`zbz${item1.year}`])) {
  221. obj[`zbz${item1.year}`] = item1.value
  222. }
  223. })
  224. return obj
  225. })
  226. if (res.data.data.length === 0) {
  227. return message.warning('暂无数据')
  228. }
  229. res.data.data[0].values.map((item1) => {
  230. this.columns.push({
  231. // 2020 指标值
  232. align: 'center',
  233. title: item1.year,
  234. children: [
  235. {
  236. title: '指标值',
  237. dataIndex: `zbz${item1.year}`,
  238. align: 'center',
  239. width: '180px',
  240. },
  241. ],
  242. })
  243. })
  244. this.tableKey++
  245. this.initEcharts()
  246. })
  247. },
  248. changecompany(val) {
  249. this.orgList = val
  250. },
  251. handlerSearch() {
  252. this.initTableData()
  253. },
  254. resetSearch() {
  255. this.orgList = []
  256. this.year = []
  257. },
  258. goBack() {
  259. // 返回上一页
  260. // window.history.go(-1)
  261. // 关闭当前页面
  262. window.close()
  263. },
  264. //
  265. onTypeChange(type) {
  266. this.action = type
  267. // 折线图
  268. this.initEcharts()
  269. },
  270. initEcharts() {
  271. const unitList = this.tableData.map((res) => res.orgName)
  272. //
  273. // 单位 CNY 如果colTitle含率则单位为%
  274. const dw = this.zbName.includes('率') ? '%' : '万元'
  275. // 根据公司分割数据
  276. const year = Object.keys(this.tableData[0] || {}).filter((val) => val.includes('zbz'))
  277. const yearList = year.map((val) => val.replace('zbz', ''))
  278. const seriesData = yearList.map((val, i) => {
  279. return {
  280. name: val,
  281. data: this.tableData.map((res) => res[`zbz${val}`]),
  282. type: this.action === 1 ? 'bar' : 'line',
  283. // 柱子宽度
  284. barMaxWidth: 50,
  285. // 柱子颜色 三选择一
  286. itemStyle: {
  287. color: i % 2 === 0 ? '#1890ff' : '#E76F00',
  288. },
  289. // 柱子间距
  290. }
  291. })
  292. this.myChart = echarts.init(document.getElementById('barLine'))
  293. const option = {
  294. title: {
  295. text: this.zbName,
  296. textStyle: {
  297. rich: {
  298. a: {
  299. fontSize: 16,
  300. fontWeight: 600,
  301. },
  302. },
  303. },
  304. top: '0%',
  305. left: '45%',
  306. },
  307. tooltip: {
  308. trigger: 'item',
  309. // 带单位
  310. formatter: '{a} <br/>{b} : {c}' + dw,
  311. },
  312. grid: {
  313. left: '5%',
  314. containLabel: true,
  315. },
  316. // x轴滚动
  317. dataZoom: [
  318. {
  319. type: 'slider',
  320. show: true,
  321. xAxisIndex: [0],
  322. startValue: 0, // 起始值
  323. endValue: 10, // 结束值
  324. },
  325. {
  326. type: 'inside',
  327. xAxisIndex: [0],
  328. start: 0,
  329. end: 10,
  330. },
  331. ],
  332. xAxis: {
  333. type: 'category',
  334. data: unitList,
  335. // 每组数据间隔
  336. axisTick: {
  337. alignWithLabel: true,
  338. },
  339. axisLabel: {
  340. show: true, // 是否显示刻度标签,默认显示
  341. interval: 0, // 坐标轴刻度标签的显示间隔,在类目轴中有效;默认会采用标签不重叠的策略间隔显示标签;可以设置成0强制显示所有标签;如果设置为1,表示『隔一个标签显示一个标签』,如果值为2,表示隔两个标签显示一个标签,以此类推。
  342. inside: false, // 刻度标签是否朝内,默认朝外
  343. margin: 6, // 刻度标签与轴线之间的距离
  344. // 文字大小
  345. fontSize: 18,
  346. // formatter: '{value}', // 刻度标签的内容格式器
  347. // 旋转15
  348. rotate: -15,
  349. },
  350. //
  351. },
  352. yAxis: {
  353. name: dw,
  354. type: 'value',
  355. minInterval: 1,
  356. splitLine: {
  357. lineStyle: {
  358. type: 'dashed',
  359. color: '#111',
  360. },
  361. },
  362. },
  363. // tooltip: {
  364. // trigger: 'axis',
  365. // axisPointer: {
  366. // type: 'shadow',
  367. // },
  368. // },
  369. // 图例
  370. legend: {
  371. data: [year],
  372. textStyle: {
  373. align: 'right',
  374. },
  375. top: '2%',
  376. right: '2%',
  377. },
  378. series: seriesData,
  379. }
  380. this.myChart.setOption(option)
  381. window.addEventListener('resize', () => {
  382. this.myChart.resize()
  383. })
  384. },
  385. },
  386. }
  387. </script>
  388. <style module lang="scss">
  389. @use '@/common/design' as *;
  390. .bar-line {
  391. width: 100%;
  392. height: 600px;
  393. }
  394. .zb-type {
  395. margin: 10px 0;
  396. }
  397. .bar-line-type {
  398. span {
  399. cursor: pointer;
  400. }
  401. }
  402. </style>