apply-form.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. <template>
  2. <div>
  3. <div v-if="operateType === 'edit'" class="tool-btn" style="width: 800px; margin: 0 auto; text-align: right;">
  4. <el-button size="small" type="primary" icon="el-icon-printer" v-print="printConfig" @click="isPrintPage = true">打印</el-button>
  5. </div>
  6. <div id="applyDoc" class="apply-form" v-loading="loading">
  7. <h3 class="page-title" style="height: 60px; line-height: 60px; margin: 0;">{{ teantData.tenantName }}</h3>
  8. <h3 class="page-title" style="margin: 5px 0 16px;">{{ getDocTile }}</h3>
  9. <div class="project-basic-info">
  10. <div class="info-row">{{ `研发项目名称:${ formData.xmmc || '' }` }}</div>
  11. <div class="info-row">{{ `项目负责人:${ getXmfzrName || '' }` }}</div>
  12. <div class="info-row">{{ `项目申请单位:${ xmsqdwName }` }}</div>
  13. <div class="info-row">{{ `项目执行期:${ getXmDateRange || '' }` }}</div>
  14. </div>
  15. <!-- 打印强制分页 -->
  16. <div style="page-break-after: always;"></div>
  17. <h3 class="page-title" style="margin: 24px 0 16px;">研发立项申请表</h3>
  18. <table>
  19. <tbody>
  20. <tr>
  21. <td class="doc-label">
  22. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>研发项目名称
  23. </td>
  24. <td class="doc-input">
  25. <el-input v-if="!isPrintPage" v-model="formData.xmmc" placeholder="请输入项目名称" :disabled="isEdit" />
  26. <span v-else style="display: inline-block; padding: 12px 6px;">{{ formData.xmmc }}</span>
  27. </td>
  28. <td class="doc-label">
  29. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目编号
  30. </td>
  31. <td class="doc-input">
  32. <el-input v-if="!isPrintPage" v-model="formData.xmbh" placeholder="请输入项目编号" :disabled="isEdit" />
  33. <span v-else style="display: inline-block; padding: 12px 6px;">{{ formData.xmbh }}</span>
  34. </td>
  35. </tr>
  36. <tr>
  37. <td class="doc-label">
  38. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>研发开始时间
  39. </td>
  40. <td class="doc-input">
  41. <el-date-picker
  42. v-if="!isPrintPage"
  43. v-model="formData.xmkssj"
  44. format="yyyy年MM月dd日"
  45. value-format="yyyy-MM-dd"
  46. placeholder="请选择日期"
  47. style="width: 100%"
  48. :disabled="isEdit"
  49. ></el-date-picker>
  50. <span v-else style="display: inline-block; padding: 12px 6px;">{{ formData.xmkssj }}</span>
  51. </td>
  52. <td class="doc-label">
  53. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>研发结束时间
  54. </td>
  55. <td class="doc-input">
  56. <el-date-picker
  57. v-if="!isPrintPage"
  58. v-model="formData.xmjssj"
  59. format="yyyy年MM月dd日"
  60. value-format="yyyy-MM-dd"
  61. placeholder="请选择日期"
  62. style="width: 100%"
  63. :disabled="isEdit"
  64. ></el-date-picker>
  65. <span v-else style="display: inline-block; padding: 12px 6px;">{{ formData.xmjssj }}</span>
  66. </td>
  67. </tr>
  68. <tr>
  69. <td class="doc-label">
  70. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目申请单位
  71. </td>
  72. <td colspan="3">
  73. <second-unit-cascader
  74. v-show="!isPrintPage"
  75. ref="secondUnitCascader"
  76. v-model="formData.xmsqdwid"
  77. :yearAndMonth="yearAndMonth"
  78. style="width: 100%;"
  79. :disabled="isEdit"
  80. @change="handleSecondUnitChange"
  81. >
  82. </second-unit-cascader>
  83. <span v-show="isPrintPage" style="display: inline-block; padding: 12px; color: #333;">{{ xmsqdwName }}</span>
  84. </td>
  85. </tr>
  86. <tr>
  87. <td class="doc-label">
  88. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目负责人
  89. </td>
  90. <td class="doc-input">
  91. <person-select v-show="!isPrintPage" v-model="formData.xmfzr" :yearAndMonth="xmStartDateYearAndMonth" valueKey="id" :disabled="isEdit" style="width: 100%" />
  92. <span v-show="isPrintPage" style="display: inline-block; padding: 12px 6px;">{{ getXmfzrName }}</span>
  93. </td>
  94. <td class="doc-label">
  95. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>研究类型
  96. </td>
  97. <td class="doc-input">
  98. <avue-select
  99. v-if="!isPrintPage"
  100. v-model="formData.yjlx"
  101. placeholder="请选择"
  102. :dic="studyTypeList"
  103. style="width: 100%"
  104. ></avue-select>
  105. <span v-else style="display: inline-block; padding: 12px;">{{ formData.yjlx }}</span>
  106. </td>
  107. </tr>
  108. <tr>
  109. <td class="doc-label">
  110. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目来源
  111. </td>
  112. <td class="doc-input">
  113. <avue-select
  114. v-if="!isPrintPage"
  115. v-model="formData.xmly"
  116. placeholder="请选择"
  117. :dic="projectSourceList"
  118. style="width: 100%"
  119. ></avue-select>
  120. <span v-else style="display: inline-block; padding: 12px;">{{ formData.xmly }}</span>
  121. </td>
  122. <td class="doc-label">
  123. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目开展形式
  124. </td>
  125. <td class="doc-input">
  126. <avue-select
  127. v-if="!isPrintPage"
  128. v-model="formData.xmkzxs"
  129. placeholder="请选择"
  130. :dic="implementFormatList"
  131. style="width: 100%"
  132. ></avue-select>
  133. <span v-else style="display: inline-block; padding: 12px;">{{ formData.xmkzxs }}</span>
  134. </td>
  135. </tr>
  136. <tr>
  137. <td class="doc-label">
  138. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>预期成果形式
  139. </td>
  140. <td class="doc-input">
  141. <avue-select
  142. v-if="!isPrintPage"
  143. multiple
  144. v-model="formData.yqcgxs"
  145. placeholder="请选择"
  146. :dic="expectedOutComeFormList"
  147. style="width: 100%"
  148. ></avue-select>
  149. <template v-else>
  150. <div style="padding: 12px;">
  151. <div v-for="(item, index) of formData.yqcgxs" :key="index">{{ item }}</div>
  152. </div>
  153. </template>
  154. </td>
  155. <td class="doc-label">
  156. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目技术经济目标
  157. </td>
  158. <td class="doc-input">
  159. <avue-select
  160. v-if="!isPrintPage"
  161. multiple
  162. v-model="formData.xmjsjjmb"
  163. placeholder="请选择"
  164. :dic="economicObjectivesList"
  165. style="width: 100%"
  166. ></avue-select>
  167. <template v-else>
  168. <div style="padding: 12px;">
  169. <div v-for="(item, index) of formData.xmjsjjmb" :key="index">{{ item }}</div>
  170. </div>
  171. </template>
  172. </td>
  173. </tr>
  174. <tr>
  175. <td class="doc-label">
  176. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>项目预算总额(万元)
  177. </td>
  178. <td class="doc-input">
  179. <!-- <el-input-number v-model="formData.xmysze" type="number" :min="0" controls-position="right" :disabled="isEdit" /> -->
  180. {{ getXmysze }}
  181. </td>
  182. <td class="doc-label">
  183. <span v-if="!isPrintPage" style="color: red; padding-right: 3px; font-size: 16px;">*</span>其中
  184. </td>
  185. <td class="doc-input">
  186. <div class="year-list">
  187. <div class="year-list-item" v-for="year of yearList" :key="year" :style="{ height: yearList.length == 1 ? '51px' : '32px', lineHeight: yearList.length == 1 ? '51px' : '32px' }">
  188. <div class="year" >{{ year }}</div>
  189. <div class="year-input">
  190. <input v-if="!isPrintPage" v-model="formData[year]" type="number" @input="handleYearInput" style="padding: 0 6px;" :disabled="isEdit" />
  191. <span v-else style="padding-left: 12px;">{{ formData[year] }}万元</span>
  192. </div>
  193. </div>
  194. </div>
  195. </td>
  196. </tr>
  197. </tbody>
  198. </table>
  199. <avue-form v-show="!isPrintPage" v-model="formData" :option="option" style="margin-top: 30px; padding: 0;">
  200. <template slot="lxpwLabel">
  201. <label>立项批文</label>
  202. <el-link type="primary" style="position: absolute; left: 220px; z-index: 1;">下载模板</el-link>
  203. </template>
  204. <template slot="lxbgLabel">
  205. <label>立项报告</label>
  206. <el-link type="primary" style="position: absolute; left: 220px; z-index: 1;">下载模板</el-link>
  207. </template>
  208. <template slot="qtzlLabel">
  209. <label>其他资料</label>
  210. <el-link type="primary" style="position: absolute; left: 220px; z-index: 1;">下载模板</el-link>
  211. </template>
  212. </avue-form>
  213. <div v-show="isPrintPage" class="file-list" style="margin-top: 30px;">
  214. <div class="file-list-item" style="display: flex; margin-bottom: 18px;">
  215. <div class="name">立项批文:</div>
  216. <div class="file-wrap">
  217. <div v-for="(item, idx) of formData.lxpw" :key="idx">{{ item.label }}</div>
  218. </div>
  219. </div>
  220. <div class="file-list-item" style="display: flex; margin-bottom: 18px;">
  221. <div class="name">立项报告:</div>
  222. <div class="file-wrap">
  223. <div v-for="(item, idx) of formData.lxbg" :key="idx">{{ item.label }}</div>
  224. </div>
  225. </div>
  226. <div class="file-list-item" style="display: flex;">
  227. <div class="name">其他资料:</div>
  228. <div class="file-wrap">
  229. <div v-for="(item, idx) of formData.qtzl" :key="idx">{{ item.label }}</div>
  230. </div>
  231. </div>
  232. </div>
  233. <p v-if="!isPrintPage" class="tip">注:可一次上传多个相关文件(文档、表格、图片等)。 支持格式:DOC, PDF, Excel, PNG, JPG, PPT 等。 请确保文件内容清晰有效。</p>
  234. <div class="btn-wrap printHide" style="text-align: center;">
  235. <el-button type="primary" style="width: 160px;" @click="handleSaveBtn">保存</el-button>
  236. </div>
  237. </div>
  238. </div>
  239. </template>
  240. <script>
  241. import secondUnitCascader from "@/components/second-unit-cascader";
  242. import personSelect from "@/components/person-select";
  243. import { getDictionary } from "@/api/system/dictbiz";
  244. import { add, update, getApprove } from "@/api/projectManage/projectList";
  245. import moment from "moment";
  246. import { deepClone } from "@/util/util";
  247. import Decimal from "decimal.js";
  248. import { mapGetters } from "vuex";
  249. import { getDetail as getTenantDetail } from '@/api/system/tenant';
  250. import { downloadFileByUrl } from "@/util/util";
  251. export default {
  252. components: {
  253. personSelect,
  254. secondUnitCascader
  255. },
  256. props: {
  257. // add or edit
  258. operateType: String,
  259. projectId: [String, Number]
  260. },
  261. data() {
  262. return {
  263. loading: false,
  264. formData: {
  265. xmmc: '',
  266. xmbh: '',
  267. xmkssj: '',
  268. xmjssj: '',
  269. xmsqdwid: [],
  270. xmfzr: '',
  271. yjlx: '',
  272. xmly: '',
  273. xmkzxs: '',
  274. yqcgxs: [],
  275. xmjsjjmb: [],
  276. lxpw: [],
  277. lxbg: [],
  278. qtzl: []
  279. },
  280. yearList: [],
  281. // 预算是否超出
  282. budgetIsExceed: false,
  283. // 项目负责人列表
  284. fzrList: [],
  285. // 研究类型数据字典
  286. studyTypeList: [],
  287. // 项目来源列表
  288. projectSourceList: [],
  289. // 开展形式
  290. implementFormatList: [],
  291. // 预期成果形式
  292. expectedOutComeFormList: [],
  293. // 经济目标
  294. economicObjectivesList: [],
  295. xmsqdwName: '',
  296. // 租户信息
  297. teantData: {},
  298. isPrintPage: false,
  299. printConfig: {
  300. el: '#applyDoc', //被打印部分的id
  301. closeCallback: () => {
  302. this.isPrintPage = false;
  303. }
  304. },
  305. };
  306. },
  307. watch: {
  308. 'formData.xmkssj'(newVal) {
  309. this.yearList = this.getDateRangeYear(newVal, this.formData.xmjssj);
  310. let cMonth = newVal ? moment(newVal).format('yyyyMM') : '';
  311. if (cMonth != this.xmStartDateYearAndMonth) {
  312. this.xmStartDateYearAndMonth = cMonth;
  313. }
  314. },
  315. 'formData.xmjssj'(newVal) {
  316. this.yearList = this.getDateRangeYear(this.formData.xmkssj, newVal);
  317. },
  318. 'formData.xmysze'(newVal) {
  319. this.calcBudgetIsExceed(newVal);
  320. },
  321. },
  322. computed: {
  323. ...mapGetters(["userInfo"]),
  324. isEdit() {
  325. return this.operateType == 'edit';
  326. },
  327. // 获取项目预算总额
  328. getXmysze() {
  329. let total = new Decimal(0);
  330. this.yearList.forEach(year => {
  331. total = total.add (new Decimal(this.formData[year] || 0));
  332. });
  333. return total.toFixed(2);
  334. },
  335. option() {
  336. return {
  337. submitBtn: false,
  338. emptyBtn: false,
  339. submitText: '保存',
  340. menuBtn: false,
  341. column: [
  342. {
  343. label: "立项批文",
  344. prop: "lxpw",
  345. type: "upload",
  346. multiple: true,
  347. span: 24,
  348. disabled: this.isEdit,
  349. dataType: "object",
  350. propsHttp: {
  351. url: "link",
  352. name: "originalName",
  353. res: "data",
  354. },
  355. action: '/api/kd-resource/oss/endpoint/put-file',
  356. uploadPreview: (file, column, done) => {
  357. downloadFileByUrl(file.url, file.name);
  358. return;
  359. },
  360. // rules: [{
  361. // required: true,
  362. // message: "请上传立项批文"
  363. // }]
  364. },
  365. {
  366. label: "立项报告",
  367. prop: "lxbg",
  368. type: "upload",
  369. multiple: true,
  370. span: 24,
  371. dataType: "object",
  372. propsHttp: {
  373. url: "link",
  374. name: "originalName",
  375. res: "data",
  376. },
  377. action: '/api/kd-resource/oss/endpoint/put-file',
  378. disabled: this.isEdit,
  379. uploadPreview: (file, column, done) => {
  380. downloadFileByUrl(file.url, file.name);
  381. return;
  382. },
  383. // rules: [{
  384. // required: true,
  385. // message: "请上传立项报告"
  386. // }]
  387. },
  388. {
  389. label: "其他资料",
  390. prop: "qtzl",
  391. type: "upload",
  392. multiple: true,
  393. span: 24,
  394. action: '/api/kd-resource/oss/endpoint/put-file',
  395. disabled: this.isEdit,
  396. uploadPreview: (file, column, done) => {
  397. downloadFileByUrl(file.url, file.name);
  398. return;
  399. },
  400. dataType: "object",
  401. propsHttp: {
  402. url: "link",
  403. name: "originalName",
  404. res: "data",
  405. },
  406. },
  407. ],
  408. }
  409. },
  410. getDocTile() {
  411. let tit = '研发项目资料';
  412. if (this.formData.xmmc) {
  413. return `${this.formData.xmmc}${tit}`;
  414. }
  415. return tit;
  416. },
  417. getXmfzrName() {
  418. // if (this.formData.xmfzr) {
  419. // let fzrObj = this.fzrList.find(item => item.value == this.formData.xmfzr);
  420. // return fzrObj ? fzrObj.label : "";
  421. // }
  422. return this.formData.xmfzrxm;
  423. },
  424. getXmDateRange() {
  425. if (this.formData.xmkssj && this.formData.xmjssj) {
  426. let xmkssj = moment(this.formData.xmkssj).format('yyyy年MM月DD日');
  427. let xmjssj = moment(this.formData.xmjssj).format('yyyy年MM月DD日')
  428. return `${xmkssj}至${xmjssj}`;
  429. }
  430. return `年 月 日至 年 月 日`;
  431. },
  432. yearAndMonth() {
  433. return !!this.formData.xmkssj ? moment(this.formData.xmkssj).format('yyyy') : '';
  434. }
  435. },
  436. mounted() {
  437. this.getTenantDetailFunc(this.userInfo.tenant_id);
  438. this.getDictList("study_type", "studyTypeList");
  439. this.getDictList("project_source", "projectSourceList");
  440. this.getDictList("implementation_format", "implementFormatList");
  441. this.getDictList("expected_outcome_form", "expectedOutComeFormList");
  442. this.getDictList("economic_objectives", "economicObjectivesList");
  443. if (this.projectId) {
  444. this.getProjectDetail(this.projectId);
  445. }
  446. },
  447. methods: {
  448. // 获取租户详情信息
  449. getTenantDetailFunc(tenantId) {
  450. getTenantDetail(tenantId).then(({ data }) => {
  451. if (data.code == 200) {
  452. this.teantData = data.data;
  453. }
  454. });
  455. },
  456. handleSecondUnitChange(val, nameArr) {
  457. this.xmsqdwName = nameArr.join('/');
  458. },
  459. getProjectDetail(xmId) {
  460. this.loading = true;
  461. getApprove({ xmId }).then(({ data }) => {
  462. this.loading = false;
  463. if (data.code == 200) {
  464. let beanData = { ...data.data };
  465. beanData.xmfzr = beanData.xmfzr.toString();
  466. beanData.yqcgxs = beanData.yqcgxs.split(",");
  467. beanData.xmjsjjmb = beanData.xmjsjjmb.split(",");
  468. beanData.lxpw = beanData.lxpw ? JSON.parse(beanData.lxpw) : [];
  469. beanData.lxbg = beanData.lxbg ? JSON.parse(beanData.lxbg) : [];
  470. beanData.qtzl = beanData.qtzl ? JSON.parse(beanData.qtzl) : [];
  471. beanData.xmyszemx = beanData.xmyszemx ? JSON.parse(beanData.xmyszemx) : [];
  472. beanData.xmyszemx.forEach(item => {
  473. beanData[item.year] = item.amount;
  474. });
  475. this.formData = { ...beanData };
  476. }
  477. }).catch(err => {
  478. this.loading = false;
  479. });
  480. },
  481. getDateRangeYear(sDate, eDate) {
  482. let yearArr = [];
  483. if (sDate && eDate) {
  484. let sDateYear = moment(sDate).format('yyyy');
  485. let dDateYear = moment(eDate).format('yyyy');
  486. for (let i=sDateYear; i<=dDateYear; i++) {
  487. yearArr.push(i);
  488. }
  489. }
  490. return yearArr;
  491. },
  492. getDictList(code, toListKey) {
  493. getDictionary({ code }).then((res) => {
  494. this[toListKey] = res.data.data.map((item) => {
  495. return { label: item.dictValue, value: item.dictKey };
  496. });
  497. });
  498. },
  499. handleYearInput(e) {
  500. this.calcBudgetIsExceed(this.formData.xmysze);
  501. },
  502. /**
  503. * 计算是否超出预算
  504. * @param total 预算总额
  505. */
  506. calcBudgetIsExceed(total) {
  507. let yearTotal = 0;
  508. let projectBudget = Number(total || 0);
  509. this.yearList.forEach(year => {
  510. let num = Number(this.formData[year] || 0);
  511. yearTotal += num;
  512. });
  513. if (yearTotal > projectBudget) {
  514. this.budgetIsExceed = true;
  515. } else {
  516. this.budgetIsExceed = false;
  517. }
  518. },
  519. validForm() {
  520. let errorText = '';
  521. if (!this.formData.xmmc) {
  522. errorText = '请输入项目名称';
  523. } else if (/技改|技术改造|推广|打样|翻新|产业化|生产线|改造|年产|示范/g.test(this.formData.xmmc)) {
  524. errorText = '研发项目名称,不符合统计部门的命名要求';
  525. } else if (!this.formData.xmbh) {
  526. errorText = '请输入项目编号';
  527. } else if (!this.formData.xmsqdwid || !this.formData.xmsqdwid.length) {
  528. errorText = '请选择项目申请单位';
  529. } else if (!this.formData.xmkssj) {
  530. errorText = '请选择项目开始时间';
  531. } else if (!this.formData.xmjssj) {
  532. errorText = '请选择项目结束时间';
  533. } else if (!this.formData.yjlx) {
  534. errorText = '请选择研究类型'
  535. } else if (!this.formData.xmfzr) {
  536. errorText = '请选择项目负责人';
  537. } else if (!this.formData.xmly) {
  538. errorText = '请选择项目来源';
  539. } else if (!this.formData.xmkzxs) {
  540. errorText = '请选择项目开展形式';
  541. } else if (!this.formData.yqcgxs) {
  542. errorText = '请选择预期成果形式';
  543. } else if (!this.formData.xmjsjjmb) {
  544. errorText = '请选择项目技术经济目标';
  545. }
  546. else {
  547. this.yearList.forEach(year => {
  548. if (this.formData[year] === null || this.formData[year] === undefined || this.formData[year] === '') {
  549. errorText = `${year}年的预算不能为空`;
  550. }
  551. });
  552. }
  553. return errorText;
  554. },
  555. handleResetBtn() {
  556. this.yearList.forEach(year => {
  557. this.formData[year] = '';
  558. });
  559. this.formData = {
  560. xmmc: '',
  561. xmbh: '',
  562. xmkssj: '',
  563. xmjssj: '',
  564. xmsqdwid: [],
  565. xmfzr: '',
  566. yjlx: '',
  567. xmly: '',
  568. xmkzxs: '',
  569. yqcgxs: [],
  570. xmjsjjmb: [],
  571. lxpw: [],
  572. lxbg: [],
  573. qtzl: []
  574. };
  575. this.yearList = [];
  576. this.$refs.secondUnitCascader.cascaderVal = [];
  577. },
  578. handleSaveBtn() {
  579. if (!this.operateType || this.operateType === 'add') {
  580. let errorText = this.validForm();
  581. if (errorText) {
  582. this.$message.error(errorText+'!');
  583. return;
  584. }
  585. let params = deepClone(this.formData);
  586. params.yqcgxs = params.yqcgxs ? params.yqcgxs.join(',') : '';
  587. params.xmjsjjmb = params.xmjsjjmb ? params.xmjsjjmb.join(',') : '';
  588. params.xmsqdwid = params.xmsqdwid ? params.xmsqdwid[params.xmsqdwid.length - 1] : '';
  589. params.lxbg = JSON.stringify(params.lxbg);
  590. params.lxpw = JSON.stringify(params.lxpw);
  591. params.qtzl = JSON.stringify(params.qtzl);
  592. let yearAmountList = [];
  593. this.yearList.forEach(year => {
  594. yearAmountList.push({ year: Number(year), amount: params[year] || 0 });
  595. delete params[year];
  596. });
  597. params.xmyszemx = JSON.stringify(yearAmountList);
  598. params.xmysze = this.getXmysze;
  599. this.addOrUpdate(params);
  600. } else if (this.operateType === 'edit') {
  601. let params = {
  602. xmId: this.formData.id,
  603. yjlx: this.formData.yjlx,
  604. xmly: this.formData.xmly,
  605. xmkzxs: this.formData.xmkzxs,
  606. yqcgxs: this.formData.yqcgxs.join(','),
  607. xmjsjjmb: this.formData.xmjsjjmb.join(',')
  608. };
  609. this.addOrUpdate(params);
  610. }
  611. },
  612. addOrUpdate(params) {
  613. let func = this.operateType === 'edit' ? update : add;
  614. this.loading = true;
  615. func(params).then(({ data }) => {
  616. this.loading = false;
  617. if (data.code == 200) {
  618. this.handleResetBtn();
  619. this.$emit('success', data.data);
  620. this.$message.success(this.operateType === 'edit' ? '修改成功!' : '保存成功!');
  621. }
  622. }).catch(err => {
  623. this.loading = false;
  624. });
  625. }
  626. },
  627. };
  628. </script>
  629. <style lang="scss" scoped>
  630. .page-title {
  631. text-align: center;
  632. font-size: 24px;
  633. }
  634. .project-basic-info .info-row {
  635. line-height: 26px;
  636. color: #333;
  637. }
  638. .apply-form {
  639. width: 800px;
  640. margin: 30px auto;
  641. }
  642. table {
  643. width: 100%;
  644. border: 1px solid #333;
  645. }
  646. .doc-label {
  647. width: 100px;
  648. text-align: center;
  649. padding: 6px;
  650. color: #777;
  651. font-size: 14px;
  652. }
  653. .doc-input {
  654. width: 300px;
  655. text-align: center;
  656. color: #333;
  657. }
  658. .el-input__inner {
  659. border: none;
  660. }
  661. tr td {
  662. border: 1px solid #333;
  663. }
  664. .year-list {
  665. &-item {
  666. display: flex;
  667. height: 32px;
  668. line-height: 32px;
  669. border-bottom: 1px solid #333;
  670. &:last-child {
  671. border-bottom: 0;
  672. }
  673. .year {
  674. width: 65px;
  675. border-right: 1px solid #333;
  676. }
  677. .year-input {
  678. input {
  679. width: 100%;
  680. min-height: 30px;
  681. border: 0;
  682. }
  683. }
  684. }
  685. }
  686. .red {
  687. color: red;
  688. }
  689. .tip {
  690. position: relative;
  691. top: 0;
  692. color: red;
  693. padding-left: 90px;
  694. margin-top: 0;
  695. font-size: 12px;
  696. }
  697. </style>