Merge remote-tracking branch 'origin/dev_tide' into dev_tide
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ååå°è´¦å页 |
| | | export function contractListPage(query) { |
| | | return request({ url: '/staff/contract/listPage', method: 'get', params: query }) |
| | | } |
| | | // åå详æ
|
| | | export function contractInfo(id) { |
| | | return request({ url: '/staff/contract/' + id, method: 'get' }) |
| | | } |
| | | // æ°å¢åå |
| | | export function contractAdd(data) { |
| | | return request({ url: '/staff/contract/add', method: 'post', data }) |
| | | } |
| | | // ä¿®æ¹åå |
| | | export function contractUpdate(data) { |
| | | return request({ url: '/staff/contract/update', method: 'post', data }) |
| | | } |
| | | // å é¤åå |
| | | export function contractDel(ids) { |
| | | return request({ url: '/staff/contract/del', method: 'delete', data: ids }) |
| | | } |
| | | // ç»ç¾åå |
| | | export function contractRenew(id, data) { |
| | | return request({ url: '/staff/contract/renew/' + id, method: 'post', data }) |
| | | } |
| | | // è§£é¤åå |
| | | export function contractTerminate(id, data) { |
| | | return request({ url: '/staff/contract/terminate/' + id, method: 'post', data }) |
| | | } |
| | |
| | | data: params, |
| | | }); |
| | | } |
| | | |
| | | // å¨èå°è´¦ç»è®¡ï¼å¨èäººæ° / èªèµåè®¡ï¼ |
| | | export function staffOnJobStatistics() { |
| | | return request({ |
| | | url: "/staff/staffOnJob/statistics", |
| | | method: "get", |
| | | }); |
| | | } |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange" class="out-tabs"> |
| | | <el-tab-pane label="åæ" name="issue" /> |
| | | <el-tab-pane label="éå®åºåº" name="sales" /> |
| | | <el-tab-pane label="éè´§åºåº" name="purchaseReturn" /> |
| | | </el-tabs> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" |
| | | :row-key="row => row.id" |
| | | show-summary |
| | | style="width: 100%" |
| | | :summary-method="summarizeMainTable" |
| | | height="calc(100vh - 18.5em)" |
| | | height="calc(100vh - 21em)" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="æ¹æ¬¡å·" prop="code" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="æ¹æ¬¡å·" width="150" show-overflow-tooltip> |
| | | <template #default="scope">{{ scope.row.code || scope.row.inboundBatches }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="ç©åç±»å" prop="itemType" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" width="90" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <el-table-column v-if="activeTab === 'issue'" label="ç©åç±»å" prop="itemType" show-overflow-tooltip /> |
| | | <el-table-column v-if="activeTab === 'sales'" label="客æ·åç§°" prop="customerName" show-overflow-tooltip /> |
| | | <el-table-column v-if="activeTab === 'purchaseReturn'" label="ä¾åºå" prop="supplierName" show-overflow-tooltip /> |
| | | <el-table-column :label="cfg.availLabel" prop="inboundNum0" width="110" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="110" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row);">åæ</el-button> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row)">{{ cfg.outLabel }}</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="40%" @close="closeDia" draggable> |
| | | <el-dialog v-model="dialogFormVisible" :title="cfg.dialogTitle" width="40%" @close="closeDia" draggable> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <div>{{getAvailableQuantityText()}}:{{currentRowNum}}</div> |
| | | <el-form-item :label="getQuantityLabel()" prop="inboundQuantity"> |
| | | <div v-if="activeTab === 'purchaseReturn'" style="margin-bottom: 12px"> |
| | | ä¾åºåï¼{{ currentRow.supplierName || '-' }} |
| | | </div> |
| | | <div>{{ cfg.availLabel }}ï¼{{ currentRowNum }}</div> |
| | | <el-form-item :label="cfg.qtyLabel" prop="inboundQuantity"> |
| | | <el-input-number :step="0.01" :min="0" :max="currentRowNum" style="width: 100%" v-model="form.inboundQuantity" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | <el-form-item :label="getDateLabel()" prop="inboundTime"> |
| | | <el-form-item :label="cfg.dateLabel" prop="inboundTime"> |
| | | <el-date-picker style="width: 100%" v-model="form.inboundTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | <el-form-item :label="getPersonLabel()" prop="nickName"> |
| | | <el-form-item :label="cfg.personLabel" prop="nickName"> |
| | | <el-select v-model="form.nickName" |
| | | filterable |
| | | default-first-option |
| | |
| | | |
| | | <script setup> |
| | | import pagination from '@/components/PIMTable/Pagination.vue' |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue' |
| | | import { ref, reactive, toRefs, onMounted, computed, getCurrentInstance } from 'vue' |
| | | import { ElMessageBox } from "element-plus"; |
| | | import useUserStore from '@/store/modules/user' |
| | | import { userListNoPageByTenantId } from "@/api/system/user.js"; |
| | | import { |
| | | getInPageByCustom |
| | | getInPageByCustom, |
| | | getStockInPage, |
| | | getStockInPageByProduction, |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | import { |
| | | delStockManage, |
| | | stockOut, |
| | | stockOut, |
| | | } from "@/api/inventoryManagement/stockManage.js"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const tableData = ref([]) |
| | | const selectedRows = ref([]) |
| | | const userList = ref([]) |
| | | const tableLoading = ref(false) |
| | | const activeTab = ref('issue') |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }) |
| | | const total = ref(0) |
| | | const fileList = ref([]) |
| | | |
| | | // ä¸ç§åºåºç±»åé
ç½®ï¼åæ(type=3 èªå®ä¹åºåº)ãéå®åºåº(type=2)ãéè´§åºåº(type=5 éè´éè´§åºåº) |
| | | const tabConfig = { |
| | | issue: { |
| | | type: 3, |
| | | outLabel: 'åæ', |
| | | dialogTitle: 'æ°å¢åæ', |
| | | availLabel: 'å¯åææ°é', |
| | | qtyLabel: 'åææ°éï¼', |
| | | dateLabel: 'åææ¥æï¼', |
| | | personLabel: 'åæäººï¼', |
| | | exportUrl: '/stockmanagement/exportTwo', |
| | | exportName: 'åæå°è´¦.xlsx', |
| | | }, |
| | | sales: { |
| | | type: 2, |
| | | outLabel: 'éå®åºåº', |
| | | dialogTitle: 'æ°å¢éå®åºåº', |
| | | availLabel: 'å¯åºåºæ°é', |
| | | qtyLabel: 'åºåºæ°éï¼', |
| | | dateLabel: 'åºåºæ¥æï¼', |
| | | personLabel: 'ç»æäººï¼', |
| | | exportUrl: '/stockmanagement/exportOne', |
| | | exportName: 'éå®åºåºå°è´¦.xlsx', |
| | | }, |
| | | purchaseReturn: { |
| | | type: 5, |
| | | outLabel: 'éè´§åºåº', |
| | | dialogTitle: 'æ°å¢éè´§åºåº', |
| | | availLabel: 'å¯éè´§æ°é', |
| | | qtyLabel: 'éè´§æ°éï¼', |
| | | dateLabel: 'éè´§æ¥æï¼', |
| | | personLabel: 'ç»æäººï¼', |
| | | exportUrl: '/stockmanagement/exportPurchaseReturn', |
| | | exportName: 'éè´§åºåºå°è´¦.xlsx', |
| | | }, |
| | | } |
| | | const cfg = computed(() => tabConfig[activeTab.value] || tabConfig.issue) |
| | | |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const dialogFormVisible = ref(false) |
| | | const currentRow = ref({}) |
| | | const currentRowNum = ref(0) |
| | | const data = reactive({ |
| | | searchForm: { |
| | | inboundQuantity:'', |
| | | inboundTime:'', |
| | | nickName: '', |
| | | userId: '', |
| | | productCategory:'', |
| | | // timeStr: getCurrentDate(), |
| | | productCategory: '', |
| | | }, |
| | | form: { |
| | | productrecordId: '', |
| | |
| | | }) |
| | | const { searchForm, form, rules } = toRefs(data) |
| | | |
| | | // æ¥è¯¢å表 |
| | | const handleTabChange = () => { |
| | | page.current = 1 |
| | | getList() |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1 |
| | |
| | | page.size = obj.limit; |
| | | getList() |
| | | } |
| | | // æ tab éæ©"å¯åºåºåºå"æ¥æºï¼åæ=èªå®ä¹å
¥åºï¼éå®åºåº=ç产å
¥åºï¼éè´§åºåº=éè´å
¥åº |
| | | const fetchSource = (params) => { |
| | | if (activeTab.value === 'sales') return getStockInPageByProduction(params) |
| | | if (activeTab.value === 'purchaseReturn') return getStockInPage(params) |
| | | return getInPageByCustom(params) |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | const params = { ...page } |
| | | params.productCategory = searchForm.value.productCategory |
| | | params.flag = true |
| | | const apiCall = getInPageByCustom(params) |
| | | apiCall.then(res => { |
| | | fetchSource(params).then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | tableData.value = res.data.records || [] |
| | | total.value = res.data.total |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | const findNodeById = (nodes, productId) => { |
| | | for (let i = 0; i < nodes.length; i++) { |
| | | if (nodes[i].value === productId) { |
| | | return nodes[i].label; // æ¾å°èç¹ï¼è¿å该èç¹ |
| | | } |
| | | if (nodes[i].children && nodes[i].children.length > 0) { |
| | | const foundNode = findNodeById(nodes[i].children, productId); |
| | | if (foundNode) { |
| | | return foundNode.label; // å¨åèç¹ä¸æ¾å°ï¼è¿å该èç¹ |
| | | } |
| | | } |
| | | } |
| | | return null; // æ²¡ææ¾å°èç¹ï¼è¿ånull |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | // è¿æ»¤æåæ°æ® |
| | | selectedRows.value = selection.filter(item => item.id); |
| | | console.log('selection', selectedRows.value) |
| | | } |
| | | const expandedRowKeys = ref([]) |
| | | |
| | | // 主表åè®¡æ¹æ³ |
| | | const summarizeMainTable = (param) => { |
| | | return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']); |
| | | }; |
| | | const currentRowId = ref(null) // æ°å¢ï¼åå¨å½åæä½çè¡ID |
| | | |
| | | const currentRowNum = ref(0) |
| | | const salesLedgerProductId = ref(null); |
| | | return proxy.summarizeTable(param, ['taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']); |
| | | } |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = async (row) => { |
| | | dialogFormVisible.value = true |
| | | currentRowId.value = row.id |
| | | currentRowNum.value = row.inboundNum0 |
| | | salesLedgerProductId.value = row.salesLedgerProductId |
| | | currentRow.value = row || {} |
| | | currentRowNum.value = row ? row.inboundNum0 : 0 |
| | | form.value = {} |
| | | |
| | | // å è½½ç¨æ·å表 |
| | | try { |
| | | const userLists = await userListNoPageByTenantId() |
| | | userList.value = userLists.data |
| | | |
| | | // ææåºåºé»è®¤åæäºº |
| | | const defaultPersonName = 'å´çæ¢
' |
| | | const defaultPerson = userList.value.find(user => user.nickName === defaultPersonName) |
| | | const defaultUserId = defaultPerson ? defaultPerson.userId : '' |
| | | |
| | | // åå§åè¡¨åæ°æ® |
| | | form.value = { |
| | | productrecordId: '', |
| | | inboundQuantity: currentRowNum.value, // 使ç¨currentRowNumä½ä¸ºé»è®¤å¼ |
| | | inboundTime: getCurrentDate(), // é»è®¤å½åæ¥æ |
| | | nickName: defaultUserId, // æ ¹æ®tabç±»å设置é»è®¤å货人 |
| | | inboundQuantity: currentRowNum.value, |
| | | inboundTime: getCurrentDate(), |
| | | nickName: defaultUserId, |
| | | } |
| | | console.log('form',form.value) |
| | | } catch (error) { |
| | | console.error('å è½½ç¨æ·å表失败:', error) |
| | | // 妿å 载失败ï¼ä½¿ç¨ç©ºå¼åå§å |
| | | form.value = { |
| | | productrecordId: '', |
| | | inboundQuantity: currentRowNum.value, |
| | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | let num = Number(form.value.inboundQuantity) |
| | | if(num <= 0 || num > currentRowNum.value){ |
| | | if (num <= 0 || num > currentRowNum.value) { |
| | | return proxy.$modal.msgWarning("请填å
¥æææ°å") |
| | | } |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid && currentRowId.value) { |
| | | if (valid && currentRow.value && currentRow.value.id) { |
| | | const outData = { |
| | | id: currentRowId.value, // åå§è®°å½ID |
| | | salesLedgerProductId: 0, |
| | | id: currentRow.value.id, // æ¥æºå
¥åºè®°å½ID |
| | | salesLedgerProductId: currentRow.value.salesLedgerProductId || 0, |
| | | quantity: form.value.inboundQuantity, // åºåºæ°é |
| | | time: form.value.inboundTime, // åºåºæ¶é´ |
| | | userId: form.value.nickName, // æä½äºº |
| | | type: 3 // åºåºç±»åï¼èªå®ä¹/ææ |
| | | userId: form.value.nickName, // ç»æäºº |
| | | type: cfg.value.type, // åºåºç±»åï¼3åæ / 2éå®åºåº / 5éè´§åºåº |
| | | supplierName: currentRow.value.supplierName || '', // éè´§åºåº-éåä¾åºå |
| | | } |
| | | console.log(outData) |
| | | |
| | | stockOut(outData).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå") |
| | | closeDia() |
| | |
| | | type: 'warning', |
| | | } |
| | | ).then(() => { |
| | | const exportUrl = "/stockin/exportTwo" |
| | | proxy.download(exportUrl, {}, 'åºåºå°è´¦.xlsx') |
| | | proxy.download(cfg.value.exportUrl, {}, cfg.value.exportName) |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶") |
| | | }) |
| | | } |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = [] |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning('è¯·éæ©æ°æ®') |
| | | return |
| | | } |
| | | ElMessageBox.confirm( |
| | | 'éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼', |
| | | '导åº', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | } |
| | | ).then(() => { |
| | | delStockManage(ids).then(res => { |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | getList() |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶") |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®tabç±»åè·åå¼¹æ¡æ é¢ |
| | | const getDialogTitle = () => { |
| | | return 'æ°å¢åæ'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·åå¯åºåºæ°éææ¬ |
| | | const getAvailableQuantityText = () => { |
| | | return 'å¯åææ°é'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·åæ°éåæ®µæ ç¾ |
| | | const getQuantityLabel = () => { |
| | | return 'åææ°éï¼'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·åæ¥æåæ®µæ ç¾ |
| | | const getDateLabel = () => { |
| | | return 'åææ¥æï¼'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·å人ååæ®µæ ç¾ |
| | | const getPersonLabel = () => { |
| | | return 'åæäººï¼'; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| | | |
| | | |
| | | <style scoped lang="scss"> |
| | | .out-tabs { |
| | | margin-bottom: 6px; |
| | | } |
| | | </style> |
| | |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="130"> |
| | | <template #default="scope"> |
| | | <el-select v-model="scope.row.taxRate" placeholder="è¯·éæ©ç¨ç" @change="() => calculateExclusivePrice(scope.row)"> |
| | | <el-option v-for="item in taxRateOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ»ä»·(å
)" |
| | | prop="taxInclusiveTotalPrice" |
| | |
| | | <el-table-column label="ç©åç±»å" prop="itemType" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" show-overflow-tooltip /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="100" /> |
| | | <el-table-column label="åä»·(å
)" prop="taxInclusiveUnitPrice" width="150" /> |
| | | <el-table-column label="æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150" /> |
| | | <el-table-column label="å
¥åºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">å§åï¼</span> |
| | | <el-input v-model="searchForm.staffName" style="width: 240px" placeholder="请è¾å
¥å§åæç´¢" @change="handleQuery" |
| | | clearable :prefix-icon="Search" /> |
| | | <span style="margin-left: 10px" class="search_title">ååç»ææ¥æï¼</span> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | | <el-input v-model="searchForm.staffName" style="width: 200px" placeholder="请è¾å
¥å§åæç´¢" @change="handleQuery" clearable :prefix-icon="Search" /> |
| | | <span style="margin-left: 10px" class="search_title">ç¶æï¼</span> |
| | | <el-select v-model="searchForm.status" placeholder="å
¨é¨" clearable style="width: 140px" @change="handleQuery"> |
| | | <el-option label="ææ" :value="0" /> |
| | | <el-option label="å·²ç»ç¾" :value="1" /> |
| | | <el-option label="已解é¤" :value="2" /> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="openForm('add')">æ°å¢å
¥è</el-button>--> |
| | | <!-- <el-button type="info" @click="handleImport">导å
¥</el-button>--> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢åå</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination" |
| | | :total="page.total"></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | |
| | | <!-- åå导å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="upload.title" |
| | | v-model="upload.open" |
| | | width="400px" |
| | | append-to-body |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <!-- <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link |
| | | > --> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <!-- æ°å¢/ç¼è¾åå --> |
| | | <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢åå' : 'ç¼è¾åå'" width="60%" @close="closeDia"> |
| | | <el-form :model="form" label-width="120px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="åå·¥å§åï¼" prop="staffName"><el-input v-model="form.staffName" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="åå·¥ç¼å·ï¼" prop="staffNo"><el-input v-model="form.staffNo" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="å²ä½ï¼" prop="postJob"><el-input v-model="form.postJob" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="ååå¹´éï¼" prop="contractTerm"><el-input-number v-model="form.contractTerm" :min="0" :step="1" :precision="0" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="ç¾è®¢æ¥æï¼" prop="signDate"><el-date-picker v-model="form.signDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="ååå¼å§æ¥æï¼" prop="startDate"><el-date-picker v-model="form.startDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="ååç»ææ¥æï¼" prop="endDate"><el-date-picker v-model="form.endDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"><el-form-item label="ååå
容ï¼" prop="contractContent"><el-input v-model="form.contractContent" type="textarea" :rows="4" placeholder="请è¾å
¥ååå
容" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <files-dia ref="filesDia"></files-dia> |
| | | |
| | | <!-- ç»ç¾ --> |
| | | <el-dialog v-model="renewVisible" title="ç»ç¾åå" width="40%"> |
| | | <el-form :model="renewForm" label-width="140px" label-position="top"> |
| | | <el-form-item label="ç»ç¾æ¥æï¼"><el-date-picker v-model="renewForm.renewDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item> |
| | | <el-form-item label="ç»ç¾åå°ææ¥æï¼"><el-date-picker v-model="renewForm.renewEndDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item> |
| | | <el-form-item label="ååå¹´éï¼"><el-input-number v-model="renewForm.contractTerm" :min="0" :step="1" :precision="0" style="width:100%" /></el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="submitRenew">确认ç»ç¾</el-button> |
| | | <el-button @click="renewVisible = false">åæ¶</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- è§£é¤ --> |
| | | <el-dialog v-model="terminateVisible" title="è§£é¤åå" width="40%"> |
| | | <el-form :model="terminateForm" label-width="140px" label-position="top"> |
| | | <el-form-item label="è§£é¤æ¥æï¼"><el-date-picker v-model="terminateForm.terminateDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item> |
| | | <el-form-item label="è§£é¤åå ï¼"><el-input v-model="terminateForm.terminateReason" type="textarea" :rows="3" placeholder="请è¾å
¥è§£é¤åå " /></el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="submitTerminate">确认解é¤</el-button> |
| | | <el-button @click="terminateVisible = false">åæ¶</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { onMounted, ref } from "vue"; |
| | | import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue"; |
| | | import { onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js"; |
| | | import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue"; |
| | | import { |
| | | contractListPage, contractAdd, contractUpdate, contractDel, contractRenew, contractTerminate, |
| | | } from "@/api/personnelManagement/contract.js"; |
| | | import dayjs from "dayjs"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | import FilesDia from "./filesDia.vue"; |
| | | const data = reactive({ |
| | | searchForm: { |
| | | staffName: "", |
| | | entryDate: [ |
| | | dayjs().format("YYYY-MM-DD"), |
| | | dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | ], // å½å
¥æ¥æ |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | }, |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const data = reactive({ searchForm: { staffName: "", status: undefined } }); |
| | | const { searchForm } = toRefs(data); |
| | | |
| | | const statusText = (s) => (s == 0 ? "ææ" : s == 1 ? "å·²ç»ç¾" : s == 2 ? "已解é¤" : ""); |
| | | const statusType = (s) => (s == 0 ? "primary" : s == 1 ? "warning" : s == 2 ? "danger" : ""); |
| | | |
| | | const tableColumn = ref([ |
| | | { label: "åå·¥ç¼å·", prop: "staffNo" }, |
| | | { label: "åå·¥å§å", prop: "staffName" }, |
| | | { label: "å²ä½", prop: "postJob" }, |
| | | { label: "ç¾è®¢æ¥æ", prop: "signDate", width: 120 }, |
| | | { label: "ååå¼å§æ¥æ", prop: "startDate", width: 120 }, |
| | | { label: "ååç»ææ¥æ", prop: "endDate", width: 120 }, |
| | | { label: "ååå¹´é", prop: "contractTerm", width: 90 }, |
| | | { label: "ååå
容", prop: "contractContent", showOverflowTooltip: true }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "staffState", |
| | | dataType: "tag", |
| | | formatData: (params) => { |
| | | if (params == 0) { |
| | | return "离è"; |
| | | } else if (params == 1) { |
| | | return "å¨è"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params == 0) { |
| | | return "danger"; |
| | | } else if (params == 1) { |
| | | return "primary"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | label: "ç¶æ", prop: "status", dataType: "tag", |
| | | formatData: (p) => statusText(p), formatType: (p) => statusType(p), |
| | | }, |
| | | { label: "ç»ç¾æ¥æ", prop: "renewDate", width: 120 }, |
| | | { label: "è§£é¤æ¥æ", prop: "terminateDate", width: 120 }, |
| | | { |
| | | label: "åå·¥ç¼å·", |
| | | prop: "staffNo", |
| | | }, |
| | | { |
| | | label: "å§å", |
| | | prop: "staffName", |
| | | }, |
| | | { |
| | | label: "æ§å«", |
| | | prop: "sex", |
| | | }, |
| | | { |
| | | label: "ç±è´¯", |
| | | prop: "nativePlace", |
| | | }, |
| | | { |
| | | label: "å²ä½", |
| | | prop: "postJob", |
| | | }, |
| | | { |
| | | label: "å®¶åºä½å", |
| | | prop: "adress", |
| | | width: 200 |
| | | }, |
| | | { |
| | | label: "第ä¸å¦å", |
| | | prop: "firstStudy", |
| | | }, |
| | | { |
| | | label: "ä¸ä¸", |
| | | prop: "profession", |
| | | width: 100 |
| | | }, |
| | | { |
| | | label: "身份è¯å·", |
| | | prop: "identityCard", |
| | | width: 200 |
| | | }, |
| | | { |
| | | label: "å¹´é¾", |
| | | prop: "age", |
| | | }, |
| | | { |
| | | label: "èç³»çµè¯", |
| | | prop: "phone", |
| | | width: 150 |
| | | }, |
| | | { |
| | | label: "ç´§æ¥è系人", |
| | | prop: "emergencyContact", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "ç´§æ¥è系人çµè¯", |
| | | prop: "emergencyContactPhone", |
| | | width: 150 |
| | | }, |
| | | { |
| | | label: "ååå¹´é", |
| | | prop: "contractTerm", |
| | | }, |
| | | // { |
| | | // label: "ååå¼å§æ¥æ", |
| | | // prop: "contractStartTime", |
| | | // width: 120 |
| | | // }, |
| | | { |
| | | label: "ååç»ææ¥æ", |
| | | prop: "contractExpireTime", |
| | | width: 120 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | width: 120, |
| | | dataType: "action", label: "æä½", align: "center", fixed: "right", width: 200, |
| | | operation: [ |
| | | { |
| | | name: "详æ
", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "éä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => openForm("edit", row) }, |
| | | { name: "ç»ç¾", type: "text", clickFun: (row) => openRenew(row) }, |
| | | { name: "è§£é¤", type: "text", clickFun: (row) => openTerminate(row) }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const filesDia = ref() |
| | | |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const formDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | const page = reactive({ current: 1, size: 100, total: 0 }); |
| | | const formDia = ref(); |
| | | |
| | | const changeDaterange = (value) => { |
| | | searchForm.value.entryDateStart = undefined; |
| | | searchForm.value.entryDateEnd = undefined; |
| | | if (value) { |
| | | searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); |
| | | searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref(""); |
| | | const formRef = ref(); |
| | | const form = ref({}); |
| | | const rules = { |
| | | staffName: [{ required: true, message: "请è¾å
¥åå·¥å§å", trigger: "blur" }], |
| | | signDate: [{ required: true, message: "è¯·éæ©ç¾è®¢æ¥æ", trigger: "change" }], |
| | | }; |
| | | |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| | | if (type === "add") { |
| | | form.value = { status: 0, contractTerm: 1 }; |
| | | } else { |
| | | form.value = { ...row }; |
| | | } |
| | | getList(); |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | // æå¼éä»¶å¼¹æ¡ |
| | | const openFilesFormDia = (row) => { |
| | | console.log(row) |
| | | nextTick(() => { |
| | | filesDia.value?.openDialog( row,'åå') |
| | | }) |
| | | const closeDia = () => { proxy.resetForm("formRef"); dialogFormVisible.value = false; }; |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (!valid) return; |
| | | const payload = { ...form.value }; |
| | | const p = operationType.value === "add" ? contractAdd(payload) : contractUpdate(payload); |
| | | p.then(() => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | }); |
| | | }; |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | |
| | | const renewVisible = ref(false); |
| | | const renewForm = ref({}); |
| | | const currentId = ref(null); |
| | | const openRenew = (row) => { |
| | | currentId.value = row.id; |
| | | renewForm.value = { renewDate: dayjs().format("YYYY-MM-DD"), renewEndDate: row.endDate, contractTerm: row.contractTerm }; |
| | | renewVisible.value = true; |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | const submitRenew = () => { |
| | | contractRenew(currentId.value, renewForm.value).then(() => { |
| | | proxy.$modal.msgSuccess("ç»ç¾æå"); |
| | | renewVisible.value = false; |
| | | getList(); |
| | | }); |
| | | }; |
| | | |
| | | const terminateVisible = ref(false); |
| | | const terminateForm = ref({}); |
| | | const openTerminate = (row) => { |
| | | currentId.value = row.id; |
| | | terminateForm.value = { terminateDate: dayjs().format("YYYY-MM-DD"), terminateReason: "" }; |
| | | terminateVisible.value = true; |
| | | }; |
| | | const submitTerminate = () => { |
| | | contractTerminate(currentId.value, terminateForm.value).then(() => { |
| | | proxy.$modal.msgSuccess("è§£é¤æå"); |
| | | terminateVisible.value = false; |
| | | getList(); |
| | | }); |
| | | }; |
| | | |
| | | const handleQuery = () => { page.current = 1; getList(); }; |
| | | const pagination = (obj) => { page.current = obj.page; page.size = obj.limit; getList(); }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | params.entryDate = undefined |
| | | staffOnJobListPage(params).then(res => { |
| | | contractListPage({ ...searchForm.value, ...page }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | tableLoading.value = false; |
| | | }) |
| | | }).catch(() => { tableLoading.value = false; }); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | const handleSelectionChange = (selection) => { selectedRows.value = selection; }; |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | const handleDelete = () => { |
| | | if (!selectedRows.value.length) { proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); return; } |
| | | const ids = selectedRows.value.map((i) => i.id); |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤", { |
| | | confirmButtonText: "确认", cancelButtonText: "åæ¶", type: "warning", |
| | | }).then(() => { |
| | | contractDel(ids).then(() => { proxy.$modal.msgSuccess("å 餿å"); getList(); }); |
| | | }).catch(() => { proxy.$modal.msg("已忶"); }); |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/staff/staffOnJob/export", {}, "åå管ç.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | confirmButtonText: "确认", cancelButtonText: "åæ¶", type: "warning", |
| | | }).then(() => { |
| | | proxy.download("/staff/contract/export", { ...searchForm.value }, "åå管ç.xlsx"); |
| | | }).catch(() => { proxy.$modal.msg("已忶"); }); |
| | | }; |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼åå导å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼åå导å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // æ¯å¦æ´æ°å·²ç»åå¨çç¨æ·æ°æ® |
| | | updateSupport: 1, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import", |
| | | }); |
| | | /** 导å
¥æé®æä½ */ |
| | | function handleImport() { |
| | | upload.title = "åå导å
¥"; |
| | | upload.open = true; |
| | | } |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | console.log(upload.url + '?updateSupport=' + upload.updateSupport) |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | /**æä»¶ä¸ä¼ ä¸å¤ç */ |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true; |
| | | }; |
| | | /** æä»¶ä¸ä¼ æåå¤ç */ |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | proxy.$refs["uploadRef"].handleRemove(file); |
| | | getList(); |
| | | }; |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | |
| | | onMounted(() => { getList(); }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¦»èæ¥æï¼" prop="leaveDate"> |
| | | <el-date-picker v-model="form.leaveDate" type="date" placeholder="è¯·éæ©ç¦»èæ¥æ" value-format="YYYY-MM-DD" format="YYYY-MM-DD" clearable style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="离èåå ï¼" prop="leaveReason"> |
| | | <el-input v-model="form.leaveReason" placeholder="请è¾å
¥ç¦»èåå " clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å·¥ä½äº¤æ¥æ
åµï¼" prop="handoverInfo"> |
| | | <el-input v-model="form.handoverInfo" type="textarea" :rows="3" placeholder="请è¾å
¥å·¥ä½äº¤æ¥æ
åµ" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | contractStartTime: "", |
| | | contractEndTime: "", |
| | | staffState: "", |
| | | leaveDate: "", |
| | | leaveReason: "", |
| | | handoverInfo: "", |
| | | }, |
| | | rules: { |
| | | staffNo: [{ required: true, message: "请è¾å
¥", trigger: "blur" },], |
| | |
| | | contractTerm: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contractStartTime: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contractEndTime: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | leaveDate: [{ required: true, message: "è¯·éæ©ç¦»èæ¥æ", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | |
| | | > |
| | | </div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="openForm('add')">æ°å¢å
¥è</el-button>--> |
| | | <el-button type="primary" @click="openEdit('add')">æ°å¢åå·¥</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | </div> |
| | | </div> |
| | | <div class="stat_bar"> |
| | | <span>å¨è人æ°ï¼<b>{{ stats.onJobCount }}</b></span> |
| | | <span style="margin-left: 24px">èªèµå计ï¼<b>{{ stats.salaryTotal }}</b></span> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | |
| | | :total="page.total" |
| | | ></PIMTable> |
| | | </div> |
| | | |
| | | <!-- ç¼è¾/æ°å¢å¨èåå·¥ --> |
| | | <el-dialog v-model="editVisible" :title="editType === 'add' ? 'æ°å¢å¨èåå·¥' : 'ç¼è¾å¨èåå·¥'" width="60%" @close="closeEdit"> |
| | | <el-form :model="editForm" label-width="120px" label-position="top" :rules="editRules" ref="editFormRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="å§åï¼" prop="staffName"><el-input v-model="editForm.staffName" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="åå·¥ç¼å·ï¼" prop="staffNo"><el-input v-model="editForm.staffNo" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="å²ä½ï¼" prop="postJob"><el-input v-model="editForm.postJob" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="èç³»çµè¯ï¼" prop="phone"><el-input v-model="editForm.phone" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="å
¥èæ¶é´ï¼" prop="entryDate"><el-date-picker v-model="editForm.entryDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="èªèµï¼" prop="salary"><el-input-number v-model="editForm.salary" :min="0" :precision="2" :step="100" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"><el-form-item label="ååå¹´éï¼" prop="contractTerm"><el-input v-model="editForm.contractTerm" placeholder="请è¾å
¥" /></el-form-item></el-col> |
| | | <el-col :span="12"><el-form-item label="ååç»ææ¥æï¼" prop="contractExpireTime"><el-date-picker v-model="editForm.contractExpireTime" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="è¯·éæ©" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitEdit">确认</el-button> |
| | | <el-button @click="editVisible = false">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import { onMounted, reactive, ref, toRefs, getCurrentInstance, nextTick } from "vue"; |
| | | import FormDia from "@/views/personnelManagement/employeeRecord/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js"; |
| | | import { createStaffOnJob, updateStaffOnJob, staffOnJobStatistics } from "@/api/personnelManagement/staffOnJob.js"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | staffName: "", |
| | | entryDate: [ |
| | | dayjs().format("YYYY-MM-DD"), |
| | | dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | ], // å½å
¥æ¥æ |
| | | ], |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | }, |
| | |
| | | label: "ç¶æ", |
| | | prop: "staffState", |
| | | dataType: "tag", |
| | | formatData: (params) => { |
| | | if (params == 0) { |
| | | return "离è"; |
| | | } else if (params == 1) { |
| | | return "å¨è"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatType: (params) => { |
| | | if (params == 0) { |
| | | return "danger"; |
| | | } else if (params == 1) { |
| | | return "primary"; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | formatData: (params) => (params == 0 ? "离è" : params == 1 ? "å¨è" : null), |
| | | formatType: (params) => (params == 0 ? "danger" : params == 1 ? "primary" : null), |
| | | }, |
| | | { |
| | | label: "åå·¥ç¼å·", |
| | | prop: "staffNo", |
| | | }, |
| | | { |
| | | label: "å§å", |
| | | prop: "staffName", |
| | | }, |
| | | { |
| | | label: "æ§å«", |
| | | prop: "sex", |
| | | }, |
| | | { |
| | | label: "ç±è´¯", |
| | | prop: "nativePlace", |
| | | }, |
| | | { |
| | | label: "å²ä½", |
| | | prop: "postJob", |
| | | }, |
| | | { |
| | | label: "å®¶åºä½å", |
| | | prop: "adress", |
| | | width:200 |
| | | }, |
| | | { |
| | | label: "第ä¸å¦å", |
| | | prop: "firstStudy", |
| | | }, |
| | | { |
| | | label: "ä¸ä¸", |
| | | prop: "profession", |
| | | width:100 |
| | | }, |
| | | { |
| | | label: "身份è¯å·", |
| | | prop: "identityCard", |
| | | width:200 |
| | | }, |
| | | { |
| | | label: "å¹´é¾", |
| | | prop: "age", |
| | | }, |
| | | { |
| | | label: "èç³»çµè¯", |
| | | prop: "phone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "ç´§æ¥è系人", |
| | | prop: "emergencyContact", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "ç´§æ¥è系人çµè¯", |
| | | prop: "emergencyContactPhone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "ååå¹´é", |
| | | prop: "contractTerm", |
| | | }, |
| | | // { |
| | | // label: "ååå¼å§æ¥æ", |
| | | // prop: "contractStartTime", |
| | | // width: 120 |
| | | // }, |
| | | { |
| | | label: "ååç»ææ¥æ", |
| | | prop: "contractExpireTime", |
| | | width: 120 |
| | | }, |
| | | { label: "åå·¥ç¼å·", prop: "staffNo" }, |
| | | { label: "å§å", prop: "staffName" }, |
| | | { label: "æ§å«", prop: "sex" }, |
| | | { label: "ç±è´¯", prop: "nativePlace" }, |
| | | { label: "å²ä½", prop: "postJob" }, |
| | | { label: "å
¥èæ¶é´", prop: "entryDate", width: 120 }, |
| | | { label: "èªèµ", prop: "salary" }, |
| | | { label: "å®¶åºä½å", prop: "adress", width: 200 }, |
| | | { label: "第ä¸å¦å", prop: "firstStudy" }, |
| | | { label: "ä¸ä¸", prop: "profession", width: 100 }, |
| | | { label: "身份è¯å·", prop: "identityCard", width: 200 }, |
| | | { label: "å¹´é¾", prop: "age" }, |
| | | { label: "èç³»çµè¯", prop: "phone", width: 150 }, |
| | | { label: "ååå¹´é", prop: "contractTerm" }, |
| | | { label: "ååç»ææ¥æ", prop: "contractExpireTime", width: 120 }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | width: 120, |
| | | operation: [ |
| | | { |
| | | name: "详æ
", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | }, |
| | | { name: "详æ
", type: "text", clickFun: (row) => openForm("edit", row) }, |
| | | { name: "ç¼è¾", type: "text", clickFun: (row) => openEdit("edit", row) }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const formDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | const page = reactive({ current: 1, size: 100, total: 0 }); |
| | | const formDia = ref(); |
| | | |
| | | // ç»è®¡ |
| | | const stats = reactive({ onJobCount: 0, salaryTotal: 0 }); |
| | | const getStats = () => { |
| | | staffOnJobStatistics().then((res) => { |
| | | stats.onJobCount = res.data.onJobCount; |
| | | stats.salaryTotal = res.data.salaryTotal; |
| | | }); |
| | | }; |
| | | |
| | | // ç¼è¾/æ°å¢ |
| | | const editVisible = ref(false); |
| | | const editType = ref("edit"); |
| | | const editFormRef = ref(); |
| | | const editForm = ref({}); |
| | | const editRules = { |
| | | staffName: [{ required: true, message: "请è¾å
¥å§å", trigger: "blur" }], |
| | | staffNo: [{ required: true, message: "请è¾å
¥åå·¥ç¼å·", trigger: "blur" }], |
| | | }; |
| | | const openEdit = (type, row) => { |
| | | editType.value = type; |
| | | if (type === "add") { |
| | | editForm.value = { staffState: 1, salary: 0 }; |
| | | } else { |
| | | editForm.value = { ...row }; |
| | | } |
| | | editVisible.value = true; |
| | | }; |
| | | const closeEdit = () => { |
| | | proxy.resetForm("editFormRef"); |
| | | editVisible.value = false; |
| | | }; |
| | | const submitEdit = () => { |
| | | editFormRef.value.validate((valid) => { |
| | | if (!valid) return; |
| | | const payload = { ...editForm.value }; |
| | | if (editType.value === "add") { |
| | | payload.staffState = 1; |
| | | delete payload.id; |
| | | createStaffOnJob(payload).then(() => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå"); |
| | | closeEdit(); |
| | | handleQuery(); |
| | | getStats(); |
| | | }); |
| | | } else { |
| | | const id = payload.id; |
| | | updateStaffOnJob(id, payload).then(() => { |
| | | proxy.$modal.msgSuccess("ä¿åæå"); |
| | | closeEdit(); |
| | | handleQuery(); |
| | | getStats(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const changeDaterange = (value) => { |
| | | searchForm.value.entryDateStart = undefined; |
| | |
| | | } |
| | | getList(); |
| | | }; |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const handleQuery = () => { page.current = 1; getList(); }; |
| | | const pagination = (obj) => { page.current = obj.page; page.size = obj.limit; getList(); }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | params.entryDate = undefined |
| | | staffOnJobListPage({...params, staffState: 1}).then(res => { |
| | | params.entryDate = undefined; |
| | | staffOnJobListPage({ ...params, staffState: 1 }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | tableLoading.value = false; |
| | | }) |
| | | }).catch(() => { tableLoading.value = false; }); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | const handleSelectionChange = (selection) => { selectedRows.value = selection; }; |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | nextTick(() => { formDia.value?.openDialog(type, row); }); |
| | | }; |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/staff/staffOnJob/export", {staffState: 1}, "å¨èåå·¥å°è´¦.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | confirmButtonText: "确认", cancelButtonText: "åæ¶", type: "warning", |
| | | }).then(() => { |
| | | proxy.download("/staff/staffOnJob/export", { staffState: 1 }, "å¨èåå·¥å°è´¦.xlsx"); |
| | | }).catch(() => { proxy.$modal.msg("已忶"); }); |
| | | }; |
| | | onMounted(() => { |
| | | getList(); |
| | | getStats(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | <style scoped> |
| | | .stat_bar { |
| | | margin: 6px 0 10px; |
| | | padding: 8px 12px; |
| | | background: #f0f1f5; |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | } |
| | | .stat_bar b { |
| | | color: #409eff; |
| | | font-size: 16px; |
| | | } |
| | | </style> |