index.vue 35 KB

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