edit.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <!--
  2. * @Author: wanglj wanglijie@dashoo.cn
  3. * @Date: 2025-03-24 09:17:15
  4. * @LastEditors: wanglj wanglijie@dashoo.cn
  5. * @LastEditTime: 2025-04-08 16:28:03
  6. * @FilePath: \labsop_h5\src\view\instr\detail.vue
  7. * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  8. -->
  9. <template>
  10. <div class="container">
  11. <van-form ref="formRef" required="auto">
  12. <h4>到款信息</h4>
  13. <van-cell-group class="mt10">
  14. <van-field v-model="state.form.projectName" label="项目到款" readonly />
  15. <van-field v-model="state.form.amount" label="到款金额" readonly>
  16. <template #input>{{ formatAmount(state.form.amount) }}</template>
  17. <template #extra>元</template>
  18. </van-field>
  19. <van-field v-model="state.form.taxAmount" label="管理费" readonly>
  20. <template #input>{{ formatAmount(state.form.manageAmount) }}</template>
  21. <template #extra>元</template>
  22. </van-field>
  23. <van-field v-model="state.form.taxAmount" label="税费" readonly>
  24. <template #input>{{ formatAmount(state.form.taxAmount) }}</template>
  25. <template #extra>元</template>
  26. </van-field>
  27. <van-field v-model="state.form.unAmount" label="待认领金额" readonly>
  28. <template #input>{{ formatAmount(state.form.unAmount) }}</template>
  29. <template #extra>元</template>
  30. </van-field>
  31. <van-field v-model="state.form.date" label="到款日期" readonly>
  32. <template #input>{{ formatDate(new Date(state.form.date), 'YYYY-mm-dd') }}</template>
  33. </van-field>
  34. <van-field v-model="state.form.type" label="到款类型" readonly>
  35. <template #input>{{ getDictLabel(paymentReceivedTypeOptions, state.form.type) }}</template>
  36. </van-field>
  37. <van-field v-model="state.form.unit" label="打款单位" readonly />
  38. </van-cell-group>
  39. <h4>认领经费</h4>
  40. <van-cell-group class="mt10">
  41. <van-field v-for="item in state.detail" :key="item.id" :label="item.subjName" :placeholder="item.subjName" v-model="item.amount">
  42. <template #extra>元</template>
  43. </van-field>
  44. </van-cell-group>
  45. </van-form>
  46. </div>
  47. <van-action-bar placeholder>
  48. <van-action-bar-icon icon="wap-home-o" text="首页" @click="onRouterPush('/home')" />
  49. <van-action-bar-icon icon="balance-o" text="经费认领" @click="onRouterPush('/fund/claim')" />
  50. <van-action-bar-button class="w100" type="primary" text="提交" @click="onClickButton" />
  51. </van-action-bar>
  52. </template>
  53. <script lang="ts" setup>
  54. import to from 'await-to-js'
  55. import { useRoute, useRouter } from 'vue-router'
  56. import { computed, onMounted, reactive, ref } from 'vue'
  57. import { formatDate } from '/@/utils/formatTime'
  58. import { showNotify } from 'vant'
  59. import { useUserInfo } from '/@/stores/userInfo'
  60. import { storeToRefs } from 'pinia'
  61. import instAppoint from '/@/api/instr/instAppoint'
  62. import { useConfigApi } from '/@/api/system/config'
  63. import { useFundApi } from '/@/api/fund'
  64. import { useDictApi } from '/@/api/system/dict'
  65. import { getDictLabel, formatAmountYuan } from '/@/utils/other'
  66. import { useClaimApi } from '/@/api/fund/claim'
  67. import { useLoginApi } from '/@/api/login'
  68. import { Local, Session } from '/@/utils/storage'
  69. const storesUseUserInfo = useUserInfo()
  70. const { userInfos, openId, unionId } = storeToRefs(storesUseUserInfo)
  71. const route = useRoute()
  72. const router = useRouter()
  73. const configApi = useConfigApi()
  74. const fundApi = useFundApi()
  75. const loginApi = useLoginApi()
  76. const dictApi = useDictApi()
  77. const claimApi = useClaimApi()
  78. const serviceList = ref([])
  79. const formRef = ref()
  80. const paymentReceivedTypeOptions = ref<RowDicDataType[]>([])
  81. const state = reactive({
  82. loading: false,
  83. isActiveService: false,
  84. showProject: false,
  85. shwoService: false,
  86. showExpenseCard: false,
  87. showAppointUser: false,
  88. isInstrHead: false,
  89. fundDetail: {} as any,
  90. detail: [] as any,
  91. form: {
  92. allotAmount: null,
  93. amount: null, //到款金额
  94. unAmount: 0, // 待认领金额
  95. manageAmount: 0,
  96. taxAmount: 0,
  97. projectName: '',
  98. createdName: '',
  99. createdTime: '',
  100. date: '',
  101. id: 0,
  102. remark: '',
  103. serialNo: '',
  104. type: '',
  105. unit: ''
  106. }
  107. })
  108. const getDict = () => {
  109. Promise.all([dictApi.getDictDataByType('PaymentReceivedType'), fundApi.getAllFirstSubj()]).then(([type, parList]) => {
  110. paymentReceivedTypeOptions.value = type?.data?.values || []
  111. state.detail =
  112. parList?.data.map((item: any) => ({
  113. ...item,
  114. amount: 0
  115. })) || []
  116. })
  117. }
  118. const AccountAmount = computed(() => {
  119. const amount = state.form.amount ? Number(state.form.amount * 100 - state.form.manageAmount * 100 - state.form.taxAmount * 100) : 0
  120. return (amount / 100).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  121. })
  122. const formatAmount = (cellValue: number) => {
  123. cellValue = cellValue * 100
  124. return (cellValue / 100).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  125. }
  126. const getFundDetail = async (id: number) => {
  127. const [err, res]: ToResponse = await to(fundApi.getDetails({ id }))
  128. if (err) return
  129. state.fundDetail = res.data
  130. state.form = { ...state.form, ...res.data }
  131. state.form.unAmount = state.form.amount - state.form.manageAmount - state.form.taxAmount
  132. // state.form.projectName = res.data.projectName
  133. // state.form.amount = res.data.amount
  134. // state.form.manageAmount = res.data.manageAmount
  135. // state.form.taxAmount = res.data.taxAmount
  136. // state.form.date = res.data.date
  137. // state.form.type = res.data.type
  138. // state.form.unit = res.data.unit
  139. }
  140. const onRouterPush = (val: string, params?: any) => {
  141. router.push({
  142. path: val,
  143. query: { ...params }
  144. })
  145. }
  146. const onClickButton = async () => {
  147. const totalAmount = state.detail.reduce((acc, current) => {
  148. return acc + Number(current.amount * 100)
  149. }, 0)
  150. if (Number(state.form.amount * 100) / 100 != totalAmount / 100) {
  151. showNotify({
  152. type: 'warning',
  153. message: '认领金额必须等于本次到款总计金额'
  154. })
  155. return
  156. }
  157. state.loading = true
  158. const params = JSON.parse(JSON.stringify(state.form))
  159. params.fundId = state.form.id
  160. params.detail = state.detail
  161. params.amount = Number(params.amount)
  162. params.detail = params.detail.map((item: any) => ({
  163. ...item,
  164. amount: Number(item.amount * 100)
  165. }))
  166. params.externalAmount = Number(params.externalAmount)
  167. params.internalAmount = Number(params.internalAmount)
  168. const [err]: ToResponse = await to(claimApi.create(params))
  169. state.loading = false
  170. if (err) return
  171. showNotify({
  172. type: 'success',
  173. message: '操作成功'
  174. })
  175. router.push({
  176. path: '/fund/claim',
  177. query: {
  178. id: params.instId
  179. }
  180. })
  181. }
  182. onMounted(async () => {
  183. // 进行openId登录
  184. const code: string = route.query.code ? route.query.code.toString() : ''
  185. await storesUseUserInfo.setOpenId(code)
  186. let param = {
  187. code: openId.value,
  188. unionId: unionId.value,
  189. }
  190. if (openId.value) {
  191. const [err, res]: ToResponse = await to(loginApi.weChatLoginUnionId(param))
  192. if (err) {
  193. // 跳转到登录页面
  194. Local.remove('token')
  195. router.push('/login')
  196. return
  197. }
  198. // 存储 token 到浏览器缓存
  199. Local.set('token', res?.data?.token)
  200. Local.set('Tenant', res.data.tenant)
  201. }
  202. const id = route.query.id ? +route.query.id : 0
  203. getDict()
  204. getFundDetail(id)
  205. })
  206. </script>
  207. <style lang="scss" scoped>
  208. .container {
  209. flex: 1;
  210. padding: 10px;
  211. background-color: #f9f9f9;
  212. overflow-y: auto;
  213. h4 {
  214. height: 18px;
  215. line-height: 18px;
  216. display: flex;
  217. margin: 10px 0;
  218. span {
  219. font-weight: normal;
  220. margin-left: auto;
  221. }
  222. &::before {
  223. display: inline-block;
  224. content: '';
  225. width: 3px;
  226. height: 18px;
  227. background-color: #1c9bfd;
  228. margin-right: 4px;
  229. vertical-align: middle;
  230. }
  231. }
  232. }
  233. </style>