reimburse.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. <template>
  2. <div>
  3. <el-row>
  4. <el-col :span="6">
  5. <el-form-item
  6. label="报销日期:"
  7. >
  8. <el-date-picker
  9. v-model="condition.time"
  10. type="month"
  11. placeholder="请选择报销月份"
  12. format="YYYY-MM"
  13. value-format="YYYY-MM"
  14. clearable
  15. />
  16. </el-form-item>
  17. </el-col>
  18. <el-col
  19. :span="6"
  20. :offset="1"
  21. >
  22. <el-form-item
  23. label="报销人:"
  24. >
  25. <el-input
  26. v-model="condition.name"
  27. placeholder="请输入报销人"
  28. clearable
  29. />
  30. </el-form-item>
  31. </el-col>
  32. <el-col
  33. :span="2"
  34. :offset="1"
  35. >
  36. <el-button
  37. type="primary"
  38. :icon="Search"
  39. @click="searchReimburse"
  40. >查询</el-button>
  41. </el-col>
  42. <el-col
  43. :span="2"
  44. style="margin-left: 30px"
  45. >
  46. <el-button
  47. type="primary"
  48. :icon="Plus"
  49. @click="changeReimburseAddShow"
  50. >
  51. 新增
  52. </el-button>
  53. </el-col>
  54. </el-row>
  55. <el-row>
  56. <el-col :span="23">
  57. <el-row>
  58. <el-table
  59. :data="submit.reimburseList"
  60. stripe
  61. >
  62. <el-table-column
  63. label="报销人"
  64. prop="applicant"
  65. align="center"
  66. width="180px"
  67. />
  68. <el-table-column
  69. label="报销日期"
  70. prop="applicationTime"
  71. align="center"
  72. width="180px"
  73. />
  74. <el-table-column
  75. label="报销金额(元)"
  76. prop="reimbursementPrice"
  77. align="center"
  78. width="250px"
  79. />
  80. <el-table-column
  81. label="操作"
  82. align="center"
  83. >
  84. <template #default="scope">
  85. <el-button
  86. text
  87. type="primary"
  88. :icon="Edit"
  89. @click="openReimburseEdit(scope.row)"
  90. >
  91. 编辑
  92. </el-button>
  93. <el-button
  94. text
  95. type="primary"
  96. :icon="Delete"
  97. @click="reimburseDelete(scope.row)"
  98. >
  99. 删除
  100. </el-button>
  101. </template>
  102. </el-table-column>
  103. </el-table>
  104. </el-row>
  105. <el-row justify="end">
  106. <el-pagination
  107. v-model:current-page="condition.pageInfo.page"
  108. background
  109. layout="prev, pager, next"
  110. :page-size="8"
  111. :total="submit.reimburseTotal"
  112. @change="changeReimbursePage"
  113. />
  114. </el-row>
  115. </el-col>
  116. </el-row>
  117. <el-drawer
  118. v-model="reimburseAddShow"
  119. title="新增报销记录"
  120. size="40%"
  121. >
  122. <el-form
  123. label-position="left"
  124. label-width="100"
  125. class="mt-5"
  126. >
  127. <el-form-item
  128. label="申请人:"
  129. >
  130. <el-input
  131. v-model="createData.applicant"
  132. placeholder="请输入申请人名称"
  133. clearable
  134. @clear="createData.applicant = ''"
  135. />
  136. </el-form-item>
  137. <el-form-item
  138. label="报销日期:"
  139. >
  140. <el-date-picker
  141. v-model="createData.applicationTime"
  142. placeholder="请选择报销日期"
  143. format="YYYY-MM-DD"
  144. value-format="YYYY-MM-DD"
  145. clearable
  146. @clear="createData.applicationTime = ''"
  147. />
  148. </el-form-item>
  149. <el-form-item
  150. label="审批人:"
  151. >
  152. <el-select
  153. v-model="createData.approval"
  154. filterable
  155. placeholder="请选择审批人"
  156. clearable
  157. @clear="createData.approval = ''"
  158. >
  159. <el-option
  160. v-for="item in userList"
  161. :key="item.ID"
  162. :label="item.nickName"
  163. :value="item.ID"
  164. />
  165. </el-select>
  166. </el-form-item>
  167. <el-form-item
  168. label="费用类型:"
  169. >
  170. <el-select
  171. v-model="createData.genre"
  172. filterable
  173. placeholder="请选择费用类型"
  174. clearable
  175. @clear="createData.genre = ''"
  176. >
  177. <el-option
  178. v-for="item in costList"
  179. :key="item.ID"
  180. :label="item.name"
  181. :value="item.ID"
  182. />
  183. </el-select>
  184. </el-form-item>
  185. <el-form-item label="报销总金额:">
  186. <el-text size="large">{{ totality }}</el-text>
  187. </el-form-item>
  188. <el-row
  189. v-for="(item,index) in createData.feeDetails"
  190. :key="index"
  191. >
  192. <el-col :span="12">
  193. <el-form-item
  194. label="报销金额:"
  195. >
  196. <el-input-number
  197. v-model="item.feePrice"
  198. placeholder="请输入报销金额"
  199. clearable
  200. size="large"
  201. />
  202. </el-form-item>
  203. </el-col>
  204. <el-col :span="12">
  205. <el-form-item
  206. label="报销备注:"
  207. >
  208. <el-input
  209. v-model="item.remarks"
  210. placeholder="请输入报销备注"
  211. type="textarea"
  212. maxlength="150"
  213. show-word-limit
  214. clearable
  215. size="large"
  216. @clear="item.remarks = ''"
  217. />
  218. </el-form-item>
  219. </el-col>
  220. </el-row>
  221. </el-form>
  222. <template #footer>
  223. <div class="dialog-footer">
  224. <el-button
  225. v-show="createData.feeDetails.length > 1"
  226. size="large"
  227. @click="createData.feeDetails.splice(createData.feeDetails.length - 1,1)"
  228. >
  229. 删除报销详情
  230. </el-button>
  231. <el-button
  232. size="large"
  233. @click="addFeeDetails"
  234. >
  235. 添加报销详情
  236. </el-button>
  237. <el-button
  238. type="primary"
  239. size="large"
  240. @click="addReimburse"
  241. >
  242. 确定
  243. </el-button>
  244. </div>
  245. </template>
  246. </el-drawer>
  247. <el-drawer
  248. v-model="reimburseEditShow"
  249. title="编辑报销记录"
  250. size="40%"
  251. >
  252. <el-form
  253. label-position="left"
  254. label-width="100"
  255. class="mt-5"
  256. >
  257. <el-form-item
  258. label="申请人:"
  259. >
  260. <el-input
  261. v-model="editData.applicant"
  262. placeholder="请输入申请人名称"
  263. clearable
  264. @clear="editData.applicant = ''"
  265. />
  266. </el-form-item>
  267. <el-form-item
  268. label="报销日期:"
  269. >
  270. <el-date-picker
  271. v-model="editData.applicationTime"
  272. placeholder="请选择报销日期"
  273. format="YYYY-MM-DD"
  274. value-format="YYYY-MM-DD"
  275. clearable
  276. @clear="editData.applicationTime = ''"
  277. />
  278. </el-form-item>
  279. <el-form-item
  280. label="审批人:"
  281. >
  282. <el-select
  283. v-model="editData.approval"
  284. filterable
  285. placeholder="请选择审批人"
  286. clearable
  287. @clear="editData.approval = ''"
  288. >
  289. <el-option
  290. v-for="item in userList"
  291. :key="item.ID"
  292. :label="item.nickName"
  293. :value="item.ID"
  294. />
  295. </el-select>
  296. </el-form-item>
  297. <el-form-item
  298. label="费用类型:"
  299. >
  300. <el-select
  301. v-model="editData.genre"
  302. filterable
  303. placeholder="请选择费用类型"
  304. clearable
  305. @clear="editData.genre = ''"
  306. >
  307. <el-option
  308. v-for="item in costList"
  309. :key="item.ID"
  310. :label="item.name"
  311. :value="item.ID"
  312. />
  313. </el-select>
  314. </el-form-item>
  315. <el-row>
  316. <el-col :span="10">
  317. <el-form-item label="报销总金额:">
  318. <el-text size="large">{{ editTotality }}</el-text>
  319. </el-form-item>
  320. </el-col>
  321. </el-row>
  322. <el-row
  323. v-for="(item,index) in editData.feeDetails"
  324. :key="index"
  325. >
  326. <el-col :span="12">
  327. <el-form-item
  328. label="报销金额:"
  329. >
  330. <el-input-number
  331. v-model="item.feePrice"
  332. placeholder="请输入报销金额"
  333. clearable
  334. size="large"
  335. />
  336. </el-form-item>
  337. </el-col>
  338. <el-col :span="12">
  339. <el-form-item
  340. label="报销备注:"
  341. >
  342. <el-input
  343. v-model="item.remarks"
  344. placeholder="请输入报销备注"
  345. type="textarea"
  346. maxlength="150"
  347. show-word-limit
  348. clearable
  349. size="large"
  350. @clear="item.remarks = ''"
  351. />
  352. </el-form-item>
  353. </el-col>
  354. </el-row>
  355. </el-form>
  356. <template #footer>
  357. <div class="dialog-footer">
  358. <el-button
  359. v-show="deleteDetailShow"
  360. size="large"
  361. @click="delFeeDetails"
  362. >
  363. 删除报销详情
  364. </el-button>
  365. <el-button
  366. size="large"
  367. @click="addEditFeeDetails"
  368. >
  369. 添加报销详情
  370. </el-button>
  371. <el-button
  372. type="primary"
  373. size="large"
  374. @click="editReimburse"
  375. >
  376. 确定
  377. </el-button>
  378. </div>
  379. </template>
  380. </el-drawer>
  381. </div>
  382. </template>
  383. <script setup>
  384. import { Search, Delete, Edit, Plus } from '@element-plus/icons-vue'
  385. import { reactive, ref, onMounted, computed, defineExpose } from 'vue'
  386. import { reimburseOperate } from '@/pinia/reimbursement/Reimbursement'
  387. import { codeOperate } from '@/pinia/code/code'
  388. import { queryExpensesGenre } from '@/api/finance'
  389. import { getAllUsers } from '@/api/user'
  390. import { ElMessage, ElMessageBox } from 'element-plus'
  391. import { createReimburse, deleteReimburse, updateReimburse } from '@/api/reimbursement'
  392. defineOptions({
  393. name: 'Reimburse'
  394. })
  395. // pinia
  396. const submit = reimburseOperate()
  397. const serial = codeOperate()
  398. // 数据
  399. const reimburseAddShow = ref(false)
  400. const condition = reactive({
  401. pageInfo: {
  402. page: 1,
  403. pageSize: 8
  404. },
  405. code: '',
  406. name: '',
  407. time: ''
  408. })
  409. const createData = reactive({
  410. projectCode: '',
  411. applicant: '',
  412. applicationTime: '',
  413. approval: '',
  414. reimbursementPrice: 0,
  415. genre: '',
  416. feeDetails: [{
  417. remarks: '',
  418. feePrice: 0
  419. }]
  420. })
  421. const editData = reactive({})
  422. const reimburseEditShow = ref(false)
  423. const costList = reactive([])
  424. const userList = reactive([])
  425. // 计算属性
  426. const deleteDetailShow = computed(() => {
  427. for (const i in editData) {
  428. if (i === 'feeDetails' && editData[i].length > 1) {
  429. return true
  430. }
  431. }
  432. return false
  433. })
  434. const totality = computed(() => {
  435. let middle = 0
  436. createData.feeDetails.forEach(item => {
  437. middle += item.feePrice
  438. })
  439. return middle
  440. })
  441. const editTotality = computed(() => {
  442. let middle = 0
  443. editData.feeDetails.forEach(item => {
  444. middle += parseFloat(item.feePrice)
  445. })
  446. return middle
  447. })
  448. // const overall = ref(0)
  449. // 方法
  450. onMounted(() => {
  451. queryExpensesGenre().then(res => {
  452. if (res.code === 0) {
  453. costList.push(...res.data)
  454. }
  455. })
  456. getAllUsers().then(res => {
  457. if (res.code === 0) {
  458. userList.length = 0
  459. userList.push(...res.data)
  460. }
  461. })
  462. })
  463. const searchReimburse = () => {
  464. condition.code = serial.currentCode
  465. condition.pageInfo.page = 1
  466. submit.getReimburseList(condition)
  467. }
  468. const openReimburseEdit = (row) => {
  469. reimburseEditShow.value = true
  470. Object.assign(editData, row)
  471. }
  472. const reimburseDelete = (row) => {
  473. ElMessageBox.confirm(
  474. '确定要删除该报销记录吗?',
  475. '删除记录',
  476. {
  477. confirmButtonText: '删除',
  478. cancelButtonText: '取消',
  479. type: 'warning',
  480. }
  481. )
  482. .then(() => {
  483. const id = { id: row.ID }
  484. deleteReimburse(id).then(res => {
  485. if (res.code === 0) {
  486. ElMessage({
  487. message: '删除成功',
  488. type: 'success',
  489. showClose: true,
  490. duration: 2000
  491. })
  492. refreshList()
  493. }
  494. })
  495. }).catch(() => {})
  496. }
  497. const changeReimbursePage = (value) => {
  498. condition.pageInfo.page = value
  499. submit.getReimburseList(condition)
  500. }
  501. const addReimburse = () => {
  502. // // 报销总金额
  503. createData.reimbursementPrice = totality.value
  504. createData.projectCode = serial.currentCode
  505. for (const i in createData) {
  506. if (createData[i] === '' || createData[i] === 0) {
  507. ElMessage({
  508. message: '请将信息填写完整',
  509. type: 'error',
  510. showClose: true,
  511. duration: 3000
  512. })
  513. return
  514. }
  515. }
  516. createReimburse(createData).then(res => {
  517. if (res.code === 0) {
  518. ElMessage({
  519. message: '添加成功',
  520. type: 'success',
  521. showClose: true,
  522. duration: 2000
  523. })
  524. const reset = {
  525. projectCode: '',
  526. applicant: '',
  527. applicationTime: '',
  528. approval: '',
  529. genre: '',
  530. feeDetails: [{
  531. remarks: '',
  532. feePrice: 0
  533. }]
  534. }
  535. Object.assign(createData, reset)
  536. createData.reimbursementPrice = totality.value
  537. reimburseAddShow.value = false
  538. refreshList()
  539. }
  540. })
  541. }
  542. const editReimburse = () => {
  543. const editCondition = {
  544. projectCode: serial.currentCode,
  545. id: editData.ID,
  546. applicant: editData.applicant,
  547. applicationTime: editData.applicationTime,
  548. approval: editData.approval,
  549. reimbursementPrice: editTotality.value,
  550. genre: editData.genre,
  551. feeDetails: editData.feeDetails
  552. }
  553. updateReimburse(editCondition).then(res => {
  554. if (res.code === 0) {
  555. ElMessage({
  556. message: '编辑成功',
  557. type: 'success',
  558. showClose: true,
  559. duration: 2000
  560. })
  561. reimburseEditShow.value = false
  562. refreshList()
  563. }
  564. })
  565. }
  566. const refreshList = () => {
  567. const refresh = condition
  568. refresh.code = serial.currentCode
  569. submit.getReimburseList(refresh)
  570. }
  571. const addFeeDetails = () => {
  572. createData.feeDetails.push({
  573. remarks: '',
  574. feePrice: 0
  575. })
  576. }
  577. const addEditFeeDetails = () => {
  578. editData.feeDetails.push({
  579. remarks: '',
  580. feePrice: 0
  581. })
  582. }
  583. const delFeeDetails = () => {
  584. editData.feeDetails.splice(editData.feeDetails.length - 1, 1)
  585. }
  586. const outsideChangePage = () => {
  587. condition.pageInfo.page = 1
  588. }
  589. const changeReimburseAddShow = () => {
  590. reimburseAddShow.value = true
  591. }
  592. defineExpose({
  593. outsideChangePage
  594. })
  595. </script>
  596. <style scoped>
  597. </style>