EstablishmentDialog.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. <template>
  2. <el-dialog
  3. :title="title"
  4. :visible.sync="visible"
  5. z-index="8000"
  6. width="70%"
  7. :close-on-click-modal="false"
  8. @close="handleClose"
  9. >
  10. <div class="dialog-content">
  11. <el-form
  12. ref="initiationForm"
  13. :model="formData"
  14. :rules="establishRules"
  15. label-width="150px"
  16. class="initiation-form two-column-form"
  17. :disabled="type == 2"
  18. >
  19. <!-- 成本监审项目名称 -->
  20. <el-form-item label="成本监审项目名称:" prop="projectName">
  21. <el-input
  22. v-model="formData.projectName"
  23. placeholder="请输入成本监审项目名称"
  24. style="width: 100%"
  25. maxlength="30"
  26. ></el-input>
  27. </el-form-item>
  28. <!-- 关联成本监审目录 -->
  29. <el-form-item label="关联成本监审目录:" prop="catalogId">
  30. <CatalogCascader
  31. ref="catalogCascader"
  32. :form-item="{ placeholder: '请选择监审目录' }"
  33. style="width: 100%"
  34. :value="formData.catalogId"
  35. @change="handleCatalogChange"
  36. />
  37. </el-form-item>
  38. <!-- 监审地区 -->
  39. <el-form-item label="监审地区:" prop="areaCode">
  40. <RegionSelector
  41. :initial-area-code="formData.areaCode"
  42. :disabled="false"
  43. @region-change="handleRegionChange"
  44. ></RegionSelector>
  45. </el-form-item>
  46. <!-- 被监审单位 -->
  47. <el-form-item label="被监审单位:" prop="auditedUnitId">
  48. <el-select
  49. v-model="formData.auditedUnitId"
  50. placeholder="请选择单位"
  51. clearable
  52. multiple
  53. style="width: 76%"
  54. >
  55. <el-option
  56. v-for="unit in areaUnitList"
  57. :key="unit.unitId"
  58. :label="unit.unitName"
  59. :value="unit.unitId"
  60. />
  61. </el-select>
  62. <!-- <el-input
  63. v-model="formData.auditedUnitName"
  64. style="width: 70%"
  65. placeholder="请输入被监审单位"
  66. readonly
  67. />
  68. <el-button type="primary" class="ml10" @click="showUnitDialog = true">
  69. 选择单位
  70. </el-button>
  71. <UnitSelectDialog
  72. :visible.sync="showUnitDialog"
  73. @unit-selected="handleUnitSelected"
  74. /> -->
  75. <el-button
  76. type="primary"
  77. class="ml10"
  78. @click="dialogAddUnitVisible = true"
  79. >
  80. 新增单位
  81. </el-button>
  82. </el-form-item>
  83. <!-- 监审主体 -->
  84. <el-form-item label="监审主体:" prop="orgName">
  85. <el-select
  86. v-model="formData.orgId"
  87. placeholder="请选择监审主体"
  88. style="width: 100%"
  89. clearable
  90. >
  91. <el-option
  92. v-for="Org in OrgList"
  93. :key="Org.id"
  94. :label="Org.name"
  95. :value="Org.id"
  96. />
  97. </el-select>
  98. <!-- <el-input
  99. v-model="formData.orgName"
  100. style="width: 76%"
  101. placeholder="请输入监审主体"
  102. readonly
  103. />
  104. <el-button
  105. type="primary"
  106. class="ml10"
  107. style="width: 22%"
  108. @click="showOrgDialog = true"
  109. >
  110. 选择部门
  111. </el-button>
  112. <OrgSelectDialog
  113. :visible.sync="showOrgDialog"
  114. @org-selected="handleOrgSelected"
  115. /> -->
  116. </el-form-item>
  117. <!-- 归属年度 -->
  118. <el-form-item label="归属年度:" prop="projectYear">
  119. <el-date-picker
  120. v-model="formData.projectYear"
  121. style="width: 100%"
  122. type="year"
  123. placeholder="请选择归属年度"
  124. format="yyyy"
  125. value-format="yyyy"
  126. clearable
  127. ></el-date-picker>
  128. <!-- <el-select
  129. v-model="formData.projectYear"
  130. placeholder="请选择计划年度"
  131. style="width: 100%"
  132. >
  133. <el-option
  134. v-for="item in dictData['attributionYear']"
  135. :key="item.key"
  136. :label="item.name"
  137. :value="item.key"
  138. ></el-option>
  139. </el-select> -->
  140. </el-form-item>
  141. <!-- 立项来源 -->
  142. <el-form-item label="立项来源:" prop="sourceType">
  143. <el-select
  144. v-model="formData.sourceType"
  145. placeholder="请选择立项类型"
  146. style="width: 100%"
  147. >
  148. <el-option
  149. v-for="item in dictData['projectProposal']"
  150. :key="item.key"
  151. :label="item.name"
  152. :value="item.key"
  153. ></el-option>
  154. </el-select>
  155. </el-form-item>
  156. <!-- 监审形式 -->
  157. <el-form-item label="监审形式:" prop="auditType">
  158. <el-select
  159. v-model="formData.auditType"
  160. placeholder="请选择监审形式"
  161. style="width: 100%"
  162. >
  163. <el-option
  164. v-for="item in dictData['auditType']"
  165. :key="item.key"
  166. :label="item.name"
  167. :value="item.key"
  168. ></el-option>
  169. </el-select>
  170. </el-form-item>
  171. <!-- 监审期间 -->
  172. <el-form-item label="监审期间:" prop="auditPeriodArray">
  173. <div class="cost-period-container">
  174. <el-button
  175. type="primary"
  176. size="small"
  177. class="add-cost-year-btn"
  178. @click="addCostYear"
  179. >
  180. +
  181. </el-button>
  182. <div class="cost-years-wrapper">
  183. <div
  184. v-for="(year, index) in formData.auditPeriodArray"
  185. :key="index"
  186. class="cost-year-item"
  187. >
  188. <el-date-picker
  189. v-model="year.value"
  190. style="width: 82%"
  191. type="year"
  192. placeholder="请选择年份"
  193. format="yyyy"
  194. value-format="yyyy"
  195. clearable
  196. @change="validateAuditPeriod"
  197. ></el-date-picker>
  198. <!-- <el-select
  199. v-model="year.value"
  200. placeholder="请选择年份"
  201. style="width: 80%"
  202. @change="validateAuditPeriod"
  203. >
  204. <el-option
  205. v-for="item in dictData['attributionYear']"
  206. :key="item.key"
  207. :label="item.name"
  208. :value="item.key"
  209. ></el-option>
  210. </el-select> -->
  211. <el-button
  212. type="danger"
  213. size="small"
  214. class="delete-cost-year-btn"
  215. @click="deleteCostYear(index)"
  216. >
  217. 删除
  218. </el-button>
  219. </div>
  220. </div>
  221. </div>
  222. </el-form-item>
  223. <!-- 是否参加听证 -->
  224. <el-form-item label="是否参加听证:" prop="needHearing">
  225. <el-radio-group v-model="formData.needHearing">
  226. <el-radio :label="0">是</el-radio>
  227. <el-radio :label="1">否</el-radio>
  228. </el-radio-group>
  229. </el-form-item>
  230. <!-- 是否应急项目 -->
  231. <el-form-item label="是否应急项目:" prop="isEmergency">
  232. <el-radio-group v-model="formData.isEmergency">
  233. <el-radio :label="0">是</el-radio>
  234. <el-radio :label="1">否</el-radio>
  235. </el-radio-group>
  236. </el-form-item>
  237. <!-- 立项理由 -->
  238. <el-form-item label="立项理由:" prop="establishmentReason">
  239. <el-input
  240. v-model="formData.establishmentReason"
  241. type="textarea"
  242. :rows="4"
  243. placeholder="请输入立项理由"
  244. style="width: 100%"
  245. maxlength="200"
  246. ></el-input>
  247. </el-form-item>
  248. <!-- 立项依据 -->
  249. <el-form-item label="立项依据:">
  250. <UploadComponent
  251. :upload-mode="'multiple'"
  252. :max-size="50 * 1024 * 1024"
  253. :allowed-types="['xlsx', 'xls', 'doc', 'docx', 'pdf']"
  254. :files-list="accordingFileList"
  255. :is-disabled="type == 2"
  256. @removeFile="removeAccordingFile"
  257. @saveFiles="saveAccordingFiles"
  258. />
  259. </el-form-item>
  260. <!-- 其他材料 -->
  261. <el-form-item label="其他材料:">
  262. <UploadComponent
  263. :upload-mode="'multiple'"
  264. :max-size="50 * 1024 * 1024"
  265. :allowed-types="['xlsx', 'xls', 'doc', 'docx', 'pdf']"
  266. :files-list="otherFileList"
  267. :is-disabled="type == 2"
  268. @removeFile="removeOtherFile"
  269. @saveFiles="saveOtherFiles"
  270. />
  271. </el-form-item>
  272. <!-- 监审任务负责人 -->
  273. <el-form-item label="监审任务负责人:" prop="leaderId">
  274. <el-select
  275. v-model="formData.leaderId"
  276. placeholder="请选择负责人"
  277. style="width: 100%"
  278. >
  279. <el-option
  280. v-for="(item, index) in areaUserList"
  281. :key="index"
  282. :label="item.fullname"
  283. :value="item.userId"
  284. ></el-option>
  285. </el-select>
  286. </el-form-item>
  287. <!-- 监审任务组成员 -->
  288. <el-form-item label="监审任务组成员:" prop="projectMembers">
  289. <el-select
  290. v-model="formData.projectMembers"
  291. placeholder="请选择成员"
  292. style="width: 100%"
  293. multiple
  294. >
  295. <el-option
  296. v-for="(item, index) in areaUserList"
  297. :key="index"
  298. :label="item.fullname"
  299. :value="item.userId"
  300. ></el-option>
  301. </el-select>
  302. </el-form-item>
  303. <!-- 其他要求 -->
  304. <el-form-item label="其他专家:" prop="expertStr">
  305. <el-input
  306. v-model="formData.expertStr"
  307. placeholder="请输入其他专家"
  308. style="width: 100%"
  309. maxlength="30"
  310. ></el-input>
  311. </el-form-item>
  312. <!-- 操作按钮 -->
  313. <el-form-item>
  314. <div class="form-buttons">
  315. <el-button
  316. v-if="type === 0 || type === 3"
  317. type="primary"
  318. @click="handleAdd"
  319. >
  320. 立项
  321. </el-button>
  322. <el-button v-if="type === 1" type="primary" @click="handleSave">
  323. 保存
  324. </el-button>
  325. <el-button @click="handleCancel">取消</el-button>
  326. </div>
  327. </el-form-item>
  328. </el-form>
  329. </div>
  330. <!-- 新增监审单位 -->
  331. <AuditEntityFormtDialog
  332. :dialog-visible="dialogAddUnitVisible"
  333. dialog-title="新增被监审单位"
  334. @confirm="handleDialogSuccess"
  335. @update:dialogVisible="dialogAddUnitVisible = $event"
  336. />
  337. </el-dialog>
  338. </template>
  339. <script>
  340. import AuditEntityFormtDialog from '@/components/costAudit/AuditEntityFormtDialog.vue'
  341. import RegionSelector from '../../views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/RegionSelector.vue'
  342. import CatalogCascader from '../../views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/CatalogCascader.vue'
  343. // import OrgSelectDialog from './OrgSelectDialog.vue'
  344. // import UnitSelectDialog from '@/components/costAudit/UnitSelectDialog.vue'
  345. import UploadComponent from '@/components/costAudit/UploadComponent.vue'
  346. import { Message } from 'element-ui'
  347. import { getAllUnitListByRegionCode } from '@/api/auditEntityManage'
  348. import {
  349. addProjectApproval,
  350. editProjectApproval,
  351. } from '@/api/auditInitiation'
  352. import { getAllUserList } from '@/api/uc'
  353. import { dictMixin } from '@/mixins/useDict'
  354. import { getDefaultDem, getOrgListByDemId } from '@/api/annualReviewPlan'
  355. export default {
  356. name: 'EstablishmentDialog',
  357. components: {
  358. RegionSelector,
  359. CatalogCascader,
  360. // OrgSelectDialog,
  361. // UnitSelectDialog,
  362. UploadComponent,
  363. AuditEntityFormtDialog,
  364. },
  365. mixins: [dictMixin],
  366. props: {
  367. title: {
  368. type: String,
  369. default: '成本监审立项',
  370. },
  371. visible: {
  372. type: Boolean,
  373. default: true,
  374. },
  375. provinces: {
  376. type: Array,
  377. default: () => [],
  378. },
  379. initialData: {
  380. type: Object,
  381. default: () => ({}),
  382. },
  383. //type 0 新建 1编辑 2查看 3快速立项
  384. type: {
  385. type: Number,
  386. default: 0,
  387. },
  388. },
  389. data() {
  390. return {
  391. // 用户信息
  392. userList: [],
  393. unitList: [],
  394. OrgList: [],
  395. showUnitDialog: false, // 选择被监审单位弹窗
  396. showOrgDialog: false, // 选择监审主体弹窗
  397. dialogAddUnitVisible: false, // 新增单位弹窗
  398. accordingFileList: [], // 立项依据文件列表
  399. otherFileList: [], // 其他材料文件列表
  400. formData: {
  401. projectName: '',
  402. catalogId: '',
  403. areaCode: '',
  404. auditedUnitName: '',
  405. auditedUnitId: [],
  406. orgId: '',
  407. orgName: '',
  408. planYear: '',
  409. projectYear: '',
  410. sourceType: '',
  411. auditPeriod: '',
  412. auditPeriodArray: [{ value: '' }],
  413. needHearing: 1,
  414. isEmergency: 1,
  415. establishmentReason: '',
  416. accordingFileUrl: '',
  417. otherFileUrl: '',
  418. expertStr: '',
  419. leaderId: '',
  420. projectMembers: [],
  421. },
  422. dictData: {
  423. attributionYear: [], // 归属年度
  424. projectProposal: [], // 立项来源
  425. auditType: [], //监审形式
  426. },
  427. formDistricts: [],
  428. establishRules: {
  429. projectName: [
  430. {
  431. required: true,
  432. message: '请输入成本监审项目名称',
  433. trigger: 'blur',
  434. },
  435. ],
  436. catalogId: [
  437. {
  438. required: true,
  439. message: '请选择关联成本监审目录',
  440. trigger: 'change',
  441. },
  442. ],
  443. auditedUnitName: [
  444. { required: true, message: '请选择被监审单位', trigger: 'change' },
  445. ],
  446. orgId: [
  447. { required: true, message: '请选择监审主体', trigger: 'change' },
  448. ],
  449. projectYear: [
  450. { required: true, message: '请选择计划年度', trigger: 'change' },
  451. ],
  452. sourceType: [
  453. { required: true, message: '请选择立项类型', trigger: 'change' },
  454. ],
  455. auditType: [
  456. { required: true, message: '请选择监审形式', trigger: 'change' },
  457. ],
  458. areaCode: [
  459. { required: true, message: '请选择监审地区', trigger: 'change' },
  460. ],
  461. auditPeriodArray: [
  462. {
  463. required: true,
  464. validator: this.validateAuditPeriodArray,
  465. trigger: 'change',
  466. },
  467. ],
  468. leaderId: [
  469. {
  470. required: true,
  471. message: '请选择监审任务负责人',
  472. trigger: 'change',
  473. },
  474. ],
  475. projectMembers: [
  476. {
  477. required: true,
  478. message: '请选择监审任务组成员',
  479. trigger: 'change',
  480. },
  481. ],
  482. },
  483. areaUserList: [],
  484. }
  485. },
  486. computed: {
  487. areaUnitList() {
  488. // 过滤出区域单位
  489. let user = this.$permission.getUserInfo()
  490. let arr = []
  491. if (this.$permission.isAdminOrProvince()) {
  492. // 管理员或省级权限,显示所有数据
  493. arr = this.unitList
  494. } else {
  495. // 非管理员且数据范围为区域时,筛选出当前用户区域下的市区数据
  496. arr = this.unitList.filter((item) => item.areaLevel >= user.dataScope)
  497. }
  498. return arr
  499. },
  500. },
  501. watch: {
  502. visible(val) {
  503. // 当弹窗显示时初始化数据
  504. // type 0 新建 1编辑 2查看 3快速立项
  505. if (this.type === 1 || this.type === 2) {
  506. if (val && this.initialData) {
  507. console.log('this.initialData', this.initialData)
  508. this.formData = { ...this.formData, ...this.initialData }
  509. this.formData.needHearing = Number(this.initialData.needHearing)
  510. this.formData.isEmergency = Number(this.initialData.isEmergency)
  511. this.formData.projectMembers = this.initialData.projectMembers
  512. ? this.initialData.projectMembers.split(',')
  513. : []
  514. if (this.formData.auditPeriod) {
  515. this.formData.auditPeriodArray = this.formData.auditPeriod
  516. .split(',')
  517. .map((year) => ({ value: year }))
  518. }
  519. this.formData.auditedUnitId = this.initialData.auditedUnitId
  520. ? this.initialData.auditedUnitId.split(',')
  521. : []
  522. if (this.initialData.accordingFileUrl) {
  523. this.accordingFileList =
  524. this.initialData.accordingFileUrl.split(',')
  525. }
  526. if (this.initialData.otherFileUrl) {
  527. this.otherFileList = this.initialData.otherFileUrl.split(',')
  528. }
  529. }
  530. // 当弹窗关闭时重置表单
  531. if (!val) {
  532. this.accordingFileList = []
  533. this.otherFileList = []
  534. this.$nextTick(() => {
  535. if (this.$refs.initiationForm) {
  536. this.$refs.initiationForm.resetFields()
  537. }
  538. })
  539. }
  540. } else if (this.type === 3) {
  541. // 当弹窗显示时设置数据
  542. if (val && this.initialData) {
  543. this.formData.projectName = this.initialData.projectName
  544. this.formData.auditType = this.initialData.auditType
  545. this.formData.catalogId = this.initialData.catalogId
  546. this.formData.areaCode = this.initialData.areaCode
  547. this.formData.auditedUnitName = this.initialData.auditedUnitName
  548. this.formData.auditedUnitId = this.initialData.auditedUnitId
  549. ? this.initialData.auditedUnitId.split(',')
  550. : []
  551. this.formData.orgId = this.initialData.orgId
  552. this.formData.planYear = this.initialData.planYear
  553. if (this.formData.auditPeriod) {
  554. this.formData.auditPeriodArray = this.initialData.auditPeriod
  555. .split(',')
  556. .map((year) => ({ value: year }))
  557. }
  558. }
  559. // 当弹窗关闭时重置表单
  560. if (!val) {
  561. this.accordingFileList = []
  562. this.otherFileList = []
  563. this.$nextTick(() => {
  564. if (this.$refs.initiationForm) {
  565. this.$refs.initiationForm.resetFields()
  566. }
  567. })
  568. }
  569. } else {
  570. // 当弹窗显示时初始化数据
  571. if (val) {
  572. // this.formData.areaCode = ''
  573. if (this.$permission.getUserInfo()) {
  574. let user = this.$permission.getUserInfo()
  575. if (user.dataScope === 0) {
  576. this.formData.areaCode = user.provinceCode
  577. } else if (user.dataScope === 1) {
  578. this.formData.areaCode = user.cityCode
  579. } else if (user.dataScope === 2) {
  580. this.formData.areaCode = user.countyCode
  581. }
  582. }
  583. // 其他初始化逻辑
  584. }
  585. // 当弹窗关闭时重置表单
  586. if (!val) {
  587. this.accordingFileList = []
  588. this.otherFileList = []
  589. this.$nextTick(() => {
  590. if (this.$refs.initiationForm) {
  591. this.$refs.initiationForm.resetFields()
  592. }
  593. })
  594. }
  595. }
  596. },
  597. 'formData.districtId'(districtId) {
  598. if (districtId) {
  599. const district = this.formDistricts.find(
  600. (item) => item.id === districtId
  601. )
  602. if (district) {
  603. this.formData.district = district.name
  604. }
  605. }
  606. },
  607. // 监听auditPeriodArray变化,同步更新auditPeriod字符串
  608. 'formData.auditPeriodArray': {
  609. deep: true,
  610. handler() {
  611. this.updateAuditPeriodString()
  612. },
  613. },
  614. // 'formData.areaCode': function(newVal) {
  615. // if (newVal) {
  616. // const region = this.getRegionByCode(newVal)
  617. // if (region) {
  618. // this.filterUser(region)
  619. // }
  620. // }
  621. // }
  622. },
  623. mounted() {
  624. this.getAllUnitList()
  625. this.getDefaultDem()
  626. this.getUser() // 获取用户信息
  627. },
  628. methods: {
  629. getAllUnitList() {
  630. getAllUnitListByRegionCode().then((res) => {
  631. this.unitList = res.value || []
  632. // 过滤掉状态为停用的数据
  633. this.unitList = this.unitList.filter((item) => item.status == 1)
  634. })
  635. },
  636. // 获取默认维度
  637. getDefaultDem() {
  638. getDefaultDem().then((res) => {
  639. if (res && res.code === 200) {
  640. const demId = res.value ? res.value.id : null
  641. if (demId) {
  642. this.getOrgListByDemId(demId)
  643. }
  644. }
  645. })
  646. },
  647. // 根据维度ID获取单位列表
  648. getOrgListByDemId(demId) {
  649. getOrgListByDemId({ demId }).then((res) => {
  650. if (res && res.code === 200) {
  651. this.OrgList = res.value || []
  652. }
  653. })
  654. },
  655. // 获取用户信息
  656. getUser() {
  657. getAllUserList()
  658. .then((res) => {
  659. this.userList = res.value || []
  660. })
  661. .catch(() => {})
  662. },
  663. // 立项依据文件处理
  664. saveAccordingFiles(data) {
  665. this.accordingFileList = data
  666. // 将所有文件的savePath以逗号分隔的形式保存
  667. this.formData.accordingFileUrl = data
  668. .map((file) => file.savePath)
  669. .filter(Boolean)
  670. .join(',')
  671. },
  672. // 移除立项依据文件(支持单个文件删除)
  673. removeAccordingFile(index) {
  674. // 如果传入索引,则删除单个文件
  675. if (typeof index === 'number') {
  676. this.accordingFileList.splice(index, 1)
  677. } else {
  678. // 否则清空所有文件
  679. this.accordingFileList = []
  680. }
  681. // 更新文件路径字符串
  682. this.formData.accordingFileUrl = this.accordingFileList
  683. .map((file) => file.savePath)
  684. .filter(Boolean)
  685. .join(',')
  686. },
  687. // 其他材料文件处理
  688. saveOtherFiles(data) {
  689. this.otherFileList = data
  690. // 将所有文件的savePath以逗号分隔的形式保存
  691. this.formData.otherFileUrl = data
  692. .map((file) => file.savePath)
  693. .filter(Boolean)
  694. .join(',')
  695. },
  696. // 移除其他材料文件(支持单个文件删除)
  697. removeOtherFile(index) {
  698. // 如果传入索引,则删除单个文件
  699. if (typeof index === 'number') {
  700. this.otherFileList.splice(index, 1)
  701. } else {
  702. // 否则清空所有文件
  703. this.otherFileList = []
  704. }
  705. // 更新文件路径字符串
  706. this.formData.otherFileUrl = this.otherFileList
  707. .map((file) => file.savePath)
  708. .filter(Boolean)
  709. .join(',')
  710. },
  711. // 处理地区选择变化
  712. handleRegionChange(region) {
  713. if (region && region.code) {
  714. this.formData.areaCode = region.code
  715. // 筛选一下该地区的用户
  716. this.filterUser(region)
  717. }
  718. },
  719. filterUser(region) {
  720. if (region.level == 0) {
  721. this.areaUserList = this.userList.filter(
  722. (item) => item.provinceCode === region.code
  723. )
  724. } else if (region.level == 1) {
  725. this.areaUserList = this.userList.filter(
  726. (item) => item.cityCode == region.code
  727. )
  728. } else if (region.level == 2) {
  729. this.areaUserList = this.userList.filter(
  730. (item) => item.countyCode == region.code
  731. )
  732. }
  733. },
  734. // 处理监审目录选择后的回调
  735. handleCatalogChange(value) {
  736. // this.formData.catalogId = value.join(',')
  737. this.formData.catalogId = value
  738. },
  739. // 处理选择被监审单位后的回调
  740. handleUnitSelected(selectedUnit) {
  741. this.formData.auditedUnitId = selectedUnit.unitId
  742. this.formData.auditedUnitName = selectedUnit.unitName
  743. },
  744. // 添加监审年份
  745. addCostYear() {
  746. this.formData.auditPeriodArray.push({ value: '' })
  747. },
  748. // 删除监审年份
  749. deleteCostYear(index) {
  750. // 若只剩1条,禁止删除并提示
  751. if (this.formData.auditPeriodArray.length <= 1) {
  752. Message.warning('监审期间至少需保留1条,无法删除')
  753. return
  754. }
  755. this.formData.auditPeriodArray.splice(index, 1)
  756. },
  757. // 更新auditPeriod字符串
  758. updateAuditPeriodString() {
  759. const values = this.formData.auditPeriodArray
  760. .map((item) => item.value)
  761. .filter(Boolean)
  762. const uniqueValues = [...new Set(values)]
  763. this.formData.auditPeriod = uniqueValues.join(',')
  764. },
  765. // 验证监审期间数组
  766. validateAuditPeriodArray(rule, value, callback) {
  767. const hasValidYear = this.formData.auditPeriodArray.some(
  768. (item) => item.value
  769. )
  770. if (!hasValidYear) {
  771. callback(new Error('请至少选择一个监审年份'))
  772. } else {
  773. callback()
  774. }
  775. },
  776. // 验证监审期间
  777. validateAuditPeriod() {
  778. this.$refs.initiationForm.validateField('auditPeriodArray')
  779. },
  780. // 处理选择监审主体后的回调
  781. handleOrgSelected(selectedOrg) {
  782. this.formData.orgId = selectedOrg.id
  783. this.formData.orgName = selectedOrg.name
  784. },
  785. // 保存表单数据
  786. handleAdd() {
  787. this.$refs.initiationForm.validate((valid) => {
  788. if (valid) {
  789. this.updateAuditPeriodString()
  790. // 提交数据
  791. let data = {
  792. ...this.formData,
  793. projectMembers: Array.isArray(this.formData.projectMembers)
  794. ? this.formData.projectMembers.join(',')
  795. : this.formData.projectMembers || '',
  796. auditedUnitId: (this.formData.auditedUnitId = Array.isArray(
  797. this.formData.auditedUnitId
  798. )
  799. ? this.formData.auditedUnitId.join(',')
  800. : this.formData.auditedUnitId || ''),
  801. }
  802. addProjectApproval(data)
  803. .then((res) => {
  804. Message.success('立项成功')
  805. this.$emit('save')
  806. })
  807. .catch(() => {
  808. // Message.error('立项失败,请重试')
  809. })
  810. }
  811. })
  812. },
  813. handleSave() {
  814. this.$refs.initiationForm.validate((valid) => {
  815. if (valid) {
  816. this.updateAuditPeriodString()
  817. let data = {
  818. ...this.formData,
  819. projectMembers: this.formData.projectMembers.join(','),
  820. auditedUnitId: this.formData.auditedUnitId.join(','),
  821. }
  822. // 提交数据
  823. editProjectApproval(data)
  824. .then((res) => {
  825. Message.success('保存成功')
  826. this.$emit('save')
  827. })
  828. .catch(() => {
  829. Message.error('保存失败,请重试')
  830. })
  831. } else {
  832. Message.error('请填写完整表单信息')
  833. return false
  834. }
  835. })
  836. },
  837. handleCancel() {
  838. this.$emit('cancel')
  839. },
  840. handleClose() {
  841. this.$emit('close')
  842. },
  843. handleDialogSuccess(data, value) {
  844. this.dialogAddUnitVisible = false
  845. this.getAllUnitList()
  846. this.formData.auditedUnitId.push(value)
  847. this.formData.areaCode = data.areaCode[data.areaCode.length - 1]
  848. },
  849. },
  850. }
  851. </script>
  852. <style scoped lang="scss">
  853. @import '@/styles/costAudit.scss';
  854. .form-buttons {
  855. margin-top: 20px;
  856. text-align: right;
  857. }
  858. .file-item {
  859. margin-bottom: 8px;
  860. padding: 4px;
  861. background-color: #f5f7fa;
  862. border-radius: 4px;
  863. }
  864. .cost-period-container {
  865. display: flex;
  866. align-items: flex-start;
  867. }
  868. .add-cost-year-btn {
  869. margin-right: 10px;
  870. }
  871. .delete-cost-year-btn {
  872. margin-left: 10px;
  873. }
  874. .cost-years-wrapper {
  875. flex: 1;
  876. }
  877. .cost-year-item {
  878. margin-bottom: 10px;
  879. display: flex;
  880. align-items: center;
  881. }
  882. .ml10 {
  883. margin-left: 10px;
  884. }
  885. .two-column-form {
  886. display: grid;
  887. grid-template-columns: repeat(2, 1fr);
  888. }
  889. /* 特殊处理宽字段,使其跨越两列 */
  890. .two-column-form .el-form-item.full-width {
  891. grid-column: span 2;
  892. }
  893. </style>