dash.vue 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. <template>
  2. <el-card shadow="hover" class="full-height full-width flex flex-col">
  3. <div class="flex flex-col padding white-bg">
  4. <div class="flex flex-align-center tip">
  5. <el-icon class="ml-20" color="#BC002D">
  6. <WarningFilled />
  7. </el-icon>
  8. <span class="ml-5"
  9. >项目总投资额<span class="main-color bold">{{
  10. num ? Number.parseFloat(num).toLocaleString() : '0'
  11. }}</span
  12. >万元</span
  13. >
  14. </div>
  15. <div
  16. class="flex ml-20 hide-scrollbar full-width flex-wrap"
  17. v-show="numList && numList.length > 0"
  18. >
  19. <div
  20. v-for="(item, index) in numList"
  21. :key="item.id"
  22. :class="active === index ? 'total-s' : 'total'"
  23. class="flex flex-center flex-justify-between mt-20 bold font-16 pointer"
  24. @click="switchTab(item, index)"
  25. >
  26. <span class="sp">{{ item.name }}</span>
  27. <span class="sp1"
  28. >{{ item.number }}<span class="grey font-13">个</span></span
  29. >
  30. </div>
  31. </div>
  32. <div class="flex flex-center flex-justify-start">
  33. <base-button
  34. class="ml-20 mt-20"
  35. icon="Plus"
  36. title="新增"
  37. v-if="
  38. dataType === 'project' &&
  39. permissions.vaildPermission('project_new_create')
  40. "
  41. @click="showAdd = true"
  42. />
  43. <base-button
  44. class="ml-20 mt-20"
  45. icon="el-icon-upload"
  46. title="数据导入"
  47. v-if="dataType === 'project'"
  48. @click="diaType = 0"
  49. />
  50. <base-button
  51. class="ml-20 mt-20"
  52. icon="el-icon-download"
  53. title="数据导出"
  54. @click="diaType = 1"
  55. />
  56. <base-button
  57. class="ml-20 mt-20"
  58. type="0"
  59. icon="el-icon-download"
  60. title="汇总数据导出"
  61. @click="diaType = 2"
  62. />
  63. <base-button
  64. class="ml-20 mt-20"
  65. type="0"
  66. icon="el-icon-coordinate"
  67. title="项目结转"
  68. @click="projectCarry"
  69. />
  70. <el-tooltip content="申报的项目必须为已入库并且已经上报的项目">
  71. <base-button
  72. class="ml-20 mt-20"
  73. type="0"
  74. icon="el-icon-folder-checked"
  75. title="入库申报"
  76. v-if="dataType === 'asset'"
  77. @click="projectStore"
  78. />
  79. </el-tooltip>
  80. </div>
  81. </div>
  82. <avue-crud
  83. ref="crud"
  84. v-model="form"
  85. v-model:page="page"
  86. :before-open="beforeOpen"
  87. :permission="permissions"
  88. :data="data"
  89. :option="option"
  90. :table-loading="loading"
  91. class="curd"
  92. @row-del="rowDel"
  93. @tree-load="treeLoad"
  94. @current-change="currentChange"
  95. @size-change="sizeChange"
  96. @refresh-change="refreshChange"
  97. @selection-change="selectionChange"
  98. @on-load="onLoad"
  99. >
  100. <template #menu="{ row }">
  101. <el-button
  102. v-if="
  103. dataType === 'asset' && row.project_stage !== 7 && row.can_update
  104. "
  105. icon="Upload"
  106. type="primary"
  107. text
  108. @click="report(row)"
  109. >
  110. {{ row.is_report === 1 ? '项目已上报' : '项目上报' }}
  111. </el-button>
  112. <el-button
  113. v-if="
  114. (row.report_type === 0 ||
  115. row.report_type === 1 ||
  116. row.report_type === 4) &&
  117. row.can_update
  118. "
  119. text
  120. type="primary"
  121. icon="el-icon-upload"
  122. @click="projectReport(row)"
  123. >上报审核
  124. </el-button>
  125. <el-button
  126. text
  127. v-if="
  128. permissions.vaildPermission('projectApprovalBtn') &&
  129. row.report_type === 2
  130. "
  131. type="primary"
  132. icon="el-icon-bell"
  133. @click="rowClick(row, 1)"
  134. >审核
  135. </el-button>
  136. <el-button
  137. v-if="
  138. row.hasOwnProperty('report_type') &&
  139. row.report_type === 3 &&
  140. row.can_update
  141. "
  142. text
  143. type="primary"
  144. icon="el-icon-upload"
  145. @click="projectReportFormal(row)"
  146. >上报固定资产
  147. </el-button>
  148. <el-button
  149. text
  150. type="primary"
  151. icon="el-icon-folder-remove"
  152. @click="projectCancel(row)"
  153. v-if="row.project_stage !== 7 && row.can_update"
  154. >退库
  155. </el-button>
  156. <el-button
  157. text
  158. type="primary"
  159. icon="el-icon-delete"
  160. @click="rowDel(row)"
  161. v-if="row.can_update"
  162. >删除
  163. </el-button>
  164. </template>
  165. <template #plan_storage_time-header="{ column }">
  166. <div class="flex flex-center">
  167. <div class="mr-5">{{ (column || {}).label }}</div>
  168. <el-tooltip content="红色为计划开工时间,蓝色为实际开工时间">
  169. <el-icon>
  170. <InfoFilled />
  171. </el-icon>
  172. </el-tooltip>
  173. </div>
  174. </template>
  175. <template #plan_storage_time="{ row }">
  176. <div class="flex flex-center">
  177. <div
  178. class="mr-5 red"
  179. v-if="row.plan_storage_time !== undefined && row.is_storage === 0"
  180. >
  181. {{ row.plan_storage_time.substring(0, 10) }}
  182. </div>
  183. <div class="mr-5 blue" v-else>
  184. {{ row.storage_time ? row.storage_time.substring(0, 10) : '' }}
  185. </div>
  186. </div>
  187. </template>
  188. <template #plan_commencement_time-header="{ column }">
  189. <div class="flex flex-center">
  190. <div class="mr-5">{{ (column || {}).label }}</div>
  191. <el-tooltip content="红色为计划开工时间,蓝色为实际开工时间">
  192. <el-icon>
  193. <InfoFilled />
  194. </el-icon>
  195. </el-tooltip>
  196. </div>
  197. </template>
  198. <template #plan_commencement_time="{ row }">
  199. <div class="flex flex-center">
  200. <div
  201. class="mr-5 red"
  202. v-if="
  203. row.plan_commencement_time !== undefined &&
  204. (row.is_start === undefined || row.is_start === 0)
  205. "
  206. >
  207. {{ row.plan_commencement_time.substring(0, 10) }}
  208. </div>
  209. <div class="mr-5 blue" v-else>
  210. {{ row.start_time ? row.start_time.substring(0, 10) : '' }}
  211. </div>
  212. </div>
  213. </template>
  214. <template #project_stage="{ row }">
  215. <div class="flex flex-center">
  216. <div>{{ row['$project_stage'] }}</div>
  217. <el-tooltip :content="row.exit_msg" v-if="row.project_stage === 7">
  218. <el-icon @click="showReceipt(row.exit_msg)">
  219. <InfoFilled />
  220. </el-icon>
  221. </el-tooltip>
  222. </div>
  223. </template>
  224. <template #report_type="{ row }">
  225. <div class="flex flex-center">
  226. <el-tag>{{ row.report_type_name }}</el-tag>
  227. <el-tooltip :content="row.receipt_msg">
  228. <el-icon
  229. v-if="row.report_type === 4"
  230. class="ml-10"
  231. @click="showReceipt(row.receipt_msg)"
  232. >
  233. <WarningFilled />
  234. </el-icon>
  235. </el-tooltip>
  236. </div>
  237. </template>
  238. </avue-crud>
  239. <!-- 新增-->
  240. <el-dialog
  241. v-model="showAdd"
  242. append-to-body
  243. center
  244. title="新增项目"
  245. width="35%"
  246. >
  247. <div v-loading="addLoading">
  248. <el-form
  249. ref="form"
  250. :model="projectForm"
  251. class="lab mt-20"
  252. label-width="100px"
  253. :rules="rules"
  254. >
  255. <div class="flex flex-center flex-col mr-20">
  256. <el-form-item class="full-width" label="项目名称" prop="name">
  257. <el-input
  258. v-model="projectForm.name"
  259. clearable
  260. placeholder="输入项目名称"
  261. />
  262. </el-form-item>
  263. <el-form-item
  264. class="full-width"
  265. label="项目总投"
  266. prop="totalAmount"
  267. >
  268. <el-input
  269. v-model="projectForm.totalAmount"
  270. clearable
  271. placeholder="输入项目总投(万元)"
  272. >
  273. <template #append>(万元)</template>
  274. </el-input>
  275. </el-form-item>
  276. <el-form-item class="full-width" label="项目标签" prop="tags">
  277. <el-select
  278. v-model="projectForm.tags"
  279. clearable
  280. placeholder="选择项目标签"
  281. style="width: 100%"
  282. >
  283. <el-option
  284. v-for="item in tagsList"
  285. :key="item.dictKey"
  286. :label="item.dictValue"
  287. :value="item.dictKey"
  288. />
  289. </el-select>
  290. </el-form-item>
  291. <el-form-item class="full-width" label="建设内容">
  292. <el-input
  293. v-model="projectForm.introduction"
  294. :rows="6"
  295. clearable
  296. placeholder="输入项目建设内容"
  297. type="textarea"
  298. />
  299. </el-form-item>
  300. <div class="flex flex-center mt-10">
  301. <base-button
  302. class="mr-20"
  303. icon="Close"
  304. title="取消"
  305. type="0"
  306. @click="showAdd = false"
  307. />
  308. <base-button icon="Check" title="保存" @click="projectSave" />
  309. </div>
  310. </div>
  311. </el-form>
  312. </div>
  313. </el-dialog>
  314. <form-dialog
  315. :dialogType="diaType"
  316. @close="formDialogClose"
  317. @export="exportExcel"
  318. :ids="selectList.map(ele => ele.id)"
  319. :year="owerQuery.projectYear"
  320. />
  321. <summary-dialog
  322. :dialogType="diaType"
  323. @close="diaType = -1"
  324. :select-num="selectList.length === 0 ? page.total : selectList.length"
  325. @export="exportExcelTotal"
  326. />
  327. <el-dialog v-model="reportShow" width="500px" title="请选择上报时间">
  328. <div v-if="currentReport">
  329. <el-date-picker
  330. v-model="currentReport.report_time"
  331. format="YYYY-MM-DD"
  332. class="mb-20"
  333. placeholder="选择上报时间"
  334. style="width: 100%"
  335. value-format="YYYY-MM-DD"
  336. />
  337. </div>
  338. <div class="flex flex-center full-width flex-justify-end">
  339. <el-button @click="reportShow = false">取 消</el-button>
  340. <el-button @click="track(currentReport)">确 定</el-button>
  341. </div>
  342. </el-dialog>
  343. <!-- 项目审批-->
  344. <el-dialog v-model="showApproval" title="审核" width="500px">
  345. <div class="flex flex-justify-start flex-col">
  346. <div class="full-width flex flex-justify-start flex-align-center mb-20">
  347. <span>审核状态:</span>
  348. <el-radio-group v-model="approvalStatus">
  349. <el-radio :label="3">通过</el-radio>
  350. <el-radio :label="4">不通过</el-radio>
  351. </el-radio-group>
  352. </div>
  353. <el-input
  354. class="mt-20"
  355. type="textarea"
  356. :rows="5"
  357. v-model="approvalMsg"
  358. placeholder="请填写审批意见"
  359. />
  360. <div class="full-width flex flex-justify-end mt-20">
  361. <el-button plain type="primary" @click="showApproval = false"
  362. >取消
  363. </el-button>
  364. <el-button type="primary" @click="projectApproval">确定</el-button>
  365. </div>
  366. </div>
  367. </el-dialog>
  368. </el-card>
  369. </template>
  370. <script>
  371. import BaseButton from '../../../components/base-button.vue'
  372. import permissionStore from '@/store/permission.js'
  373. import formDialog from '@/views/home/component/form_dialog.vue'
  374. import { getLazyList } from '@/api/project/index.js'
  375. import summaryDialog from '@/views/home/component/summary_dialog.vue'
  376. import { useStore } from '@/store/user.js'
  377. import confing from '@/config/website'
  378. import { ElMessage, ElMessageBox } from 'element-plus'
  379. export default {
  380. name: 'dash',
  381. components: { BaseButton, formDialog, summaryDialog },
  382. setup() {
  383. const permissions = permissionStore()
  384. const user = useStore()
  385. return { permissions, user }
  386. },
  387. data() {
  388. return {
  389. showApproval: false,
  390. approvalMsg: '',
  391. approvalStatus: 3,
  392. reportTime: '',
  393. currentReport: null,
  394. reportShow: false,
  395. dialogLoading: false,
  396. disable: false,
  397. showAdd: false,
  398. active: 0,
  399. loading: false,
  400. addLoading: false,
  401. data: [],
  402. form: {},
  403. option: {
  404. menuBtnTitle: '操作',
  405. refreshBtn: false,
  406. tip: false,
  407. lazy: true,
  408. columnBtn: false,
  409. searchShow: true,
  410. selection: true,
  411. editBtn: true,
  412. editBtnText: '资料管理',
  413. editBtnIcon: 'Document',
  414. addBtn: false,
  415. delBtn: false,
  416. border: true,
  417. reserveSelection: true,
  418. align: 'center',
  419. viewBtn: true,
  420. viewBtnText: '详情',
  421. dialogClickModal: false,
  422. column: [
  423. {
  424. label: '项目名称',
  425. prop: 'name',
  426. addDisplay: false,
  427. editDisplay: false,
  428. fixed: true,
  429. minWidth: 200
  430. },
  431. {
  432. label: '项目情况',
  433. prop: 'project_stage',
  434. type: 'select',
  435. slot: true,
  436. width: 140,
  437. dicUrl:
  438. '/api/blade-system/dict-biz/dictionary?code=project-situation',
  439. props: {
  440. label: 'dictValue',
  441. value: 'dictKey'
  442. }
  443. },
  444. {
  445. label: '项目总投资(万元)',
  446. prop: 'total_amount',
  447. width: 120,
  448. type: 'number',
  449. precision: 2,
  450. formatter: (val, value, label) => {
  451. return val.total_amount.toLocaleString()
  452. }
  453. },
  454. {
  455. label: '责任单位',
  456. prop: 'unit_name',
  457. width: 180
  458. },
  459. {
  460. label: '子项目数量',
  461. prop: 'lot',
  462. width: 120,
  463. hide: true
  464. },
  465. {
  466. label: '是否入库',
  467. prop: 'is_storage',
  468. width: 120,
  469. dicData: [
  470. {
  471. label: '否',
  472. value: 0
  473. },
  474. {
  475. label: '是',
  476. value: 1
  477. }
  478. ]
  479. },
  480. {
  481. label: '计划(实际)入库时间',
  482. prop: 'plan_storage_time',
  483. width: 120,
  484. formatter: (val, value, label) => {
  485. return value.substring(0, 10)
  486. }
  487. },
  488. {
  489. label: '是否开工',
  490. prop: 'is_start',
  491. width: 120,
  492. dicData: [
  493. {
  494. label: '否',
  495. value: 0
  496. },
  497. {
  498. label: '是',
  499. value: 1
  500. }
  501. ]
  502. },
  503. {
  504. label: '计划(实际)开工时间',
  505. prop: 'plan_commencement_time',
  506. width: 120,
  507. formatter: (val, value, label) => {
  508. return value.substring(0, 10)
  509. }
  510. },
  511. {
  512. label: '上报时间',
  513. prop: 'report_time',
  514. width: 120
  515. },
  516. {
  517. label: '认定时间',
  518. prop: 'year',
  519. width: 120
  520. },
  521. {
  522. label: '项目状态',
  523. prop: 'report_type',
  524. width: 170,
  525. slot: true
  526. }
  527. ]
  528. },
  529. page: {
  530. size: 10,
  531. current: 1,
  532. total: 0
  533. },
  534. stage: [],
  535. numList: [],
  536. typeList: [],
  537. tagsList: [],
  538. num: '',
  539. projectForm: {
  540. name: '',
  541. totalAmount: '',
  542. projectType: '1589613582090166274',
  543. tags: '',
  544. introduction: ''
  545. },
  546. rules: {
  547. name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
  548. projectType: [
  549. {
  550. required: true,
  551. message: '请选择项目类型',
  552. trigger: 'change'
  553. }
  554. ],
  555. tags: [
  556. {
  557. required: true,
  558. message: '请选择项目标签',
  559. trigger: 'change'
  560. }
  561. ]
  562. },
  563. diaType: -1,
  564. parentId: 0,
  565. queryData: null,
  566. owerQuery: {},
  567. projectStageQuery: {},
  568. selectList: [],
  569. dev: false,
  570. dataType: 'project'
  571. }
  572. },
  573. created() {
  574. this.dev = sessionStorage.getItem('dev') === 'true'
  575. const index = this.option.column.findIndex(sub => sub.prop === 'lot')
  576. const indexLabel = this.option.column.findIndex(
  577. sub => sub.prop === 'unit_name'
  578. )
  579. this.dataType = localStorage.getItem('data-type')
  580. if (this.user.info.viewStage === 1) {
  581. // 发改
  582. this.option.column[index].hide = true
  583. this.option.column[indexLabel].label = '责任单位'
  584. } else {
  585. this.option.column[index].hide = false
  586. this.option.column[indexLabel].label = '责任股(科)室'
  587. }
  588. this.$bus.on('serach', (res, type) => {
  589. this.owerQuery = res
  590. if (res.type === false) {
  591. this.projectStageQuery.projectStage = ''
  592. this.active = 0
  593. }
  594. this.onLoad(Object.assign(this.owerQuery, this.projectStageQuery))
  595. this.getNumList(Object.assign(this.owerQuery, this.projectStageQuery))
  596. })
  597. this.getTypeList()
  598. this.getNumList()
  599. },
  600. unmounted() {
  601. sessionStorage.removeItem('selectList')
  602. },
  603. methods: {
  604. switchTab(item, index) {
  605. this.active = index
  606. this.num = this.numList[index].totalAmount
  607. this.projectStageQuery = { projectStage: item.dictKey }
  608. this.onLoad(Object.assign(this.owerQuery, this.projectStageQuery))
  609. },
  610. onLoad(query = {}) {
  611. this.loading = true
  612. if (!Object.hasOwn(this.owerQuery, 'projectYear')) {
  613. this.owerQuery.projectYear = new Date().getFullYear()
  614. }
  615. const data = { ...this.owerQuery, parentId: this.parentId }
  616. this.queryData = data
  617. this.$api.project
  618. .projectList(this.page.currentPage, this.page.pageSize, this.queryData)
  619. .then(res => {
  620. this.loading = false
  621. if (res.code === 200) {
  622. this.data = res.data.records.map(e => {
  623. e.projectStage = e.projectStage + ''
  624. e.selected = true
  625. const xian = e.name.indexOf('县')
  626. e.name = this.dev ? e.name.substring(xian + 1) : e.name
  627. const status = confing.reportTypes.find(
  628. ele => ele.value === e.report_type
  629. )
  630. if (status) {
  631. e.report_type_name = status.label
  632. }
  633. return e
  634. })
  635. this.page.total = res.data.total
  636. }
  637. })
  638. .finally(() => {
  639. this.loading = false
  640. })
  641. },
  642. selectionChange(list) {
  643. this.selectList = list
  644. },
  645. beforeOpen(done, type) {
  646. if (['edit'].includes(type)) {
  647. const routeData = this.$router.resolve({
  648. path: '/home/details',
  649. query: {
  650. id: this.form.id,
  651. type: '0',
  652. ownerId: this.form.createUser
  653. }
  654. })
  655. window.open(routeData.href, '_blank')
  656. } else if (type === 'view') {
  657. const routeData = this.$router.resolve({
  658. path: '/home/pro_detail',
  659. query: { id: this.form.id, projectStage: this.form.project_stage }
  660. })
  661. window.open(routeData.href, '_blank')
  662. }
  663. },
  664. currentChange(currentPage) {
  665. this.page.current = currentPage
  666. },
  667. sizeChange(pageSize) {
  668. this.page.size = pageSize
  669. },
  670. refreshChange() {
  671. this.getNumList()
  672. this.onLoad()
  673. },
  674. treeLoad(tree, treeNode, resolve) {
  675. this.loading = true
  676. getLazyList(tree.id).then(res => {
  677. this.loading = false
  678. resolve(
  679. res.data.data.childrenList.map(e => {
  680. e.project_stage = e.project_stage.toString()
  681. return e
  682. })
  683. )
  684. })
  685. },
  686. rowDel(row) {
  687. this.$confirm('确定删除选择的项目?', {
  688. confirmButtonText: '确定',
  689. cancelButtonText: '取消',
  690. type: 'warning'
  691. }).then(() => {
  692. this.$api.project.projectRemove({ ids: row.id }).then(res => {
  693. if (res.code === 200) {
  694. this.$message.success(res.msg)
  695. this.onLoad()
  696. } else {
  697. this.$message.error(res.msg)
  698. }
  699. })
  700. })
  701. },
  702. getNumList(data) {
  703. this.$api.project.userNunList(data).then(res => {
  704. if (res.code === 200) {
  705. this.numList = res.data.projectStage
  706. this.num = res.data.projectStage[0].totalAmount
  707. }
  708. })
  709. },
  710. getTypeList() {
  711. this.$api.project
  712. .typeList({ type: 1, size: 999, current: 1 })
  713. .then(res => {
  714. this.typeList = res.data.records
  715. })
  716. this.$api.common.dicList({ code: 'project-tags' }).then(res => {
  717. if (res.code === 200) {
  718. this.tagsList = res.data
  719. }
  720. })
  721. },
  722. report(res) {
  723. if (res.is_report === 1) {
  724. this.$message.error('该项目已经上报')
  725. return
  726. }
  727. this.currentReport = res
  728. this.reportShow = true
  729. },
  730. /**
  731. * 股室上报项目到管理员
  732. * @param res
  733. */
  734. projectReport(res) {
  735. this.$confirm('确认上报至管理员进行审核?').then(ele => {
  736. if (ele === 'confirm') {
  737. this.$api.project.upReportType({ id: res.id }).then(res => {
  738. if (res.code === 200) {
  739. this.$message.success(res.msg)
  740. this.refreshChange()
  741. } else {
  742. this.$message.error(res.msg)
  743. }
  744. })
  745. }
  746. })
  747. },
  748. rowClick(item, type) {
  749. this.form = item
  750. if (type === 1) {
  751. this.showApproval = true
  752. }
  753. },
  754. /**
  755. * 管理员审批项目
  756. * approvalStatus === 4 审核不通过,需要填写原因
  757. */
  758. projectApproval() {
  759. if (this.approvalStatus === 4 && this.approvalMsg.length === 0) {
  760. this.$message.error('请填写审核意见')
  761. return
  762. }
  763. this.showApproval = false
  764. this.$api.project
  765. .approvalProject({
  766. id: this.form.id,
  767. reportType: this.approvalStatus,
  768. receiptMsg: this.approvalMsg
  769. })
  770. .then(res => {
  771. if (res.code === 200) {
  772. this.$message.success(res.msg)
  773. this.approvalStatus = 3
  774. this.approvalMsg = ''
  775. this.refreshChange()
  776. } else {
  777. this.$message.error(res.msg)
  778. }
  779. })
  780. },
  781. /**
  782. * 管理员已经审核通过的项目,上报到固定资产
  783. * @param res
  784. */
  785. projectReportFormal(item) {
  786. this.$confirm('确定上报到固定资产?').then(res => {
  787. if (res === 'confirm') {
  788. this.$api.project.reportToAssets({ ids: item.id }).then(res => {
  789. if (res.code === 200) {
  790. this.$message.success(res.msg)
  791. this.refreshChange()
  792. } else {
  793. this.$message.error(res.msg)
  794. }
  795. })
  796. }
  797. })
  798. },
  799. /**
  800. * 项目结转
  801. */
  802. projectCarry() {
  803. if (this.selectList.length === 0) {
  804. this.$message.error('请先选择要结转的项目')
  805. return
  806. }
  807. this.$api.project
  808. .projectCarry({ ids: this.selectList.map(ele => ele.id).join(',') })
  809. .then(res => {
  810. if (res.code === 200) {
  811. this.$message.success(res.msg)
  812. this.refreshChange()
  813. } else {
  814. this.$message.error(res.msg)
  815. }
  816. })
  817. },
  818. /**
  819. * 项目入库预审
  820. */
  821. projectStore() {
  822. if (this.selectList.length === 0) {
  823. this.$message.error('请先选择要入库预审的项目')
  824. return
  825. }
  826. this.selectList.forEach(ele => {
  827. if (ele.is_storage === 0) {
  828. this.$message.error('存在未入库的项目')
  829. throw ele
  830. }
  831. if (ele.is_report === 0) {
  832. this.$message.error('存在未上报的项目')
  833. throw ele
  834. }
  835. })
  836. ElMessageBox.confirm('确定将已经勾选的项目提交入库预审?', '', {}).then(
  837. res => {
  838. if (res === 'confirm') {
  839. this.$api.project
  840. .projectStore({
  841. ids: this.selectList.map(ele => ele.id).join(',')
  842. })
  843. .then(res => {
  844. if (res.code === 200) {
  845. this.$message.success(res.msg)
  846. } else {
  847. this.$message.error(res.msg)
  848. }
  849. })
  850. }
  851. }
  852. )
  853. },
  854. /**
  855. * 项目退库
  856. */
  857. projectCancel(res) {
  858. ElMessageBox.prompt('请输入退库原因', '提示', {}).then(({ value }) => {
  859. console.log(value)
  860. if (value === null || value.length === 0) {
  861. this.$message.error('请输入退库原因')
  862. return
  863. }
  864. this.$api.project
  865. .projectCancel({ id: res.id, exitMsg: value })
  866. .then(res => {
  867. if (res.code === 200) {
  868. this.$message.success(res.msg)
  869. this.refreshChange()
  870. } else {
  871. this.$message.error(res.msg)
  872. }
  873. })
  874. })
  875. },
  876. track(res) {
  877. const data = {
  878. id: res.id,
  879. is_report: 1,
  880. report_time: res.report_time
  881. }
  882. this.$api.project.proUpdate(data).then(res => {
  883. this.reportShow = false
  884. if (res.code === 200) {
  885. this.onLoad()
  886. this.$message.success(res.msg)
  887. } else {
  888. this.$message.error(res.msg)
  889. }
  890. })
  891. },
  892. projectSave() {
  893. if (this.disable) {
  894. this.$message.error('正在处理,请稍后...')
  895. return
  896. }
  897. this.$refs.form.validate(valid => {
  898. if (valid) {
  899. this.disable = true
  900. this.addLoading = true
  901. this.$api.project.projectAdd(this.projectForm).then(res => {
  902. this.disable = false
  903. this.addLoading = false
  904. if (res.code === 200) {
  905. this.showAdd = false
  906. this.$message.success(res.msg)
  907. this.projectForm = {
  908. name: '',
  909. totalAmount: '',
  910. projectType: '1589613582090166274',
  911. tags: '',
  912. introduction: ''
  913. }
  914. this.onLoad()
  915. } else {
  916. this.showAdd = false
  917. this.$message.error(res.msg)
  918. }
  919. })
  920. }
  921. })
  922. },
  923. formDialogClose() {
  924. if (this.diaType === 0) {
  925. this.onLoad()
  926. }
  927. this.diaType = -1
  928. },
  929. exportExcel(res, year) {
  930. const data = Object.assign(
  931. { ...this.queryData },
  932. {
  933. columnName: res,
  934. projectIds: this.selectList.map(ele => ele.id).join(','),
  935. previewType: 1,
  936. projectYear: year
  937. }
  938. )
  939. this.$router.push({ query: data, path: '/home/excel' })
  940. },
  941. showReceipt(msg) {
  942. this.$confirm(msg, {
  943. confirmButtonText: '确定',
  944. cancelButtonText: '取消',
  945. type: 'warning'
  946. })
  947. },
  948. exportExcelTotal(item) {
  949. const dataIds = {
  950. ...this.queryData,
  951. ...item,
  952. projectIds: this.selectList.map(ele => ele.id).join(','),
  953. previewType: 2
  954. }
  955. this.$router.push({ query: dataIds, path: '/home/excel' })
  956. }
  957. }
  958. }
  959. </script>
  960. <style lang="scss" scoped>
  961. .tip {
  962. width: 260px;
  963. height: 38px;
  964. background-color: #fbf6ed;
  965. font-weight: 500;
  966. flex-wrap: nowrap;
  967. margin-left: 20px;
  968. }
  969. .total-s {
  970. width: 160px;
  971. height: 50px;
  972. border: 1px solid #825618;
  973. border-radius: 10px;
  974. margin-right: 20px;
  975. box-shadow: 2px 2px 10px 2px rgba(113, 73, 39, 0.3);
  976. .sp {
  977. color: #ecab56;
  978. white-space: nowrap;
  979. margin-left: 20px;
  980. }
  981. .sp1 {
  982. color: #ecab56;
  983. margin-right: 20px;
  984. }
  985. }
  986. .total {
  987. width: 160px;
  988. height: 50px;
  989. border-radius: 10px;
  990. margin-right: 20px;
  991. background-color: #f0f2f7;
  992. .sp {
  993. color: #707070;
  994. white-space: nowrap;
  995. margin-left: 20px;
  996. }
  997. .sp1 {
  998. color: #825618;
  999. margin-right: 20px;
  1000. }
  1001. }
  1002. .curd {
  1003. :deep(.avue-crud__menu) {
  1004. min-height: 10px;
  1005. }
  1006. }
  1007. </style>