view.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. <template>
  2. <el-dialog title="社保人员信息" v-model="visible" :width="width" append-to-body draggable @close="close">
  3. <!-- 功能按钮 -->
  4. <div style="padding: 8px 24px 16px 24px">
  5. <el-form size="small" label-width="100px" v-model="form">
  6. <el-row :gutter="30">
  7. <el-col :span="12">
  8. <el-form-item label="客户名称">
  9. <div>{{ form.companyName }}</div>
  10. </el-form-item>
  11. </el-col>
  12. <el-col :span="12">
  13. <el-form-item label="所属月份">
  14. <div>{{ form.year }}-{{ form.month }}</div>
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="12">
  18. <el-form-item label="政务网账号" required class="edit-label">
  19. <template #label>
  20. <div>政务网账号</div>
  21. </template>
  22. <el-input v-if="form.isFirstSocialSecurity === 0 || editStatus" v-model="form.governmentAccountNo"
  23. placeholder="请输入政务网账号" />
  24. <div v-else>{{ form.governmentAccountNo }}</div>
  25. </el-form-item>
  26. </el-col>
  27. <el-col :span="12">
  28. <el-form-item label="政务网密码" required class="edit-label">
  29. <template #label>
  30. <div>政务网密码</div>
  31. </template>
  32. <el-input v-if="form.isFirstSocialSecurity === 0 || editStatus" v-model="form.governmentPassword"
  33. placeholder="请输入政务网密码" @blur="(value) => passwordCheckHandler(value, 'governmentPassword')
  34. " />
  35. <div v-else>{{ form.governmentPassword }}</div>
  36. </el-form-item>
  37. </el-col>
  38. <el-col :span="12">
  39. <el-form-item label="社保账号" required class="edit-label">
  40. <template #label>
  41. <div>社保账号</div>
  42. </template>
  43. <el-input v-if="form.isFirstSocialSecurity === 0 || editStatus" v-model="form.socialSecurityAccountNo"
  44. placeholder="请输入社保账号" />
  45. <div v-else>{{ form.socialSecurityAccountNo }}</div>
  46. </el-form-item>
  47. </el-col>
  48. <el-col :span="12">
  49. <el-form-item label="社保密码" required class="edit-label">
  50. <template #label>
  51. <div>社保密码</div>
  52. </template>
  53. <el-input v-if="form.isFirstSocialSecurity === 0 || editStatus" v-model="form.socialSecurityPassword"
  54. placeholder="请输入社保密码" @blur="(value) =>
  55. passwordCheckHandler(value, 'socialSecurityPassword')
  56. " />
  57. <div v-else>{{ form.socialSecurityPassword }}</div>
  58. </el-form-item>
  59. </el-col>
  60. <el-col :span="12">
  61. <el-form-item label="用工密码" required class="edit-label">
  62. <template #label>
  63. <div>用工密码</div>
  64. </template>
  65. <el-input v-if="form.isFirstSocialSecurity === 0 || editStatus" v-model="form.employeePassword"
  66. placeholder="请输入用工密码" @blur="(value) => passwordCheckHandler(value, 'employeePassword')
  67. " />
  68. <div v-else>{{ form.employeePassword }}</div>
  69. </el-form-item>
  70. </el-col>
  71. <el-col :span="24" class="details-container">
  72. <!--操作按钮 开始-->
  73. <div class="details-head">
  74. <div class="title">
  75. <i class="fa fa-th-list" aria-hidden="true" /> 人员信息
  76. </div>
  77. </div>
  78. <div class="details-body">
  79. <div>
  80. <el-table ref="sourceTable" :data="form.details" size="small" max-height="260px" border
  81. highlight-current-row header-row-class-name="list-header-row" :row-class-name="tableRowClassName"
  82. @selection-change="handleCheckChange" @current-change="handleCurrentChange">
  83. <!-- <el-table-column type="selection" width="40" align="center" /> -->
  84. <el-table-column type="index" label="序号" width="55" align="center" />
  85. <el-table-column label="姓名" width="80" align="center">
  86. <template #default="scope">
  87. <div>
  88. {{ scope.row.employeeName }}
  89. </div>
  90. <span style="
  91. color: red;
  92. position: absolute;
  93. z-index: 10;
  94. top: 4px;
  95. right: 6px;
  96. ">*</span>
  97. </template>
  98. </el-table-column>
  99. <el-table-column label="电话号" width="130" align="center">
  100. <template #default="scope">
  101. <div>
  102. {{ scope.row.phone }}
  103. </div>
  104. <span style="
  105. color: red;
  106. position: absolute;
  107. z-index: 10;
  108. top: 4px;
  109. right: 6px;
  110. ">*</span>
  111. </template>
  112. </el-table-column>
  113. <el-table-column label="身份证正面" width="120" align="center">
  114. <template #default="scope">
  115. <div class="show-image" style="display: flex; justify-content: center">
  116. <img class="img" :src="baseUrl + '/' + scope.row.idCardImage" alt=""
  117. @click="handleImageView(scope.row.idCardImage)" />
  118. </div>
  119. <span style="
  120. color: red;
  121. position: absolute;
  122. z-index: 10;
  123. top: 4px;
  124. right: 6px;
  125. ">*</span>
  126. </template>
  127. </el-table-column>
  128. <el-table-column label="身份证反面" width="120" align="center">
  129. <template #default="scope">
  130. <div class="show-image" style="display: flex; justify-content: center">
  131. <img class="img" :src="baseUrl + '/' + scope.row.idCardImageBack" alt=""
  132. @click="handleImageView(scope.row.idCardImageBack)" />
  133. </div>
  134. <span style="
  135. color: red;
  136. position: absolute;
  137. z-index: 10;
  138. top: 4px;
  139. right: 6px;
  140. ">*</span>
  141. </template>
  142. </el-table-column>
  143. <el-table-column label="基数" width="100" align="center">
  144. <template #default="scope">
  145. <div>
  146. {{ scope.row.cardinalNumber }}
  147. </div>
  148. <span style="
  149. color: red;
  150. position: absolute;
  151. z-index: 10;
  152. top: 4px;
  153. right: 6px;
  154. ">*</span>
  155. </template>
  156. </el-table-column>
  157. <el-table-column label="医疗基数" width="100" align="center">
  158. <template #default="scope">
  159. <div>
  160. {{ scope.row.medicalCardinalNumber }}
  161. </div>
  162. <span style="
  163. color: red;
  164. position: absolute;
  165. z-index: 10;
  166. top: 4px;
  167. right: 6px;
  168. ">*</span>
  169. </template>
  170. </el-table-column>
  171. <!-- <el-table-column label="签名" width="100" header-align="center" required>
  172. </el-table-column> -->
  173. <el-table-column label="备注" header-align="center">
  174. <template #default="scope">
  175. <div>
  176. {{ scope.row.remark }}
  177. </div>
  178. </template>
  179. </el-table-column>
  180. </el-table>
  181. </div>
  182. </div>
  183. </el-col>
  184. <el-col :span="24">
  185. <el-divider />
  186. </el-col>
  187. <el-col :span="24">
  188. <el-form-item label="是否变更">
  189. {{ form.isChanged === 1 ? "是" : "否" }}
  190. </el-form-item>
  191. </el-col>
  192. <el-col :span="24">
  193. <el-form-item label="备注">
  194. {{ form.content }}
  195. </el-form-item>
  196. </el-col>
  197. <el-col v-if="showVerify()" :span="24">
  198. <el-divider />
  199. </el-col>
  200. <el-col :span="24">
  201. <el-form-item label="审核备注">
  202. <el-input v-if="showVerify()" v-model.trim="form.verifyContent" maxlength="200" show-word-limit
  203. type="textarea" rows="2" />
  204. <div v-else>{{ form.verifyContent }}</div>
  205. </el-form-item>
  206. </el-col>
  207. </el-row>
  208. </el-form>
  209. </div>
  210. <div class="form-btns-container" style="height: 40px">
  211. <el-button v-if="showVerify()" type="danger" size="small" icon="back" style="float: right; margin-left: 12px"
  212. @click="handleVerify(4)">
  213. 驳回</el-button>
  214. <el-button v-if="showVerify()" type="primary" size="small" icon="check" style="float: right; margin-left: 12px"
  215. @click="handleVerify(3)">审核通过</el-button>
  216. <el-button v-if="verifiable() && form.status === 3" type="warning" size="small" icon="back"
  217. style="float: right; margin-left: 12px" @click="returnStatus()">退回</el-button>
  218. </div>
  219. <feedback-dialog ref="feedbackDialogView" :verify="verify" />
  220. <el-image-viewer v-if="showViewer" :url-list="currentFileList" @close="closeImages" :initial-index="showIndex" />
  221. <!-- <print-dialog ref="printDialog" /> -->
  222. </el-dialog>
  223. </template>
  224. <script setup>
  225. import {
  226. getDetail,
  227. verifyDetail,
  228. turnBackDetail,
  229. } from "@/api/business/production/socialSecurityConfirm";
  230. import feedbackDialog from "../feedbackDialog.vue";
  231. import useUserStore from "@/store/modules/user";
  232. import { ref } from "vue";
  233. const { proxy } = getCurrentInstance();
  234. const visible = ref(false);
  235. const width = ref(800);
  236. const selections = ref([]);
  237. const currentSource = ref(null);
  238. const showViewer = ref(false);
  239. const currentFileList = ref([]);
  240. const showIndex = ref(0);
  241. const editStatus = ref(false);
  242. const baseUrl = ref(import.meta.env.VITE_APP_BASE_API);
  243. const permissions = useUserStore().permissions;
  244. const all_permission = "*:*:*";
  245. const feedbackDialogView = ref(null);
  246. const confirmChoices = ref([
  247. {
  248. label: "是",
  249. value: 1,
  250. },
  251. {
  252. label: "否",
  253. value: 0,
  254. },
  255. ]);
  256. const props = defineProps({
  257. getList: {
  258. type: Function,
  259. default: () => { },
  260. },
  261. });
  262. const { getList } = toRefs(props);
  263. const total = ref(0);
  264. const employeeEmptyData = {
  265. id: null,
  266. title: "",
  267. remark: "",
  268. employeeName: "",
  269. departmentName: "",
  270. idCode: "",
  271. salaryAmount: "",
  272. bonusAmount: "",
  273. allowanceAmount: "",
  274. subsidyAmount: "",
  275. absenceCut: "",
  276. planSalary: 0,
  277. actuallySalary: 0,
  278. endowmentInsurance: 0,
  279. medicalInsurance: 0,
  280. unemploymentBenefit: 0,
  281. seriousIllnessInsurance: 0,
  282. housingFund: 0,
  283. otherCut: 0,
  284. cumulativeIncome: 0,
  285. cumulativeSpecialCut: 0,
  286. cumulativeChildEduCut: 0,
  287. cumulativeHouseLoanInterestCut: 0,
  288. cumulativeHouseRentCut: 0,
  289. cumulativeSupportElderCut: 0,
  290. cumulativeContinuingEduCut: 0,
  291. cumulativeBabyCareCut: 0,
  292. sumSpecialCumulativeCut: 0,
  293. cumulativeOtherCut: 0,
  294. cumulativeIndividualIncomeTax: 0,
  295. cumulativeHasPaidIit: 0,
  296. currentIndividualIncomeTax: 0,
  297. idiograph: "",
  298. details: [],
  299. editStatus: true,
  300. };
  301. const form = ref({
  302. amount: null,
  303. details: [],
  304. });
  305. const emptyForm = {
  306. details: [],
  307. };
  308. function open(detail) {
  309. console.log(detail);
  310. visible.value = true;
  311. form.value = detail;
  312. loadData();
  313. }
  314. function loadData() {
  315. getDetail(form.value).then((res) => {
  316. form.value = { ...proxy.deepClone(emptyForm), ...res.data };
  317. computeTotal();
  318. });
  319. }
  320. function close() {
  321. visible.value = false;
  322. reset();
  323. }
  324. function reset() {
  325. form.value = proxy.deepClone(emptyForm);
  326. total.value = 0;
  327. }
  328. function printSalary() { }
  329. function exportSalary() { }
  330. function showVerify() {
  331. if (
  332. form.value.id == null ||
  333. form.value.status === 0 ||
  334. form.value.status === 3 ||
  335. form.value.status === 4
  336. ) {
  337. return false;
  338. } else if (verifiable()) {
  339. return true;
  340. } else {
  341. return false;
  342. }
  343. }
  344. function verifiable() {
  345. // console.log(permissions)
  346. // console.log(permissions)
  347. return (
  348. permissions.includes(all_permission) ||
  349. permissions.includes("business:socialSecurityConfirm:verify")
  350. );
  351. }
  352. function handleCurrentChange(row) {
  353. currentSource.value = row;
  354. }
  355. function handleCheckChange(selection) {
  356. selections.value = selection.map((item) => item);
  357. }
  358. function getSummaries(param) {
  359. const { columns, data } = param;
  360. const sums = [];
  361. columns.forEach((column, index) => {
  362. if (index === 0) {
  363. sums[index] = "合计";
  364. return;
  365. } else if (index === 1) {
  366. sums[index] = "";
  367. return;
  368. }
  369. const values = data.map((item) => Number(item[column.property]));
  370. if (!values.every((value) => isNaN(value))) {
  371. sums[index] = values.reduce((prev, curr) => {
  372. const value = Number(curr);
  373. if (!isNaN(value)) {
  374. return (Number(prev) + Number(curr)).toFixed(2);
  375. } else {
  376. return Number(prev).toFixed(2);
  377. }
  378. }, 0);
  379. } else {
  380. sums[index] = "";
  381. }
  382. });
  383. return sums;
  384. }
  385. function handleImageView(fileUrl) {
  386. window.open(`${baseUrl.value}${fileUrl}`);
  387. }
  388. function handleVerify(status) {
  389. if (status === 4) {
  390. const saveValue = proxy.deepClone(form.value);
  391. saveValue.status = status;
  392. feedbackDialogView.value.open(saveValue);
  393. } else {
  394. proxy.$modal
  395. .confirm("确认审核么?")
  396. .then((_) => {
  397. const saveValue = proxy.deepClone(form.value);
  398. saveValue.status = status;
  399. verify(saveValue);
  400. })
  401. .catch((_) => {
  402. proxy.$modal.msg("已取消审核");
  403. });
  404. }
  405. }
  406. function verify(data) {
  407. verifyDetail(data).then((res) => {
  408. reset();
  409. getList.value();
  410. close();
  411. });
  412. }
  413. function rowChangeSum(row) {
  414. let actuallySalary = 0;
  415. actuallySalary += row.planSalary == null ? 0 : row.planSalary;
  416. actuallySalary += row.bonusAmount == null ? 0 : row.bonusAmount;
  417. actuallySalary -= row.endowmentInsurance == null ? 0 : row.endowmentInsurance;
  418. actuallySalary -= row.medicalInsurance == null ? 0 : row.medicalInsurance;
  419. actuallySalary -=
  420. row.unemploymentBenefit == null ? 0 : row.unemploymentBenefit;
  421. actuallySalary -=
  422. row.seriousIllnessInsurance == null ? 0 : row.seriousIllnessInsurance;
  423. actuallySalary -= row.housingFund == null ? 0 : row.housingFund;
  424. if (form.value.hasIndividualIncomeTax === 1) {
  425. actuallySalary -=
  426. row.individualIncomeTaxConfirm == null
  427. ? 0
  428. : row.individualIncomeTaxConfirm;
  429. } else {
  430. actuallySalary -=
  431. row.currentIndividualIncomeTax == null
  432. ? 0
  433. : row.currentIndividualIncomeTax;
  434. }
  435. actuallySalary -= row.otherCut == null ? 0 : row.otherCut;
  436. row.actuallySalary = actuallySalary;
  437. computeTotal();
  438. }
  439. function computeTotal() {
  440. let totalSalay = 0;
  441. form.value.details.forEach((l) => {
  442. totalSalay += l.actuallySalary == null ? 0 : l.actuallySalary;
  443. });
  444. form.value.amount = totalSalay.toFixed(2);
  445. }
  446. function returnStatus(status) {
  447. proxy.$modal
  448. .confirm("确认退回么?")
  449. .then((_) => {
  450. turnBackDetail(form.value).then((res) => {
  451. // if (res.data.successStatus = true) {
  452. // reset()
  453. // getList.value()
  454. // close()
  455. // } else {
  456. // proxy.$modal.msg(res.data.message)
  457. // }
  458. reset();
  459. getList.value();
  460. close();
  461. });
  462. })
  463. .catch((_) => {
  464. proxy.$modal.msg("已取消退回");
  465. });
  466. }
  467. function changeIndividual(arg) {
  468. // if (arg === 1) {
  469. form.value.details.forEach((row) => {
  470. let actuallySalary = 0;
  471. actuallySalary += row.planSalary == null ? 0 : row.planSalary;
  472. actuallySalary += row.bonusAmount == null ? 0 : row.bonusAmount;
  473. actuallySalary -=
  474. row.endowmentInsurance == null ? 0 : row.endowmentInsurance;
  475. actuallySalary -= row.medicalInsurance == null ? 0 : row.medicalInsurance;
  476. actuallySalary -=
  477. row.unemploymentBenefit == null ? 0 : row.unemploymentBenefit;
  478. actuallySalary -=
  479. row.seriousIllnessInsurance == null ? 0 : row.seriousIllnessInsurance;
  480. actuallySalary -= row.housingFund == null ? 0 : row.housingFund;
  481. if (arg === 1) {
  482. actuallySalary -=
  483. row.individualIncomeTaxConfirm == null
  484. ? 0
  485. : row.individualIncomeTaxConfirm;
  486. } else {
  487. actuallySalary -=
  488. row.currentIndividualIncomeTax == null
  489. ? 0
  490. : row.currentIndividualIncomeTax;
  491. }
  492. actuallySalary -= row.otherCut == null ? 0 : row.otherCut;
  493. row.actuallySalary = actuallySalary;
  494. });
  495. computeTotal();
  496. }
  497. function passwordCheckHandler(value, field) {
  498. // console.log(value)
  499. if (!passwordCheck(form.value[field])) {
  500. proxy.$modal.msgError("请输入正确密码");
  501. }
  502. }
  503. function closeImages() {
  504. showViewer.value = false;
  505. }
  506. function tableRowClassName({ row, index }) {
  507. if (row.changeStatus === 1) {
  508. return "list-row add-row";
  509. } else if (row.changeStatus === 2) {
  510. return "list-row delete-row";
  511. } else {
  512. return "list-row";
  513. }
  514. }
  515. // 暴露给父组件的方法
  516. defineExpose({
  517. open,
  518. });
  519. </script>
  520. <style scoped>
  521. .img {
  522. width: 23px;
  523. height: 23px;
  524. display: flex;
  525. justify-content: center;
  526. align-items: center;
  527. }
  528. ::v-deep(.el-upload) {
  529. display: flex;
  530. text-align: center;
  531. justify-content: center;
  532. cursor: pointer;
  533. outline: 0;
  534. }
  535. .required::after {
  536. content: "*";
  537. color: red;
  538. }
  539. </style>
  540. <style>
  541. .el-table .delete-row {
  542. background-color: rgb(251, 159, 173);
  543. }
  544. .el-table .add-row {
  545. background-color: rgb(184, 234, 147);
  546. }
  547. </style>