details.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. <template>
  2. <div class="edit">
  3. <van-nav-bar title="报销凭证详情" left-text="返回" @click-left="back" fixed left-arrow />
  4. <van-form class="edit_form" label-width="140">
  5. <!-- 报销人 -->
  6. <van-field
  7. label="报销人"
  8. @click="ownerIdShowCli(1)"
  9. readonly
  10. clickable
  11. required
  12. >
  13. <template #input>
  14. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName' :openid='formshowText.name'></TranslationOpenDataText></span>
  15. <span v-else>{{formshowText.name}}</span>
  16. </template>
  17. </van-field>
  18. <div v-if="auditTypeItem.auditType == 2">
  19. <van-field label="第一审核人" @click="ownerIdShowCli(2)" readonly clickable required :disabled="editForm.reviewProcess > 0">
  20. <template #input>
  21. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  22. :openid='firstCheckerText.name'></TranslationOpenDataText></span>
  23. <span v-else>{{ firstCheckerText.name }}</span>
  24. </template>
  25. </van-field>
  26. <van-field label="第二审核人" @click="ownerIdShowCli(3)" readonly clickable required :disabled="editForm.reviewProcess > 1">
  27. <template #input>
  28. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  29. :openid='secondCheckerText.name'></TranslationOpenDataText></span>
  30. <span v-else>{{ secondCheckerText.name }}</span>
  31. </template>
  32. </van-field>
  33. </div>
  34. <van-popup v-model="ownerIdShow" position="bottom" v-if="false">
  35. <van-picker
  36. value-key="name"
  37. show-toolbar
  38. :columns="userList"
  39. @confirm="ownerIdChange"
  40. @cancel="
  41. ownerIdShow = false;
  42. $forceUpdate();
  43. "
  44. />
  45. </van-popup>
  46. <!-- 填报日期 -->
  47. <van-field
  48. v-model="editForm.createDate"
  49. label="填报日期"
  50. @click="createDateShow = true"
  51. readonly
  52. clickable
  53. required
  54. ></van-field>
  55. <van-popup v-model="createDateShow" position="bottom" v-if="canEdit">
  56. <van-datetime-picker
  57. type="date"
  58. title="选择填报日期"
  59. @confirm="createDateChange"
  60. @cancel="
  61. createDateShow = false;
  62. $forceUpdate();
  63. "
  64. v-model="currentDate1"
  65. :min-date="minDate"
  66. :max-date="maxDate"
  67. />
  68. </van-popup>
  69. <!-- 发票张数 -->
  70. <van-field label="发票张数" :readonly="!canEdit" v-if="user.timeType.easyExpense==0 && editForm.type != 14454">
  71. <template #input>
  72. <van-stepper v-model="editForm.ticketNum" :disabled="!canEdit" disable-input @plus="ticNumChange(1)" @minus="ticNumChange(0)" />
  73. </template>
  74. </van-field>
  75. <!-- 费用类型 -->
  76. <van-field v-model="editForm.type" label="费用主类型" @click="typeShow = true" readonly clickable>
  77. <template #input>{{expenseMainType.text}}</template>
  78. </van-field>
  79. <van-popup v-model="typeShow" position="bottom" v-if="canEdit">
  80. <van-picker
  81. show-toolbar
  82. :columns="typeList"
  83. @confirm="typeChange"
  84. @cancel="typeShow = false;$forceUpdate();"/>
  85. </van-popup>
  86. <van-field label="设备归属人" @click="equipmentOwnershipVisable = true" v-if="editForm.type == 14454">
  87. <template #input>
  88. {{ equipmentOwner.name }}
  89. </template>
  90. </van-field>
  91. <van-popup v-model="equipmentOwnershipVisable" position="bottom">
  92. <van-picker show-toolbar :columns="equipmentOwnerList" @confirm="deviceTypeChange"
  93. @cancel="equipmentOwnershipVisable = false; $forceUpdate();" />
  94. </van-popup>
  95. <!-- 备注 -->
  96. <van-field v-model="editForm.remark" label="备注" :readonly="!canEdit" type="textarea"></van-field>
  97. <!-- 发票 -->
  98. <van-field label="发票" readonly>
  99. <template #input
  100. >总费用: ¥{{ totalCost }}</template
  101. >
  102. </van-field>
  103. <div class="invoice" v-if="invoiceList.length != 0">
  104. <div
  105. v-for="(item, index) in invoiceList"
  106. :key="item.id"
  107. style="position: relative"
  108. :class="index == 0 ? '' : 'invoice_item'"
  109. >
  110. <van-icon
  111. name="delete-o"
  112. class="deletebtn"
  113. @click="deleteInvoice(index)"
  114. v-if="canEdit && index != 0"
  115. />
  116. <van-field
  117. label="所属项目:"
  118. v-model="item.projectId"
  119. @click="(in_projectShow = true), (invoiceIndex = index)"
  120. readonly
  121. clickable
  122. required
  123. >
  124. <template #input>{{
  125. formshowText.inProjectName[index]
  126. }}</template>
  127. </van-field>
  128. <van-field
  129. label="费用日期:"
  130. v-model="item.happenDate"
  131. @click="(in_dateShow = true), (invoiceIndex = index)"
  132. readonly
  133. clickable
  134. required
  135. ></van-field>
  136. <van-field
  137. label="发票种类:"
  138. v-model="item.invoiceType"
  139. @click="(in_typeShow = true), (invoiceIndex = index)"
  140. readonly
  141. clickable
  142. required
  143. v-if="user.timeType.easyExpense==0"
  144. >
  145. <template #input>{{
  146. inTypeList[item.invoiceType]
  147. }}</template>
  148. </van-field>
  149. <van-field
  150. label="费用类型:"
  151. v-model="item.expenseType"
  152. @click="(in_exTypeShow = true), (invoiceIndex = index)"
  153. readonly
  154. clickable
  155. required
  156. ></van-field>
  157. <van-field
  158. :label="`${user.timeType.easyExpense==0?'费用金额(含税)':'费用金额'}:`"
  159. v-model="item.amount"
  160. type="number"
  161. :readonly="!canEdit"
  162. required
  163. ></van-field>
  164. <van-field
  165. label="发票号:"
  166. v-model="item.invoiceNo"
  167. readonly
  168. v-if="user.timeType.easyExpense==0"
  169. ></van-field>
  170. <van-field
  171. label="税率%:"
  172. v-model="item.taxPercent"
  173. :readonly="!canEdit"
  174. v-if="user.timeType.easyExpense==0"
  175. ></van-field>
  176. <van-field
  177. label="税额:"
  178. readonly
  179. v-if="user.timeType.easyExpense==0"
  180. ><template #input>¥{{getTaxValue(item.amount,item.taxPercent)}}</template></van-field>
  181. <van-field label="备注:" v-model="item.remark" :readonly="!canEdit"></van-field>
  182. <van-field
  183. @click="invoiceIndex = index"
  184. :clickable="!canEdit"
  185. label-width="0em"
  186. >
  187. <template #input>
  188. <div class="imgListVan">
  189. <div>报销凭证:</div>
  190. <div class="vanUploaderImg">
  191. <!-- <van-uploader
  192. v-model="uploader[index]"
  193. :before-read="beforeRead"
  194. :after-read="afterRead"
  195. @delete="item.pic = null"
  196. :max-count="1"
  197. :disabled="!canEdit"
  198. :deletable="canEdit"
  199. /> -->
  200. <van-uploader
  201. v-model="uploader[index]"
  202. :before-read="beforeRead"
  203. :after-read="afterRead"
  204. @delete="(file, Item) => {deteleImg(file, Item, index)}"
  205. :max-count="10"
  206. :disabled="!canEdit"
  207. :deletable="canEdit"
  208. multiple
  209. />
  210. </div>
  211. </div>
  212. </template>
  213. </van-field>
  214. <van-field
  215. label="状态" v-if="user.companyId != mechanicalCompanyId">
  216. <template #input>
  217. <span :class="statusClass[item.status]">{{
  218. statusList[item.status] }}</span>
  219. </template>
  220. </van-field>
  221. <van-field
  222. label="审核人" v-if="item.auditorName && user.companyId != mechanicalCompanyId">
  223. <template #input>
  224. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName' :openid='item.auditorName'></TranslationOpenDataText></span>
  225. <span v-else>{{item.auditorName}}</span>
  226. </template>
  227. </van-field>
  228. <van-field
  229. label="操作" v-if="isAudit && item.isIncharger && item.status == 1"
  230. >
  231. <template #input>
  232. <div style="float:right;">
  233. <van-button type="info" :loading="item.approveLoading"
  234. @click.stop="approveSingle(item)">通过</van-button>
  235. <van-button style="margin-left:25px" type="danger" :loading="item.approveLoading"
  236. @click.stop="denySingle(item)">驳回</van-button>
  237. </div>
  238. </template>
  239. </van-field>
  240. </div>
  241. </div>
  242. <div class="addinvoice" v-if="canEdit"><van-button size="small" icon="plus" type="info" plain hairline @click="addInvoice">添加发票</van-button></div>
  243. <!-- 发票-popup -->
  244. <span>
  245. <!-- 所属项目 -->
  246. <van-popup v-model="in_projectShow" position="bottom" v-if="canEdit">
  247. <van-picker
  248. value-key="projectName"
  249. show-toolbar
  250. :columns="inProjectList"
  251. @confirm="inProjectChange"
  252. @cancel="
  253. in_projectShow = false;
  254. $forceUpdate();
  255. "
  256. />
  257. </van-popup>
  258. <!-- 费用日期 -->
  259. <van-popup v-model="in_dateShow" position="bottom" v-if="canEdit">
  260. <van-datetime-picker
  261. type="date"
  262. title="选择费用日期"
  263. v-model="currentDate2"
  264. @confirm="inDateChange"
  265. @cancel="
  266. in_dateShow = false;
  267. $forceUpdate();
  268. "
  269. :min-date="minDate"
  270. :max-date="maxDate"
  271. />
  272. </van-popup>
  273. <!-- 发票种类 -->
  274. <van-popup v-model="in_typeShow" position="bottom" v-if="canEdit && user.timeType.easyExpense==0" >
  275. <van-picker
  276. show-toolbar
  277. :columns="inTypeList"
  278. @confirm="inTypeChange"
  279. @cancel="
  280. in_typeShow = false;
  281. $forceUpdate();
  282. "
  283. />
  284. </van-popup>
  285. <!-- 费用类型 -->
  286. <van-popup v-model="in_exTypeShow" position="bottom" v-if="canEdit">
  287. <van-picker
  288. value-key="typeName"
  289. show-toolbar
  290. :columns="inexTypeList"
  291. @confirm="inexTypeChange"
  292. @cancel="
  293. in_exTypeShow = false;
  294. $forceUpdate();
  295. "
  296. />
  297. </van-popup>
  298. </span>
  299. </van-form>
  300. <!-- 提交 -->
  301. <div class="form_btn" style="position: fixed; bottom: 0px; width: 100%" v-if="canEdit">
  302. <div style="padding-bottom: 10px">
  303. <van-button
  304. square
  305. block
  306. type="info"
  307. @click="submitExpense"
  308. :loading="confirmLoading"
  309. style="width: 100%; float: left"
  310. >提交</van-button
  311. >
  312. </div>
  313. </div>
  314. </div>
  315. </template>
  316. <script>
  317. export default {
  318. data() {
  319. return {
  320. statusList: ['审核通过', '待审核', '已驳回', '已撤销'],
  321. statusClass: ['', 'waiting', 'rejected', ''],
  322. isAudit: false,
  323. user: JSON.parse(localStorage.userInfo),
  324. canEdit: this.$route.params.canEdit,
  325. currentDate1 : new Date(),
  326. currentDate2 : new Date(),
  327. minDate: new Date(2020,0,1),
  328. maxDate: new Date(2025,11,31),
  329. editForm: {
  330. ownerId: '',
  331. createDate: '',
  332. ticketNum: 0,
  333. type: 0,
  334. remark: ''
  335. },
  336. invoiceList: [],
  337. confirmLoading: false,
  338. formshowText: {
  339. name: '',
  340. inProjectName: []
  341. },
  342. ownerIdShow: false,
  343. userList: [],
  344. createDateShow: false,
  345. typeShow: false,
  346. typeList: ['一般','差旅','外包'],
  347. invoiceIndex: 0,
  348. in_projectShow: false,
  349. inProjectList: [],
  350. in_dateShow: false,
  351. in_typeShow: false,
  352. inTypeList: ['增值税专用发票','增值税普通发票'],
  353. in_exTypeShow: false,
  354. allexTypeList: [],
  355. inexTypeList: [],
  356. uploader: [[]],
  357. expenseMainType:{
  358. text:''
  359. },
  360. firstCheckerText: {},
  361. secondCheckerText: {},
  362. auditTypeItem: {},
  363. mechanicalCompanyId: 4811,
  364. equipmentOwnerList: [],
  365. equipmentOwner: {},
  366. equipmentOwnershipVisable: false
  367. }
  368. },
  369. computed: {
  370. totalCost(){
  371. let costnum = 0
  372. for(let i in this.invoiceList){
  373. costnum += (this.invoiceList[i].amount ? parseFloat(this.invoiceList[i].amount) : 0)
  374. }
  375. return costnum.toFixed(2)
  376. }
  377. },
  378. filters: {
  379. numtosum(value) {
  380. if (value == undefined || !value) return '0.00'
  381. value = value.toFixed(2)
  382. const intPart = Math.trunc(value)
  383. const intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
  384. let floatPart = '.00'
  385. const valueArray = value.toString().split('.')
  386. if (valueArray.length === 2) { // 有小数部分
  387. floatPart = valueArray[1].toString() // 取得小数部分
  388. return intPartFormat + '.' + floatPart
  389. }
  390. return intPartFormat + floatPart
  391. },
  392. },
  393. mounted() {
  394. console.log(this.$route.params);
  395. this.isAudit = this.$route.params.isAudit;
  396. this.getAuditType()
  397. this.getDetail()
  398. if(this.canEdit){
  399. this.getProjectList()
  400. }
  401. this.getExpensMainTypes()
  402. if(this.user.companyId == this.mechanicalCompanyId) {
  403. this.getEquipmentOwnerList()
  404. }
  405. },
  406. methods: {
  407. deviceTypeChange(value) {
  408. console.log(value)
  409. this.equipmentOwner = value
  410. this.equipmentOwnershipVisable = false
  411. },
  412. getEquipmentOwnerList() {
  413. this.$axios.post("/equipment-owner/getList", {})
  414. .then(res => {
  415. if (res.code == "ok") {
  416. this.equipmentOwnerList = (res.data || []).map(item => {
  417. return {
  418. name: item.equipmentOwner,
  419. id: item.id,
  420. text: item.equipmentOwner
  421. };
  422. });
  423. } else {
  424. this.$toast.fail(res.msg || res.code || '获取失败');
  425. }
  426. }).catch(err => { this.$toast.clear(); console.log(err) });
  427. },
  428. back(){
  429. history.back();
  430. },
  431. formatDate(date) {
  432. let mon = date.getMonth() + 1
  433. return `${date.getFullYear()}-${mon<10?'0'+mon:mon}-${date.getDate()<10?'0'+date.getDate():date.getDate()}`;
  434. },
  435. getTaxValue(amount,percent){
  436. let per = percent / 100
  437. let amo = amount / (1 + per)*per
  438. return amo.toFixed(2)
  439. },
  440. // costCount(){
  441. // let costnum = 0
  442. // for(let i in this.invoiceList){
  443. // costnum += this.invoiceList[i].amount*1
  444. // }
  445. // this.totalCost = costnum
  446. // },
  447. ownerIdChange(value,key){
  448. this.editForm.ownerId = value.id
  449. this.formshowText.name = value.name
  450. this.ownerIdShow = false
  451. },
  452. createDateChange(value,key){
  453. this.editForm.createDate = this.formatDate(value)
  454. this.createDateShow = false
  455. },
  456. typeChange(value,key){
  457. this.editForm.type = value.id
  458. this.expenseMainType.text=value.name
  459. this.typeShow = false
  460. for(let i in this.invoiceList){
  461. this.invoiceList[i].expenseType=''
  462. }
  463. console.log(this.editForm.type)
  464. this.inexTypeList = this.allexTypeList.filter(a=>a.mainType == this.editForm.type)
  465. },
  466. ticNumChange(value){
  467. if(value){
  468. this.invoiceList.push({
  469. projectId: '',
  470. happenDate: '',
  471. invoiceType: '',
  472. expenseType: '',
  473. amount: '',
  474. invoiceNo: '',
  475. taxPercent: '',
  476. taxValue: '',
  477. remark: '',
  478. pic: '',
  479. })
  480. }else{
  481. this.invoiceList.pop()
  482. }
  483. },
  484. getExpensMainTypes(){
  485. this.$axios.post("/expense-main-type/list", {})
  486. .then(res => {
  487. if(res.code == "ok") {
  488. for(var i in res.data) {
  489. res.data[i].text = res.data[i].name
  490. }
  491. this.typeList=res.data
  492. if(!this.editForm.type) {
  493. this.expenseMainType.text=res.data[0].name
  494. this.editForm.type=res.data[0].id
  495. }
  496. this.getExTypeList
  497. } else {
  498. this.$toast.fail('获取失败');
  499. }
  500. }).catch(err=> {this.$toast.clear();console.log(err)});
  501. },
  502. addInvoice(){
  503. this.invoiceList.push({
  504. projectId: '',
  505. happenDate: '',
  506. invoiceType: '',
  507. expenseType: '',
  508. amount: '',
  509. invoiceNo: '',
  510. taxPercent: '',
  511. taxValue: '',
  512. remark: '',
  513. pic: '',
  514. })
  515. this.uploader.push([])
  516. this.editForm.ticketNum = this.invoiceList.length
  517. },
  518. deleteInvoice(index){
  519. this.invoiceList.splice(index,1)
  520. this.editForm.ticketNum = this.invoiceList.length
  521. this.uploader.splice(index,1)
  522. },
  523. inProjectChange(value,key){
  524. this.formshowText.inProjectName[this.invoiceIndex] = value.projectName
  525. this.invoiceList[this.invoiceIndex].projectId = value.id
  526. this.in_projectShow = false
  527. },
  528. inDateChange(value,key){
  529. this.invoiceList[this.invoiceIndex].happenDate = this.formatDate(value)
  530. this.in_dateShow = false
  531. },
  532. inTypeChange(value,key){
  533. this.invoiceList[this.invoiceIndex].invoiceType = key
  534. this.in_typeShow = false
  535. },
  536. inexTypeChange(value,key){
  537. this.invoiceList[this.invoiceIndex].expenseType = value.typeName
  538. this.in_exTypeShow = false
  539. },
  540. beforeRead(file){
  541. // if(file.type != 'image/jpeg' && file.type != 'image/png'){
  542. // this.$toast.fail('请选择jpg或png格式的图片')
  543. // return false
  544. // }
  545. // return true
  546. let newFile = Array.isArray(file) ? file : [file]
  547. for(var i in newFile) {
  548. const fileItem = newFile[i]
  549. if (fileItem.type != 'image/jpeg' && fileItem.type != 'image/png' && fileItem.type != 'image/jpg') {
  550. this.$toast.fail('请选择jpg或png格式的图片')
  551. return false
  552. }
  553. }
  554. return true
  555. },
  556. afterRead(file){
  557. // let formData = new FormData();
  558. // formData.append("multipartFile", file.file);
  559. // this.$axios.post("/common/uploadFile", formData)
  560. // .then(res => {
  561. // if(res.code == "ok") {
  562. // this.invoiceList[this.invoiceIndex].pic = res.data
  563. // } else {
  564. // this.$toast.fail('上传失败');
  565. // this.uploader[this.invoiceIndex] = []
  566. // }
  567. // }).catch(err=> {this.$toast.clear();console.log(err);this.uploader[this.invoiceIndex]=[]});
  568. let newFile = Array.isArray(file) ? file : [file]
  569. let formData = new FormData();
  570. for(var i in newFile) {
  571. formData.append("multipartFiles", newFile[i].file);
  572. }
  573. this.$axios.post("/common/uploadFileArray", formData)
  574. .then(res => {
  575. if (res.code == "ok") {
  576. let newPic = this.invoiceList[this.invoiceIndex].pic || []
  577. let newData = res.data.split(';')
  578. this.invoiceList[this.invoiceIndex].pic = [...newPic, ...newData]
  579. console.log(this.invoiceList[this.invoiceIndex].pic, '<=== 合计图片')
  580. } else {
  581. this.$toast.fail('上传失败');
  582. this.uploader[this.invoiceIndex] = []
  583. }
  584. }).catch(err => { this.$toast.clear(); console.log(err); this.uploader[this.invoiceIndex] = [] });
  585. },
  586. // 删除图片
  587. deteleImg(file, item, arrIndex) {
  588. let index = item.index
  589. this.invoiceList[arrIndex].pic = this.invoiceList[arrIndex].pic.filter((item,i) => i != index)
  590. },
  591. submitExpense(){
  592. if(!this.editForm.ownerId){
  593. this.$toast.fail('请选择报销人')
  594. return
  595. }
  596. if(!this.editForm.createDate){
  597. this.$toast.fail('请选择填报日期')
  598. return
  599. }
  600. if(this.auditTypeItem.auditType == 2) {
  601. if(!this.firstCheckerText.id || !this.secondCheckerText.id) {
  602. this.$toast.fail(`${!this.firstCheckerText.id ? '请选择第一审核人' : '请选择第二审核人'}`)
  603. return
  604. } else {
  605. this.editForm.firstCheckerId = this.firstCheckerText.id
  606. this.editForm.secondCheckerId = this.secondCheckerText.id
  607. }
  608. }
  609. let required1 = false
  610. let required2 = false
  611. let required3 = false
  612. let required4 = false
  613. let required5 = false
  614. for(let i in this.invoiceList){
  615. if(!this.invoiceList[i].projectId){
  616. required1 = '所属项目'
  617. }
  618. if(!this.invoiceList[i].happenDate){
  619. required2 = '费用日期'
  620. }
  621. if(!this.invoiceList[i].invoiceType){
  622. required3 = '发票种类'
  623. }
  624. if(!this.invoiceList[i].expenseType){
  625. required4 = '费用类型'
  626. }
  627. if(!this.invoiceList[i].amount){
  628. required5 = '费用金额(含税)'
  629. }
  630. }
  631. if(required1 || required2 || required3 || required4 || required5){
  632. let requiredStr = (required1 ? required1 + '、' : '')
  633. + (required2 ? required2 + '、' : '')
  634. + (required3 ? required3 + '、' : '')
  635. + (required4 ? required4 + '、' : '')
  636. + (required5 ? required5 + '、' : '')
  637. requiredStr = requiredStr.substring(0,requiredStr.length - 1)
  638. this.$toast.fail('请添加发票的[' + requiredStr + ']')
  639. return
  640. }
  641. let newList = JSON.parse(JSON.stringify(this.invoiceList))
  642. for(let i in newList) {
  643. if(newList[i].pic) {
  644. newList[i].pic = newList[i].pic.join(',')
  645. }
  646. }
  647. delete this.editForm.invoiceList
  648. // this.editForm.items = JSON.stringify(this.invoiceList)
  649. this.editForm.items = JSON.stringify(newList)
  650. this.editForm.totalAmount = this.totalCost
  651. this.confirmLoading = true
  652. this.$axios.post("/expense-sheet/add", this.editForm)
  653. .then(res => {
  654. if(res.code == "ok") {
  655. this.$toast.success('提交成功')
  656. this.confirmLoading = false
  657. this.back()
  658. } else {
  659. this.confirmLoading = false
  660. this.$toast.fail(res.msg || res.code || '获取失败');
  661. }
  662. }).catch(err=> {this.confirmLoading = false;this.$toast.clear();console.log(err)});
  663. },
  664. getDetail(){
  665. this.$axios.post("/expense-sheet/getDetail", {id: this.$route.params.id})
  666. .then(res => {
  667. if(res.code == "ok") {
  668. this.editForm = res.data
  669. if(this.canEdit){this.getExTypeList()}
  670. this.formshowText.name = res.data.ownerName
  671. this.totalCost = res.data.totalAmount
  672. this.invoiceList = res.data.invoiceList
  673. this.expenseMainType.text = res.data.expenseMainTypeName
  674. this.equipmentOwner = {
  675. id: res.data.equipmentOwnerId,
  676. text: res.data.equipmentOwnerName,
  677. name: res.data.equipmentOwnerName
  678. }
  679. if(this.auditTypeItem.auditType == 2) {
  680. this.firstCheckerText = {
  681. id: res.data.firstCheckerId,
  682. name: res.data.firstCheckerName
  683. }
  684. this.secondCheckerText = {
  685. id: res.data.secondCheckerId,
  686. name: res.data.secondCheckerName
  687. }
  688. }
  689. for(let i in res.data.invoiceList){
  690. this.formshowText.inProjectName.push(res.data.invoiceList[i].projectName)
  691. res.data.invoiceList[i].approveLoading = false;
  692. if(res.data.invoiceList[i].pic){
  693. // this.uploader[i] = [{url:'/upload/' + res.data.invoiceList[i].pic}]
  694. let pic = res.data.invoiceList[i].pic
  695. let picArr = pic.split(',').map(item => {
  696. return { url: `/upload/${item}`}
  697. // return { url: `http://47.101.180.183/upload/${item}`}
  698. })
  699. res.data.invoiceList[i].pic = pic.split(',').map(item => item)
  700. this.uploader[i] = picArr
  701. console.log('每一项的图片', picArr)
  702. }else{
  703. this.uploader[i] = []
  704. }
  705. }
  706. } else {
  707. this.$toast.fail(res.msg || res.code || '获取失败');
  708. }
  709. }).catch(err=> {this.$toast.clear();console.log(err)});
  710. },
  711. getUserList(){
  712. this.$axios.post("/user/getSimpleActiveUserList", {})
  713. .then(res => {
  714. if(res.code == "ok") {
  715. this.userList = res.data
  716. } else {
  717. this.$toast.fail(res.msg || res.code || '获取失败');
  718. }
  719. }).catch(err=> {this.$toast.clear();console.log(err)});
  720. },
  721. getProjectList(){
  722. this.$axios.post("/project/getProjectList", {})
  723. .then(res => {
  724. if(res.code == "ok") {
  725. this.inProjectList = res.data
  726. } else {
  727. this.$toast.fail(res.msg || res.code || '获取失败');
  728. }
  729. }).catch(err=> {this.$toast.clear();console.log(err)});
  730. },
  731. getExTypeList(){
  732. this.$axios.post("/expense-type/getList", {})
  733. .then(res => {
  734. if(res.code == "ok") {
  735. this.allexTypeList = res.data
  736. this.inexTypeList = this.allexTypeList.filter(a=>a.mainType == this.editForm.type)
  737. } else {
  738. this.$toast.fail(res.msg || res.code || '获取失败');
  739. }
  740. }).catch(err=> {this.$toast.clear();console.log(err)});
  741. },
  742. // 单据审核
  743. approveSingle(item) {
  744. item.approveLoading = true;
  745. this.$axios.post("/expense-sheet/approveSingleProject", { id: item.id })
  746. .then(res => {
  747. if (res.code == "ok") {
  748. this.$toast.success('已通过')
  749. item.approveLoading = false
  750. this.getDetail();
  751. } else {
  752. this.$toast.fail(res.msg || res.code || '获取失败');
  753. }
  754. }).catch(err => { this.$toast.clear(); console.log(err) });
  755. },
  756. denySingle(item) {
  757. item.approveLoading = true;
  758. this.$axios.post("/expense-sheet/denySingleProject", {id: item.id})
  759. .then(res => {
  760. if (res.code == "ok") {
  761. this.$toast.success('已驳回')
  762. item.approveLoading = false
  763. this.getDetail();
  764. } else {
  765. this.$toast.fail(res.msg || res.code || '获取失败');
  766. }
  767. }).catch(err => { this.$toast.clear(); console.log(err) });
  768. },
  769. getAuditType() {
  770. this.$axios.post("/expense-audit-setting/get", {})
  771. .then(res => {
  772. if (res.code == "ok") {
  773. this.auditTypeItem = res.data;
  774. } else {
  775. this.$message({
  776. message: res.msg,
  777. type: "error"
  778. });
  779. }
  780. }).catch(err => { this.$toast.clear(); console.log(err) });
  781. },
  782. ownerIdShowCli(type) {
  783. this.ownerIdShowType = type
  784. this.userRadio = ''
  785. this.ownerIdShow = true
  786. }
  787. },
  788. };
  789. </script>
  790. <style lang="less" scoped>
  791. .edit{
  792. margin-top: 46px;
  793. overflow: auto;
  794. .form_btn{
  795. z-index: 1000;
  796. }
  797. .edit_form{
  798. .userCheckbox {
  799. padding: 10px;
  800. }
  801. padding-bottom: 46px;
  802. .invoice{
  803. border: 0.5px solid rgb(135, 195, 255);
  804. margin: 0.2rem;
  805. .deletebtn{
  806. position: absolute;
  807. z-index: 1000;
  808. font-size: 24px;
  809. right: 0.08rem;
  810. top: 0.08rem;
  811. color: #c03131;
  812. }
  813. .invoice_item{
  814. border-top: 0.5px solid rgb(135, 195, 255);
  815. }
  816. }
  817. .addinvoice{
  818. padding: 0 0.3rem 0.3rem;
  819. margin-top: 0.2rem;
  820. text-align: right;
  821. }
  822. }
  823. .imgListVan {
  824. display: flex;
  825. flex-direction: column;
  826. }
  827. .vanUploaderImg {
  828. // display: flex;
  829. margin-top: 6px;
  830. /deep/ .van-uploader__preview-image {
  831. width: 70px;
  832. height: 70px;
  833. }
  834. /deep/ .van-uploader__upload {
  835. width: 70px;
  836. height: 70px;
  837. }
  838. }
  839. }
  840. .waiting {
  841. color: orange;
  842. }
  843. .rejected {
  844. color: red;
  845. }
  846. </style>
  847. <style>
  848. .edit_form .invoice .van-field__label{
  849. color: #999;
  850. }
  851. .edit_form .invoice .van-field__control{
  852. color: #999;
  853. }
  854. </style>