index.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  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>{{typeList[editForm.type]}}</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. }
  300. },
  301. computed: {
  302. totalCost(){
  303. let costnum = 0
  304. for(let i in this.invoiceList){
  305. costnum += (this.invoiceList[i].amount ? parseFloat(this.invoiceList[i].amount) : 0)
  306. }
  307. return costnum.toFixed(2)
  308. }
  309. },
  310. filters: {
  311. numtosum(value) {
  312. if (value == undefined || !value) return '0.00'
  313. value = value.toFixed(2)
  314. const intPart = Math.trunc(value)
  315. const intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
  316. let floatPart = '.00'
  317. const valueArray = value.toString().split('.')
  318. if (valueArray.length === 2) { // 有小数部分
  319. floatPart = valueArray[1].toString() // 取得小数部分
  320. return intPartFormat + '.' + floatPart
  321. }
  322. return intPartFormat + floatPart
  323. },
  324. },
  325. mounted() {
  326. this.activeChange()
  327. for(let i in this.user.functionList){
  328. if(this.user.functionList[i].name == '费用审核'){
  329. this.canExamine = true
  330. }
  331. }
  332. if(!this.canExamine){
  333. this.editForm.ownerId = this.user.id
  334. this.formshowText.name = this.user.name
  335. }else{
  336. this.getUserList()
  337. }
  338. this.getProjectList()
  339. this.getExTypeList()
  340. },
  341. methods: {
  342. back(){
  343. sessionStorage.removeItem("page");
  344. history.back();
  345. },
  346. formatDate(date) {
  347. let mon = date.getMonth() + 1
  348. return `${date.getFullYear()}-${mon<10?'0'+mon:mon}-${date.getDate()<10?'0'+date.getDate():date.getDate()}`;
  349. },
  350. getTaxValue(amount,percent){
  351. let per = percent / 100
  352. let amo = amount / (1 + per)*per
  353. return amo.toFixed(2)
  354. },
  355. activeChange(){
  356. sessionStorage.setItem('page',JSON.stringify(this.active))
  357. if(this.active == 1){
  358. this.getBillList()
  359. }
  360. if(this.active == 2){
  361. this.getExamineList()
  362. }
  363. },
  364. // #region 费用报销
  365. ownerIdChange(){
  366. this.editForm.ownerId = this.userRadio.id
  367. this.formshowText.name = this.userRadio.name
  368. this.ownerIdShow = false
  369. },
  370. createDateChange(value,key){
  371. this.editForm.createDate = this.formatDate(value)
  372. this.createDateShow = false
  373. },
  374. typeChange(value,key){
  375. this.editForm.type = key
  376. this.typeShow = false
  377. this.inexTypeList = this.allexTypeList.filter(a=>a.mainType == this.editForm.type)
  378. },
  379. ticNumChange(value){
  380. if(value){
  381. this.invoiceList.push({
  382. projectId: '',
  383. happenDate: '',
  384. invoiceType: '',
  385. expenseType: '',
  386. amount: '',
  387. invoiceNo: '',
  388. taxPercent: '',
  389. taxValue: '',
  390. remark: '',
  391. pic: '',
  392. })
  393. }else{
  394. this.invoiceList.pop()
  395. }
  396. },
  397. // 发票
  398. inProjectChange(value,key){
  399. this.formshowText.inProjectName[this.invoiceIndex] = value.projectName
  400. this.invoiceList[this.invoiceIndex].projectId = value.id
  401. this.in_projectShow = false
  402. },
  403. inDateChange(value,key){
  404. this.invoiceList[this.invoiceIndex].happenDate = this.formatDate(value)
  405. this.in_dateShow = false
  406. },
  407. inTypeChange(value,key){
  408. this.invoiceList[this.invoiceIndex].invoiceType = key
  409. this.in_typeShow = false
  410. },
  411. inexTypeChange(value,key){
  412. this.invoiceList[this.invoiceIndex].expenseType = value.typeName
  413. this.in_exTypeShow = false
  414. },
  415. addInvoice(){
  416. this.invoiceList.push({
  417. projectId: '',
  418. happenDate: '',
  419. invoiceType: '',
  420. expenseType: '',
  421. amount: '',
  422. invoiceNo: '',
  423. taxPercent: '',
  424. taxValue: '',
  425. remark: '',
  426. pic: '',
  427. })
  428. this.uploader.push([])
  429. this.editForm.ticketNum = this.invoiceList.length
  430. },
  431. deleteInvoice(index){
  432. this.invoiceList.splice(index,1)
  433. this.uploader.splice(index,1)
  434. this.editForm.ticketNum = this.invoiceList.length
  435. },
  436. // 上传报销凭证
  437. beforeRead(file){
  438. if(file.type != 'image/jpeg' && file.type != 'image/png'){
  439. this.$toast.fail('请选择jpg或png格式的图片')
  440. return false
  441. }
  442. return true
  443. },
  444. afterRead(file){
  445. let formData = new FormData();
  446. formData.append("multipartFile", file.file);
  447. this.$axios.post("/common/uploadFile", formData)
  448. .then(res => {
  449. if(res.code == "ok") {
  450. this.invoiceList[this.invoiceIndex].pic = res.data
  451. } else {
  452. this.$toast.fail('上传失败');
  453. this.uploader[this.invoiceIndex] = []
  454. }
  455. }).catch(err=> {this.$toast.clear();console.log(err);this.uploader[this.invoiceIndex]=[]});
  456. },
  457. // 提交
  458. submitExpense(){
  459. if(!this.editForm.ownerId){
  460. this.$toast.fail('请选择报销人')
  461. return
  462. }
  463. if(!this.editForm.createDate){
  464. this.$toast.fail('请选择填报日期')
  465. return
  466. }
  467. let required1 = false
  468. let required2 = false
  469. let required3 = false
  470. let required4 = false
  471. let required5 = false
  472. for(let i in this.invoiceList){
  473. if(!this.invoiceList[i].projectId){
  474. required1 = '所属项目'
  475. }
  476. if(!this.invoiceList[i].happenDate){
  477. required2 = '费用日期'
  478. }
  479. if(!this.invoiceList[i].invoiceType){
  480. required3 = '发票种类'
  481. }
  482. if(!this.invoiceList[i].expenseType){
  483. required4 = '费用类型'
  484. }
  485. if(!this.invoiceList[i].amount){
  486. required5 = '费用金额(含税)'
  487. }
  488. }
  489. if(required1 || required2 || required3 || required4 || required5){
  490. let requiredStr = (required1 ? required1 + '、' : '')
  491. + (required2 ? required2 + '、' : '')
  492. + (required3 ? required3 + '、' : '')
  493. + (required4 ? required4 + '、' : '')
  494. + (required5 ? required5 + '、' : '')
  495. requiredStr = requiredStr.substring(0,requiredStr.length - 1)
  496. this.$toast.fail('请添加发票的[' + requiredStr + ']')
  497. return
  498. }
  499. if(this.invoiceList.length == 0){
  500. this.$toast.fail('请添加发票')
  501. return
  502. }
  503. for(let i in this.invoiceList){
  504. this.invoiceList[i].taxValue = this.getTaxValue(this.invoiceList[i].amount,this.invoiceList[i].taxPercent)
  505. }
  506. this.editForm.items = JSON.stringify(this.invoiceList)
  507. this.editForm.totalAmount = this.totalCost
  508. // 获取新的票据编号
  509. this.confirmLoading = true
  510. this.$axios.post("/expense-sheet/getNextCode", {})
  511. .then(res => {
  512. if(res.code == "ok") {
  513. this.editForm.code = res.data
  514. // 提交
  515. this.$axios.post("/expense-sheet/add", this.editForm)
  516. .then(res => {
  517. this.confirmLoading = false
  518. if(res.code == "ok") {
  519. this.$toast.success('填报成功')
  520. this.editForm = {
  521. ownerId: '',
  522. createDate: '',
  523. ticketNum: 0,
  524. type: 0,
  525. remark: ''
  526. }
  527. // this.formshowText = {
  528. // name: '',
  529. // inProjectName: []
  530. // }
  531. this.formshowText.name = ''
  532. this.formshowText.inProjectName = []
  533. this.invoiceList = []
  534. this.uploader = []
  535. } else {
  536. this.$toast.fail('获取失败');
  537. }
  538. }).catch(err=> {this.confirmLoading = false;this.$toast.clear();console.log(err)});
  539. } else {
  540. this.confirmLoading = false
  541. this.$toast.fail('获取失败');
  542. }
  543. }).catch(err=> {
  544. this.confirmLoading = false;
  545. this.$toast.clear();
  546. console.log(err)});
  547. },
  548. // #endregion
  549. // 单据列表
  550. deleteBill(pid){
  551. this.$dialog.confirm({
  552. message: '确认删除?',
  553. })
  554. .then(() => {
  555. // on confirm
  556. this.$axios.post("/expense-sheet/delete", {id: pid})
  557. .then(res => {
  558. if(res.code == "ok") {
  559. this.$toast.success('删除成功')
  560. this.getBillList()
  561. } else {
  562. this.$toast.fail('获取失败');
  563. }
  564. }).catch(err=> {this.$toast.clear();console.log(err)});
  565. })
  566. .catch(() => {
  567. // on cancel
  568. });
  569. },
  570. // 单据审核
  571. approve(item){
  572. item.approveLoading = true
  573. this.$axios.post("/expense-sheet/approve", {id: item.id})
  574. .then(res => {
  575. if(res.code == "ok") {
  576. this.$toast.success('已通过')
  577. item.approveLoading = false
  578. this.getExamineList()
  579. } else {
  580. this.$toast.fail('获取失败');
  581. }
  582. }).catch(err=> {this.$toast.clear();console.log(err)});
  583. },
  584. denyToReason(pid){
  585. this.denyParm.id = pid
  586. this.denyReasonDialog = true
  587. this.denyParm.denyReason = ''
  588. this.deny()
  589. },
  590. deny(){
  591. this.denyLoading = true
  592. this.$axios.post("/expense-sheet/deny", this.denyParm)
  593. .then(res => {
  594. if(res.code == "ok") {
  595. this.$toast.success('已驳回')
  596. this.denyReasonDialog = false
  597. this.denyLoading = false
  598. this.getExamineList()
  599. } else {
  600. this.$toast.fail('获取失败');
  601. }
  602. }).catch(err=> {this.$toast.clear();console.log(err)});
  603. },
  604. getUserList(){
  605. this.$axios.post("/user/getSimpleActiveUserList", {})
  606. .then(res => {
  607. if(res.code == "ok") {
  608. this.userList = res.data
  609. } else {
  610. this.$toast.fail('获取失败');
  611. }
  612. }).catch(err=> {this.$toast.clear();console.log(err)});
  613. },
  614. getProjectList(){
  615. this.$axios.post("/project/getProjectList", {})
  616. .then(res => {
  617. if(res.code == "ok") {
  618. this.inProjectList = res.data
  619. } else {
  620. this.$toast.fail('获取失败');
  621. }
  622. }).catch(err=> {this.$toast.clear();console.log(err)});
  623. },
  624. getExTypeList(){
  625. this.$axios.post("/expense-type/getList", {})
  626. .then(res => {
  627. if(res.code == "ok") {
  628. this.allexTypeList = res.data
  629. this.inexTypeList = this.allexTypeList.filter(a=>a.mainType == 0)
  630. } else {
  631. this.$toast.fail('获取失败');
  632. }
  633. }).catch(err=> {this.$toast.clear();console.log(err)});
  634. },
  635. getBillList(){
  636. this.$axios.post("/expense-sheet/list", {
  637. pageSize: 999,
  638. pageIndex: 1,
  639. startDate: '',
  640. endDate: '',
  641. ownerId: '',
  642. type: ''
  643. }).then(res => {
  644. if(res.code == "ok") {
  645. this.billList = res.data.records
  646. } else {
  647. this.$toast.fail('获取失败');
  648. }
  649. }).catch(err=> {this.$toast.clear();console.log(err)});
  650. },
  651. getExamineList(){
  652. this.$axios.post("/expense-sheet/list", {
  653. pageSize: 999,
  654. pageIndex: 1,
  655. startDate: '',
  656. endDate: '',
  657. ownerId: '',
  658. type: '',
  659. status: 1
  660. }).then(res => {
  661. if(res.code == "ok") {
  662. this.examineList = res.data.records
  663. for(let i in this.examineList){
  664. this.$set(this.examineList[i],'approveLoading',false)
  665. }
  666. } else {
  667. this.$toast.fail('获取失败');
  668. }
  669. }).catch(err=> {this.$toast.clear();console.log(err)});
  670. }
  671. },
  672. }
  673. </script>
  674. <style lang="less" scoped>
  675. .content{
  676. margin-top: 46px;
  677. overflow: auto;
  678. .edit{
  679. .userCheckbox {
  680. padding: 10px;
  681. }
  682. padding-bottom: 46px;
  683. .form_btn{
  684. z-index: 1000;
  685. }
  686. .edit_form{
  687. .invoice{
  688. border: 0.5px solid rgb(135, 195, 255);
  689. margin: 0.2rem;
  690. .deletebtn{
  691. position: absolute;
  692. z-index: 900;
  693. font-size: 24px;
  694. right: 0.08rem;
  695. top: 0.08rem;
  696. color: #c03131;
  697. }
  698. .invoice_item{
  699. border-top: 0.5px solid rgb(135, 195, 255);
  700. }
  701. }
  702. .addinvoice{
  703. padding: 0 0.3rem 0.3rem;
  704. margin-top: 0.2rem;
  705. text-align: right;
  706. }
  707. }
  708. }
  709. .list{
  710. .list_collapse>div{
  711. margin: 4px;
  712. }
  713. .list_collapse{
  714. .collapse_label_l{
  715. width: 50%;
  716. padding: 4px;
  717. display: inline-block;
  718. }
  719. .collapse_label_r{
  720. width: 50%;
  721. padding: 4px;
  722. display: inline-block;
  723. .waiting {
  724. color:orange;
  725. }
  726. .rejected {
  727. color:red;
  728. }
  729. }
  730. .wrapper{
  731. div{
  732. margin: 8px 16px;
  733. }
  734. div span:nth-child(1){
  735. width: 30%;
  736. display: inline-block;
  737. }
  738. div span:nth-child(2){
  739. width: 70%;
  740. display: inline-block;
  741. }
  742. }
  743. .operation{
  744. display: flex;
  745. align-items: center;
  746. justify-content: flex-end;
  747. }
  748. }
  749. }
  750. .audit{
  751. .list_collapse>div{
  752. margin: 4px;
  753. }
  754. .list_collapse{
  755. .collapse_label_l{
  756. width: 60%;
  757. padding: 4px;
  758. display: inline-block;
  759. }
  760. .collapse_label_r{
  761. width: 40%;
  762. padding: 4px;
  763. display: inline-block;
  764. .waiting {
  765. color:orange;
  766. }
  767. .rejected {
  768. color:red;
  769. }
  770. }
  771. .operation{
  772. margin-top: 5px;
  773. padding-top: 5px;
  774. border-top: 0.5px solid #ebedf0;
  775. display: flex;
  776. align-items: center;
  777. justify-content: flex-end;
  778. button{
  779. width: 1.2rem;
  780. }
  781. }
  782. .wrapper{
  783. div{
  784. margin: 8px 16px;
  785. }
  786. div span:nth-child(1){
  787. width: 30%;
  788. display: inline-block;
  789. }
  790. div span:nth-child(2){
  791. width: 70%;
  792. display: inline-block;
  793. }
  794. }
  795. .lookup{
  796. display: flex;
  797. align-items: center;
  798. justify-content: flex-end;
  799. }
  800. }
  801. }
  802. }
  803. </style>
  804. <style>
  805. .edit_form .invoice .van-field__label{
  806. color: #999;
  807. }
  808. .edit_form .invoice .van-field__control{
  809. color: #999;
  810. }
  811. </style>