detailsPage.vue 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. <template>
  2. <div class="borderless">
  3. <div class="customer-head">
  4. <div class="customer-back">
  5. <el-button type="danger" style="border: none;background: none;color: red" icon="el-icon-arrow-left"
  6. @click="backToList">返回列表
  7. </el-button>
  8. <div class="upper_right_button">
  9. <el-button type="success"
  10. size="small"
  11. class="el-button--small-yh "
  12. :disabled="true"
  13. @click.stop="addMainProject">复制新单
  14. </el-button>
  15. <el-button class="el-button--small-yh "
  16. type="primary"
  17. @click.stop="editMainProject"
  18. size="small"
  19. >{{this.id?"确认修改" :"确认新增"}}
  20. </el-button>
  21. </div>
  22. </div>
  23. </div>
  24. <div class="customer-main">
  25. <containerTitle title="基础信息"></containerTitle>
  26. <basic-container>
  27. <el-form :model="form" ref="form" label-width="100px" class="demo-ruleForm">
  28. <el-row>
  29. <el-col v-for="(item, index) in basicData.column" :span="item.span?item.span:6" :key="index">
  30. <el-form-item :label="item.label" :prop="item.prop" :rules="item.rules">
  31. <el-date-picker v-if="item.type === 'datetime'" style="width: 100%;" v-model="form[item.prop]" size="small" type="datetime" :disabled="item.disabled?true:false" placeholder="选择日期" value-format="yyyy-MM-dd HH:mm:ss"/>
  32. <el-date-picker v-else-if="item.type === 'date'" style="width: 100%;" v-model="form[item.prop]" size="small" type="date" placeholder="选择日期" value-format="yyyy-MM-dd"/>
  33. <el-select v-else-if="item.prop === 'paymentType'" style="width: 100%" v-model="form[item.prop]" size="small" placeholder="请选择" clearable filterable>
  34. <el-option v-for="(item,index) in paymentTerm" :key="index" :label="item.dictValue" :value="item.dictValue"></el-option>
  35. </el-select>
  36. <selectComponent v-else-if="item.prop === 'corpId'" v-model="form[item.prop]" :configuration="configuration"/>
  37. <el-input type="textarea" v-else-if="(item.prop === 'remark')" v-model="form[item.prop]" size="small" autocomplete="off" placeholder="请输入"></el-input>
  38. <el-input type="age" v-else-if="item.type === 'unit'" v-model="form[item.prop]" @change="debitChange" :disabled="item.disabled?true:false" size="small" autocomplete="off" placeholder="请输入">
  39. <template slot="append">元</template>
  40. </el-input>
  41. <el-input type="age" v-else v-model="form[item.prop]" :disabled="item.disabled?true:false" size="small" value="0" autocomplete="off" placeholder="请输入">
  42. <template v-if="item.prop === 'advanceAmount'||item.prop === 'settlmentAmount'||item.prop === 'balanceAmount'" slot="append">元</template>
  43. </el-input>
  44. </el-form-item>
  45. </el-col>
  46. </el-row>
  47. </el-form>
  48. </basic-container>
  49. <containerTitle title="明细列表"></containerTitle>
  50. <basic-container>
  51. <avue-crud
  52. ref="crud"
  53. :data="data"
  54. :option="optionTable"
  55. :page.sync="page"
  56. :table-loading="loading"
  57. v-model="optionFrom"
  58. @row-del="rowDel"
  59. @row-save="rowSave"
  60. @row-update="rowUpdate"
  61. @size-change="sizeChange"
  62. @current-change="currentChange"
  63. @selection-change="selectionChange"
  64. @search-change="searchChange"
  65. @saveColumn="saveColumn"
  66. >
  67. <template slot-scope="scope" slot="menuLeft">
  68. <el-button type="primary"
  69. size="small"
  70. icon="el-icon-plus"
  71. @click="serviceDialog = true">录入明细
  72. </el-button>
  73. <el-button type="info"
  74. size="small"
  75. :disabled="crudSelection == 0"
  76. @click.stop="beforePleaseCheck()">请 核
  77. </el-button>
  78. </template>
  79. <template slot="menuRight">
  80. <el-button
  81. size="small"
  82. type="info"
  83. @click.stop="openReport()"
  84. >导出报表
  85. </el-button>
  86. </template>
  87. <template slot-scope="{row,index}" slot="menu">
  88. <el-button
  89. type="text"
  90. size="small"
  91. @click="rowCellTwo(row,index)"
  92. :disabled="row.strStatus !== '录入'"
  93. >{{row.$cellEdit?'修改完成':'修改'}}</el-button>
  94. <el-button
  95. type="text"
  96. size="small"
  97. @click="rowDel(row,index)"
  98. :disabled="row.strStatus == '结算完成'"
  99. >删除</el-button>
  100. </template>
  101. <template slot="userid" slot-scope="{row,index}">
  102. <span v-if="row.$cellEdit" style="float: left;color: #F56C6C;">*</span>
  103. <span style="margin-left: 12px;padding-top: 2px">{{ row.userName }}</span>
  104. <el-button v-if="row.$cellEdit" type="text" size="mini" style="float: right" @click="selectUser(row)">选择</el-button>
  105. </template>
  106. <template slot="amount" slot-scope="{ row }">
  107. <el-input
  108. v-if="row.$cellEdit"
  109. v-model="row.amount"
  110. placeholder="请输入"
  111. size="small"
  112. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  113. @change="totalChange(row,'金额')"
  114. ></el-input>
  115. <span v-else>{{ row.amount }}</span>
  116. </template>
  117. <template slot="serviceCharge" slot-scope="{ row }">
  118. <el-input
  119. v-if="row.$cellEdit"
  120. v-model="row.serviceCharge"
  121. placeholder="请输入"
  122. size="small"
  123. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  124. @change="totalChange(row,'服务')"
  125. ></el-input>
  126. <span v-else>{{ row.serviceCharge }}</span>
  127. </template>
  128. <template slot="matMoney" slot-scope="{ row }">
  129. <el-input
  130. v-if="row.$cellEdit"
  131. v-model="row.matMoney"
  132. placeholder="请输入"
  133. size="small"
  134. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d).*$/, "$1.$2")'
  135. @change="totalChange(row,'代垫')"
  136. ></el-input>
  137. <span v-else>{{ row.matMoney }}</span>
  138. </template>
  139. </avue-crud>
  140. </basic-container>
  141. <containerTitle title="附件上传"></containerTitle>
  142. <basic-container style="margin-bottom: 40px">
  143. <avue-crud
  144. :option="upLoadOption"
  145. v-model="upLoadForm"
  146. :data="upLoadData"
  147. @row-save="upLoadSave"
  148. @row-update="upLoadUpdate"
  149. @row-del="upLoadDel"
  150. ></avue-crud>
  151. </basic-container>
  152. </div>
  153. <el-dialog
  154. title="导入服务项目"
  155. append-to-body
  156. class="el-dialogDeep"
  157. :visible.sync="serviceDialog"
  158. width="70%"
  159. :close-on-click-modal="false"
  160. :destroy-on-close="true"
  161. :close-on-press-escape="false">
  162. <el-row style="height: 0;">
  163. <el-col :span="5" >
  164. <div>
  165. <el-scrollbar>
  166. <basic-container>
  167. <avue-tree :option="serviceTreeOption" @node-click="serviceNodeClick"/>
  168. </basic-container>
  169. </el-scrollbar>
  170. </div>
  171. </el-col>
  172. <el-col :span="19">
  173. <basic-container>
  174. <avue-crud ref="serviceCrud"
  175. :page.sync="servicePage"
  176. :search.sync="serviceSearch"
  177. :option="serviceOption"
  178. :table-loading="serviceLoading"
  179. :data="serviceData"
  180. @refresh-change="serviceRefreshChange"
  181. @selection-change="serviceSelectionChange"
  182. @search-change="serviceSearchChange"
  183. @on-load="serviceOnLoad">
  184. </avue-crud>
  185. </basic-container>
  186. </el-col>
  187. </el-row>
  188. <span slot="footer" class="dialog-footer">
  189. <el-button type="primary" @click="serviceConfirm()" :disabled="this.serviceSelectList.length == 0">导 入</el-button>
  190. <el-button @click="serviceDialog = false">取 消</el-button>
  191. </span>
  192. </el-dialog>
  193. <el-dialog
  194. title="导入用户"
  195. :visible.sync="userDialog"
  196. class="el-dialogDeep"
  197. append-to-body
  198. width="80%">
  199. <el-row style="margin-top: -5px;height: 0">
  200. <el-col :span="5">
  201. <div class="box">
  202. <el-scrollbar>
  203. <basic-container>
  204. <avue-tree :option="userTreeOption" :data="userTreeData" @node-click="userNodeClick"/>
  205. </basic-container>
  206. </el-scrollbar>
  207. </div>
  208. </el-col>
  209. <el-col :span="19">
  210. <basic-container>
  211. <avue-crud ref="userCrud"
  212. :option="userOption"
  213. :data="userDataList"
  214. :table-loading="userLoading"
  215. :page.sync="userPage"
  216. v-model="userForm"
  217. @search-change="userSearchChange"
  218. @search-reset="userSearchReset"
  219. @refresh-change="userRefreshChange"
  220. @selection-change="userSelectionChange"
  221. @on-load="userOnLoad"
  222. >
  223. </avue-crud>
  224. </basic-container>
  225. </el-col>
  226. </el-row>
  227. <span slot="footer" class="dialog-footer">
  228. <el-button @click="userDialog = false">取 消</el-button>
  229. <el-button type="primary" :disabled="this.userSelection.length == 1 ? false:true" @click="userConfirm" >确 定</el-button>
  230. </span>
  231. </el-dialog>
  232. <el-dialog
  233. title="流程"
  234. append-to-body
  235. class="el-dialogDeep"
  236. :visible.sync="processDialog"
  237. width="60%"
  238. :close-on-click-modal="false"
  239. :destroy-on-close="true"
  240. :modal-append-to-body='false'
  241. :close-on-press-escape="false"
  242. v-dialog-drag
  243. >
  244. <examine-approve
  245. :itemId ="itemId"
  246. :closeFun="dialogProcessClose"
  247. >
  248. </examine-approve>
  249. </el-dialog>
  250. </div>
  251. </template>
  252. <script>
  253. import option from "./configuration/detailsPage.json";
  254. import startOption from "./configuration/startDialog.json";
  255. import { projectDetail,editMianProject,updateItemStatus,getSysNo,getPidByItemId} from "@/api/workManagement/mainProject";
  256. //上传文件json
  257. import upLoadOption from "../../exportTrade/purchaseContract/config/uploadList.json"
  258. //服务列表接口
  259. import {getServiceProjectList,getServiceTypeTree,} from "@/api/workManagement/serviceProject";
  260. import serviceOption from "./configuration/serviceDialogList.json";
  261. //业务字典
  262. import { getDictionary } from "@/api/system/dictbiz";
  263. // 当前登录人
  264. import { getUserInfo } from "@/api/system/user";
  265. //用户组件
  266. import userOption from "./configuration/userList.json";
  267. import { getList } from "@/api/system/user";
  268. import { getDeptLazyTree} from "@/api/system/dept";
  269. //上传附件删除
  270. import { corpsbank } from "@/api/basicData/configuration"
  271. //事务
  272. import examineApprove from "@/components/examineApprove/index";
  273. //对象数组比较
  274. import { contrastObj,contrastList } from "@/util/contrastData";
  275. import _ from "lodash";
  276. export default {
  277. data() {
  278. return {
  279. id:'',
  280. loading: false,
  281. form:{},
  282. optionFrom:{},
  283. data: [],
  284. crudSelection:[],
  285. deptDicData:[],//任务部门数据
  286. serviceDialog:false,//服务导入窗口
  287. userDialog:false,//用户导入窗口
  288. //客户组件配置控制
  289. configuration:{
  290. multipleChoices:false,
  291. multiple:false,
  292. disabled:false,
  293. searchShow:true,
  294. collapseTags:false,
  295. placeholder:'请点击右边按钮选择',
  296. dicData:[]
  297. },
  298. page: {
  299. currentPage: 1,
  300. total: 0,
  301. pageSize: 10
  302. },
  303. detailsSelect: {},
  304. paymentTerm:[],
  305. //顶部from数据
  306. basicData: {
  307. column: [
  308. {
  309. label: '系统编号',
  310. prop: 'sysNo',
  311. disabled: true,
  312. rules: [
  313. {
  314. required: false,
  315. message: ' ',
  316. trigger: 'blur'
  317. }
  318. ]
  319. }, {
  320. label: '项目编码',
  321. prop: 'code',
  322. rules: [
  323. {
  324. required: true,
  325. message: ' ',
  326. trigger: 'blur'
  327. }
  328. ]
  329. }, {
  330. label: '项目名称',
  331. prop: 'cname',
  332. rules: [
  333. {
  334. required: true,
  335. message: ' ',
  336. trigger: 'blur'
  337. }
  338. ]
  339. }, {
  340. label: '客户名称',
  341. prop: 'corpId',
  342. },{
  343. label: '合同金额',
  344. prop: 'debitAmount',
  345. type:'unit',
  346. rules: [
  347. {
  348. required: true,
  349. message: ' ',
  350. trigger: 'blur'
  351. },
  352. {
  353. pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
  354. message: ' ',
  355. trigger: 'blur'
  356. },
  357. ]
  358. },
  359. {
  360. label: '首付金额',
  361. prop: 'advanceAmount',
  362. type:'unit',
  363. rules: [
  364. {
  365. pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
  366. message: ' ',
  367. trigger: 'blur'
  368. }
  369. ]
  370. },
  371. {
  372. label: '已收金额',
  373. prop: 'settlmentAmount',
  374. disabled: true,
  375. type:'unit',
  376. rules: [
  377. {
  378. pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
  379. message: ' ',
  380. trigger: 'blur'
  381. }
  382. ]
  383. },
  384. {
  385. label: '未收金额',
  386. type:'unit',
  387. prop: 'balanceAmount',
  388. disabled: true,
  389. rules: [
  390. {
  391. pattern:/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
  392. message: ' ',
  393. trigger: 'blur'
  394. }
  395. ]
  396. },
  397. {
  398. label: '总服务费',
  399. prop: 'serviceCharge',
  400. type:'unit',
  401. disabled: true,
  402. rules: [
  403. {
  404. pattern:/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
  405. message: ' ',
  406. trigger: 'blur'
  407. }
  408. ]
  409. },
  410. {
  411. label: '总代垫费',
  412. prop: 'matMoney',
  413. type:'unit',
  414. disabled: true,
  415. rules: [
  416. {
  417. pattern:/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
  418. message: ' ',
  419. trigger: 'blur'
  420. }
  421. ]
  422. },
  423. {
  424. label: '责任人',
  425. prop: 'corpAttn',
  426. }, {
  427. label: '承揽人',
  428. prop: 'salesName',
  429. },
  430. {
  431. label: '制单人',
  432. prop: 'createUserName',
  433. disabled: true
  434. }, {
  435. label: '制单日期',
  436. prop: 'createTime',
  437. type: 'datetime',
  438. valueFormat:"yyyy-MM-dd HH:mm:ss",
  439. format:"yyyy-MM-dd",
  440. disabled: true
  441. },
  442. {
  443. label: '电话',
  444. prop: 'corpTel',
  445. },
  446. {
  447. label: '收款方式',
  448. prop: 'paymentType',
  449. type:'select',
  450. dataType: "number",
  451. width: 120,
  452. dicUrl: "/api/blade-system/dict-biz/dictionary?code=affair_payment_term",
  453. props: {
  454. label: "dictValue",
  455. value: "dictKey"
  456. },
  457. },
  458. {
  459. label: '开始日期',
  460. prop: 'beginTime',
  461. valueFormat:"yyyy-MM-dd HH:mm:ss",
  462. format:"yyyy-MM-dd",
  463. type:'datetime',
  464. },
  465. {
  466. label: '结束日期',
  467. prop: 'endTime',
  468. valueFormat:"yyyy-MM-dd HH:mm:ss",
  469. format:"yyyy-MM-dd",
  470. type:'datetime',
  471. },
  472. {
  473. label: '备注',
  474. span: 24,
  475. prop: 'remark'
  476. }
  477. ],
  478. },
  479. optionTable: option,
  480. //上传文件
  481. upLoadOption: upLoadOption,
  482. upLoadData:[],
  483. upLoadForm:{},
  484. //服务窗口定义
  485. serviceTreeOption: {
  486. nodeKey: 'id',
  487. lazy: true,
  488. treeLoad: function(node, resolve) {
  489. const parentId = node.level === 0 ? 0 : node.data.id;
  490. getServiceTypeTree(parentId).then(res => {
  491. resolve(
  492. res.data.data.map(item => {
  493. return {
  494. ...item,
  495. leaf: !item.hasChildren
  496. };
  497. })
  498. );
  499. });
  500. },
  501. addBtn: false,
  502. menu: false,
  503. size: 'small',
  504. props: {
  505. labelText: '标题',
  506. label: 'title',
  507. value: 'value',
  508. children: 'children'
  509. }
  510. },
  511. serviceOption:serviceOption,
  512. serviceLoading:false,
  513. serviceData:[],
  514. servicePage:{
  515. currentPage: 1,
  516. total: 0,
  517. pageSize: 10
  518. },
  519. serviceSearch:{},
  520. serviceTreeDeptId:"",
  521. serviceSelectList:[],
  522. //用户窗口定义
  523. userTreeOption: {
  524. nodeKey: 'id',
  525. lazy: true,
  526. treeLoad: function (node, resolve) {
  527. const parentId = (node.level === 0) ? 0 : node.data.id;
  528. getDeptLazyTree(parentId).then(res => {
  529. resolve(res.data.data.map(item => {
  530. return {
  531. ...item,
  532. leaf: !item.hasChildren
  533. }
  534. }))
  535. });
  536. },
  537. addBtn: false,
  538. menu: false,
  539. size: 'small',
  540. props: {
  541. labelText: '标题',
  542. label: 'title',
  543. value: 'value',
  544. children: 'children'
  545. }
  546. },
  547. userTreeData:[],
  548. userOption:userOption,
  549. userLoading:false,
  550. userDataList:[],
  551. userSelection:[],
  552. userTreeDeptId:"",
  553. userForm:{},
  554. userPage:{
  555. currentPage: 1,
  556. total: 0,
  557. pageSize: 10
  558. },
  559. itemId:'',
  560. //请核窗口定义
  561. processDialog:false,
  562. pleaseCheckContact:startOption,
  563. pleaseCheckLoading:false,
  564. pleaseCheckData:[],
  565. pleaseCheckPage:{
  566. pageSize: 10,
  567. currentPage: 1,
  568. total: 0
  569. },
  570. //新旧数据比较
  571. oldData:[],
  572. oldUpLoadData:[],
  573. oldForm:{}
  574. };
  575. },
  576. created() {
  577. // 表格行编辑 输入框change事件
  578. //单价
  579. this.optionTable.column[5].change = function (val) {
  580. val.row.amount = val.row.quantity*val.value;
  581. }
  582. //数量
  583. this.optionTable.column[7].change = function (val) {
  584. val.row.amount = val.row.price*val.value;
  585. }
  586. this.$set(this.form,"debitAmount",0)
  587. this.$set(this.form,"advanceAmount",0)
  588. this.$set(this.form,"settlmentAmount",0)
  589. this.$set(this.form,"balanceAmount",0)
  590. if(this.$route.query.id){
  591. this.id = BigInt(this.$route.query.id);//字符串转数字 超长用BigInt
  592. this.getProjectDetail();
  593. }
  594. if(this.$route.query.itemId){
  595. getPidByItemId(this.$route.query.itemId).then((res)=>{
  596. this.id = res.data.data;
  597. this.getProjectDetail();
  598. })
  599. }
  600. const params = {
  601. code : "affair_payment_term"
  602. }
  603. getDictionary(params).then(res =>{
  604. this.paymentTerm = res.data.data;
  605. })
  606. },
  607. components:{
  608. examineApprove
  609. },
  610. mounted() {
  611. },
  612. methods: {
  613. //合计
  614. totalChange(row,type){
  615. let amountList = this.data.map(item => {
  616. if(item.amount){
  617. return parseFloat(item.amount);
  618. }else return 0
  619. });
  620. let serviceChargeList = this.data.map(item => {
  621. if(item.serviceCharge){
  622. return parseFloat(item.serviceCharge);
  623. }else return 0
  624. });
  625. let matMoneyList = this.data.map(item => {
  626. if(item.matMoney){
  627. return parseFloat(item.matMoney);
  628. }else return 0
  629. });
  630. if(type==='金额'){
  631. if(this.form.debitAmount){
  632. if(this.form.debitAmount < amountList.reduce((n,m) => n + m)){
  633. this.$message.error("明细列表合同金额不能大于总金额!")
  634. }
  635. }
  636. }
  637. if(type==='服务'){
  638. this.form.serviceCharge = serviceChargeList.reduce((n,m) => n + m)
  639. }
  640. if(type==='代垫'){
  641. this.form.matMoney = matMoneyList.reduce((n,m) => n + m)
  642. }
  643. if(row.serviceCharge && row.matMoney){
  644. if(row.amount < _.add(parseFloat(row.serviceCharge),parseFloat(row.matMoney))){
  645. this.$message.error("服务费代垫费不能超过合同金额!")
  646. row.serviceCharge = 0;
  647. row.matMoney = 0;
  648. }
  649. }
  650. },
  651. //查询明细
  652. getProjectDetail(pleaseCheck){
  653. if(this.id){
  654. projectDetail(this.id,"0,1,2,3,4,5").then(res =>{
  655. this.form = res.data.data;
  656. this.oldForm = Object.assign({},res.data.data);
  657. console.log(res.data.data.corpName)
  658. this.configuration.dicData = this.form.corpName;
  659. // this.configuration.dicData = res.data.data.corpName; //给客户名称赋值
  660. if(res.data.data.itemList){
  661. this.operationDetailList(res.data.data.itemList);
  662. }
  663. if(res.data.data.filesList){
  664. this.upLoadData = res.data.data.filesList
  665. this.oldUpLoadData = this.deepClone(res.data.data.filesList)
  666. }
  667. })
  668. }else{
  669. getSysNo().then(res =>{
  670. this.$set(this.form,"sysNo", res.data.data)
  671. let date = new Date();
  672. let strDate = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
  673. this.$set(this.form,"createTime",strDate)
  674. });
  675. getUserInfo().then(res =>{
  676. this.$set(this.form,"createUserName", res.data.data.name)
  677. })
  678. }
  679. },
  680. operationDetailList(itemList){
  681. this.data = itemList;
  682. this.oldData = this.deepClone(itemList)
  683. let status = [];
  684. this.data.forEach(item =>{
  685. item.status == 0 ? status.push(true) : status.push(false)
  686. })
  687. //如果 明细列表存在 请核之后的状态 禁止编辑一些输入框
  688. if(status.findIndex(item => item == false) == 0){
  689. this.basicData.column.forEach(item =>{
  690. if(item.prop == "code" || item.prop == "cname" || item.prop == "corpId" || item.prop == "debitAmount"){
  691. item.disabled = true
  692. this.configuration.disabled = true
  693. }
  694. })
  695. }else{
  696. this.basicData.column.forEach(item =>{
  697. if(item.prop == "code" || item.prop == "cname" || item.prop == "corpId" || item.prop == "debitAmount"){
  698. item.disabled = false
  699. this.configuration.disabled = false
  700. }
  701. })
  702. }
  703. },
  704. //删除列表后面的删除按钮触发触发(row, index, done)
  705. rowDel(row, index) {
  706. this.$confirm("确定将此明细删除?", {
  707. confirmButtonText: "确定",
  708. cancelButtonText: "取消",
  709. type: "warning"
  710. }).then(() => {
  711. this.data.splice(index,1)
  712. });
  713. },
  714. // 合同金额
  715. debitChange(val){
  716. if(val){
  717. if(!this.form.settlmentAmount){
  718. this.$set(this.form,"balanceAmount",val)
  719. }
  720. }
  721. // if(this.form.debitAmount){
  722. // if(this.form.serviceCharge && parseFloat(this.form.serviceCharge) > parseFloat(this.form.debitAmount)){
  723. // this.$message.warning('服务费不得大于合同金额!')
  724. // this.$set(this.form,"serviceCharge","");
  725. // return
  726. // }
  727. // if(this.form.matMoney && parseFloat(this.form.matMoney) > parseFloat(this.form.debitAmount)){
  728. // this.$message.warning('代垫费费不得大于合同金额!')
  729. // this.$set(this.form,"matMoney","");
  730. // return
  731. // }
  732. // if(this.form.serviceCharge && this.form.matMoney){
  733. // if(_.add(parseFloat(this.form.serviceCharge),parseFloat(this.form.matMoney))> parseFloat(this.form.debitAmount)){
  734. // this.$message.warning('服务费代垫费总和不得大于合同金额!')
  735. // this.$set(this.form,"serviceCharge","");
  736. // this.$set(this.form,"matMoney","");
  737. // }
  738. // }
  739. // }
  740. },
  741. //新单
  742. addMainProject(){
  743. this.$confirm("需先将此单据保存", {
  744. confirmButtonText: "确定",
  745. cancelButtonText: "取消",
  746. type: "warning"
  747. }).then(()=>{
  748. this.editMainProject(10010);
  749. })
  750. },
  751. openPleaseCheckDialog(){
  752. this.processDialog = true;
  753. this.itemId = this.crudSelection[0].id //记得不能写死
  754. },
  755. //请核之前
  756. beforePleaseCheck(){
  757. if(this.crudSelection){
  758. let id = [];
  759. let result = [];
  760. this.crudSelection.forEach(item=>{
  761. // 新录入状态下 才可提交审核
  762. item.id ? id.push(true) : id.push(false) //如果没有id并且为新录入 提示保存
  763. item.strStatus === "录入" ? result.push(true) : result.push(false) //判断所有的是否为录入状态
  764. })
  765. if(id.findIndex(item => item != true) == -1){
  766. if(result.findIndex(item => item != true) == -1){
  767. if(contrastObj(this.form,this.oldForm) || contrastList(this.data,this.oldData)){ //判断是否改动过此页面
  768. this.$confirm("您已改动此页面,请先保存之后在请核?", "提示", {
  769. confirmButtonText: "保存",
  770. cancelButtonText: "取消",
  771. type: "warning",
  772. }).then(() => {
  773. this.editMainProject();
  774. }).catch(()=>{
  775. return
  776. })
  777. }else{
  778. this.pleaseCheck()
  779. // this.openPleaseCheckDialog();
  780. }
  781. }else{
  782. this.$message({
  783. type: "error",
  784. message: "请核数据中存在已请核数据!"
  785. });
  786. return
  787. }
  788. }else{
  789. this.$confirm("列表内存在新录入数据,是否先保存此数据?", {
  790. confirmButtonText: "确定",
  791. cancelButtonText: "取消",
  792. type: "warning"
  793. }).then(() => {
  794. this.editMainProject();
  795. })
  796. }
  797. }
  798. },
  799. //新增 修改
  800. editMainProject(pleaseCheck){
  801. this.$refs["form"].validate((valid) => {
  802. //校验明细列表
  803. let valids = true;
  804. if(this.data.length !=0){
  805. this.data.forEach((item) =>{
  806. if((item.userid =="" || !item.deptid) && valids){
  807. this.$message({
  808. type: "warning",
  809. message: "请检查明细列表第 "+(item.$index +1 )+" 行必填项"
  810. });
  811. valids = false;
  812. }
  813. })
  814. }
  815. if(valid && valids){
  816. const params = {
  817. ...this.form,
  818. itemList:this.data,
  819. filesList:this.upLoadData
  820. }
  821. editMianProject(params).then(res =>{
  822. this.id = res.data.data
  823. if(pleaseCheck === 10010){ //复制新单新单
  824. this.$router.push({
  825. path: "/mainItems_detailsPage",
  826. query: {id: ''},
  827. });
  828. //清空关键信息
  829. this.form = {}
  830. this.data = []
  831. this.upLoadData = []
  832. this.id = ''
  833. }else if(pleaseCheck === 10001){ //返回列表保存数据
  834. this.$message({
  835. type: "success",
  836. message: "操作成功!"
  837. });
  838. this.goBackPage();
  839. }else{
  840. this.$message({
  841. type: "success",
  842. message: "操作成功!"
  843. });
  844. this.getProjectDetail()
  845. }
  846. })
  847. }
  848. })
  849. },
  850. //请核
  851. pleaseCheck(){
  852. this.crudSelection.forEach(item =>{
  853. updateItemStatus(this.data[item.$index].id,1).then(res =>{
  854. if(res.data.success){
  855. }
  856. })
  857. this.$message({
  858. type: "success",
  859. message: "请核成功!"
  860. });
  861. //刷新列表
  862. this.getProjectDetail();
  863. })
  864. },
  865. //返回主营项目列表
  866. backToList(){
  867. if(contrastObj(this.form,this.oldForm) || contrastList(this.data,this.oldData)
  868. || contrastList(this.upLoadData,this.oldUpLoadData)
  869. ){
  870. this.$confirm("是否保存当前页面?", "提示", {
  871. confirmButtonText: "保存",
  872. cancelButtonText: "取消",
  873. type: "warning",
  874. }).then(() => {
  875. this.editMainProject(10001)
  876. }).catch(()=>{
  877. this.goBackPage();
  878. })
  879. }else{
  880. this.goBackPage();
  881. }
  882. },
  883. //返回列表判断返回那一个
  884. goBackPage(){
  885. if(this.$route.query.itemId){ //如果是从统计列表跳转过来的 那么在调回去
  886. this.$router.push({
  887. path: '/statistical_List',
  888. query: {}
  889. });
  890. }else{
  891. this.$router.$avueRouter.closeTag();
  892. this.$router.push({
  893. path: '/workManagement/main-items/list',
  894. query: {}
  895. });
  896. }
  897. },
  898. //点击修改或保存时触发
  899. rowCellTwo(row,index){
  900. this.$refs.crud.rowCell(row, index);
  901. },
  902. //选择时
  903. selectionChange(row){
  904. this.crudSelection = row;
  905. },
  906. //新增修改时保存触发
  907. rowSave(row, done, loading) {
  908. done()
  909. },
  910. rowUpdate(row, index, done, loading) {
  911. done(row)
  912. },
  913. searchChange(params, done) {
  914. this.getList(this.page, params);
  915. done();
  916. },
  917. sizeChange(val) {
  918. this.page.pageSize = val;
  919. this.getList();
  920. },
  921. currentChange(val) {
  922. this.page.currentPage = val;
  923. this.getList();
  924. },
  925. saveColumn(row, column) {
  926. console.log(row, column);
  927. },
  928. //上传文件保存
  929. upLoadSave(row, done, loading){
  930. this.upLoadData.push(row)
  931. done()
  932. },
  933. //修改附件上传触发
  934. upLoadUpdate(row, done){
  935. done(row);
  936. },
  937. //删除附件上传触发
  938. upLoadDel(row, index,){
  939. this.$confirm("确定将选择数据删除?", {
  940. confirmButtonText: "确定",
  941. cancelButtonText: "取消",
  942. type: "warning"
  943. }).then(() => {
  944. if (row.id){
  945. corpsbank(row.id).then(res=>{
  946. if(res.data.success){
  947. this.$message({
  948. type: "success",
  949. message: "操作成功!"
  950. });
  951. this.bankOfDepositData.splice(index, 1);
  952. }
  953. })
  954. }else {
  955. this.$message({
  956. type: "success",
  957. message: "操作成功!"
  958. });
  959. this.bankOfDepositData.splice(index, 1);
  960. }
  961. })
  962. },
  963. //服务窗口事件
  964. serviceNodeClick(data) {
  965. this.serviceTreeDeptId = data.id;
  966. this.serviceOnLoad(this.servicePage);
  967. },
  968. serviceRefreshChange(){
  969. this.serviceOnLoad(this.servicePage, this.serviceSearch)
  970. },
  971. serviceSearchChange(params, done){
  972. this.serviceOnLoad(this.servicePage, params)
  973. done();
  974. },
  975. serviceSelectionChange(row){
  976. this.serviceSelectList = row;
  977. },
  978. serviceOnLoad(page, params = {}) {
  979. this.serviceLoading = true;
  980. getServiceProjectList(page.currentPage, page.pageSize, params, this.serviceTreeDeptId).then(res => {
  981. this.serviceData = res.data.data.records
  982. this.servicePage.total = res.data.data.total
  983. this.serviceLoading = false
  984. })
  985. },
  986. serviceConfirm(){
  987. if(this.serviceSelectList.length != 0){
  988. this.serviceSelectList.forEach((item)=>{
  989. const params = {
  990. strStatus:"录入",
  991. pname:item.cname,
  992. remarks:item.remarks,
  993. price:item.price,
  994. unit:item.unit,
  995. frequency:item.rate,
  996. }
  997. this.$refs.crud.rowCellAdd(params);
  998. this.$refs.crud.rowCell(item, this.optionFrom.length-1)
  999. })
  1000. }
  1001. this.serviceSelectList = []
  1002. this.serviceDialog = false
  1003. this.$message({
  1004. type: "success",
  1005. message: "导入成功!"
  1006. });
  1007. },
  1008. //用户窗口事件
  1009. selectUser(row){
  1010. this.userDialog = true
  1011. this.detailsSelect = row.$index;
  1012. },
  1013. userSearchChange(params, done){
  1014. this.userOnLoad(this.userPage, params);
  1015. done()
  1016. },
  1017. userSearchReset(){
  1018. },
  1019. userRefreshChange(){
  1020. this.userOnLoad(this.userPage)
  1021. },
  1022. userSelectionChange(row){
  1023. this.userSelection = row;
  1024. },
  1025. userOnLoad(page,params={}){
  1026. this.userLoading = true;
  1027. getList(page.currentPage, page.pageSize, params, this.userTreeDeptId).then(res => {
  1028. this.userDataList = res.data.data.records
  1029. this.userPage.total = res.data.data.total
  1030. this.userLoading = false;
  1031. });
  1032. },
  1033. userNodeClick(data){
  1034. this.userTreeDeptId = data.id;
  1035. this.userOnLoad(this.userPage);
  1036. },
  1037. //确定
  1038. userConfirm(){
  1039. if(this.userSelection){
  1040. this.data[this.detailsSelect].userid = this.userSelection[0].id;
  1041. this.$set(this.data[this.detailsSelect],'userName',this.userSelection[0].realName)
  1042. this.userDialog = !this.userDialog
  1043. }
  1044. },
  1045. dialogProcessClose(){
  1046. this.processDialog = false
  1047. this.getProjectDetail()
  1048. },
  1049. },
  1050. };
  1051. </script>
  1052. <style scoped lang="scss">
  1053. .main-head {
  1054. position: fixed;
  1055. top: 105px;
  1056. width: 100%;
  1057. margin-left: -10px;
  1058. height: 62px;
  1059. background: #ffffff;
  1060. box-shadow: 0 4px 12px 0px rgba(232, 232, 235, 1);
  1061. z-index: 999;
  1062. }
  1063. .upper_right_button{
  1064. display: flex;
  1065. position: fixed;
  1066. right: 12px;
  1067. top: 47px;
  1068. }
  1069. .main-back {
  1070. cursor: pointer;
  1071. line-height: 62px;
  1072. font-size: 16px;
  1073. color: #323233;
  1074. font-weight: 400;
  1075. }
  1076. .avue-tree {
  1077. overflow: hidden;
  1078. max-height: 660px;
  1079. }
  1080. ::v-deep .el-form-item {
  1081. margin-bottom: 0;
  1082. }
  1083. ::v-deep .el-form-item__content{
  1084. line-height: 32px;
  1085. }
  1086. </style>