km-integral-statistics.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <template>
  2. <a-card>
  3. <p :class="$style.integarsl">积分统计</p>
  4. <sd-detail-form
  5. ref="docform"
  6. :page-id="pageId"
  7. :class="$style.docform"
  8. @actionBtnClick="submitData"
  9. >
  10. <template v-slot="{ model, fields }">
  11. <sd-form-item name="type" />
  12. <sd-form-item v-if="model.type === '0'" name="selectMember" />
  13. <sd-form-item v-if="model.type === '1'" name="selectDept" />
  14. <sd-form-item name="year">
  15. <a-select
  16. ref="select"
  17. v-model="model.year"
  18. :get-popup-container="
  19. (triggerNode) => {
  20. return triggerNode.parentNode || document.body
  21. }
  22. "
  23. @change="handleChange"
  24. >
  25. <a-select-option v-for="item in yearData" :key="item" :value="item">
  26. {{ item }}
  27. </a-select-option>
  28. </a-select>
  29. </sd-form-item>
  30. <sd-form-item name="monthReport">
  31. <a-radio-group
  32. v-model="model.monthReport"
  33. name="monthradioGroup"
  34. @change="onChange(model, 'monthReport')"
  35. >
  36. <a-radio
  37. v-for="item in fields.monthReport.attr.selectListItem"
  38. :key="item.value"
  39. :value="item.value"
  40. :disabled="currentM && Number(item.value) > currentM"
  41. >
  42. {{ item.label }}
  43. </a-radio>
  44. </a-radio-group>
  45. </sd-form-item>
  46. <sd-form-item name="quarterReport" component="a-radio-group">
  47. <a-radio-group
  48. v-model="model.quarterReport"
  49. name="quarterradioGroup"
  50. @change="onChange(model, 'quarterReport')"
  51. >
  52. <a-radio
  53. v-for="item in fields.quarterReport.attr.selectListItem"
  54. :key="item.value"
  55. :value="item.value"
  56. :disabled="currentM && item.value !== String(moment().quarter())"
  57. >
  58. {{ item.label }}
  59. </a-radio>
  60. </a-radio-group>
  61. </sd-form-item>
  62. <sd-form-item name="halfYearReport">
  63. <a-radio-group
  64. v-model="model.halfYearReport"
  65. name="halfAYearradioGroup"
  66. @change="onChange(model, 'halfYearReport')"
  67. >
  68. <a-radio
  69. v-for="item in fields.halfYearReport.attr.selectListItem"
  70. :key="item.value"
  71. :value="item.value"
  72. :disabled="
  73. currentM &&
  74. item.value !==
  75. String(Math.floor(currentM % 6 === 0 ? currentM / 6 : currentM / 6 + 1))
  76. "
  77. >
  78. {{ item.label }}
  79. </a-radio>
  80. </a-radio-group>
  81. </sd-form-item>
  82. <sd-form-item name="yearReport">
  83. <a-radio-group
  84. v-model="model.yearReport"
  85. name="yearradioGroup"
  86. @change="onChange(model, 'yearReport')"
  87. >
  88. <a-radio
  89. v-for="item in fields.yearReport.attr.selectListItem"
  90. :key="item.value"
  91. :value="item.value"
  92. >
  93. {{ item.label }}({{ year === '' ? '' : year }})
  94. </a-radio>
  95. </a-radio-group>
  96. </sd-form-item>
  97. </template>
  98. </sd-detail-form>
  99. <a-modal
  100. v-model="echartsModal"
  101. :destroy-on-close="true"
  102. :width="900"
  103. title="积分统计"
  104. ok-text="导出"
  105. @ok="handleOk"
  106. >
  107. <div :class="$style.detailModal">
  108. <p>{{ echartsTitle }}</p>
  109. <sd-echart :class="$style.bar" :options="bar" autoresize />
  110. <sd-data-table
  111. ref="dataTable"
  112. data-url="api/xcoa-mobile/v1/km-point/statistics-list"
  113. :columns="getColumns(objType)"
  114. >
  115. </sd-data-table>
  116. </div>
  117. </a-modal>
  118. </a-card>
  119. </template>
  120. <script>
  121. // 为了按需加载,下面的组件需要手工导入
  122. import 'echarts/lib/chart/bar'
  123. import 'echarts/lib/component/legend'
  124. import 'echarts/lib/component/tooltip'
  125. import moment from 'moment'
  126. import { Message } from 'ant-design-vue'
  127. import errorUtil from '@/common/services/error-util'
  128. import download from '@/common/services/download'
  129. import KmKnowledageService from '../km-knowledage-service'
  130. import components from './_import-components/km-integral-statistics-import'
  131. /**
  132. * 标注类型后,各个属性就可以自动完成 + 帮助提示
  133. * @type {import("echarts").EChartOption}
  134. */
  135. export default {
  136. name: 'KmIntegralStatistics',
  137. metaInfo: {
  138. title: '积分统计',
  139. },
  140. components,
  141. data() {
  142. return {
  143. showForm: false,
  144. pageId: 'km/point/kmPointStatistics',
  145. docId: null,
  146. bar: {},
  147. year: null,
  148. currentM: null,
  149. yearData: [],
  150. echartsModal: false,
  151. echartsTitle: '',
  152. size: null,
  153. objType: '',
  154. echartsData: [],
  155. echartsColor: null,
  156. }
  157. },
  158. watch: {
  159. year(val) {
  160. if (val === Number(moment().format('YYYY'))) {
  161. this.currentM = moment().format('M')
  162. } else {
  163. this.currentM = false
  164. }
  165. },
  166. },
  167. created() {
  168. const nowYear = moment().format('YYYY')
  169. this.years = this.getYearTen(nowYear)
  170. },
  171. methods: {
  172. getColumns(objType) {
  173. if (objType === '0') {
  174. return [
  175. {
  176. title: '序号',
  177. customRender: (text, record, index) => `${index + 1}`,
  178. },
  179. {
  180. title: '姓名',
  181. dataIndex: 'name',
  182. },
  183. {
  184. title: '部门',
  185. dataIndex: 'deptName',
  186. },
  187. {
  188. title: '积分',
  189. dataIndex: 'point',
  190. },
  191. ]
  192. } else {
  193. return [
  194. {
  195. title: '序号',
  196. customRender: (text, record, index) => `${index + 1}`,
  197. },
  198. {
  199. title: '部门',
  200. dataIndex: 'deptName',
  201. },
  202. {
  203. title: '积分',
  204. dataIndex: 'point',
  205. },
  206. ]
  207. }
  208. },
  209. handleChange(v) {
  210. this.year = v
  211. },
  212. getYearTen(cur) {
  213. const years = []
  214. for (let i = 0; i <= 20; i++) {
  215. this.yearData.push(cur - i)
  216. }
  217. return years
  218. },
  219. popupScroll() {
  220. const addYears = this.getYearTen(this.yearData[this.yearData.length])
  221. this.yearData.push(...addYears)
  222. },
  223. moment,
  224. onChange(v, key) {
  225. const arr = ['quarterReport', 'monthReport', 'halfYearReport', 'yearReport']
  226. arr.forEach((k) => {
  227. if (k !== key) v[k] = ''
  228. })
  229. },
  230. // 提交
  231. submitData(evt, btn) {
  232. if (btn.buttonId === 'save') {
  233. evt.preventDefault()
  234. this.$refs.docform.validateFields().then(() => {
  235. if (
  236. this.$refs.docform.getFieldValue('monthReport') === undefined ||
  237. this.$refs.docform.getFieldValue('quarterReport') === undefined ||
  238. this.$refs.docform.getFieldValue('halfYearReport') === undefined ||
  239. this.$refs.docform.getFieldValue('yearReport') === undefined
  240. ) {
  241. Message.warn('统计方式不能为空!')
  242. } else {
  243. this.previewStatistics()
  244. }
  245. })
  246. }
  247. },
  248. previewStatistics() {
  249. const obj = this.$refs.docform.getFieldsValue()
  250. this.objType = this.$refs.docform.getFieldValue('type')
  251. const objYear = obj.year + '年'
  252. const objType = obj.type === '0' ? '个人积分' : '部门积分'
  253. const objCountType =
  254. obj.monthReport !== ''
  255. ? obj.monthReport + '月'
  256. : obj.quarterReport !== ''
  257. ? obj.quarterReport + '季度'
  258. : obj.halfYearReport !== ''
  259. ? obj.halfYearReport === '1'
  260. ? '上半年'
  261. : '下半年'
  262. : obj.yearReport !== ''
  263. ? '年报'
  264. : ''
  265. this.echartsTitle = objYear + objCountType + objType
  266. // 柱状图 根据个人部门颜色区分
  267. this.echartsColor = obj.type === '0' ? ['#c23531'] : ['#3398DB']
  268. const params = {
  269. inputs: [
  270. {
  271. name: 'type',
  272. value: Number(obj.type),
  273. },
  274. {
  275. name: 'selectDept',
  276. value: JSON.stringify(obj.selectDept),
  277. },
  278. {
  279. name: 'selectMember',
  280. value: JSON.stringify(obj.selectMember),
  281. },
  282. {
  283. name: 'year',
  284. value: Number(obj.year),
  285. },
  286. ],
  287. }
  288. params.inputs.push(
  289. Object.assign(
  290. { name: 'monthReport' },
  291. obj.monthReport ? { value: Number(obj.monthReport) } : ''
  292. )
  293. )
  294. params.inputs.push(
  295. Object.assign(
  296. { name: 'quarterReport' },
  297. obj.quarterReport ? { value: Number(obj.quarterReport) } : ''
  298. )
  299. )
  300. params.inputs.push(
  301. Object.assign(
  302. { name: 'halfYearReport' },
  303. obj.halfYearReport ? { value: Number(obj.halfYearReport) } : ''
  304. )
  305. )
  306. params.inputs.push(
  307. Object.assign(
  308. { name: 'yearReport' },
  309. obj.yearReport ? { value: Number(obj.yearReport) } : ''
  310. )
  311. )
  312. KmKnowledageService.getPreviewStatistics(params)
  313. .then((res) => {
  314. if (res.status === 200) {
  315. this.size = res.data
  316. Message.success('提交成功')
  317. this.echartsModal = true
  318. this.statisticsList()
  319. }
  320. })
  321. .catch((err) => {
  322. Message.warning({ content: errorUtil.getMessage(err) })
  323. this.echartsModal = false
  324. })
  325. },
  326. statisticsList() {
  327. const params = {
  328. maxResults: 10,
  329. startPosition: 0,
  330. formId: 'kmPointStatistics',
  331. }
  332. KmKnowledageService.getStatisticsList(params).then((res) => {
  333. const data = res.data.data || []
  334. if (data.length > 0) {
  335. this.echartsData = data
  336. const tenData = data.length > 10 ? this.echartsData.slice(0, 10) : this.echartsData
  337. const bar = {
  338. color: this.echartsColor,
  339. tooltip: {},
  340. xAxis: {
  341. type: 'category',
  342. data:
  343. this.$refs.docform.getFieldValue('type') === '0'
  344. ? tenData.map((d) => d.name)
  345. : tenData.map((d) => d.deptName),
  346. },
  347. yAxis: {
  348. type: 'value',
  349. },
  350. series: [
  351. {
  352. type: 'bar',
  353. barWidth: 40, // 柱图宽度
  354. barMaxWidth: 40, // 最大宽度
  355. label: {
  356. show: true,
  357. position: 'top',
  358. },
  359. data: tenData.map((d) => d.point),
  360. },
  361. ],
  362. }
  363. this.bar = bar
  364. }
  365. })
  366. },
  367. // 导出
  368. handleOk() {
  369. KmKnowledageService.getExportStatistics().then((res) => {
  370. const url = URL.createObjectURL(res)
  371. download(url, `${this.echartsTitle} ` + '统计.csv')
  372. })
  373. this.echartsModal = false
  374. },
  375. },
  376. }
  377. </script>
  378. <style module lang="scss">
  379. @use '@/common/design' as *;
  380. .integarsl {
  381. margin: 20px 0 40px;
  382. font-size: $padding-lg;
  383. font-weight: bold;
  384. text-align: center;
  385. }
  386. .docform {
  387. width: 1000px;
  388. margin: 0 auto;
  389. :global(.sd-form-btns-close) {
  390. display: none;
  391. }
  392. :global(.sd-form-btns-save) {
  393. margin-left: 20%;
  394. }
  395. }
  396. .detail-modal {
  397. width: 800px;
  398. margin: 0 auto;
  399. text-align: center;
  400. .bar {
  401. width: 800px;
  402. margin: 0 auto;
  403. }
  404. }
  405. </style>