form.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. <template>
  2. <!-- 添加或修改项目信息对话框 -->
  3. <div class="el-drawer__wrapper company-list">
  4. <el-drawer :title="title" v-model="visible" direction="rtl" size="100%">
  5. <div class="page-container form-container">
  6. <!-- 功能按钮区域 -->
  7. <div class="form-btns-container">
  8. <span class="title-label"><el-icon>
  9. <Document />
  10. </el-icon>
  11. 对账单表单</span>
  12. <el-button v-show="form.status === 0" type="primary" size="small" icon="Finished"
  13. v-hasPermi="['business:deduct:confirm']" @click="handleConfirm">确认扣款</el-button>
  14. <el-button v-show="form.status === 0" type="danger" icon="back" size="small" @click="handleReject"
  15. v-hasPermi="['business:deduct:confirm']">驳回扣款</el-button>
  16. <el-button v-if="form.id" type="success" size="small" icon="refresh" @click="getForm">刷新</el-button>
  17. <div class="screen-btn" @click="handleScreen">
  18. <template v-if="!isFullscreen">
  19. <i class="fa fa-window-maximize" aria-hidden="true" />
  20. <!-- <span>全屏</span> -->
  21. </template>
  22. <template v-else>
  23. <i class="fa fa-window-restore" aria-hidden="true" />
  24. <!-- <span>还原</span> -->
  25. </template>
  26. </div>
  27. <div class="close-btn" @click="cancel">
  28. <i class="fa fa-times" aria-hidden="true" />
  29. <!-- <span>关闭</span> -->
  30. </div>
  31. </div>
  32. <el-form ref="companyRef" class="master-container" size="small" :model="form" :rules="rules" label-width="120px">
  33. <el-row :gutter="30">
  34. <el-col :span="6"> 结算单位:{{ form.contactCompany }} </el-col>
  35. <el-col :span="6"> 结算订单编号:{{ form.formNo }} </el-col>
  36. <el-col :span="4"> 上期余额:{{ form.prevRemainAmount }} </el-col>
  37. <el-col :span="4"> 本期消耗:{{ form.amount }} </el-col>
  38. <el-col :span="4"> 本期余额:{{ form.remainAmount }} </el-col>
  39. <el-col :span="24">
  40. <el-tabs v-model="activeName">
  41. <el-tab-pane label="汇总" name="base" class="baseTable">
  42. <table class="header" cellspacing="0" cellpadding="0" style="table-layout: fixed">
  43. <tbody>
  44. <tr class="bg-white-color">
  45. <td :colspan="1" style="width: 100px">自然月</td>
  46. <td :colspan="2" style="width: 200px">项目分类</td>
  47. <td :colspan="1" style="width: 100px">
  48. 客户数量(单位:户)
  49. </td>
  50. <td :colspan="1" style="width: 100px">
  51. 单价(单位:元)
  52. </td>
  53. <td :colspan="1" style="width: 100px">
  54. 小计(单位:元)
  55. </td>
  56. <td :colspan="1" style="width: 100px">优惠后单价</td>
  57. <td :colspan="1" style="width: 100px">优惠后金额</td>
  58. <td :colspan="1" style="width: 100px">减免金额</td>
  59. <td :colspan="1" style="width: 100px">实际支付</td>
  60. <td :colspan="2" class="tdLast" style="width: 100px">
  61. 说明
  62. </td>
  63. </tr>
  64. <tr class="bg-white-color" v-for="(item, index) in form.collect" :key="index">
  65. <td :colspan="1" v-if="index === 0" :rowspan="form.collect.length">
  66. {{ item.year }}年{{ item.month }}月
  67. </td>
  68. <td :colspan="1">{{ item.taskType }}</td>
  69. <td :colspan="1">
  70. {{
  71. item.taskType === "代理记账"
  72. ? item.annualIncome
  73. : item.taskType === "社保代缴" ||
  74. item.taskType === "公积金代缴"
  75. ? item.haveChanged === 1
  76. ? "有变化"
  77. : "无变化"
  78. : ""
  79. }}
  80. </td>
  81. <td :colspan="1">{{ item.companyNum }}</td>
  82. <td :colspan="1">{{ item.price }}</td>
  83. <td :colspan="1">
  84. {{ item.amount }}
  85. </td>
  86. <td :colspan="1">{{ item.discountPrice }}</td>
  87. <td :colspan="1">{{ item.discountAmount }}</td>
  88. <td :colspan="1">{{ item.freeAmount }}</td>
  89. <td :colspan="1">{{ item.actuallyAmount }}</td>
  90. <td :colspan="2" class="tdLast" v-if="index === 0" :rowspan="form.collect.length">
  91. {{ form.description }}
  92. </td>
  93. </tr>
  94. </tbody>
  95. </table>
  96. <table class="header" cellspacing="0" cellpadding="0">
  97. <tbody></tbody>
  98. </table>
  99. </el-tab-pane>
  100. <el-tab-pane label="循环任务" name="loop">
  101. <el-table v-loading="loading" :data="form.loopList" size="small" border height="100%">
  102. <!-- <el-table-column label="工单号" align="center" prop="workOrderNo" width="200" /> -->
  103. <el-table-column label="客户名称" align="center" width="150" prop="companyName" />
  104. <el-table-column label="税号" align="center" prop="socialCreditCode" width="150" />
  105. <el-table-column label="注册地址" align="center" prop="formNo" width="120">
  106. <template #default="scope">
  107. {{ scope.row.province }}-{{ scope.row.city }}-{{
  108. scope.row.district
  109. }}
  110. </template>
  111. </el-table-column>
  112. <el-table-column label="年收入" align="center" prop="annualIncome" width="100">
  113. </el-table-column>
  114. <el-table-column label="税务申报" align="center" width="80">
  115. <template #default="scope">
  116. {{ scope.row.isTax === 1 ? "是" : "否" }}
  117. </template>
  118. </el-table-column>
  119. <el-table-column label="社保" prop="remainAmount" align="center" width="80">
  120. <template #default="scope">
  121. {{ scope.row.isSocialSecurity === 1 ? "是" : "否" }}
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="公积金" prop="status" align="center" width="80">
  125. <template #default="scope">
  126. {{ scope.row.isHousingFund === 1 ? "是" : "否" }}
  127. </template>
  128. </el-table-column>
  129. <el-table-column label="纳税性质" align="center" prop="taxType" width="100" />
  130. <el-table-column label="征收方式" align="center" prop="collectionMethod" width="100" />
  131. <el-table-column label="定额金额" align="center" prop="quotaAmount" width="80" />
  132. <el-table-column label="实际年收入" align="center" prop="actuallyAnnualIncome" width="100" />
  133. <el-table-column label="社保有无变化" prop="status" align="center" width="100">
  134. <template #default="scope">
  135. {{
  136. scope.row.changedSocialSecurity === 1 ? "是" : "否"
  137. }}
  138. </template>
  139. </el-table-column>
  140. <el-table-column label="公积金有无变化" prop="status" align="center" width="100">
  141. <template #default="scope">
  142. {{ scope.row.changedHousingFund === 1 ? "是" : "否" }}
  143. </template>
  144. </el-table-column>
  145. <el-table-column label="累计年收入" prop="status" align="center" width="100">
  146. <template #default="scope">
  147. {{ scope.row.cumulativeIncome }}
  148. </template>
  149. </el-table-column>
  150. </el-table>
  151. </el-tab-pane>
  152. <el-tab-pane label="工商任务" name="once">
  153. <el-table v-loading="loading" :data="form.onceList" size="small" border height="100%">
  154. <!-- <el-table-column label="工单号" align="center" prop="workOrderNo" width="200" /> -->
  155. <el-table-column label="客户名称" align="center" width="200" prop="companyName" />
  156. <el-table-column label="税号" align="center" prop="socialCreditCode" width="150" />
  157. <el-table-column label="所在区" align="center" prop="formNo" width="120">
  158. <template #default="scope">
  159. {{ scope.row.province }}-{{ scope.row.city }}-{{
  160. scope.row.district
  161. }}
  162. </template>
  163. </el-table-column>
  164. <el-table-column label="办理事项" align="center" prop="annualIncome" width="120">
  165. <template #default="scope">
  166. {{ scope.row.taskTypeName }}-{{
  167. scope.row.taskTypeDetailName
  168. }}
  169. </template>
  170. </el-table-column>
  171. <el-table-column label="下单时间" prop="entrustDate" align="center" width="100">
  172. </el-table-column>
  173. <el-table-column label="完成时间" prop="finishedDate" align="center" width="100">
  174. </el-table-column>
  175. <el-table-column label="收费" prop="amount" align="center" width="80">
  176. </el-table-column>
  177. <el-table-column label="说明" align="center" prop="description" />
  178. </el-table>
  179. </el-tab-pane>
  180. </el-tabs>
  181. </el-col>
  182. </el-row>
  183. </el-form>
  184. </div>
  185. </el-drawer>
  186. <!-- 图片预览 -->
  187. <el-image-viewer v-if="showViewer" :url-list="currentFileList" @close="closeImages" :initial-index="showIndex" />
  188. </div>
  189. </template>
  190. <script setup>
  191. import { getToken } from "@/utils/auth";
  192. import {
  193. addFollow,
  194. listFollow,
  195. delFollow,
  196. } from "@/api/business/crm/companyFollowDetail";
  197. import {
  198. getDeduct,
  199. genDeduct,
  200. addDeduct,
  201. updateDeduct,
  202. confirmDeduct,
  203. rejectDeduct,
  204. } from "@/api/business/entrust/deduct";
  205. import useUserStore from "@/store/modules/user";
  206. import { deepClone } from "@/utils";
  207. import {
  208. incomeDefault,
  209. taxTypes,
  210. confirmDefault,
  211. collectionMethods,
  212. yesOrNo,
  213. } from "@/utils/default";
  214. const { proxy } = getCurrentInstance();
  215. /** 父组件传参 */
  216. const props = defineProps({
  217. getList: {
  218. type: Function,
  219. default: () => { },
  220. },
  221. });
  222. const { getList } = toRefs(props);
  223. /** 字典数组区 */
  224. import { uploadFile } from "@/api/tool/file";
  225. const CustomerFormComRef = ref(null);
  226. /** 表单抽屉 页变量 */
  227. const title = ref("");
  228. const loading = ref(false);
  229. const multiple = ref(true);
  230. const visible = ref(false);
  231. const editStatus = ref(false);
  232. const isFullscreen = ref(false);
  233. const addDetailNum = ref(1);
  234. const currentMember = {};
  235. const activeName = ref("base");
  236. const provinces = ref(proxy.region.getProvinces());
  237. provinces.value.unshift({ code: "", name: "全部" });
  238. const cities = ref([]);
  239. const districts = ref([]);
  240. const sourceCategories = ref([]);
  241. const area = ref([]);
  242. const fileList = ref([]);
  243. const showViewer = ref(false);
  244. const currentFileList = ref([]);
  245. const showIndex = ref(0);
  246. const types = ref([]);
  247. const taxDeclarationCategories = ref([]);
  248. const baseUrl = ref(import.meta.env.VITE_APP_BASE_API);
  249. const webHost = import.meta.env.VITE_APP_BASE_API;
  250. const setHeaders = {
  251. Authorization: getToken(),
  252. };
  253. const data = reactive({
  254. form: {},
  255. });
  256. const { form, rules } = toRefs(data);
  257. const contactorEmptyData = {
  258. id: null,
  259. name: "",
  260. position: "",
  261. gender: "男",
  262. phone: "",
  263. email: "",
  264. isMain: "是",
  265. remark: "",
  266. };
  267. const deductEmptyData = {
  268. id: null,
  269. collect: [],
  270. loopList: [],
  271. onceList: [],
  272. creatorId: useUserStore().user.id,
  273. };
  274. const queryRadio = ref("base-form");
  275. const defaultIsZero = ref(0);
  276. /*********************** 表单页方法 ****************************/
  277. function sourceValidator(rule, value, callback) {
  278. // console.log(form.value)
  279. if (form.value.sourceCategoryName === "") {
  280. callback(new Error("来源类型不能为空"));
  281. return;
  282. }
  283. // console.log(`referrerDataSource: ${form.value.referrerDataSource}`)
  284. // console.log(`sourceName: ${form.value.sourceName}`)
  285. if (
  286. form.value.referrerDataSource !== "" &&
  287. form.value.referrerDataSource != null &&
  288. (form.value.sourceName === "" || form.value.sourceName == null)
  289. ) {
  290. callback(new Error("来源不能为空"));
  291. return;
  292. }
  293. return callback();
  294. }
  295. /** 抽屉打开 */
  296. function open(id) {
  297. reset();
  298. visible.value = true;
  299. if (id) {
  300. getDeduct(id).then((response) => {
  301. form.value = response.data;
  302. editStatus.value = false;
  303. });
  304. }
  305. }
  306. /** 取消按钮 */
  307. function cancel() {
  308. visible.value = false;
  309. reset();
  310. }
  311. /** 表单重置 */
  312. function reset() {
  313. form.value = deepClone(deductEmptyData);
  314. if (CustomerFormComRef.value) CustomerFormComRef.value.reset();
  315. proxy.resetForm("companyRef");
  316. }
  317. /** 上传后方法处理 */
  318. function uploadSuccess(res) {
  319. if (res.code == 200) {
  320. const newAttach = {
  321. name: res.data.name,
  322. url: res.data.url,
  323. };
  324. form.value.attaches.push(newAttach);
  325. } else {
  326. proxy.$modal.msgError("上传失败" + res.msg);
  327. }
  328. }
  329. function handleDownLoad(url) {
  330. window.open(webHost + url);
  331. }
  332. // 全屏缩放
  333. function handleScreen() {
  334. const dom = document.querySelector(
  335. ".list-container > .el-drawer__wrapper > .el-overlay"
  336. );
  337. isFullscreen.value = !isFullscreen.value;
  338. dom.style.position = isFullscreen.value ? "fixed" : "absolute";
  339. }
  340. function getForm() {
  341. loading.value = true;
  342. getDeduct(form.value.id).then((response) => {
  343. form.value = response.data;
  344. editStatus.value = false;
  345. });
  346. }
  347. function checkZero() {
  348. if (defaultIsZero.value === 1) {
  349. return true;
  350. } else if (
  351. defaultIsZero.value != form.value.isZero &&
  352. form.value.isZero === 1
  353. ) {
  354. proxy.$modal.msgError("不可将非零申报客户改为零申报");
  355. return false;
  356. } else {
  357. return true;
  358. }
  359. }
  360. /** 添加从表 */
  361. function handleAdd() {
  362. for (var i = 0; i < addDetailNum.value; i++) {
  363. form.value.members.push({});
  364. }
  365. }
  366. /** 删除从表 */
  367. function handleDel(index) {
  368. proxy.$modal
  369. .confirm("确定删除?")
  370. .then(() => {
  371. form.value.members.splice(index, 1);
  372. })
  373. .catch(() => {
  374. proxy.$modal.msg("已取消删除");
  375. });
  376. }
  377. function handleDelAttach(index) {
  378. proxy.$modal
  379. .confirm("确定删除?")
  380. .then(() => {
  381. form.value.attaches.splice(index, 1);
  382. })
  383. .catch(() => {
  384. proxy.$modal.msg("已取消删除");
  385. });
  386. }
  387. /** 单选添加 */
  388. function handleDialogOpen(person) {
  389. multiple.value = false;
  390. currentMember.value = person;
  391. proxy.$refs.personRef.open();
  392. }
  393. /** 多选添加 */
  394. function handleAddBatch() {
  395. multiple.value = true;
  396. proxy.$refs.personRef.open();
  397. }
  398. function handleSingleSelected(person) {
  399. // console.log('单选带回', person)
  400. if (
  401. form.value.members.findIndex((item) => item.personId === person.id) === -1
  402. ) {
  403. currentMember.value.personId = person.id;
  404. currentMember.value.name = person.name;
  405. currentMember.value.code = person.code;
  406. currentMember.value.gender = person.gender;
  407. currentMember.value.age = person.age;
  408. currentMember.value.phone = person.phone;
  409. } else {
  410. proxy.$modal.msgError(person.name + "已存在,请勿重复添加!");
  411. }
  412. }
  413. function handleMultipleSelected(selection) {
  414. // console.log('多选回带', selection)
  415. for (var i = 0; i < selection.length; ++i) {
  416. const newPerson = {};
  417. if (
  418. form.value.members.findIndex(
  419. (item) => item.personId === selection[i].id
  420. ) === -1
  421. ) {
  422. newPerson.personId = selection[i].id;
  423. newPerson.name = selection[i].name;
  424. newPerson.code = selection[i].code;
  425. newPerson.gender = selection[i].gender;
  426. newPerson.age = selection[i].age;
  427. newPerson.phone = selection[i].phone;
  428. form.value.members.push(newPerson);
  429. } else {
  430. proxy.$modal.msgError(selection[i].name + "已存在,请勿重复添加!");
  431. }
  432. }
  433. }
  434. function scrollTargetTo(target) {
  435. const targetElement = document.getElementById(target);
  436. if (targetElement) {
  437. targetElement.scrollIntoView();
  438. }
  439. }
  440. function validDetails() {
  441. const contactors = form.value.contactors;
  442. if (contactors.length === 0) {
  443. return true;
  444. }
  445. return true;
  446. }
  447. function closeImages() {
  448. reset();
  449. showViewer.value = false;
  450. }
  451. function handleConfirm() {
  452. proxy.$modal
  453. .confirm("确认扣款么?")
  454. .then((_) => {
  455. confirmDeduct(form.value).then((res) => {
  456. cancel();
  457. getList.value();
  458. });
  459. })
  460. .catch((_) => {
  461. proxy.$modal.msg("取消确认");
  462. });
  463. }
  464. function handleReject() {
  465. proxy.$modal
  466. .confirm("确认驳回么?")
  467. .then((_) => {
  468. rejectDeduct(form.value).then((res) => {
  469. cancel();
  470. getList.value();
  471. });
  472. })
  473. .catch((_) => {
  474. proxy.$modal.msg("取消确认");
  475. });
  476. }
  477. // 暴露给父组件的方法
  478. defineExpose({
  479. open,
  480. });
  481. </script>
  482. <style>
  483. .header {
  484. text-align: center;
  485. line-height: 30px;
  486. }
  487. .baseTable table tbody tr td {
  488. border-left: 1px solid #dadada;
  489. border-top: 1px solid #dadada;
  490. border-bottom: 1px solid #dadada;
  491. padding: 0;
  492. border-spacing: 0;
  493. }
  494. .tdLast {
  495. border-right: 1px solid #dadada;
  496. }
  497. </style>