audit-implement-status.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. <template>
  2. <div :class="$style.auditImplement">
  3. <a-card :class="$style.conditions">
  4. <a-form-model
  5. ref="advancedSearchForm"
  6. class="ant-advanced-search-form"
  7. :model="form"
  8. :rules="rules"
  9. v-bind="formItemLayout"
  10. >
  11. <a-row :gutter="24" :class="$style.antformitem">
  12. <a-col :span="8">
  13. <a-form-model-item label="年度" prop="panelYear">
  14. <a-date-picker
  15. v-model="form.panelYear"
  16. format="YYYY"
  17. mode="year"
  18. :open="showYearPicker"
  19. @openChange="
  20. (val) => {
  21. showYearPicker = val
  22. }
  23. "
  24. @panelChange="
  25. (val) => {
  26. form.panelYear = val
  27. showYearPicker = false
  28. }
  29. "
  30. />
  31. </a-form-model-item>
  32. </a-col>
  33. <a-col :span="8">
  34. <a-form-model-item label="审计机构" prop="unitNames">
  35. <AuditGroupPicker
  36. ref="unitNames"
  37. v-model="form.unitNames"
  38. :single="false"
  39. :read-only="false"
  40. :root-node="rootNode"
  41. />
  42. </a-form-model-item>
  43. </a-col>
  44. <a-col :span="8">
  45. <div :class="$style.buttonContent">
  46. <a-button @click="handleReset">重置</a-button>
  47. <a-button type="primary" @click="handleAction('serach')">查询</a-button>
  48. <a-button :loading="exportLoading" type="primary" @click="handleAction('export')"
  49. >导出</a-button
  50. >
  51. </div>
  52. </a-col>
  53. </a-row>
  54. </a-form-model>
  55. </a-card>
  56. <p :class="$style.tableTitle"> 项目执行情况统计 </p>
  57. <a-card class="reporttablecardxm">
  58. <div id="hj" style="display: none">
  59. <sd-data-table-hj
  60. ref="dataTablehj"
  61. :key="dataKeysum"
  62. :process-req="processReqsum"
  63. :columns="columnssum"
  64. :projectlist="true"
  65. :defultpagination-pagesize="50"
  66. data-url="api/xcoa-mobile/v1/iam-statistics/getProjectExecList"
  67. @dataLoaded1="dataLoadedsum"
  68. @rowClick="rowClick"
  69. >
  70. <template slot="number" slot-scope="text, record">
  71. {{ text ? text : '0' }}
  72. </template>
  73. </sd-data-table-hj>
  74. </div>
  75. <sd-data-table
  76. ref="dataTable"
  77. :key="dataKey"
  78. :process-req="processReq"
  79. :columns="columns"
  80. :projectlist="true"
  81. :defultpagination-pagesize="50"
  82. data-url="api/xcoa-mobile/v1/iam-statistics/getProjectExecList"
  83. @fnonloadsum="fnonloadsum"
  84. @dataLoaded="dataLoaded"
  85. @rowClick="rowClick"
  86. >
  87. <template slot="number" slot-scope="text, record">
  88. {{ text ? text : '0' }}
  89. </template>
  90. </sd-data-table>
  91. </a-card>
  92. </div>
  93. </template>
  94. <script>
  95. import AuditGroupPicker from '../../components/picker/audit-group-picker.vue'
  96. import components from './_import-components/audit-implement-status-import'
  97. import StatisticsService from './statistics-service'
  98. import { message } from '@/common/one-ui'
  99. import axios from '@/common/services/axios-instance'
  100. import { getUserInfo } from '@/common/store-mixin'
  101. import download from '@/common/services/download'
  102. export default {
  103. name: 'AuditImplementStatus',
  104. metaInfo: {
  105. title: '项目执行情况',
  106. },
  107. components: {
  108. ...components,
  109. AuditGroupPicker,
  110. },
  111. data() {
  112. return {
  113. exportLoading: false,
  114. form: {
  115. panelYear: null,
  116. unitNames: [],
  117. },
  118. showYearPicker: false,
  119. reqData: { dateStart: '3000', unitNames: '' },
  120. data: [],
  121. columns: [
  122. {
  123. title: '序号',
  124. dataIndex: 'id',
  125. width: '70px',
  126. },
  127. {
  128. title: '审计机构',
  129. dataIndex: 'UNIT_NAME',
  130. scopedSlots: { customRender: 'UNIT_NAME' },
  131. },
  132. {
  133. title: '实际项目数',
  134. dataIndex: 'REAL_NUM',
  135. scopedSlots: { customRender: 'number' },
  136. sdClickable: true,
  137. },
  138. {
  139. title: '未启动',
  140. dataIndex: 'TODO_NUM',
  141. scopedSlots: { customRender: 'number' },
  142. sdClickable: true,
  143. },
  144. {
  145. title: '进行中',
  146. children: [
  147. {
  148. title: '小计',
  149. dataIndex: 'DOING_NUM',
  150. width: '70px',
  151. scopedSlots: { customRender: 'number' },
  152. sdClickable: true,
  153. },
  154. {
  155. title: '准备阶段',
  156. dataIndex: 'PREPARE_NUM',
  157. scopedSlots: { customRender: 'number' },
  158. sdClickable: true,
  159. },
  160. {
  161. title: '实施阶段',
  162. dataIndex: 'EXEC_NUM',
  163. scopedSlots: { customRender: 'number' },
  164. sdClickable: true,
  165. },
  166. {
  167. title: '报告阶段',
  168. dataIndex: 'REPORT_NUM',
  169. scopedSlots: { customRender: 'number' },
  170. sdClickable: true,
  171. },
  172. ],
  173. },
  174. {
  175. title: '已关闭',
  176. dataIndex: 'CLOSE_NUM',
  177. width: '90px',
  178. scopedSlots: { customRender: 'number' },
  179. sdClickable: true,
  180. },
  181. {
  182. title: '已归档',
  183. dataIndex: 'ARCHIVE_NUM',
  184. width: '90px',
  185. scopedSlots: { customRender: 'number' },
  186. sdClickable: true,
  187. },
  188. {
  189. title: '实际完成率',
  190. dataIndex: 'PERCENT',
  191. },
  192. ],
  193. columnssum: [
  194. {
  195. title: '审计机构',
  196. dataIndex: 'UNIT_NAME',
  197. scopedSlots: { customRender: 'UNIT_NAME' },
  198. },
  199. {
  200. title: '实际项目数',
  201. dataIndex: 'REAL_NUM',
  202. scopedSlots: { customRender: 'number' },
  203. sdClickable: true,
  204. },
  205. {
  206. title: '未启动',
  207. dataIndex: 'TODO_NUM',
  208. scopedSlots: { customRender: 'number' },
  209. sdClickable: true,
  210. },
  211. {
  212. title: '进行中',
  213. children: [
  214. {
  215. title: '小计',
  216. dataIndex: 'DOING_NUM',
  217. width: '70px',
  218. scopedSlots: { customRender: 'number' },
  219. sdClickable: true,
  220. },
  221. {
  222. title: '准备阶段',
  223. dataIndex: 'PREPARE_NUM',
  224. scopedSlots: { customRender: 'number' },
  225. sdClickable: true,
  226. },
  227. {
  228. title: '实施阶段',
  229. dataIndex: 'EXEC_NUM',
  230. scopedSlots: { customRender: 'number' },
  231. sdClickable: true,
  232. },
  233. {
  234. title: '报告阶段',
  235. dataIndex: 'REPORT_NUM',
  236. scopedSlots: { customRender: 'number' },
  237. sdClickable: true,
  238. },
  239. ],
  240. },
  241. {
  242. title: '已关闭',
  243. dataIndex: 'CLOSE_NUM',
  244. width: '90px',
  245. scopedSlots: { customRender: 'number' },
  246. sdClickable: true,
  247. },
  248. {
  249. title: '已归档',
  250. dataIndex: 'ARCHIVE_NUM',
  251. width: '90px',
  252. scopedSlots: { customRender: 'number' },
  253. sdClickable: true,
  254. },
  255. {
  256. title: '实际完成率',
  257. dataIndex: 'PERCENT',
  258. },
  259. ],
  260. rules: {
  261. panelYear: [{ required: true, message: '请选择统计时间', trigger: 'change' }],
  262. unitNames: [{ required: true, message: '请选择审计机构', trigger: 'change' }],
  263. },
  264. formItemLayout: {
  265. labelCol: { span: 6 },
  266. wrapperCol: { span: 14 },
  267. },
  268. dataKeysum: 0,
  269. dataKey: 0,
  270. hj: {},
  271. hjarr: [],
  272. rootNode: {},
  273. }
  274. },
  275. created() {
  276. let userInfo = getUserInfo()
  277. const params = {
  278. orgId: userInfo.deptId,
  279. }
  280. axios({
  281. url: 'api/xcoa-mobile/v1/iamorg/getCurrentUserGroup',
  282. method: 'get',
  283. }).then((res) => {
  284. userInfo = res.data
  285. params.orgId = res.data.id
  286. axios({
  287. url: 'api/xcoa-mobile/v1/iamorg/findIamOrgId',
  288. method: 'post',
  289. params,
  290. }).then((res) => {
  291. this.id = res.data
  292. const deptCode = userInfo.id.toString()
  293. const deptName = userInfo.name
  294. this.rootNode = { code: deptCode, name: deptName, id: this.id }
  295. })
  296. })
  297. },
  298. mounted() {
  299. const ym =
  300. 'realTotal;todoTotal;doingTotal;prepareTotal;execTotal;reportTotal;closeTotal;archiveTotal;percentTotal'
  301. const arrym = ym.split(';')
  302. this.hjarr = arrym
  303. },
  304. methods: {
  305. processReq(req, pagination) {
  306. req.data = {
  307. dateStart: this.reqData.dateStart,
  308. unitIds: this.reqData.unitNames,
  309. maxResults: req.data.maxResults,
  310. startPosition: req.data.startPosition,
  311. }
  312. return req
  313. },
  314. handleReset() {
  315. this.$refs.advancedSearchForm.resetFields()
  316. },
  317. handleAction(type) {
  318. this.$refs.advancedSearchForm.validate((valid, values) => {
  319. if (valid) {
  320. // 处理时间
  321. this.reqData.dateStart = this.form.panelYear.year() + ''
  322. // 处理部门
  323. const arr = []
  324. this.form.unitNames.forEach((item) => {
  325. arr.push(`'${item.id}'`)
  326. })
  327. this.reqData.unitNames = arr.join(',')
  328. this.reqData.unitIds = arr.join(',')
  329. // 调用方法
  330. switch (type) {
  331. case 'serach':
  332. this.handleSearch()
  333. break
  334. case 'export':
  335. this.handleExport()
  336. break
  337. }
  338. }
  339. })
  340. },
  341. handleExport() {
  342. if (this.$refs.dataTable.data.length === 0) {
  343. message.warning('未查询出可导出数据', 1)
  344. return
  345. }
  346. this.exportLoading = true
  347. StatisticsService.exportImplementList(this.reqData).then((data) => {
  348. const url = URL.createObjectURL(data)
  349. download(url, '项目执行情况统计表.xls')
  350. this.exportLoading = false
  351. })
  352. },
  353. handleSearch() {
  354. this.dataKey++
  355. this.dataKeysum++
  356. },
  357. dataLoaded(res) {
  358. if (res.data.length) {
  359. res.data.forEach((item, index) => {
  360. item.id = index + 1
  361. })
  362. this.hjarr.forEach((item) => {
  363. this.hj[item] = res.respData[item]
  364. })
  365. return res
  366. }
  367. },
  368. processReqsum(req, pagination) {
  369. req.data = {
  370. dateStart: this.reqData.dateStart,
  371. unitIds: this.reqData.unitNames,
  372. maxResults: req.data.maxResults,
  373. startPosition: req.data.startPosition,
  374. }
  375. return req
  376. },
  377. dataLoadedsum(res) {
  378. if (res.data.length) {
  379. res.data.splice(0, res.data.length)
  380. const obj = {}
  381. let j = 0
  382. this.columns.forEach((item, index) => {
  383. if (index > 1) {
  384. if (item.children) {
  385. item.children.forEach((c, i) => {
  386. obj[c.dataIndex] = res.respData[this.hjarr[j]]
  387. j++
  388. })
  389. } else {
  390. obj[item.dataIndex] = res.respData[this.hjarr[j]]
  391. j++
  392. }
  393. }
  394. })
  395. obj.id = 1
  396. obj.UNIT_NAME = '总计'
  397. res.data.push(obj)
  398. return res
  399. }
  400. },
  401. fnonloadsum() {
  402. setTimeout(() => {
  403. if (
  404. document
  405. .getElementById('hj')
  406. .getElementsByClassName('ant-table-tbody')[0]
  407. .getElementsByTagName('tr').length > 0
  408. ) {
  409. const obj = document
  410. .getElementById('hj')
  411. .getElementsByClassName('ant-table-tbody')[0].firstChild
  412. obj.firstChild.colSpan = 2
  413. obj.classList.add('childsum')
  414. document.getElementsByClassName('ant-table-tbody')[1].appendChild(obj)
  415. }
  416. }, 1000)
  417. },
  418. rowClick(record, { rowIndex, column }) {
  419. const param = {
  420. planYear: this.reqData.dateStart,
  421. unitIds: "'" + record.UNIT_ID + "'",
  422. }
  423. if (record.UNIT_NAME === '总计') {
  424. param.unitIds = this.form.unitNames
  425. .map((item) => {
  426. return "'" + item.id + "'"
  427. })
  428. .join(',')
  429. }
  430. console.log(column)
  431. if (column.dataIndex === 'TODO_NUM') {
  432. // 未启动
  433. param.itemStatus = '01'
  434. } else if (column.dataIndex === 'DOING_NUM') {
  435. // 进行中
  436. param.itemStatus = "'02','03','04'"
  437. } else if (column.dataIndex === 'PREPARE_NUM') {
  438. // 准备
  439. param.itemStatus = '02'
  440. } else if (column.dataIndex === 'EXEC_NUM') {
  441. // 实施
  442. param.itemStatus = '03'
  443. } else if (column.dataIndex === 'REPORT_NUM') {
  444. // 报告
  445. param.itemStatus = '04'
  446. } else if (column.dataIndex === 'CLOSE_NUM') {
  447. // 实施
  448. param.itemStatus = '05'
  449. } else if (column.dataIndex === 'ARCHIVE_NUM') {
  450. param.itemStatus = '07'
  451. } else if (column.dataIndex === 'REAL_NUM') {
  452. param.itemStatus = "'01','02','03','04','05','07'"
  453. }
  454. const url =
  455. '#/audit-annualplancompletion-project-list?params=' +
  456. encodeURIComponent(JSON.stringify(param)) +
  457. '&type=projectimplement'
  458. window.open(url)
  459. },
  460. },
  461. }
  462. </script>
  463. <style module lang="scss">
  464. @use '@/common/design' as *;
  465. .auditImplement {
  466. :global(.ant-form-item) {
  467. margin: 0;
  468. }
  469. :global(.ant-select) {
  470. width: 100%;
  471. }
  472. .conditions {
  473. margin-bottom: 20px;
  474. }
  475. .buttonContent {
  476. padding-top: 6px;
  477. text-align: right;
  478. button {
  479. margin: 0 4px;
  480. }
  481. }
  482. :global(.anticon-setting) {
  483. display: none;
  484. }
  485. .tableTitle {
  486. padding-top: 16px;
  487. margin: 0;
  488. font-size: 22px;
  489. font-weight: bold;
  490. color: #404040;
  491. text-align: center;
  492. background: white;
  493. }
  494. :global(.reporttablecardxm) {
  495. :global(.ant-table-body) {
  496. height: auto !important;
  497. min-height: auto !important;
  498. overflow: auto;
  499. }
  500. }
  501. :global(.ant-table-placeholder) {
  502. height: auto !important;
  503. }
  504. }
  505. </style>