form.vue 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. <template>
  2. <!-- 添加或修改项目信息对话框 -->
  3. <div class="el-drawer__wrapper">
  4. <el-drawer :title="title" v-model="visible" direction="rtl" size="100%">
  5. <div class="page-container form-container">
  6. <div class="form-btns-container">
  7. <span class="title-label"><el-icon>
  8. <Document />
  9. </el-icon>
  10. 支出信息</span>
  11. <template v-if="
  12. checkPermission(['business:payment:edit', 'business:payment:add'])
  13. ">
  14. <el-button v-if="editStatus" type="primary" size="small" icon="Finished" @click="submitForm">保存</el-button>
  15. <el-button v-else-if="form.verifyStatus === 0" type="warning" size="small" icon="Edit"
  16. @click="editStatus = true">修改</el-button>
  17. <el-button v-show="form.verifyStatus == 3 " type="warning" size="small" icon="Finished" @click="returnZero"
  18. v-hasPermi="['business:payment:return']">退回</el-button>
  19. <el-button v-if="form.id && editStatus" size="small" icon="Close"
  20. @click="reForm">取消修改</el-button>
  21. </template>
  22. <el-button v-show="form.id && !editStatus && form.verifyStatus === 0"
  23. v-hasPermi="['business:payment:financialVerify']" type="primary" size="small" icon="Check"
  24. @click="verifyHandler">财务审核</el-button>
  25. <el-button v-show="form.id && !editStatus && form.verifyStatus === 1"
  26. v-hasPermi="['business:payment:cashierVerify']" type="primary" size="small" icon="Check"
  27. @click="cashierVerifyHandler">出纳审核</el-button>
  28. <div class="screen-btn" @click="handleScreen">
  29. <template v-if="!isFullscreen">
  30. <i class="fa fa-window-maximize" aria-hidden="true" />
  31. <!-- <span>全屏</span> -->
  32. </template>
  33. <template v-else>
  34. <i class="fa fa-window-restore" aria-hidden="true" />
  35. <!-- <span>还原</span> -->
  36. </template>
  37. </div>
  38. <div class="close-btn" @click="cancel">
  39. <i class="fa fa-times" aria-hidden="true" />
  40. <!-- <span>关闭</span> -->
  41. </div>
  42. </div>
  43. <div class="Y-scrollbar" style="
  44. position: absolute;
  45. top: 32px;
  46. bottom: 0;
  47. width: 100%;
  48. overflow: auto;
  49. "></div>
  50. <el-form ref="orderRef" class="master-container" size="small" :model="form" :rules="rules" label-width="100px">
  51. <el-row :gutter="30">
  52. <el-col :span="6">
  53. <el-form-item label="支出流水号:">
  54. <el-input v-if="editStatus" style="width: 100%" v-model.trim="form.flowNo" disabled size="small"
  55. type="text" placeholder="支出流水号" :clearable="true" />
  56. <span v-else>{{ form.flowNo }}</span>
  57. </el-form-item>
  58. </el-col>
  59. <el-col :span="6">
  60. <el-form-item label="申请日期" prop="formDate" required>
  61. <el-date-picker v-if="editStatus" style="width: 100%" v-model="form.formDate" size="small"
  62. :clearable="true" format="YYYY-MM-DD" value-format="YYYY-MM-DD" align="center" type="date"
  63. placeholder="申请日期" />
  64. <span v-else>{{ form.formDate }}</span>
  65. </el-form-item>
  66. </el-col>
  67. <el-col :span="6">
  68. <el-form-item label="支出类目:">
  69. <el-select v-if="editStatus" style="width: 100%" v-model.trim="form.paymentCauseId" placeholder="支出类目"
  70. size="small" :clearable="true" @change="paymentCauseChange">
  71. <el-option v-for="item in paymentTypes" :key="item.id" :label="item.name" :value="item.id" />
  72. </el-select>
  73. <span v-else>{{ form.paymentCause }}</span>
  74. </el-form-item>
  75. </el-col>
  76. <el-col :span="6">
  77. <el-form-item label="支出科目:">
  78. <el-select v-if="editStatus" style="width: 100%" v-model.trim="form.paymentSubjectId" placeholder="支出科目"
  79. size="small" :clearable="true" @change="paymentSubjectChange">
  80. <el-option v-for="item in paymentSubjects" :key="item.id" :label="item.name" :value="item.id" />
  81. </el-select>
  82. <span v-else>{{ form.paymentSubject }}</span>
  83. </el-form-item>
  84. </el-col>
  85. <el-col :span="6">
  86. <el-form-item label="收款账户名:">
  87. <el-input v-if="editStatus" style="width: 100%" v-model.trim="form.acceptAccount" size="small"
  88. type="text" placeholder="收款账户名" :clearable="true" />
  89. <span v-else>{{ form.acceptAccount }}</span>
  90. </el-form-item>
  91. </el-col>
  92. <el-col :span="6">
  93. <el-form-item label="收款账号:">
  94. <template v-if="editStatus">
  95. <el-input v-model.trim="form.acceptAccountNo" size="small" type="text" style="width: 100%"
  96. placeholder="收款账号" :clearable="true" />
  97. </template>
  98. <span v-else>{{ form.acceptAccountNo }}</span>
  99. </el-form-item>
  100. </el-col>
  101. <el-col :span="6">
  102. <el-form-item label="收款账户开户银行:" label-width="120px">
  103. <template v-if="editStatus">
  104. <el-input v-model.trim="form.bankNo" size="small" type="text" style="width: 100%"
  105. placeholder="收款账户开户银行" :clearable="true" />
  106. </template>
  107. <span v-else>{{ form.bankNo }}</span>
  108. </el-form-item>
  109. </el-col>
  110. <el-col :span="6">
  111. <el-form-item label="客户名称:" prop="companyName" required>
  112. <el-autocomplete v-if="editStatus" style="width: 100%" :fetch-suggestions="querySearchCompanyAsync"
  113. :trigger-on-focus="true" v-model="form.companyName" placeholder="请输入客户名称"
  114. popper-class="my-autocomplete" @select="handleSelectCompany">
  115. <template #default="{ item }">
  116. <div style="
  117. display: flex;
  118. flex-direction: row;
  119. justify-content: space-between;
  120. ">
  121. <div class="name" style="font-size: 12px">
  122. {{ item.name }}
  123. </div>
  124. <!-- <span class="code" style="font-size: 10px; color: darkgrey">{{ item.code }}</span> -->
  125. </div>
  126. </template>
  127. </el-autocomplete>
  128. <span v-else> <el-link :underline="false" type="primary" @click="handleInfo(form)">{{ form.companyName
  129. }}</el-link></span>
  130. </el-form-item>
  131. </el-col>
  132. <el-col :span="6">
  133. <el-form-item label="合同编号:" required>
  134. <el-input tabindex="-1" v-if="editStatus" readonly style="width: 100%" v-model.trim="form.contractNo"
  135. size="small" type="text" @click="() =>contractChoiceHandler(this)" placeholder="请选择" :clearable="true">
  136. <template #append>
  137. <el-button icon="Search" @click="() => contractChoiceHandler(this)" />
  138. </template>
  139. </el-input>
  140. <span v-else style="width: 100%">
  141. <el-link v-if="auth.hasPermi('business:archive:order:cwview')" :underline="false" type="primary" @click="handleContract(form)">{{ form.contractNo }}</el-link>
  142. <span v-else>{{form.contractNo}}</span>
  143. </span>
  144. </el-form-item>
  145. </el-col>
  146. <el-col :span="6">
  147. <el-form-item label="应收款金额:" prop="remark">
  148. <span>{{ rowNum(form.contractAmount) }}</span>
  149. </el-form-item>
  150. </el-col>
  151. <el-col :span="6">
  152. <el-form-item label="已支出金额:" prop="remark">
  153. <span>{{ rowNum(form.payedAmount) }}</span>
  154. </el-form-item>
  155. </el-col>
  156. <el-col :span="6">
  157. <el-form-item label="支出金额:" required>
  158. <el-input-number v-if="editStatus" v-model.trim="form.amount" size="small" disabled placeholder="支出金额"
  159. :clearable="true" :precision="2" controls-position="right" :controls="false" @change="amountChange" />
  160. <span v-else>{{ rowNum(form.amount) }}</span>
  161. </el-form-item>
  162. </el-col>
  163. <el-col v-if="form.verifyStatus === 2 || form.verifyStatus === 4" :span="6">
  164. <el-form-item label="驳回原因:" required>
  165. <span>{{ form.verifyComment }}</span>
  166. </el-form-item>
  167. </el-col>
  168. <el-col :span="6">
  169. <el-form-item label="甲方:" required>
  170. <span>{{ form.boss }}</span>
  171. </el-form-item>
  172. </el-col>
  173. <el-col :span="6">
  174. <el-form-item label="乙方:" required>
  175. <span>{{ form.party }}</span>
  176. </el-form-item>
  177. </el-col>
  178. <el-col :span="12">
  179. <el-form-item label="备注:">
  180. <el-input v-if="editStatus" v-model.trim="form.remark" size="small" type="text" placeholder="备注"
  181. :clearable="true" />
  182. <span v-else style="word-break: break-all">{{
  183. form.remark
  184. }}</span>
  185. </el-form-item>
  186. </el-col>
  187. </el-row>
  188. </el-form>
  189. <div class="details-container">
  190. <el-row :gutter="2" style="height: 100%">
  191. <el-col :span="18">
  192. <div class="details-head">
  193. <div class="title">
  194. <i class="fa fa-th-list" aria-hidden="true" /> 收款明细
  195. </div>
  196. </div>
  197. <div class="details-body">
  198. <el-table ref="filesTable" :data="form.details" size="small" height="100%" border
  199. header-row-class-name="list-header-row" highlight-current-row>
  200. <el-table-column type="index" label="序号" width="47" align="center" />
  201. <el-table-column label="任务名称" prop="taskTypeName" align="center" show-overflow-tooltip>
  202. </el-table-column>
  203. <el-table-column label="说明" prop="explain" align="center" show-overflow-tooltip>
  204. </el-table-column>
  205. <el-table-column label="任务金额" prop="amount" width="100" align="center">
  206. <template #default="scope">
  207. <span>{{ rowNum(scope.row.amount) }}</span>
  208. </template>
  209. </el-table-column>
  210. <el-table-column label="已收款金额" prop="reallyAmount" width="100" align="center">
  211. <template #default="scope">
  212. <span>{{ rowNum(scope.row.reallyAmount) }}</span>
  213. </template>
  214. </el-table-column>
  215. <el-table-column label="已支付金额" prop="payment" width="100" align="center">
  216. <template #default="scope">
  217. <span>{{ rowNum(scope.row.payment) }}</span>
  218. </template>
  219. </el-table-column>
  220. <el-table-column label="审核支付金额" prop="reviewAmount" width="100" align="center">
  221. <template #default="scope">
  222. <span>{{ rowNum(scope.row.reviewAmount) }}</span>
  223. </template>
  224. </el-table-column>
  225. <el-table-column label="可支出金额" align="center">
  226. <template #default="scope">
  227. {{rowNum((Number(scope.row.reallyAmount) || 0) - (Number(scope.row.payment) || 0))}}
  228. </template>
  229. </el-table-column>
  230. <el-table-column label="本次支出金额" prop="paymentAmount" width="100" align="center">
  231. <template #default="scope">
  232. <template v-if="editStatus">
  233. <el-input-number v-model="scope.row.paymentAmount" size="small" placeholder="本次支出金额"
  234. :precision="2" :controls="false" style="width: 100%" @change="
  235. (arg) =>
  236. amountChangeHandler(
  237. arg,
  238. scope.row,
  239. 'paymentAmount'
  240. )
  241. " />
  242. </template>
  243. <template v-else>{{
  244. rowNum(scope.row.paymentAmount)
  245. }}</template>
  246. </template>
  247. </el-table-column>
  248. </el-table>
  249. </div>
  250. </el-col>
  251. <el-col :span="6">
  252. <div class="details-head">
  253. <div class="title">
  254. <i class="fa fa-th-list" aria-hidden="true" /> 附件
  255. <i style="color: red">*</i>
  256. </div>
  257. <el-upload v-if="editStatus" action="#" :http-request="upload" :with-credentials="true"
  258. :show-file-list="false" multiple>
  259. <el-button size="small" type="primary" icon="Upload">点击上传</el-button>
  260. </el-upload>
  261. </div>
  262. <div class="details-body">
  263. <el-table ref="filesTable" :data="form.files" size="small" height="100%" border
  264. header-row-class-name="list-header-row" highlight-current-row>
  265. <el-table-column type="index" label="序号" width="47" align="center" />
  266. <el-table-column label="文件名" prop="originalFileName" align="center" show-overflow-tooltip>
  267. <template #default="scope">
  268. <el-button size="small" type="primary" link @click="openFile(scope.row)">{{
  269. scope.row.originalFileName }}</el-button>
  270. </template>
  271. </el-table-column>
  272. <el-table-column label="操作" width="50" align="center">
  273. <template #default="scope">
  274. <div v-if="editStatus">
  275. <el-button size="small" link type="danger"
  276. @click="handlerDelAttach(scope.row, scope.$index)">删除</el-button>
  277. </div>
  278. </template>
  279. </el-table-column>
  280. </el-table>
  281. </div>
  282. </el-col>
  283. </el-row>
  284. </div>
  285. </div>
  286. </el-drawer>
  287. <el-dialog title="财务审核详情" v-model="rejectOpen" width="500px" append-to-body draggable :close-on-click-modal="false">
  288. <el-form ref="dictRef" :model="rejectForm" label-width="100" size="small">
  289. <el-form-item label="审核状态">
  290. <el-select v-model.trim="rejectForm.verifyStatus" placeholder="请选择" size="small">
  291. <el-option v-for="i in verified" :key="i.value" :label="i.label" :value="i.value" />
  292. </el-select>
  293. </el-form-item>
  294. <el-form-item :label="rejectForm.verifyStatus == 2 ? '驳回原因' : '审核意见'" :prop="verifyRemark">
  295. <el-input v-model.trim="rejectForm.verifyComment" type="textarea" maxlength="200" show-word-limit :rows="3"
  296. placeholder="请输入审核意见" />
  297. </el-form-item>
  298. <el-form-item label="附件">
  299. <el-upload action="#" :http-request="upload2" :with-credentials="true" :show-file-list="false" multiple
  300. :limit="5">
  301. <el-button size="small" type="primary" icon="Upload">点击上传</el-button>
  302. </el-upload>
  303. <el-table ref="dbTable" :data="rejectForm.evidenceFiles" size="small" border
  304. header-row-class-name="list-header-row" row-class-name="list-row">
  305. <el-table-column label="文件名" prop="originalFileName" align="center" show-overflow-tooltip>
  306. <template #default="scope">
  307. <el-button size="small" type="text" @click="openFile(scope.row)">{{
  308. scope.row.originalFileName == ""
  309. ? "打开文件"
  310. : scope.row.originalFileName
  311. }}</el-button>
  312. </template>
  313. </el-table-column>
  314. <el-table-column label="操作" width="80" prop="fileType" align="center">
  315. <template #default="scope">
  316. <el-button size="small" link type="danger"
  317. @click="handlerEportFilesDel(scope.row, scope.$index)">删除</el-button>
  318. </template>
  319. </el-table-column>
  320. </el-table>
  321. </el-form-item>
  322. </el-form>
  323. <template #footer>
  324. <div class="dialog-footer">
  325. <el-button type="primary" icon="Finished" size="small" @click="verifyUpload()">确 定</el-button>
  326. <el-button icon="close" size="small" @click="rejectCancel">取 消</el-button>
  327. </div>
  328. </template>
  329. </el-dialog>
  330. <el-dialog title="出纳审核详情" v-model="cashierOpen" width="500px" append-to-body draggable>
  331. <el-form ref="dictRef" :model="form" label-width="100" size="small">
  332. <el-form-item label="审核状态">
  333. <el-select v-model.trim="cashierForm.verifyStatus" placeholder="请选择" size="small">
  334. <el-option v-for="i in cashierVerified" :key="i.value" :label="i.label" :value="i.value" />
  335. </el-select>
  336. </el-form-item>
  337. <el-form-item label="实际支出时间" required>
  338. <el-date-picker v-model.trim="cashierForm.actuallyDate" size="small" :clearable="true"
  339. format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" align="center" type="datetime"
  340. placeholder="实际付款时间" />
  341. </el-form-item>
  342. <!-- <el-form-item label="支出附件上传" required>
  343. </el-form-item> -->
  344. <el-form-item :label="cashierForm.verifyStatus == 4 ? '驳回原因' : '审核意见'" :prop="verifyComment">
  345. <el-input v-model.trim="cashierForm.verifyComment" type="textarea" maxlength="200" show-word-limit :rows="3"
  346. placeholder="请输入审核意见" />
  347. </el-form-item>
  348. <el-form-item label="附件">
  349. <el-upload action="#" :http-request="upload3" :with-credentials="true" :show-file-list="false" multiple
  350. :limit="5">
  351. <el-button size="small" type="primary" icon="Upload">点击上传</el-button>
  352. </el-upload>
  353. <el-table ref="dbTable" :data="cashierForm.evidenceFiles" size="small" border
  354. header-row-class-name="list-header-row" row-class-name="list-row">
  355. <el-table-column label="文件名" prop="originalFileName" align="center" show-overflow-tooltip>
  356. <template #default="scope">
  357. <el-button size="small" type="text" @click="openFile(scope.row)">{{
  358. scope.row.originalFileName == ""
  359. ? "打开文件"
  360. : scope.row.originalFileName
  361. }}</el-button>
  362. </template>
  363. </el-table-column>
  364. <el-table-column label="操作" width="80" prop="fileType" align="center">
  365. <template #default="scope">
  366. <el-button size="small" link type="danger"
  367. @click="handlerEportFilesDel(scope.row, scope.$index)">删除</el-button>
  368. </template>
  369. </el-table-column>
  370. </el-table>
  371. </el-form-item>
  372. </el-form>
  373. <template #footer>
  374. <div class="dialog-footer">
  375. <el-button type="primary" icon="Finished" size="small" @click="cashierVerifyUpload()">确 定</el-button>
  376. <el-button icon="close" size="small" @click="cashierVerifyCancel">取 消</el-button>
  377. </div>
  378. </template>
  379. </el-dialog>
  380. <dialog-contract-choice ref="contractChoiceRef" @choice="contractChoiceHandle" />
  381. <company-form ref="companyRef" :get-list="getList"></company-form>
  382. <contract-form ref="contractRef" :get-list="getList" />
  383. </div>
  384. </template>
  385. <script setup>
  386. import { uploadFile } from "@/api/tool/file";
  387. // import {
  388. // getOrder,
  389. // initTaskTypes,
  390. // addOrder,
  391. // updateOrder,
  392. // verifyOrder,
  393. // alterOrder,
  394. // dissolutionOrder,
  395. // } from "@/api/business/crm/contract";
  396. import {
  397. listCompany,
  398. getPayment,
  399. savePayment,
  400. listTypes,
  401. listContractDetail,
  402. verifyPayment, setPaymentZero
  403. } from "@/api/business/financial/payment";
  404. import { listSource } from "@/api/settings/source";
  405. import { getOrder } from "@/api/business/crm/contract";
  406. import { listUser } from "@/api/system/user";
  407. import CustomerFormCom from "@/components/CustomerFormCom";
  408. import DialogContractChoice from "@/views/dialog/DialogContractChoice.vue";
  409. import { formatDate, rowNum } from "@/utils/index";
  410. import { ref } from "vue";
  411. import companyForm from "@/views/business/crm/company/formView.vue";
  412. import contractForm from "@/views/business/crm/order/formView.vue";
  413. import useUserStore from "@/store/modules/user";
  414. import auth from "@/plugins/auth";
  415. const { proxy } = getCurrentInstance();
  416. const baseUrl = import.meta.env.VITE_APP_BASE_API;
  417. /** 父组件传参 */
  418. const props = defineProps({
  419. getList: {
  420. type: Function,
  421. default: () => { },
  422. },
  423. });
  424. const { getList } = toRefs(props);
  425. /** 字典数组区 */
  426. const { virtual_address } = proxy.useDict("virtual_address");
  427. /** 表单抽屉 页变量 */
  428. const title = ref("");
  429. const loading = ref(false);
  430. const multiple = ref(true);
  431. const visible = ref(false);
  432. const editStatus = ref(false);
  433. const sourceCategories = ref([]);
  434. const type = ref("");
  435. const rejectOpen = ref(false);
  436. const rejectForm = ref({});
  437. const cashierForm = ref({});
  438. const detailEmpty = {
  439. id: null,
  440. taskTypeName: "",
  441. taskTypeId: null,
  442. serviceNum: undefined,
  443. freeNum: undefined,
  444. price: undefined,
  445. amount: undefined,
  446. addressStyle: undefined,
  447. address: undefined,
  448. fictionAddressId: undefined,
  449. tenantId: undefined,
  450. explain: undefined,
  451. province: "",
  452. city: "",
  453. district: "",
  454. addressStyle: 1,
  455. provinceId: undefined,
  456. processes: [],
  457. defaultProcesses: [],
  458. };
  459. const provinces = ref(proxy.region.getProvinces());
  460. provinces.value.unshift({ code: "", name: "全部" });
  461. const cities = ref([]);
  462. const districts = ref([]);
  463. const paymentTypes = ref([]);
  464. const paymentSubjects = ref([]);
  465. const paymentEmpty = {
  466. id: null,
  467. flowNo: "",
  468. paymentCauseId: null,
  469. paymentSubjectId: null,
  470. acceptAccountTypeId: null,
  471. subsidiaryId: null,
  472. subsidiary: null,
  473. subsidiaryName: "",
  474. subsidiaryBankAccount: "",
  475. subsidiaryBankName: "",
  476. explain: undefined,
  477. companyId: null,
  478. companyName: "",
  479. amount: 0,
  480. verifyStatus: 0,
  481. acceptAccount: "",
  482. accountBank: "",
  483. applierId: useUserStore().user.userId,
  484. applierName: "",
  485. creatorName: useUserStore().user.nickName,
  486. details: [],
  487. files: [],
  488. };
  489. const isFullscreen = ref(false);
  490. const webHost = import.meta.env.VITE_APP_BASE_API;
  491. const data = reactive({
  492. form: {},
  493. rules: {
  494. companyName: [
  495. { required: true, message: "客户名称不能为空", trigger: "blur" },
  496. ],
  497. formDate: [
  498. { required: true, message: "支出日期不能为空", trigger: "blur" },
  499. ],
  500. },
  501. timeOptions: { start: "08:30", step: "00:15", end: "18:30" },
  502. verified: [
  503. {
  504. value: 0,
  505. label: "未审核",
  506. },
  507. {
  508. value: 1,
  509. label: "通过",
  510. },
  511. {
  512. value: 2,
  513. label: "驳回",
  514. },
  515. ],
  516. cashierVerified: [
  517. {
  518. value: 1,
  519. label: "未审核",
  520. },
  521. {
  522. value: 3,
  523. label: "通过",
  524. },
  525. {
  526. value: 4,
  527. label: "驳回",
  528. },
  529. ],
  530. cashierOpen: false,
  531. });
  532. const { form, rules, timeOptions, verified, cashierVerified, cashierOpen } =
  533. toRefs(data);
  534. /*********************** 方法区 ****************************/
  535. /** 打开抽屉 */
  536. function open(id) {
  537. reset();
  538. visible.value = true;
  539. editStatus.value = true;
  540. if (id != null) {
  541. getPayment(id).then((res) => {
  542. form.value = res.data;
  543. editStatus.value = false;
  544. form.value.paymentCauseId = form.value.paymentCauseId === "0" ? null :form.value.paymentCauseId;
  545. form.value.paymentSubjectId = form.value.paymentSubjectId === "0" ? null :form.value.paymentSubjectId;
  546. paymentCauseChange(form.value.paymentCauseId);
  547. paymentSubjectChange(form.value.paymentSubjectId);
  548. });
  549. }
  550. }
  551. function init() {
  552. Promise.all([listTypes()]).then((res) => {
  553. paymentTypes.value = res[0].rows;
  554. });
  555. }
  556. /** 取消按钮 */
  557. function cancel() {
  558. visible.value = false;
  559. reset();
  560. }
  561. /** 表单重置 */
  562. function reset() {
  563. form.value = JSON.parse(JSON.stringify(paymentEmpty));
  564. paymentSubjects.value = [];
  565. }
  566. function returnZero() {
  567. proxy.$modal
  568. .confirm("是否确认退回")
  569. .then(function () {
  570. setPaymentZero(form.value.id)
  571. })
  572. .then(() => {
  573. visible.value = false;
  574. getList.value();
  575. proxy.$modal.msgSuccess("退回成功");
  576. })
  577. .catch(() => { });
  578. }
  579. /** 全屏缩放 */
  580. function handleScreen() {
  581. const dom = document.querySelector(
  582. ".list-container > .el-drawer__wrapper > .el-overlay"
  583. );
  584. isFullscreen.value = !isFullscreen.value;
  585. dom.style.position = isFullscreen.value ? "fixed" : "absolute";
  586. }
  587. /** 提交按钮 */
  588. function submitForm() {
  589. if (form.value.contractId === 0 || form.value.contractId == null) {
  590. proxy.$modal.msgError("请输入合同");
  591. return;
  592. }
  593. if (form.value.amount == null || form.value.amount === 0) {
  594. proxy.$modal.msgError("请输入支出金额");
  595. return;
  596. }
  597. for (let i = 0; i < form.value.details.length; i++) {
  598. let item = form.value.details[i];
  599. const tempAmount = rowNum((Number(item.reallyAmount) || 0) - (Number(item.payment) || 0)) - (Number(item.reviewAmount || 0));
  600. // const countAmount = rowNum((Number(item.reviewAmount) || 0) + (Number(item.paymentAmount) || 0)) - (Number(item.thisPaymentAmount || 0));
  601. const countAmount = (Number(item.reviewAmount) || 0) + (Number(item.payment) || 0);
  602. const amount = (Number(countAmount || 0)) - (Number(item.thisPaymentAmount || 0))+(Number(item.paymentAmount || 0));
  603. console.log("总金额",(Number(item.reviewAmount) || 0) + (Number(item.payment) || 0));
  604. console.log("现总金额",amount)
  605. if (item.paymentAmount !== 0 && tempAmount < item.paymentAmount) {
  606. if(item.reallyAmount < amount){
  607. console.log(item.paymentAmount,item.reviewAmount,item.payment,item.thisPaymentAmount)
  608. proxy.$modal.msgError("当前的" + item.taskTypeName + "本次支出金额超过可支出金额,不可提交,请联系财务人员。");
  609. return;
  610. }
  611. }
  612. }
  613. proxy.$refs["orderRef"].validate((valid) => {
  614. if (valid && detailValid()) {
  615. const formValue = form.value;
  616. savePayment(formValue).then((res) => {
  617. open(res.data.id);
  618. getList.value();
  619. });
  620. }
  621. });
  622. }
  623. function detailValid() {
  624. if (form.value.files.length === 0) {
  625. proxy.$modal.msgError("收款附件为空");
  626. return false;
  627. }
  628. return true;
  629. }
  630. /** 查询表单信息 */
  631. function getForm() {
  632. loading.value = true;
  633. getOrder(form.value.id).then((response) => {
  634. loading.value = false;
  635. form.value = response.data;
  636. });
  637. }
  638. function handleServiceTypeClick(tab) {
  639. computedService();
  640. }
  641. function verifyHandler() {
  642. rejectHandler();
  643. }
  644. function cashierVerifyHandler() {
  645. cashierOpen.value = true;
  646. cashierForm.value = proxy.deepClone(form.value);
  647. }
  648. function rejectHandler() {
  649. rejectOpen.value = true;
  650. rejectForm.value = proxy.deepClone(form.value);
  651. }
  652. function rejectCancel() {
  653. rejectOpen.value = false;
  654. rejectForm.value = {};
  655. }
  656. function cashierVerifyCancel() {
  657. cashierOpen.value = false;
  658. cashierForm.value = {};
  659. }
  660. function upload2(param) {
  661. const formData = new FormData();
  662. formData.append("file", param.file);
  663. uploadFile(formData).then((res) => {
  664. if (res.code === 200) {
  665. const file = {};
  666. file.fileName = res.newFileName;
  667. file.url = res.url;
  668. file.fileType =
  669. res.newFileName.split(".")[res.newFileName.split(".").length - 1];
  670. file.originalFileName = res.originalFilename;
  671. file.fileUrl = res.fileName;
  672. console.log(11212, file);
  673. if (rejectForm.value.evidenceFiles == null) {
  674. rejectForm.value.evidenceFiles = [];
  675. }
  676. rejectForm.value.evidenceFiles.push(file);
  677. }
  678. });
  679. }
  680. function upload3(param) {
  681. const formData = new FormData();
  682. formData.append("file", param.file);
  683. uploadFile(formData).then((res) => {
  684. if (res.code === 200) {
  685. const file = {};
  686. file.fileName = res.newFileName;
  687. file.url = res.url;
  688. file.fileType =
  689. res.newFileName.split(".")[res.newFileName.split(".").length - 1];
  690. file.originalFileName = res.originalFilename;
  691. file.fileUrl = res.fileName;
  692. console.log(11212, file);
  693. if (cashierForm.value.evidenceFiles == null) {
  694. cashierForm.value.evidenceFiles = [];
  695. }
  696. cashierForm.value.evidenceFiles.push(file);
  697. }
  698. });
  699. }
  700. function handleDelFile2(index) {
  701. rejectForm.value.files.splice(index, 1);
  702. }
  703. function rejectSubmitHandler() {
  704. if (form.value.verifyRemark === "" || form.value.verifyRemark == null) {
  705. proxy.$modal.msgError("请填写驳回原因");
  706. return;
  707. }
  708. }
  709. function verifyUpload() {
  710. if (rejectForm.value.verifyStatus === 0) {
  711. proxy.$modal.msgError("请选择审核结果");
  712. return;
  713. }
  714. if (
  715. rejectForm.value.verifyStatus === 2 &&
  716. (rejectForm.value.verifyComment == null ||
  717. rejectForm.value.verifyComment === "")
  718. ) {
  719. proxy.$modal.msgError("请输入审核意见");
  720. return;
  721. }
  722. // if (
  723. // rejectForm.value.evidenceFiles == null ||
  724. // rejectForm.value.evidenceFiles.length === 0 || rejectForm.value.evidenceFiles.length>5
  725. // ) {
  726. // proxy.$modal.msgError("请上传附件并至多上传5个");
  727. // return;
  728. // }
  729. verifyPayment(rejectForm.value).then((res) => {
  730. open(form.value.id);
  731. getList.value();
  732. rejectCancel();
  733. proxy.$modal.msgSuccess("保存成功");
  734. });
  735. }
  736. function cashierVerifyUpload() {
  737. if (cashierForm.value.verifyStatus === 1) {
  738. proxy.$modal.msgError("请选择审核结果");
  739. return;
  740. }
  741. if (
  742. cashierForm.value.actuallyDate == null ||
  743. cashierForm.value.actuallyDate === ""
  744. ) {
  745. proxy.$modal.msgError("请选择支出时间");
  746. return;
  747. }
  748. // if (
  749. // cashierForm.value.evidenceFiles == null ||
  750. // cashierForm.value.evidenceFiles.length === 0 || cashierForm.value.evidenceFiles.length>5
  751. // ) {
  752. // proxy.$modal.msgError("请上传附件并至多上传5个");
  753. // return;
  754. // }
  755. if (
  756. cashierForm.value.verifyStatus === 4 &&
  757. (cashierForm.value.verifyComment == null ||
  758. cashierForm.value.verifyComment === "")
  759. ) {
  760. proxy.$modal.msgError("请输入审核意见");
  761. return;
  762. }
  763. cashierForm.value.paymentStatus =
  764. cashierForm.value.verifyStatus === 3 ? 1 : 0;
  765. verifyPayment(cashierForm.value).then((res) => {
  766. open(cashierForm.value.id);
  767. getList.value();
  768. cashierVerifyCancel();
  769. proxy.$modal.msgSuccess("保存成功");
  770. });
  771. }
  772. /** 文件上传 */
  773. function upload(param) {
  774. const fileForm = new FormData();
  775. fileForm.append("file", param.file);
  776. uploadFile(fileForm).then((res) => {
  777. if (res.code === 200) {
  778. const file = {};
  779. file.fileName = res.newFileName;
  780. file.url = res.url;
  781. file.originalFileName = res.originalFilename;
  782. file.fileUrl = res.fileName;
  783. form.value.files.push(file);
  784. }
  785. });
  786. }
  787. function handleDelFile(index) {
  788. form.value.files.splice(index, 1);
  789. }
  790. function amountChangeHandler(arg, row, field) {
  791. computeTotalAmount();
  792. }
  793. function computeTotalAmount() {
  794. let amount = 0;
  795. for (let index = 0; index < form.value.details.length; index++) {
  796. const element = form.value.details[index];
  797. amount += element.paymentAmount == null ? 0 : element.paymentAmount;
  798. }
  799. form.value.amount = amount;
  800. }
  801. function handlerEportFilesDel(row, index) {
  802. proxy.$modal
  803. .confirm("确定删除吗?")
  804. .then((_) => {
  805. rejectForm.value.evidenceFiles.splice(index, 1);
  806. })
  807. .catch((_) => {
  808. proxy.$modal.msg("已取消删除");
  809. });
  810. }
  811. function handlerEportFilesDel2(row, index) {
  812. proxy.$modal
  813. .confirm("确定删除吗?")
  814. .then((_) => {
  815. cashierForm.value.evidenceFiles.splice(index, 1);
  816. })
  817. .catch((_) => {
  818. proxy.$modal.msg("已取消删除");
  819. });
  820. }
  821. function amountChange() {
  822. let amount = 0;
  823. if (form.value.details.length > 0) {
  824. for (let i = 0; i < form.value.details.length; i++) {
  825. amount = amount + form.value.details[i].paymentAmount;
  826. }
  827. // 判断到款状态
  828. form.value.amount = amount;
  829. if (form.value.payedAmount > 0)
  830. form.value.arriveStatus =
  831. form.value.payedAmount === form.value.amount ? 1 : 2;
  832. else form.value.arriveStatus = 0;
  833. }
  834. }
  835. function handleInfo(row) {
  836. proxy.$refs.companyRef.open(row.companyId);
  837. }
  838. function handleContract() {
  839. proxy.$refs.contractRef.open(form.value.contractId);
  840. }
  841. function openFile(row) {
  842. window.open(`${baseUrl}${row.fileUrl}`);
  843. }
  844. function querySearchCompanyAsync(queryString, cb) {
  845. const query =
  846. queryString.length > 0
  847. ? {
  848. keyword: queryString,
  849. pageSize: 50,
  850. pageNum: 1,
  851. orderByColumn: "create_time",
  852. }
  853. : { pageSize: 50, pageNum: 1, orderByColumn: "create_time" };
  854. listCompany(query).then((res) => {
  855. cb(res.rows);
  856. });
  857. }
  858. function handleSelectCompany(item) {
  859. form.value.companyName = item.name;
  860. form.value.companyId = item.id;
  861. form.value.contractId = null;
  862. form.value.contractNo = null;
  863. }
  864. function paymentCauseChange(arg) {
  865. const index = paymentTypes.value.findIndex((v) => v.id === arg);
  866. if (index >= 0) {
  867. paymentSubjects.value = [].concat(
  868. paymentTypes.value[index].bizPaymentSubjectList
  869. );
  870. form.value.paymentCause = paymentTypes.value[index].name;
  871. if (
  872. paymentSubjects.value.findIndex(
  873. (v) => v.id === form.value.paymentSubjectId
  874. ) < 0
  875. ) {
  876. form.value.paymentSubjectId = null;
  877. form.value.paymentSubject = "";
  878. }
  879. }
  880. }
  881. function contractChoiceHandler() {
  882. if (form.value.companyId == null || form.value.companyId === "") {
  883. proxy.$modal.msgError("请选择客户");
  884. return;
  885. }
  886. proxy.$refs.contractChoiceRef.open({ companyId: form.value.companyId });
  887. }
  888. async function contractChoiceHandle(info) {
  889. // 清空之前的详情
  890. form.value.details = [];
  891. // 设置合同信息
  892. form.value.contractId = info.id;
  893. form.value.contractNo = info.contractNo;
  894. form.value.contractAmount = info.trueAmount;
  895. form.value.payedAmount = info.paidAmount;
  896. try {
  897. const orderResponse = await getOrder(info.id);
  898. form.value.boss = orderResponse.data.boss;
  899. form.value.party = orderResponse.data.party;
  900. const detailResponse = await listContractDetail({ contractId: info.id });
  901. const rows = detailResponse.rows;
  902. // 处理每一行数据
  903. rows.forEach((item) => {
  904. const detail = {
  905. contractId: item.contractId,
  906. contractDetailId: item.id,
  907. companyId: form.value.companyId,
  908. taskTypeId: item.taskTypeId,
  909. amount: item.amount,
  910. taskTypeName: item.taskTypeName,
  911. payment: item.payment,
  912. reallyAmount: item.reallyAmount,
  913. explain: item.explain,
  914. reviewAmount : item.reviewAmount,
  915. thisPaymentAmount : item.thisPaymentAmount
  916. };
  917. form.value.details.push(detail);
  918. });
  919. console.log(2323232, form.value);
  920. } catch (error) {
  921. console.error("在 contractChoiceHandle 中发生错误:", error);
  922. }
  923. }
  924. function handlerDelAttach(row, index) {
  925. proxy.$modal
  926. .confirm("确认删除该项么?")
  927. .then((_) => {
  928. form.value.files.splice(index, 1);
  929. })
  930. .catch((err) => {
  931. proxy.$modal.msgError("取消删除");
  932. });
  933. }
  934. function paymentSubjectChange(id) {
  935. const index = paymentSubjects.value.findIndex((v) => v.id === id);
  936. if (index >= 0) {
  937. form.value.paymentSubjectId = paymentSubjects.value[index].id;
  938. }
  939. }
  940. function checkPermission(templatePermission) {
  941. const all_permission = "*:*:*";
  942. const permissions = useUserStore().permissions;
  943. const hasPermissions = permissions.some((permission) => {
  944. return (
  945. all_permission === permission || templatePermission.includes(permission)
  946. );
  947. });
  948. return hasPermissions;
  949. }
  950. init();
  951. const reForm = () => {
  952. open(form.value.id);
  953. }
  954. const amountFormat = (row) => {
  955. console.log(row.reallyAmount,row.payment,row.reviewAmount)
  956. //rowNum((Number(scope.row.reallyAmount) || 0) - (Number(scope.row.payment) || 0)) - (Number(scope.row.reviewAmount || 0))
  957. }
  958. /** 暴露给父组件的方法 */
  959. defineExpose({
  960. open,
  961. });
  962. </script>