socialSecurityView.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. <template>
  2. <el-dialog
  3. title="社保信息"
  4. v-model="visible"
  5. :width="width"
  6. append-to-body
  7. draggable
  8. @close="close"
  9. class="dialog-form"
  10. :close-on-click-modal = "false"
  11. >
  12. <!-- 功能按钮 -->
  13. <div style="padding: 8px 24px 16px 24px">
  14. <el-form size="small" label-width="120px" v-model="form">
  15. <el-row :gutter="30">
  16. <el-col :span="12">
  17. <el-form-item label="客户名称">
  18. <div>{{ form.companyName }}</div>
  19. </el-form-item>
  20. </el-col>
  21. <el-col :span="12">
  22. <el-form-item label="所属月份">
  23. <div>{{ form.year }}-{{ form.month }}</div>
  24. </el-form-item>
  25. </el-col>
  26. <el-col :span="12">
  27. <el-form-item label="服务状态">
  28. <el-select
  29. v-model="form.status"
  30. :disabled="form.status === 3"
  31. placeholder="请选择"
  32. >
  33. <el-option
  34. v-for="item in selectStatus"
  35. :key="item.value"
  36. :value="item.value"
  37. :label="item.label"
  38. />
  39. </el-select>
  40. </el-form-item>
  41. </el-col>
  42. <el-divider content-position="left">社保人员信息</el-divider>
  43. <el-col :span="24" class="details-container">
  44. <!--操作按钮 开始-->
  45. <div class="details-head"></div>
  46. <div class="details-body">
  47. <div>
  48. <el-table
  49. ref="sourceTable"
  50. :data="form.socialSecurityConfirm.details"
  51. size="small"
  52. max-height="490px"
  53. border
  54. show-summary
  55. :summary-method="getSummaries"
  56. highlight-current-row
  57. header-row-class-name="list-header-row"
  58. row-class-name="list-row"
  59. class="salary-table"
  60. @selection-change="handleCheckChange"
  61. @current-change="handleCurrentChange"
  62. >
  63. <el-table-column type="selection" width="50" align="center" />
  64. <el-table-column
  65. type="index"
  66. label="序号"
  67. width="50"
  68. align="center"
  69. />
  70. <el-table-column label="姓名" width="80" align="center">
  71. <template #default="scope">
  72. <div>
  73. {{ scope.row.employeeName }}
  74. </div>
  75. <span
  76. style="
  77. color: red;
  78. position: absolute;
  79. z-index: 10;
  80. top: 4px;
  81. right: 12px;
  82. "
  83. >*</span
  84. >
  85. </template>
  86. </el-table-column>
  87. <el-table-column label="电话号" width="130" align="center">
  88. <template #default="scope">
  89. <div>
  90. {{ scope.row.phone }}
  91. </div>
  92. <span
  93. style="
  94. color: red;
  95. position: absolute;
  96. z-index: 10;
  97. top: 4px;
  98. right: 12px;
  99. "
  100. >*</span
  101. >
  102. </template>
  103. </el-table-column>
  104. <el-table-column
  105. label="身份证正面"
  106. width="120"
  107. align="center"
  108. >
  109. <template #default="scope">
  110. <div
  111. class="show-image"
  112. style="display: flex; justify-content: center"
  113. >
  114. <img
  115. class="img"
  116. :src="baseUrl + '/' + scope.row.idCardImage"
  117. alt=""
  118. @click="handleImageView(scope.row.idCardImage)"
  119. />
  120. </div>
  121. <span
  122. style="
  123. color: red;
  124. position: absolute;
  125. z-index: 10;
  126. top: 4px;
  127. right: 12px;
  128. "
  129. >*</span
  130. >
  131. </template>
  132. </el-table-column>
  133. <el-table-column
  134. label="身份证反面"
  135. width="120"
  136. align="center"
  137. >
  138. <template #default="scope">
  139. <div
  140. class="show-image"
  141. style="display: flex; justify-content: center"
  142. >
  143. <img
  144. class="img"
  145. :src="baseUrl + '/' + scope.row.idCardImageBack"
  146. alt=""
  147. @click="handleImageView(scope.row.idCardImageBack)"
  148. />
  149. </div>
  150. <span
  151. style="
  152. color: red;
  153. position: absolute;
  154. z-index: 10;
  155. top: 4px;
  156. right: 12px;
  157. "
  158. >*</span
  159. >
  160. </template>
  161. </el-table-column>
  162. <el-table-column label="基数" width="100" align="center">
  163. <template #default="scope">
  164. <div>
  165. {{ rowNum(scope.row.cardinalNumber) }}
  166. </div>
  167. <span
  168. style="
  169. color: red;
  170. position: absolute;
  171. z-index: 10;
  172. top: 4px;
  173. right: 12px;
  174. "
  175. >*</span
  176. >
  177. </template>
  178. </el-table-column>
  179. <el-table-column label="医疗基数" width="100" align="center">
  180. <template #default="scope">
  181. <div>
  182. {{ rowNum(scope.row.medicalCardinalNumber) }}
  183. </div>
  184. <span
  185. style="
  186. color: red;
  187. position: absolute;
  188. z-index: 10;
  189. top: 4px;
  190. right: 12px;
  191. "
  192. >*</span
  193. >
  194. </template>
  195. </el-table-column>
  196. <!-- <el-table-column label="签名" width="100" header-align="center" required>
  197. </el-table-column> -->
  198. <el-table-column label="备注" header-align="center">
  199. <template #default="scope">
  200. <div>
  201. {{ scope.row.remark }}
  202. </div>
  203. </template>
  204. </el-table-column>
  205. </el-table>
  206. </div>
  207. </div>
  208. </el-col>
  209. <el-col :span="24" style="margin-top: 10px;">
  210. <el-form-item label="备注">
  211. {{ form.socialSecurityConfirm.content }}
  212. </el-form-item>
  213. </el-col>
  214. <el-divider content-position="left">社保申报信息</el-divider>
  215. <el-col :span="12">
  216. <el-form-item label="单位养老金:">
  217. {{ rowNum(form.socialSecurityDeclare.unitPension) }}
  218. </el-form-item>
  219. </el-col>
  220. <el-col :span="12">
  221. <el-form-item label="单位医疗险:">
  222. {{ rowNum(form.socialSecurityDeclare.unitMedical) }}
  223. </el-form-item>
  224. </el-col>
  225. <el-col :span="12">
  226. <el-form-item label="单位工伤险:">
  227. {{ rowNum(form.socialSecurityDeclare.unitInjury) }}
  228. </el-form-item>
  229. </el-col>
  230. <el-col :span="12">
  231. <el-form-item label="单位失业金:">
  232. {{ rowNum(form.socialSecurityDeclare.unitUnemployment) }}
  233. </el-form-item>
  234. </el-col>
  235. <el-col :span="12">
  236. <el-form-item label="单位生育险:">
  237. {{ rowNum(form.socialSecurityDeclare.unitProcreate) }}
  238. </el-form-item>
  239. </el-col>
  240. <el-col :span="12">
  241. <el-form-item label="单位大病险:">
  242. {{ rowNum(form.socialSecurityDeclare.unitSeriousIllness) }}
  243. </el-form-item>
  244. </el-col>
  245. <el-col :span="12">
  246. <el-form-item label="单位采暖费:">
  247. {{ rowNum(form.socialSecurityDeclare.unitHeatingFee) }}
  248. </el-form-item>
  249. </el-col>
  250. <el-col :span="12">
  251. <el-form-item label="个人养老金:">
  252. {{ rowNum(form.socialSecurityDeclare.individualPension) }}
  253. </el-form-item>
  254. </el-col>
  255. <el-col :span="12">
  256. <el-form-item label="个人医疗险:">
  257. {{ rowNum(form.socialSecurityDeclare.individualMedical) }}
  258. </el-form-item>
  259. </el-col>
  260. <el-col :span="12">
  261. <el-form-item label="个人失业金:">
  262. {{ rowNum(form.socialSecurityDeclare.individualUnemployment) }}
  263. </el-form-item>
  264. </el-col>
  265. <el-col :span="12">
  266. <el-form-item label="个人大病险:">
  267. {{ rowNum(form.socialSecurityDeclare.individualSeriousIllness) }}
  268. </el-form-item>
  269. </el-col>
  270. <el-col :span="12">
  271. <el-form-item label="合计:">
  272. {{ rowNum(form.socialSecurityDeclare.amount) }}
  273. </el-form-item>
  274. </el-col>
  275. <el-col :span="24">
  276. <el-divider />
  277. </el-col>
  278. <el-col :span="24">
  279. <el-form-item label="备注">
  280. <!-- <el-input v-model.trim="form.socialSecurityDeclare.content" type="textarea" rows="2" /> -->
  281. {{ form.socialSecurityDeclare.content }}
  282. </el-form-item>
  283. </el-col>
  284. <el-col :span="24">
  285. <el-form-item label="凭证" required>
  286. <el-table
  287. ref="dbTable"
  288. :data="form.socialSecurityDeclare.evidenceFiles"
  289. size="small"
  290. border
  291. header-row-class-name="list-header-row"
  292. row-class-name="list-row"
  293. >
  294. <el-table-column
  295. label="文件名"
  296. prop="originalFileName"
  297. align="center"
  298. show-overflow-tooltip
  299. >
  300. <template #default="scope">
  301. <el-button
  302. size="small"
  303. type="text"
  304. @click="openFile(scope.row)"
  305. >{{
  306. scope.row.originalFileName == ""
  307. ? "打开文件"
  308. : scope.row.originalFileName
  309. }}</el-button
  310. >
  311. </template>
  312. </el-table-column>
  313. <!-- <el-table-column label="文件类型" width="80" prop="fileType" align="center" /> -->
  314. </el-table>
  315. </el-form-item>
  316. </el-col>
  317. </el-row>
  318. </el-form>
  319. </div>
  320. <div class="form-btns-container" style="height: 40px">
  321. <el-button size="small" style="float: right" icon="close" @click="close"
  322. >取消</el-button
  323. >
  324. </div>
  325. <el-image-viewer
  326. v-if="showViewer"
  327. :url-list="currentFileList"
  328. @close="closeImages"
  329. :initial-index="showIndex"
  330. />
  331. <!-- <feedback-dialog ref="feedbackDialogView" :parent="this" />
  332. <print-dialog ref="printDialog" :parent="this" /> -->
  333. </el-dialog>
  334. </template>
  335. <script setup>
  336. import {
  337. getDetail,
  338. saveDetail,
  339. updateDetail,
  340. } from "@/api/business/crm/serviceWorkOrder";
  341. import { rowNum, numberToCurrencyNo } from "@/utils/index";
  342. import { ref } from "vue";
  343. const { proxy } = getCurrentInstance();
  344. const visible = ref(false);
  345. const width = ref(1000);
  346. const selections = ref([]);
  347. const currentSource = ref(null);
  348. const showViewer = ref(false);
  349. const props = defineProps({
  350. getList: {
  351. type: Function,
  352. default: () => {},
  353. },
  354. });
  355. const selectStatus = ref([
  356. {
  357. label: "未开始",
  358. value: 0,
  359. color: "#fff",
  360. },
  361. {
  362. label: "进行中",
  363. value: 1,
  364. color: "#FFB836",
  365. },
  366. {
  367. label: "已完成",
  368. value: 3,
  369. color: "#2FCB81",
  370. },
  371. ]);
  372. const { getList } = toRefs(props);
  373. const total = ref(0);
  374. const employeeEmptyData = {
  375. id: null,
  376. title: "",
  377. remark: "",
  378. employeeName: "",
  379. departmentName: "",
  380. idCardImage: "",
  381. idCardImageBack: "",
  382. idiograph: "",
  383. details: [],
  384. editStatus: true,
  385. };
  386. const currentFileList = ref([]);
  387. const form = ref({});
  388. const emptyForm = {
  389. socialSecurityConfirm: {},
  390. socialSecurityDeclare: {},
  391. };
  392. const baseUrl = ref(import.meta.env.VITE_APP_BASE_API);
  393. function open(detail) {
  394. visible.value = true;
  395. form.value = { ...emptyForm, ...detail };
  396. loadData();
  397. }
  398. function loadData() {
  399. getDetail(form.value).then((res) => {
  400. form.value = { ...proxy.deepClone(emptyForm), ...res.data };
  401. computeTotal();
  402. });
  403. }
  404. function close() {
  405. visible.value = false;
  406. reset();
  407. }
  408. function reset() {
  409. form.value = proxy.deepClone(emptyForm);
  410. }
  411. function printSalary() {}
  412. function exportSalary() {}
  413. function handleCurrentChange(row) {
  414. currentSource.value = row;
  415. }
  416. function handleCheckChange(selection) {
  417. selections.value = selection.map((item) => item);
  418. }
  419. function handleSave() {
  420. proxy.$modal
  421. .confirm("确认保存么?")
  422. .then(() => {
  423. const saveValue = proxy.deepClone(form.value);
  424. saveDetail(saveValue).then((res) => {
  425. proxy.$modal.msgSuccess("保存成功");
  426. reset();
  427. close();
  428. getList.value();
  429. });
  430. })
  431. .catch((err) => {
  432. proxy.$modal.msg("取消保存");
  433. });
  434. }
  435. function getSummaries(param) {
  436. const { columns, data } = param;
  437. const sums = [];
  438. columns.forEach((column, index) => {
  439. if (index === 0) {
  440. sums[index] = "合计";
  441. return;
  442. } else if (index === 1) {
  443. sums[index] = "";
  444. return;
  445. }
  446. const values = data.map((item) => Number(item[column.property]));
  447. if (!values.every((value) => isNaN(value))) {
  448. sums[index] = values.reduce((prev, curr) => {
  449. const value = Number(curr);
  450. if (!isNaN(value)) {
  451. return (Number(prev) + Number(curr)).toFixed(2);
  452. } else {
  453. return Number(prev).toFixed(2);
  454. }
  455. }, 0);
  456. } else {
  457. sums[index] = "";
  458. }
  459. });
  460. return sums;
  461. }
  462. function handleEmployeeCreate() {
  463. // 此处必须进行深拷贝,否则添加的明细,将都指向了一个对象
  464. const _newSource = JSON.parse(JSON.stringify(employeeEmptyData));
  465. form.value.socialSecurityConfirm.details.push(_newSource);
  466. handleCurrentChange(_newSource);
  467. }
  468. function handleEmployeeBatchDelete() {
  469. proxy.$modal
  470. .confirm("确定删除?")
  471. .then(() => {
  472. form.value.socialSecurityConfirm.details =
  473. form.value.socialSecurityConfirm.details.filter(
  474. (item) => selections.value.indexOf(item) === -1
  475. );
  476. })
  477. .catch(() => {
  478. proxy.$modal.msg("已取消删除");
  479. });
  480. }
  481. function upload(param) {
  482. const formData = new FormData();
  483. formData.append("file", param.file);
  484. uploadFile(formData).then((res) => {
  485. if (res.code === 200) {
  486. const file = {};
  487. file.fileName = res.originalFilename;
  488. file.url = res.url;
  489. file.originalFileName = res.originalFilename;
  490. file.fileUrl = res.fileName;
  491. form.value.socialSecurityDeclare.evidenceFiles.push(file);
  492. }
  493. });
  494. }
  495. function openFile(row) {
  496. window.open(`${baseUrl.value}${row.fileUrl}`);
  497. }
  498. function handleDel(row, index) {
  499. proxy.$modal
  500. .confirm("确定删除吗?")
  501. .then((_) => {
  502. form.value.socialSecurityDeclare.evidenceFiles.splice(index, 1);
  503. })
  504. .catch((_) => {
  505. proxy.$modal.msg("已取消删除");
  506. });
  507. }
  508. function computeTotal() {
  509. let totalSalay = 0;
  510. form.value.socialSecurityConfirm.details.forEach((l) => {
  511. totalSalay += l.actuallySalary == null ? 0 : l.actuallySalary;
  512. });
  513. form.value.socialSecurityConfirm.amount = totalSalay.toFixed(2);
  514. }
  515. function uploadIdImage(param, row, field) {
  516. const formData = new FormData();
  517. formData.append("file", param.file);
  518. uploadFile(formData).then((res) => {
  519. if (res.code === 200) {
  520. const file = {};
  521. file.fileName = res.originalFilename;
  522. file.url = res.url;
  523. file.originalFileName = res.originalFilename;
  524. file.fileUrl = res.fileName;
  525. row[field] = file.fileUrl;
  526. }
  527. });
  528. }
  529. function handleImageView(fileUrl) {
  530. currentFileList.value = [`${baseUrl.value}${fileUrl}`];
  531. showViewer.value = true;
  532. }
  533. function closeImages() {
  534. showViewer.value = false;
  535. }
  536. // 暴露给父组件的方法
  537. defineExpose({
  538. open,
  539. });
  540. </script>
  541. <style scoped>
  542. .img {
  543. width: 23px;
  544. height: 23px;
  545. display: flex;
  546. justify-content: center;
  547. align-items: center;
  548. cursor: pointer;
  549. }
  550. ::v-deep(.el-upload) {
  551. display: flex;
  552. text-align: center;
  553. justify-content: center;
  554. cursor: pointer;
  555. outline: 0;
  556. }
  557. .required::after {
  558. content: "*";
  559. color: red;
  560. }
  561. </style>
  562. <style>
  563. .el-table .delete-row {
  564. background-color: rgb(251, 159, 173);
  565. }
  566. .el-table .add-row {
  567. background-color: rgb(184, 234, 147);
  568. }
  569. </style>