kpi-indi-task-form.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <template>
  2. <div>
  3. <sd-webflow
  4. ref="flow"
  5. :removed-tabs="['sdRelatedDoc']"
  6. :class="$style.flowform"
  7. @saveproject="saveproject"
  8. @actionBtnClick="actionBtnClick"
  9. >
  10. <template v-slot:form="{ model, fields }">
  11. <table>
  12. <tr>
  13. <!-- 任务名称 -->
  14. <sd-form-item-td name="taskName" />
  15. <!-- 报送人 -->
  16. <sd-form-item-td name="submitterName" />
  17. </tr>
  18. <tr>
  19. <!-- 报送部门 -->
  20. <sd-form-item-td name="submitterDeptName" />
  21. <!-- 创建日期 -->
  22. <sd-form-item-td name="creationTime" />
  23. </tr>
  24. <!-- 任务明细子表 -->
  25. <tr>
  26. <sd-form-item-td :label="null" name="indiTaskDetailList" :colspan="4">
  27. <template v-slot:read-and-edit="{ editable }">
  28. <template>
  29. <div :class="$style.wrapper">
  30. <div v-show="editable && sysFlag" :class="$style.btnselect">
  31. <a-button
  32. type="primary"
  33. :loading="loading"
  34. :class="$style.batchselect"
  35. @click="calGuideVal"
  36. >
  37. 重新计算系统参考值
  38. </a-button>
  39. </div>
  40. </div>
  41. </template>
  42. <xm-child-table
  43. ref="childForm"
  44. v-model="model.indiTaskDetailList"
  45. :read-only="!editable"
  46. label=""
  47. :fields="fields.indiTaskDetailList.attr.dync"
  48. :columns="childColumns"
  49. :width="1200"
  50. :captionvisiable="false"
  51. :show-selection="
  52. () => {
  53. return false
  54. }
  55. "
  56. >
  57. <!-- 指标编码 -->
  58. <template v-slot:indiNo="{ field, text, record }">
  59. <span>{{ record.indiNo }}</span>
  60. </template>
  61. <!-- 指标名称 -->
  62. <template v-slot:indiName="{ field, text, record }">
  63. <span v-if="record.indiAttr === 'factor' && record.firstFlag"
  64. >其中:{{ record.indiName }}</span
  65. >
  66. <span v-else-if="record.indiAttr === 'factor'" :class="$style.factor"
  67. >{{ record.indiName }}
  68. </span>
  69. <span v-else :class="record.indiAttr === 'monitor' ? $style.monitor : ''">{{
  70. record.indiName
  71. }}</span>
  72. </template>
  73. <!-- 监测单位 -->
  74. <template v-slot:monitorDeptName="{ field, text, record }">
  75. <span>{{ record.monitorDeptName }}</span>
  76. </template>
  77. <!-- 数据来源 -->
  78. <template v-slot:dataFrom="{ field, text, record }">
  79. <span>{{ record.dataFromName }}</span>
  80. </template>
  81. <!-- 系统参考值 -->
  82. <template v-slot:guideVal="{ field, text, record }">
  83. <span
  84. v-if="
  85. record.dataFrom === 'system' &&
  86. record.guideVal &&
  87. record.guideVal !== 'null'
  88. "
  89. >{{ record.guideVal }}</span
  90. >
  91. <span v-else>--</span>
  92. </template>
  93. <!-- 指标结果值 -->
  94. <template v-slot:indiResult="{ field, text, record }">
  95. <div v-if="record.indiAttr === 'monitor' && record.dataFrom === 'calculate'">
  96. <span v-if="record.indiResult">{{ record.indiResult }}</span>
  97. <span v-else>--</span>
  98. </div>
  99. <div v-else>
  100. <a-input
  101. v-if="editable"
  102. v-model="record.indiResult"
  103. @blur="calIndiResult(record)"
  104. ></a-input>
  105. <span v-else>{{ record.indiResult }}</span>
  106. </div>
  107. </template>
  108. <!-- 数据值单位 -->
  109. <template v-slot:indiUnit="{ field, text, record }">
  110. <span>{{ record.indiUnitName }}</span>
  111. </template>
  112. <!-- 修改说明 -->
  113. <template v-slot:editDesc="{ field, text, record }">
  114. <span v-if="record.indiAttr === 'monitor' && record.dataFrom === 'calculate'">
  115. --
  116. </span>
  117. <a-input v-else-if="editable" v-model="record.editDesc"></a-input>
  118. <span v-else>{{ record.editDesc }}</span>
  119. </template>
  120. <!-- 预警状态 -->
  121. <template v-slot:alertStatus="{ field, text, record }">
  122. <span v-if="record.indiAttr === 'factor'">--</span>
  123. <div v-else>
  124. <div
  125. v-if="!record.alertStatus || record.alertStatus === 'D'"
  126. :class="$style.status"
  127. >无</div
  128. >
  129. <div v-else-if="record.alertStatus === 'A'" :class="$style.redstatus">红</div>
  130. <div v-else-if="record.alertStatus === 'B'" :class="$style.ystatus">黄</div>
  131. <div v-else-if="record.alertStatus === 'C'" :class="$style.lstatus">绿</div>
  132. </div>
  133. </template>
  134. </xm-child-table>
  135. </template>
  136. </sd-form-item-td>
  137. </tr>
  138. <!-- 任务来源 -->
  139. <sd-form-item-td :hidden="true" name="taskFrom" />
  140. </table>
  141. </template>
  142. </sd-webflow>
  143. </div>
  144. </template>
  145. <script>
  146. import { Message } from 'ant-design-vue'
  147. import KpiService from '../kpi-service'
  148. import components from './_import-components/kpi-indi-task-form-import'
  149. export default {
  150. name: 'KpiIndiTaskForm',
  151. metaInfo: {
  152. title: '指标报送任务',
  153. },
  154. components: {
  155. ...components,
  156. },
  157. data() {
  158. return {
  159. sysFlag: false,
  160. btnName: '',
  161. loading: false,
  162. childColumns: [
  163. { dataIndex: 'id', sdHidden: true },
  164. { dataIndex: 'indiId', sdHidden: true },
  165. { dataIndex: 'indiAttr', sdHidden: true },
  166. { dataIndex: 'indiNo', title: '指标编码' },
  167. { dataIndex: 'indiName', title: '指标名称' },
  168. { dataIndex: 'monitorDeptCode', sdHidden: true },
  169. { dataIndex: 'monitorDeptName', title: '监测单位' },
  170. { dataIndex: 'monitorDeptId', title: '监测单位ID', sdHidden: true },
  171. { dataIndex: 'dataFrom', title: '数据来源' },
  172. { dataIndex: 'guideVal', title: '系统参考值' },
  173. { dataIndex: 'indiResult', title: '指标结果值' },
  174. { dataIndex: 'indiUnit', title: '数据值单位' },
  175. { dataIndex: 'editDesc', title: '修改说明' },
  176. { dataIndex: 'alertStatus', title: '预警状态' },
  177. { dataIndex: 'indiFrequency', sdHidden: true },
  178. { dataIndex: 'parentIndiId', sdHidden: true },
  179. { dataIndex: 'year', sdHidden: true },
  180. { dataIndex: 'dataPeriod', sdHidden: true },
  181. { dataIndex: 'uuid', sdHidden: true },
  182. ],
  183. }
  184. },
  185. mounted() {
  186. // 获取子表数据
  187. const id = this.$refs.flow.getFieldValue('id')
  188. this.getDetailList(id)
  189. },
  190. methods: {
  191. actionBtnClick(evt, { button, FlowData }) {
  192. // 记录点击按钮的名称
  193. this.btnName = button.fakeId
  194. },
  195. saveproject(formdata) {
  196. if (this.btnName === 'save') {
  197. // 保存成功后调用接口更新子表数据
  198. const id = formdata.processFormData.processFormPropertyValues?.find(
  199. (item) => item.name === 'id'
  200. )
  201. this.getDetailList(id.value)
  202. }
  203. },
  204. getDetailList(id) {
  205. // 获取指标报送任务明细
  206. KpiService.findTaskDetailList(id)
  207. .then((res) => {
  208. if (res) {
  209. res.forEach((item, index) => {
  210. // 首项因子指标增加标记位
  211. if (
  212. item.indiAttr === 'factor' &&
  213. res[index - 1] &&
  214. res[index - 1].indiAttr === 'monitor' &&
  215. res[index - 1].dataFrom === 'calculate'
  216. ) {
  217. item.firstFlag = true
  218. }
  219. // 系统集成标记位
  220. if (item.dataFrom === 'system') {
  221. this.sysFlag = true
  222. }
  223. })
  224. // 子表赋值
  225. this.$refs.flow.setFieldValue('indiTaskDetailList', res)
  226. }
  227. })
  228. .catch((err) => {
  229. // eslint-disable-next-line no-console
  230. console.log(err)
  231. Message.error('出错了,请联系管理员', 1)
  232. })
  233. },
  234. calGuideVal() {
  235. // 重新计算系统参考值
  236. this.loading = true
  237. const id = this.$refs.flow.getFieldValue('id')
  238. KpiService.getResetGuideVal(id)
  239. .then((res) => {
  240. if (res && res[0]) {
  241. const detail = this.$refs.flow.getFieldValue('indiTaskDetailList') // 子表数据
  242. res.forEach((item) => {
  243. if (item.guideVal === 'queryFailed') {
  244. throw new Error(`queryFailed`)
  245. }
  246. // 筛选同id同监测单位的子表数据
  247. const dtemp = detail.find(
  248. (ditem) => ditem.id === item.id && ditem.monitorDeptId === item.monitorDeptId
  249. )
  250. if (dtemp) {
  251. // 系统参考值赋值
  252. dtemp.guideVal = item.guideVal
  253. }
  254. })
  255. // 更新子表数据
  256. this.$refs.flow.setFieldValue('indiTaskDetailList', detail)
  257. Message.success('重新计算系统参考值成功')
  258. } else {
  259. Message.error('重新计算失败')
  260. }
  261. this.loading = false
  262. })
  263. .catch((err) => {
  264. this.loading = false
  265. if (err.message === 'queryFailed') {
  266. Message.error('数据库查询失败')
  267. } else {
  268. Message.error('出错了,请联系管理员')
  269. }
  270. })
  271. },
  272. calIndiResult(record) {
  273. // 校验是否输入数字
  274. if (record.indiResult && !isNaN(record.indiResult)) {
  275. // 数据值单位是 % 元 美元 时,保留2位小数
  276. if (
  277. record.indiUnitName === '%' ||
  278. record.indiUnitName === '元' ||
  279. record.indiUnitName === '美元'
  280. ) {
  281. record.indiResult = parseFloat(record.indiResult).toFixed(2)
  282. }
  283. } else {
  284. record.indiResult = ''
  285. }
  286. // 计算指标结果值,预警状态
  287. const id = this.$refs.flow.getFieldValue('id') // 主键id
  288. const detail = this.$refs.flow.getFieldValue('indiTaskDetailList')
  289. // 筛选同单位同主指标ID的因子指标
  290. const indisArr = detail?.filter((ditem) => {
  291. return (
  292. ditem.parentIndiId === record.parentIndiId &&
  293. ditem.monitorDeptCode === record.monitorDeptCode &&
  294. ditem.indiAttr === 'factor'
  295. )
  296. })
  297. // 接口参数赋值
  298. const data = []
  299. if (indisArr.length > 0) {
  300. indisArr?.forEach((res) => {
  301. if (res.parentIndiId === record.parentIndiId) {
  302. data.push({
  303. id: res.id,
  304. parentIndiId: res.parentIndiId,
  305. indiId: res.indiId,
  306. taskId: res.taskId,
  307. indiResult: res.indiResult,
  308. monitorDeptId: res.monitorDeptId,
  309. monitorDeptCode: res.monitorDeptCode,
  310. monitorDeptName: res.monitorDeptName,
  311. indiFrequency: res.indiFrequency,
  312. })
  313. } else {
  314. data.push({
  315. id: record.id,
  316. parentIndiId: record.parentIndiId,
  317. indiId: record.indiId,
  318. taskId: record.taskId,
  319. indiResult: record.indiResult,
  320. monitorDeptId: record.monitorDeptId,
  321. monitorDeptCode: record.monitorDeptCode,
  322. monitorDeptName: record.monitorDeptName,
  323. indiFrequency: record.indiFrequency,
  324. })
  325. }
  326. })
  327. } else {
  328. data.push({
  329. id: record.id,
  330. parentIndiId: record.parentIndiId,
  331. indiId: record.indiId,
  332. taskId: record.taskId,
  333. indiResult: record.indiResult,
  334. monitorDeptId: record.monitorDeptId,
  335. monitorDeptCode: record.monitorDeptCode,
  336. monitorDeptName: record.monitorDeptName,
  337. indiFrequency: record.indiFrequency,
  338. })
  339. }
  340. const redata = {
  341. taskId: id,
  342. result: data,
  343. }
  344. KpiService.getIndiResult(redata)
  345. .then((res) => {
  346. if (res) {
  347. // 筛选对应主指标,预警状态赋值
  348. const monitorIndi = detail.find(
  349. (item) => item.id === parseInt(res.id) && item.monitorDeptId === res.monitorDeptId
  350. )
  351. if (monitorIndi) {
  352. if (
  353. record.indiUnitName === '%' ||
  354. record.indiUnitName === '元' ||
  355. record.indiUnitName === '美元'
  356. ) {
  357. // 数据值单位是元和%和美元的保留2位小数
  358. if (res.indiResult && !isNaN(res.indiResult)) {
  359. monitorIndi.indiResult = parseFloat(res.indiResult).toFixed(2) // 指标结果值
  360. }
  361. } else {
  362. if (res.indiResult && !isNaN(res.indiResult)) {
  363. monitorIndi.indiResult = res.indiResult // 指标结果值
  364. }
  365. }
  366. monitorIndi.alertStatus = res.alertStatus // 预警状态
  367. }
  368. // 更新子表数据
  369. this.$refs.flow.setFieldValue('indiTaskDetailList', detail)
  370. }
  371. this.loading = false
  372. })
  373. .catch((err) => {
  374. this.loading = false
  375. // eslint-disable-next-line no-console
  376. console.log(err)
  377. Message.error('出错了,请联系管理员')
  378. })
  379. },
  380. },
  381. }
  382. </script>
  383. <style module lang="scss">
  384. @use '@/common/design' as *;
  385. .flowform {
  386. .btnselect {
  387. position: relative;
  388. top: 4px;
  389. float: right;
  390. .batchselect {
  391. z-index: 100;
  392. margin-left: 10px;
  393. }
  394. }
  395. .monitor {
  396. font-weight: bolder;
  397. }
  398. .factor {
  399. padding-left: 30px;
  400. }
  401. :global .ant-form-item-children {
  402. .ant-table colgroup > col.ant-table-selection-col {
  403. width: 0;
  404. }
  405. .ant-checkbox-wrapper {
  406. display: none;
  407. }
  408. .ant-table-row:hover .handle_sd-draggable_common::before {
  409. display: none;
  410. }
  411. .anticon-setting {
  412. display: none;
  413. }
  414. }
  415. .status {
  416. width: 25px;
  417. height: 25px;
  418. background-color: #aaaaaa;
  419. color: #fff;
  420. padding-left: 4px;
  421. border-radius: 3px;
  422. }
  423. .redstatus {
  424. width: 25px;
  425. height: 25px;
  426. background-color: #fb0606;
  427. color: #fff;
  428. padding-left: 4px;
  429. border-radius: 3px;
  430. }
  431. .ystatus {
  432. width: 25px;
  433. height: 25px;
  434. background-color: #fff600;
  435. color: #fff;
  436. padding-left: 4px;
  437. border-radius: 3px;
  438. }
  439. .lstatus {
  440. width: 25px;
  441. height: 25px;
  442. background-color: #8dcb98;
  443. color: #fff;
  444. padding-left: 4px;
  445. border-radius: 3px;
  446. }
  447. }
  448. </style>