| | |
| | | "big.js": "^6.2.2", |
| | | "clipboard": "2.0.8", |
| | | "core-js": "3.37.1", |
| | | "dayjs": "^1.11.20", |
| | | "dom-to-image": "^2.6.0", |
| | | "echarts": "5.4.0", |
| | | "element-resize-detector": "^1.2.4", |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // çæ¬¡ç¸å
³æ¥å£ |
| | | |
| | | import request from "@/utils/request"; |
| | | |
| | | // 绩æç®¡ç-人åèå¤-æ¥è¯¢äººåæå¡è®°å½ |
| | | export function getClockInRecord(query) { |
| | | return request({ |
| | | url: "/staff/attendance/getClockInRecord", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 绩æç®¡ç-人åèå¤-å页æ¥è¯¢èå¤è®°å½ |
| | | export function pageAttendanceRecord(query) { |
| | | return request({ |
| | | url: "/staff/attendance/pageAttendanceRecord", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 绩æç®¡ç-人åèå¤-æ ¡éªéæ©çè夿¶é´æ¯å¦åå¨åä¸äººåçèå¤è®°å½ |
| | | export function checkDutyDate(query) { |
| | | return request({ |
| | | url: "/staff/attendance/checkDutyDate", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 绩æç®¡ç-人åèå¤-ä¿åææ´æ°èå¤è®°å½ |
| | | export function saveOrUpdateStaffAttendanceTrackingRecord(data) { |
| | | return request({ |
| | | url: "/staff/attendance/saveOrUpdateStaffAttendanceTrackingRecord", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // 绩æç®¡ç-人åèå¤-å é¤èå¤è®°å½ |
| | | export function removeStaffAttendanceTrackingRecord(ids) { |
| | | return request({ |
| | | url: "/staff/attendance/removeStaffAttendanceTrackingRecord", |
| | | method: "delete", |
| | | data:ids |
| | | }); |
| | | } |
| | | |
| | | // 绩æç®¡ç-人åèå¤-忥èå¤è®°å½ |
| | | export function syncAttendanceRecord(query) { |
| | | return request({ |
| | | url: "/staff/attendance/syncAttendanceRecord", |
| | | method: "get", |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // 绩æç®¡ç-人åèå¤-ä¿®æ¹è¿åºè®°å½ç¶æ |
| | | export function changeEnableReport(data) { |
| | | return request({ |
| | | url: "/staff/attendance/changeEnableReport", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | |
| | | }) |
| | | } |
| | | |
| | | // è·åå²ä½éæ©æ¡å表 |
| | | export function optionSelect() { |
| | | return request({ |
| | | url: '/system/post/optionSelect', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å²ä½è¯¦ç» |
| | | export function getPost(postId) { |
| | | return request({ |
| | |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è·åç¨æ·å表 |
| | | export function selectAllUser() { |
| | | return request({ |
| | | url: "/system/newUser/selectAllUser", |
| | | method: "get", |
| | | }); |
| | | } |
| | |
| | | { label: "txt", value: ".txt" }, |
| | | { label: "mysql", value: ".mysql" }, |
| | | { label: "mqtt", value: ".mqtt" }, |
| | | { label: "sqlserver", value: ".sqlserver" }, |
| | | { label: "serialPort", value: ".serialPort" }, |
| | | { label: "png", value: ".png" } |
| | | ], |
| | | spanList: [], |
| | |
| | | <el-row> |
| | | <el-form-item label="IFSå" prop="contract"> |
| | | <el-select @keyup.enter.native="refreshTable" v-model="componentData.contract" clearable placeholder="è¯·éæ©" size="small"> |
| | | <el-option label="ZTNS" value="ZTNS"/> |
| | | <el-option label="KJNS" value="KJNS"/> |
| | | <el-option v-for="(item,index) in contractList" :key="index" :label="item.label" :value="item.value"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ¹å·" prop="updateBatchNo"> |
| | |
| | | :visible.sync="declareDialogVisible" width="800px" @close="resetFormData"> |
| | | <el-form ref="declareObj" :inline="true" :model="declareObj" :rules="declareObjRules" label-width="130px" |
| | | label-position="right"> |
| | | <el-form-item class="declareObj-form-item" label="IFSå:" prop="contract" style="width: calc(50% - 54px)"> |
| | | <el-tag :type="declareObj.contract==='ZTNS'?'':'success'">{{declareObj.contract}}</el-tag> |
| | | </el-form-item> |
| | | <el-form-item class="declareObj-form-item" label="订åå·:" prop="orderNo"> |
| | | <el-input v-model="declareObj.orderNo" :disabled="declareType !== 'add'" class="addObj-info" clearable |
| | | placeholder="" size="small"></el-input> |
| | | placeholder="" size="small"></el-input> |
| | | </el-form-item> |
| | | <el-form-item class="declareObj-form-item" label="IFSå:" prop="contract"> |
| | | <el-select v-model="declareObj.contract" v-if="declareType === 'add'" clearable size="small"> |
| | | <el-option v-for="(item,index) in contractList" :key="index" :label="item.label" :value="item.value"/> |
| | | </el-select> |
| | | <el-tag v-else :type="declareObj.contract==='ZTNS'?'':'success'">{{declareObj.contract}}</el-tag> |
| | | </el-form-item> |
| | | <el-form-item class="declareObj-form-item" label="é¶ä»¶å·:" prop="partNo"> |
| | | <el-input v-model="declareObj.partNo" :disabled="declareType !== 'add'" class="addObj-info" clearable |
| | |
| | | upLoading: false, |
| | | orderTypeList: [], |
| | | materialPropList: [], |
| | | contractList:[ |
| | | { |
| | | label:"ZTNS", |
| | | value:"ZTNS" |
| | | }, |
| | | { |
| | | label:"KJNS", |
| | | value:"KJNS" |
| | | }, |
| | | ] |
| | | } |
| | | }, |
| | | mounted() { |
| | |
| | | id: this.declareObj.id, |
| | | updateBatchNo: this.declareObj.updateBatchNo, |
| | | orderType: this.declareObj.orderType, |
| | | materialProp: this.declareObj.materialProp |
| | | materialProp: this.declareObj.materialProp, |
| | | partNo: this.declareObj.partNo, |
| | | contract: this.declareObj.contract |
| | | }).then(res => { |
| | | if (res.code === 200) { |
| | | this.declareDialogVisible = false |
| | |
| | | buyUnitMeas: '', // åä½ |
| | | isExpire: '', // åä½ |
| | | orderType: null, // éå®è®¢ååç±» |
| | | materialProp: null, // ç©æå±æ§ |
| | | } |
| | | } |
| | | }, |
| | |
| | | }, |
| | | { |
| | | id: 6, |
| | | name: "6è´¨éé¨", |
| | | name: "6è´¨éé¨å¤çæè§", |
| | | info: "", |
| | | time: "", |
| | | operator: "", |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script> |
| | | import {getClockInRecord,changeEnableReport} from '@/api/performance/attendance' |
| | | |
| | | export default { |
| | | name: "staffClockInRecord", |
| | | props: { |
| | | queryParams: { |
| | | type: Object, |
| | | default: () => ({ |
| | | personCode:null,//人åç¼å· |
| | | swingDate:null,//å·å¡æ¶é´ |
| | | shiftId:null//çæ¬¡id |
| | | }), |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | loading: false, |
| | | tableData: [], |
| | | //è¿åºé¨ç±»åå表 |
| | | enterOrExitList:[ |
| | | { |
| | | label:'è¿é¨', |
| | | value:1 |
| | | }, |
| | | { |
| | | label:'åºé¨', |
| | | value:2 |
| | | }, |
| | | { |
| | | label:'è¿/åºé¨', |
| | | value:3 |
| | | } |
| | | ], |
| | | //å¼é¨ç±»åå表 |
| | | openTypeList:[ |
| | | { |
| | | "value": 42, |
| | | "label": "åæ³å¯ç å¼é¨" |
| | | }, |
| | | { |
| | | "value": 43, |
| | | "label": "éæ³å¯ç å¼é¨" |
| | | }, |
| | | { |
| | | "value": 45, |
| | | "label": "åæ³æçº¹å¼é¨" |
| | | }, |
| | | { |
| | | "value": 46, |
| | | "label": "éæ³æçº¹å¼é¨" |
| | | }, |
| | | { |
| | | "value": 48, |
| | | "label": "è¿ç¨å¼é¨" |
| | | }, |
| | | { |
| | | "value": 49, |
| | | "label": "æé®å¼é¨" |
| | | }, |
| | | { |
| | | "value": 50, |
| | | "label": "é¥åå¼é¨" |
| | | }, |
| | | { |
| | | "value": 51, |
| | | "label": "åæ³å·å¡å¼é¨" |
| | | }, |
| | | { |
| | | "value": 52, |
| | | "label": "éæ³å·å¡å¼é¨" |
| | | }, |
| | | { |
| | | "value": 53, |
| | | "label": "é¨ç£äºä»¶" |
| | | }, |
| | | { |
| | | "value": 54, |
| | | "label": "å¼å¸¸å¼é¨" |
| | | }, |
| | | { |
| | | "value": 55, |
| | | "label": "å¼å¸¸å
³é¨" |
| | | }, |
| | | { |
| | | "value": 56, |
| | | "label": "æ£å¸¸å
³é¨" |
| | | }, |
| | | { |
| | | "value": 57, |
| | | "label": "æ£å¸¸å¼é¨" |
| | | }, |
| | | { |
| | | "value": 59, |
| | | "label": "对讲请æ±äºä»¶" |
| | | }, |
| | | { |
| | | "value": 61, |
| | | "label": "人è¸åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 62, |
| | | "label": "人è¸éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1421, |
| | | "label": "RFIDææºåæ³" |
| | | }, |
| | | { |
| | | "value": 1422, |
| | | "label": "RFIDæ æºåæ³" |
| | | }, |
| | | { |
| | | "value": 1423, |
| | | "label": "RFIDææºéæ³" |
| | | }, |
| | | { |
| | | "value": 1424, |
| | | "label": "RFIDæ æºéæ³" |
| | | }, |
| | | { |
| | | "value": 1433, |
| | | "label": "é»ååäºä»¶" |
| | | }, |
| | | { |
| | | "value": 1436, |
| | | "label": "人è¯åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1437, |
| | | "label": "人è¯éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1438, |
| | | "label": "人è¯å身份è¯éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1439, |
| | | "label": "人è¯å身份è¯åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1448, |
| | | "label": "RFIDæåºäºä»¶" |
| | | }, |
| | | { |
| | | "value": 1449, |
| | | "label": "RFIDéæ³æåºäºä»¶" |
| | | }, |
| | | { |
| | | "value": 1450, |
| | | "label": "RFIDæé®äºä»¶" |
| | | }, |
| | | { |
| | | "value": 1451, |
| | | "label": "RFIDéæ³æé®äºä»¶" |
| | | }, |
| | | { |
| | | "value": 1455, |
| | | "label": "å
å·å¡åå¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1456, |
| | | "label": "å
å·å¡åå¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1461, |
| | | "label": "å·å¡+æçº¹ç»ååæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1462, |
| | | "label": "å·å¡+æçº¹ç»åéæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1463, |
| | | "label": "å¤äººåæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1464, |
| | | "label": "å¤äººéæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1467, |
| | | "label": "人åç¼å·+å¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1468, |
| | | "label": "人åç¼å·+å¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1469, |
| | | "label": "人è¸+å¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1470, |
| | | "label": "人è¸+å¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1471, |
| | | "label": "æçº¹+å¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1472, |
| | | "label": "æçº¹+å¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1473, |
| | | "label": "æçº¹+人è¸åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1474, |
| | | "label": "æçº¹+人è¸éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1475, |
| | | "label": "å·å¡+人è¸åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1476, |
| | | "label": "å·å¡+人è¸éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1487, |
| | | "label": "æçº¹+人è¸+å¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1488, |
| | | "label": "æçº¹+人è¸+å¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1489, |
| | | "label": "å·å¡+人è¸+å¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1490, |
| | | "label": "å·å¡+人è¸+å¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1491, |
| | | "label": "å·å¡+æçº¹+å¯ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1492, |
| | | "label": "å·å¡+æçº¹+å¯ç éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1493, |
| | | "label": "å¡+æçº¹+人è¸ç»ååæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 1494, |
| | | "label": "å¡+æçº¹+人è¸ç»åéæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 4603, |
| | | "label": "å¡+æçº¹+人è¸+å¯ç ç»ååæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 4604, |
| | | "label": "å¡+æçº¹+人è¸+å¯ç ç»åéæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 4626, |
| | | "label": "人è¸+å®å
¨å¸½åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 4627, |
| | | "label": "人è¸+å®å
¨å¸½éæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 10001, |
| | | "label": "å¥åº·ç åæ³å¼é¨" |
| | | }, |
| | | { |
| | | "value": 10002, |
| | | "label": "å¼å¸¸å¥åº·ç å¼é¨" |
| | | } |
| | | ] |
| | | }; |
| | | }, |
| | | watch: { |
| | | queryParams: { |
| | | handler(newVal, oldVal) { |
| | | this.refreshTable(); |
| | | }, |
| | | deep: true, |
| | | }, |
| | | }, |
| | | created() { |
| | | this.refreshTable(); |
| | | }, |
| | | methods: { |
| | | changeEnableReport(row){ |
| | | let data = { |
| | | id:row.id, |
| | | enableReport:row.enableReport |
| | | } |
| | | changeEnableReport(data).then(res=>{ |
| | | if(res.code===200){ |
| | | this.$message.success("æä½æå") |
| | | this.refreshTable() |
| | | } |
| | | }) |
| | | }, |
| | | formatterAttendanceType(value){ |
| | | let label = ""; |
| | | this.openTypeList.forEach(item=>{ |
| | | if(item.value===value){ |
| | | label = item.label |
| | | } |
| | | }) |
| | | return label; |
| | | }, |
| | | formatterEnterOrExitType(value){ |
| | | let label = ""; |
| | | this.enterOrExitList.forEach(item=>{ |
| | | if(item.value===value){ |
| | | label = item.label |
| | | } |
| | | }) |
| | | return label; |
| | | }, |
| | | getDataSourceTypeTag(type) { |
| | | const tagMap = { |
| | | 0: 'success', |
| | | 1: '', |
| | | }; |
| | | return tagMap[type] || ''; |
| | | }, |
| | | getDataSourceTypeText(type) { |
| | | const textMap = { |
| | | 0: 'ICC忥', |
| | | 1: 'æå¨æ°å¢', |
| | | }; |
| | | return textMap[type] || 'æªç¥'; |
| | | }, |
| | | refreshTable() { |
| | | this.loading = true; |
| | | getClockInRecord({...this.queryParams}).then(res => { |
| | | this.tableData = res.data; |
| | | this.loading = false; |
| | | }).catch(() => { |
| | | this.loading = false; |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="clock-in-record"> |
| | | <div v-loading="loading"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | style="width: 100%" |
| | | height="300" |
| | | :header-cell-style="{textAlign:'center'}" |
| | | :cell-style="{textAlign:'center'}" |
| | | > |
| | | <el-table-column type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column label="æ¯å¦çº³å
¥èå¤" prop="enableReport" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-switch |
| | | @change="changeEnableReport(scope.row)" |
| | | v-model="scope.row.enableReport" |
| | | active-color="#13ce66" |
| | | inactive-color="#ff4949"> |
| | | </el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="personCode" label="å·¥å·" min-width="150" width="150"></el-table-column> |
| | | <el-table-column prop="personName" label="å§å" min-width="150" width="150"></el-table-column> |
| | | <el-table-column prop="deptName" label="é¨é¨åç§°" min-width="150" width="150"></el-table-column> |
| | | <el-table-column prop="cardNumber" label="å¡å·" min-width="150" width="150"></el-table-column> |
| | | <el-table-column prop="swingTime" label="å·å¡æ¶é´" min-width="180" width="180"></el-table-column> |
| | | <el-table-column prop="channelName" label="èå¤ç¹ééåç§°" min-width="180" width="180"></el-table-column> |
| | | <el-table-column prop="deviceName" label="èå¤è®¾å¤åç§°" min-width="150" width="150"></el-table-column> |
| | | <el-table-column prop="deviceCode" label="èå¤è®¾å¤ç¼ç " min-width="150" width="150"></el-table-column> |
| | | <el-table-column prop="enterOrExit" label="è¿åºé¨ç±»å" min-width="150" width="150" :formatter="(row)=>formatterEnterOrExitType(row.enterOrExit)"></el-table-column> |
| | | <el-table-column prop="openType" label="å¼é¨ç±»å" min-width="150" width="150" :formatter="(row)=>formatterAttendanceType(row.openType)"></el-table-column> |
| | | <el-table-column prop="isSync" label="æ°æ®æ¥æº" min-width="150" width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="getDataSourceTypeTag(scope.row.isSync)"> |
| | | {{ getDataSourceTypeText(scope.row.isSync) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="attendance-page"> |
| | | <div class="search"> |
| | | <div class="search_thing"> |
| | | <div class="search_input"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | type="datetimerange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 340px" |
| | | size="small" |
| | | @change="refreshTable" |
| | | ></el-date-picker> |
| | | </div> |
| | | </div> |
| | | <div class="search_thing"> |
| | | <div class="search_input"> |
| | | <el-input |
| | | v-model="queryParams.keyword" |
| | | placeholder="工巿åå·¥åç§°" |
| | | size="small" |
| | | style="width: 200px" |
| | | clearable |
| | | @keyup.enter.native="refreshTable" |
| | | ></el-input> |
| | | </div> |
| | | </div> |
| | | <div class="search_thing"> |
| | | <el-button size="mini" type="primary" @click="refreshTable()" |
| | | >æ¥ è¯¢</el-button |
| | | > |
| | | <el-button size="mini" @click="resetQuery">éç½®</el-button> |
| | | <el-button size="mini" type="primary" @click="openAddAttendanceDialog()">æå¨æ°å¢</el-button> |
| | | <el-button size="mini" type="success" @click="openSyncAttendanceDialog()">忥èå¤è®°å½</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="container"> |
| | | <div v-loading="loading"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | :height="tableHeight" |
| | | style="width: 100%" |
| | | :header-cell-style="{textAlign:'center'}" |
| | | :cell-style="{textAlign:'center'}" |
| | | > |
| | | <el-table-column type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column prop="personCode" label="å·¥å·" min-width="120" width="120"></el-table-column> |
| | | <el-table-column prop="personName" label="å§å" min-width="120" width="120"></el-table-column> |
| | | <el-table-column prop="deptName" label="é¨é¨åç§°" min-width="120" width="120"></el-table-column> |
| | | <el-table-column prop="shiftId" label="çæ¬¡ç±»å" min-width="120" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="getDictTypeByShift(scope.row.shiftId)">{{ getShiftByDic(scope.row.shiftId) }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="result" label="èå¤ç»æ" min-width="120" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="getResultTag(scope.row.result)" :type="getResultTag(scope.row.result).type">{{getResultTag(scope.row.result).label}}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="swingDate" label="è夿¶é´" min-width="150" width="150"></el-table-column> |
| | | <el-table-column label="ç¾å
¥/ç¾åºæ
åµ"> |
| | | <el-table-column prop="workDateTime" label="ä¸çæ¶é´" min-width="160" width="160"> |
| | | <template slot-scope="scope"> |
| | | <el-tag type="success" v-if="scope.row.workDateTime && scope.row.workClockInState===1">{{ scope.row.workDateTime }}</el-tag> |
| | | <el-tag type="danger" v-else-if="scope.row.workDateTime && scope.row.workClockInState===0">{{ scope.row.workDateTime }}</el-tag> |
| | | <span v-else>{{ scope.row.workDateTime }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="offWorkDateTime" label="ä¸çæ¶é´" min-width="160" width="160"> |
| | | <template slot-scope="scope"> |
| | | <el-tag type="success" v-if="scope.row.offWorkDateTime && scope.row.offClockInState===1">{{ scope.row.offWorkDateTime }}</el-tag> |
| | | <el-tag type="danger" v-else-if="scope.row.offWorkDateTime && scope.row.offClockInState===0">{{ scope.row.offWorkDateTime }}</el-tag> |
| | | <span v-else>{{ scope.row.offWorkDateTime }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column label="è夿¶é¿(h)"> |
| | | <el-table-column prop="plannedWorkHours" label="åºå¤æ¶é¿" min-width="80" width="80"></el-table-column> |
| | | <el-table-column prop="actualWorkHours" label="å®é
æ¶é¿" min-width="80" width="80"></el-table-column> |
| | | <el-table-column prop="absenceWorkHours" label="ç¼ºå¤æ¶é¿" min-width="80" width="80"></el-table-column> |
| | | </el-table-column> |
| | | <el-table-column prop="isSync" label="æ°æ®æ¥æº" min-width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.isSync===0" type="success">ICC忥</el-tag> |
| | | <el-tag v-else-if="scope.row.isSync===1" type="info">æå¨æ°å¢</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="150" width="150" :formatter="(row)=>formatterUserName(row.createUser)"></el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="180" width="180"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="150" width="150" :formatter="(row)=>formatterUserName(row.updateUser)"></el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="180" width="180"></el-table-column> |
| | | <el-table-column fixed="right" width="180" label="æä½"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="openClockInDialog(scope.row)">è¿åºè®°å½</el-button> |
| | | <el-button :disabled="scope.row.isSync===0" type="text" @click="openAddAttendanceDialog(scope.row)">ç¼è¾</el-button> |
| | | <el-button :disabled="scope.row.isSync===0" type="text" class="remove-btn" @click="confirmRemoveRecord(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | :total="pagination.total" |
| | | :page.sync="pagination.current" |
| | | :limit.sync="pagination.size" |
| | | @pagination="handlePageChange" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <el-dialog |
| | | title="è¿åºè®°å½" |
| | | :visible.sync="dialogVisible" |
| | | width="60%"> |
| | | <staff-clock-in-record :key="Math.random()" :query-params="clockInQueryParams" ></staff-clock-in-record> |
| | | </el-dialog> |
| | | <el-dialog |
| | | :title="attendanceForm.id?'ç¼è¾èå¤è®°å½':'æ°å¢èå¤è®°å½'" |
| | | :visible.sync="addAttendanceVisible" |
| | | @closed="closeAttendanceDialog" |
| | | width="50%"> |
| | | <el-form ref="attendanceForm" style="margin-top:20px" :model="attendanceForm" :rules="attendanceRule" label-position="right" label-width="100px"> |
| | | <div> |
| | | <el-divider content-position="left">åºæ¬ä¿¡æ¯</el-divider> |
| | | <el-row > |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·¥å·" prop="personCode"> |
| | | <el-input size="small" v-model="attendanceForm.personCode" disabled></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å§å" prop="personName"> |
| | | <el-select size="small" style="width:100%" v-model="attendanceForm.personName" placeholder="è¯·éæ©åå·¥å§å" @change="selectedPersonName" clearable> |
| | | <el-option v-for="(item,index) in userList" :key="index" :label="item.name" :value="item.name"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row > |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨åç§°" prop="deptName"> |
| | | <el-input size="small" v-model="attendanceForm.deptName" placeholder="请è¾å
¥é¨é¨åç§°" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è夿¶é´" prop="swingDate"> |
| | | <el-date-picker size="small" clearable style="width:100%" type="date" placeholder="è¯·éæ©æ¥æ" value-format="yyyy-MM-dd" v-model="attendanceForm.swingDate" @change="checkDutyDate"></el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row > |
| | | <el-col :span="12"> |
| | | <el-form-item label="çæ¬¡ç±»å" prop="shiftId"> |
| | | <el-select disabled size="small" style="width:100%" v-model="attendanceForm.shiftId" placeholder="è¯·éæ©çæ¬¡ç±»å" clearable> |
| | | <el-option v-for="(item,index) in dailyTypeList" :key="index" :label="item.dictLabel" :value="item.dictValue"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <!-- <el-form-item label="èå¤ç»æ" prop="result">--> |
| | | <!-- <el-select size="small" style="width:100%" clearable v-model="attendanceForm.result" placeholder="è¯·éæ©èå¤ç»æ">--> |
| | | <!-- <el-option v-for="(item,index) in resultList" :key="index" :label="item.label" :value="item.value"/>--> |
| | | <!-- </el-select>--> |
| | | <!-- </el-form-item>--> |
| | | </el-col> |
| | | </el-row> |
| | | <el-divider content-position="left">ç¾å
¥/ç¾åºæ
åµ</el-divider> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸çæ¶é´" prop="workTime"> |
| | | <el-time-picker |
| | | style="width:100%" |
| | | value-format="HH:mm" |
| | | v-model="attendanceForm.workDateTime" |
| | | format="HH:mm" |
| | | placeholder="ä¸çæ¶é´"> |
| | | </el-time-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸çæ¶é´" prop="offWorkTime"> |
| | | <el-time-picker |
| | | style="width:100%" |
| | | value-format="HH:mm" |
| | | format="HH:mm" |
| | | v-model="attendanceForm.offWorkDateTime" |
| | | placeholder="ä¸çæ¶é´"> |
| | | </el-time-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </el-form> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="addAttendanceVisible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="confirmAddAttendance()">ç¡® å®</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | <el-dialog |
| | | title="忥èå¤è®°å½" |
| | | :visible.sync="syncAttendanceVisible" |
| | | @close="()=>{syncDateRange=[]}" |
| | | width="25%"> |
| | | <el-date-picker |
| | | style="width:100%" |
| | | v-model="syncDateRange" |
| | | type="datetimerange" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ"> |
| | | </el-date-picker> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="syncAttendanceVisible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="confirmSyncAttendance">ç¡® å®</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import StaffClockInRecord from "./components/staffClockInRecord.vue"; |
| | | import {selectAllUser} from '@/api/system/user' |
| | | import { |
| | | pageAttendanceRecord, |
| | | checkDutyDate, |
| | | saveOrUpdateStaffAttendanceTrackingRecord, |
| | | removeStaffAttendanceTrackingRecord, |
| | | syncAttendanceRecord |
| | | } from '@/api/performance/attendance' |
| | | import {getDicts} from "@/api/system/dict/data"; |
| | | import dayjs from 'dayjs'; |
| | | export default { |
| | | name: "Attendance", |
| | | components: { |
| | | StaffClockInRecord |
| | | }, |
| | | data() { |
| | | return { |
| | | syncDateRange:[], |
| | | syncAttendanceVisible: false, |
| | | attendanceForm:{ |
| | | workDataId: null, |
| | | offWorkDataId: null, |
| | | personCode: null, |
| | | personName: null, |
| | | deptName: "è´¨éé¨", |
| | | shiftId: null, |
| | | swingDate: null, |
| | | workDateTime: null, |
| | | offWorkDateTime: null, |
| | | result: null, |
| | | }, |
| | | attendanceRule:{ |
| | | personName:{required:true,message:'è¯·éæ©åå·¥å§å',trigger:'change'}, |
| | | deptName:{required:true,message:'请è¾å
¥é¨é¨åç§°',trigger:'blur'}, |
| | | dailyName:{required:true,message:'请è¾å
¥ç次åç§°',trigger:'blur'}, |
| | | shiftId:{required:true,message:'è¯·éæ©çæ¬¡ç±»å',trigger:'change'}, |
| | | swingDate:{required:true,message:'è¯·éæ©è夿¶é´',trigger:'change'}, |
| | | workDateTime:{required:true,message:'è¯·éæ©ä¸çæ¶é´',trigger:'change'}, |
| | | offWorkDateTime:{required:true,message:'è¯·éæ©ä¸çæ¶é´',trigger:'change'}, |
| | | result:{required:true,message:'è¯·éæ©èå¤ç»æ',trigger:'change'}, |
| | | }, |
| | | addAttendanceVisible:false, |
| | | dialogVisible:false, |
| | | dateRange: [], |
| | | queryParams: { |
| | | startDate: "", |
| | | endDate: "", |
| | | keyword: "", |
| | | }, |
| | | userList:[], |
| | | loading: false, |
| | | tableData: [], |
| | | pagination: { |
| | | current: 1, |
| | | size: 20, |
| | | total: 0, |
| | | }, |
| | | tableHeight:0, |
| | | resizeHandler: null, // 鲿彿°å¼ç¨ |
| | | clockInQueryParams:{ |
| | | personCode:null,//人åç¼å· |
| | | swingDate:null,//è夿¶é´ |
| | | shiftId:null//çæ¬¡id |
| | | }, |
| | | dailyTypeList:[], |
| | | resultList:[ |
| | | { |
| | | label:"æ£å¸¸", |
| | | value:1, |
| | | type:"success" |
| | | }, |
| | | { |
| | | label:"å¼å¸¸", |
| | | value:0, |
| | | type:"danger" |
| | | }, |
| | | ], |
| | | }; |
| | | }, |
| | | created() { |
| | | this.selectEnumByCategory() |
| | | this.getUserList() |
| | | this.getTableHeight(); |
| | | this.dateRange = this.getTimeRange() |
| | | this.resizeHandler = this.debounce(() => { |
| | | this.getTableHeight(); |
| | | }, 200); |
| | | this.refreshTable(); |
| | | }, |
| | | mounted(){ |
| | | this.getTableHeight(); |
| | | window.addEventListener("resize",this.resizeHandler) |
| | | }, |
| | | beforeDestroy(){ |
| | | window.removeEventListener("resize",this.resizeHandler) |
| | | }, |
| | | methods: { |
| | | getShiftByDic(e) { |
| | | let obj = this.dailyTypeList.find((m) => m.dictValue == e); |
| | | if (obj) { |
| | | return obj.dictLabel; |
| | | } |
| | | return "æ "; |
| | | }, |
| | | getDictTypeByShift(e) { |
| | | let obj = this.dailyTypeList.find((m) => m.dictValue == e); |
| | | if (obj) { |
| | | return obj.listClass; |
| | | } |
| | | return ""; |
| | | }, |
| | | selectEnumByCategory() { |
| | | getDicts("sys_class_type").then((response) => { |
| | | this.dailyTypeList = response.data; |
| | | }); |
| | | }, |
| | | /** |
| | | * åå§åé»è®¤æ¥æèå´ï¼è¿ä¸ä¸ªæï¼å½åæ¥æ - 30天 è³ å½åæ¥æï¼ |
| | | */ |
| | | getTimeRange(format = 'YYYY-MM-DD HH:mm:ss') { |
| | | // è·åå½åæ¶é´ |
| | | const now = dayjs(); |
| | | // è·åå½åæ¥æçãæ¥ãï¼1-31ï¼ |
| | | const currentDate = now.date(); |
| | | |
| | | let startTime, endTime; |
| | | |
| | | // æ ¸å¿é»è¾ï¼å¤æå½åæ¥ææ¯å¦å¤§äº25å· |
| | | if (currentDate > 25) { |
| | | // â
æ
åµ1ï¼å½åæ¥>25 â 彿26å· ~ 次æ25å· |
| | | startTime = now.startOf('month').add(25, 'day'); // 彿1å· +25天 = 26å· |
| | | endTime = startTime.add(1, 'month').date(25).hour(23) |
| | | .minute(59) |
| | | .second(59); // 次æ25å·ï¼dayjsèªå¨å¤çè·¨å¹´ï¼ |
| | | } else { |
| | | // â
æ
åµ2ï¼å½åæ¥â¤25 â 䏿26å· ~ 彿25å· |
| | | startTime = now.subtract(1, 'month').startOf('month').add(25, 'day'); // 䏿26å· |
| | | endTime = now.date(25).hour(23) |
| | | .minute(59) |
| | | .second(59); // 彿25å· |
| | | } |
| | | |
| | | // è¿åæ ¼å¼ååçæ¶é´æ°ç» |
| | | return [startTime.format(format), endTime.format(format)]; |
| | | }, |
| | | //忥èå¤è®°å½ |
| | | confirmSyncAttendance(){ |
| | | if(!this.syncDateRange || this.syncDateRange.length<2){ |
| | | this.$message.warning("è¯·éæ©åæ¥æ¥æ"); |
| | | return |
| | | } |
| | | syncAttendanceRecord({ |
| | | startDate:this.syncDateRange[0], |
| | | endDate:this.syncDateRange[1] |
| | | }).then(res=>{ |
| | | if(res.code===200){ |
| | | this.$message.success("åå°åæ¥èå¤è®°å½ä¸ï¼è¯·å·æ°è¡¨æ ¼æ¥ç") |
| | | this.refreshTable() |
| | | } |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | | }) |
| | | this.$nextTick(()=>{ |
| | | this.syncAttendanceVisible = false |
| | | }) |
| | | }, |
| | | //æå¼åæ¥èå¤è®°å½å¼¹æ¡ |
| | | openSyncAttendanceDialog(){ |
| | | this.syncAttendanceVisible = true |
| | | }, |
| | | //å é¤èå¤è®°å½ |
| | | confirmRemoveRecord(row){ |
| | | if(!row){ |
| | | this.$message.warning("è¯·éæ©ä¸æ¡è®°å½") |
| | | return |
| | | } |
| | | this.$confirm('æ¯å¦ç¡®è®¤å é¤è¯¥æ¡èå¤è®°å½', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | let ids = [row.workDataId,row.offWorkDataId] |
| | | removeStaffAttendanceTrackingRecord(ids).then(res=>{ |
| | | if(res.code===200){ |
| | | this.$message.success("å 餿å") |
| | | this.refreshTable() |
| | | } |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | | }) |
| | | }).catch(() => { }); |
| | | }, |
| | | //å
³éæ°å¢/ç¼è¾èå¤è®°å½å¼¹æ¡ |
| | | closeAttendanceDialog(){ |
| | | this.attendanceForm.id = null |
| | | this.$refs.attendanceForm.resetFields() |
| | | }, |
| | | //éç½®èå¤è®°å½å¼¹æ¡è¡¨å |
| | | resetAttendanceForm(){ |
| | | this.attendanceForm = { |
| | | workDataId: null, |
| | | offWorkDataId: null, |
| | | personCode: null, |
| | | personName: null, |
| | | deptName: "è´¨éé¨", |
| | | shiftId: null, |
| | | swingDate: null, |
| | | workDateTime: null, |
| | | offWorkDateTime: null, |
| | | result: null, |
| | | } |
| | | this.$refs.attendanceForm.resetFields() |
| | | this.$nextTick(()=>{ |
| | | this.addAttendanceVisible = false |
| | | }) |
| | | }, |
| | | //确认ä¿åèå¤è®°å½ |
| | | confirmAddAttendance(){ |
| | | this.$refs.attendanceForm.validate(valid=>{ |
| | | if(valid){ |
| | | saveOrUpdateStaffAttendanceTrackingRecord(this.attendanceForm).then(res=>{ |
| | | if(res.code===200){ |
| | | this.$message.success('ä¿åæå') |
| | | this.refreshTable() |
| | | this.resetAttendanceForm() |
| | | } |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | //æ ¡éªæéè夿¥ææ¯å¦åå¨è¯¥äººåçèå¤è®°å½ |
| | | checkDutyDate(val){ |
| | | if(!this.attendanceForm.personCode){ |
| | | this.$message.warning("请å
éæ©äººååç§°") |
| | | this.attendanceForm.dutyDate = null |
| | | return |
| | | } |
| | | let params = { |
| | | personCode:this.attendanceForm.personCode, |
| | | swingDate: val |
| | | } |
| | | checkDutyDate(params).then(res=>{ |
| | | if(res.code===200&&res.data){ |
| | | this.attendanceForm.result = 1//é»è®¤æ£å¸¸ |
| | | this.attendanceForm.shiftId = res.data.shift |
| | | this.attendanceForm.workDateTime = res.data.startTime |
| | | this.attendanceForm.offWorkDateTime = res.data.endTime |
| | | } |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | | this.attendanceForm.swingDate = null |
| | | }) |
| | | }, |
| | | //éæ©äººåå称带åºå·¥å· |
| | | selectedPersonName(val){ |
| | | let account = "" |
| | | this.userList.forEach(item=>{ |
| | | if(item.name===val){ |
| | | account = item.account |
| | | } |
| | | }) |
| | | this.attendanceForm.personCode = account |
| | | }, |
| | | //æå¼æ°å¢/ç¼è¾èå¤è®°å½å¼¹æ¡ |
| | | openAddAttendanceDialog(row){ |
| | | if(row){ |
| | | //å¤çä¸/ä¸çæ¶é´æ ¼å¼ |
| | | let workTime = row.workDateTime&&row.workDateTime.length>8?row.workDateTime.substring(11,16):row.workDateTime |
| | | let offWorkTime = row.offWorkDateTime&&row.offWorkDateTime.length>8?row.offWorkDateTime.substring(11,16):row.offWorkDateTime |
| | | row.workDateTime = workTime |
| | | row.offWorkDateTime = offWorkTime |
| | | this.attendanceForm = {...row} |
| | | } |
| | | this.addAttendanceVisible = true |
| | | }, |
| | | //æå¼æ¥çæå¡è®°å½å¼¹æ¡ |
| | | openClockInDialog(row){ |
| | | if(row){ |
| | | this.clockInQueryParams.personCode = row.personCode |
| | | this.clockInQueryParams.shiftId = row.shiftId |
| | | this.clockInQueryParams.swingDate = row.swingDate |
| | | } |
| | | this.$nextTick(()=>{ |
| | | this.dialogVisible = true |
| | | }) |
| | | }, |
| | | //æ ¼å¼å人ååç§° |
| | | formatterUserName(value){ |
| | | let userName = "" |
| | | this.userList.forEach(item=>{ |
| | | if(item.id===value){ |
| | | userName = item.name |
| | | } |
| | | }) |
| | | return userName; |
| | | }, |
| | | //æ ¼å¼åèå¤ç»æ |
| | | getResultTag(type) { |
| | | let typeItem = null |
| | | this.resultList.forEach(item=>{ |
| | | if(item.value===type){ |
| | | typeItem = item |
| | | } |
| | | }) |
| | | return typeItem; |
| | | }, |
| | | //鲿彿° |
| | | debounce(fn, delay) { |
| | | let timer = null; |
| | | return (...args) => { |
| | | clearTimeout(timer); |
| | | timer = setTimeout(() => fn.apply(this, args), delay); |
| | | }; |
| | | }, |
| | | //卿è·åè¡¨æ ¼é«åº¦ |
| | | getTableHeight(){ |
| | | const innerHeight = window.innerHeight |
| | | const naviHeight = 96 |
| | | const otherHeight = 128 |
| | | this.tableHeight = innerHeight - naviHeight - otherHeight |
| | | }, |
| | | //å·æ°è¡¨æ ¼ |
| | | refreshTable() { |
| | | this.loading = true; |
| | | if (this.dateRange && this.dateRange.length === 2) { |
| | | this.queryParams.startDate = this.dateRange[0]; |
| | | this.queryParams.endDate = this.dateRange[1]; |
| | | } else { |
| | | this.queryParams.startDate = ""; |
| | | this.queryParams.endDate = ""; |
| | | } |
| | | pageAttendanceRecord({...this.queryParams, ...this.pagination}).then(res => { |
| | | this.tableData = res.data.records; |
| | | this.pagination.total = res.data.total; |
| | | this.pagination.current = res.data.current; |
| | | this.loading = false; |
| | | }).catch(() => { |
| | | this.loading = false; |
| | | }); |
| | | }, |
| | | //å页忢 |
| | | handlePageChange(page) { |
| | | this.pagination.current = page.page; |
| | | this.pagination.size = page.limit; |
| | | this.refreshTable(); |
| | | }, |
| | | //æ¥è¯¢ç¨æ·å表 |
| | | getUserList(){ |
| | | selectAllUser().then(res=>{ |
| | | this.userList = res.data |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | | }) |
| | | }, |
| | | //éç½®æé® |
| | | resetQuery() { |
| | | this.dateRange = this.getTimeRange(); |
| | | this.queryParams = { |
| | | startDate: "", |
| | | endDate: "", |
| | | keyword: "", |
| | | }; |
| | | this.$nextTick(()=>{ |
| | | this.refreshTable() |
| | | }) |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .attendance-page { |
| | | padding: 10px; |
| | | } |
| | | .remove-btn.el-button--text{ |
| | | color:#ff4949 |
| | | } |
| | | .search { |
| | | height: 50px; |
| | | display: flex; |
| | | align-items: center; |
| | | background-color: #fff; |
| | | margin-left:16px; |
| | | } |
| | | |
| | | .search_thing { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 50px; |
| | | margin-right: 30px |
| | | } |
| | | |
| | | .search_label { |
| | | width: 90px; |
| | | font-size: 14px; |
| | | text-align: right; |
| | | } |
| | | |
| | | .search_input { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .container { |
| | | background-color: #fff; |
| | | padding: 0 16px; |
| | | min-height: calc(100vh - 180px); |
| | | } |
| | | |
| | | ::v-deep .el-tabs__header { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | ::v-deep .el-tabs__content { |
| | | padding: 0; |
| | | } |
| | | </style> |
| | |
| | | <span style="color: red; margin-right: 4px">*</span>人ååç§°ï¼ |
| | | </div> |
| | | <div class="search_input" style="width: calc(100% - 90px)"> |
| | | <el-select v-model="schedulingQuery.userId" placeholder="è¯·éæ©" style="width: 100%" multiple clearable |
| | | collapse-tags> |
| | | <el-option v-for="item in personList" :key="item.id" :label="item.name" :value="item.id"> |
| | | </el-option> |
| | | <el-select v-model="schedulingQuery.userId" popper-class="select-with-all" placeholder="è¯·éæ©" style="width: 100%" multiple collapse-tags clearable> |
| | | <!-- <el-option v-for="item in personList" :key="item.id" :label="item.name" :value="item.id">--> |
| | | <!-- </el-option>--> |
| | | <template slot="prefix"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleSelectAll" |
| | | style="margin: 4px 0;" |
| | | > |
| | | {{ isAllSelected ? 'åæ¶å
¨é' : 'å
¨é' }} |
| | | </el-button> |
| | | <el-divider style="margin: 5px 0;" /> |
| | | </template> |
| | | <el-option |
| | | v-for="item in personList" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | |
| | | loading: false, |
| | | schedulingQuery: { |
| | | week: "", |
| | | userId: null, |
| | | userId: [], |
| | | shift: "", |
| | | }, |
| | | list: [], |
| | |
| | | menuY: 0, |
| | | selectedTarget: null, |
| | | }; |
| | | }, |
| | | computed:{ |
| | | isAllSelected() { |
| | | return this.schedulingQuery.userId.length === this.personList.length && this.personList.length > 0; |
| | | }, |
| | | }, |
| | | watch: { |
| | | |
| | |
| | | document.removeEventListener('click', this.handleClickOutside) |
| | | }, |
| | | methods: { |
| | | handleSelectAll() { |
| | | if (this.isAllSelected) { |
| | | this.schedulingQuery.userId = []; |
| | | } else { |
| | | // åªéä¸å¯ç¨é项çvalue |
| | | this.schedulingQuery.userId = this.personList.map(item => item.id); |
| | | } |
| | | }, |
| | | handleContextMenu(target,e) { |
| | | // 黿¢æµè§å¨é»è®¤å³é®èå |
| | | e.preventDefault() |
| | |
| | | this.initYear(); |
| | | } |
| | | }, |
| | | transFromNumber(num) { |
| | | let changeNum = [ |
| | | "é¶", |
| | | "ä¸", |
| | | "äº", |
| | | "ä¸", |
| | | "å", |
| | | "äº", |
| | | "å
", |
| | | "ä¸", |
| | | "å
«", |
| | | "ä¹", |
| | | ]; //changeNum[0] = "é¶" |
| | | let unit = ["", "å", "ç¾", "å", "ä¸"]; |
| | | num = parseInt(num); |
| | | let getWan = (temp) => { |
| | | let strArr = temp.toString().split("").reverse(); |
| | | let newNum = ""; |
| | | for (var i = 0; i < strArr.length; i++) { |
| | | newNum = |
| | | (i == 0 && strArr[i] == 0 |
| | | ? "" |
| | | : i > 0 && strArr[i] == 0 && strArr[i - 1] == 0 |
| | | ? "" |
| | | : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) + |
| | | newNum; |
| | | } |
| | | return newNum; |
| | | }; |
| | | let overWan = Math.floor(num / 10000); |
| | | let noWan = num % 10000; |
| | | if (noWan.toString().length < 4) noWan = "0" + noWan; |
| | | return overWan ? getWan(overWan) + "ä¸" + getWan(noWan) : getWan(num); |
| | | }, |
| | | init() { |
| | | this.pageLoading = true; |
| | | let year = this.query.year.getFullYear(); |
| | |
| | | }).then((res) => { |
| | | this.pageLoading = false; |
| | | this.list = res.data.page |
| | | // this.list = res.data.page.map((item) => { |
| | | // for (let key in item.monthlyAttendance) { |
| | | // let type = this.getDayByDic(key); |
| | | // if (type != undefined || type != null) { |
| | | // item[`day${type}`] = item.monthlyAttendance[key]; |
| | | // } |
| | | // } |
| | | // return item; |
| | | // }); |
| | | console.log(this.list) |
| | | let headerList = res.data.headerList; |
| | | this.weeks = []; |
| | | headerList.forEach((item) => { |
| | |
| | | this.schedulingVisible = false; |
| | | this.schedulingQuery = { |
| | | week: "", |
| | | userId: null, |
| | | userId: [], |
| | | shift: "", |
| | | }; |
| | | this.refresh(); |
| | |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å²ä½"> |
| | | <el-select style="width:100%" v-model="form.postIds" multiple placeholder="è¯·éæ©"> |
| | | <el-option |
| | | v-for="item in postOptions" |
| | | :key="item.postId" |
| | | :label="item.postName" |
| | | :value="item.postId" |
| | | :disabled="item.status == 1" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§è²" prop="roleIds"> |
| | | <el-select v-model="form.roleIds" multiple placeholder="è¯·éæ©è§è²" clearable> |
| | | <el-select style="width:100%" v-model="form.roleIds" multiple placeholder="è¯·éæ©è§è²" clearable> |
| | | <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" |
| | | :disabled="item.status == 1"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¯ç " prop="password"> |
| | | <el-input v-model="form.password" placeholder="请è¾å
¥ç¨æ·å¯ç " type="password" maxlength="20" show-password /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å§åEN" prop="nameEn"> |
| | | <el-input v-model="form.nameEn" placeholder="请è¾å
¥å§åEN" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½" prop="company"> |
| | | <el-select v-model="form.company" placeholder="è¯·éæ©åä½" style="width: 100%" clearable> |
| | | <el-option v-for="item in postOptions" :key="item.id" :label="item.company" |
| | | <el-option v-for="item in companyOptions" :key="item.id" :label="item.company" |
| | | :value="item.id"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å±é¨é¨" prop="deptId"> |
| | | <treeselect v-model="form.deptId" :options="enabledDeptOptions" :show-count="true" |
| | | placeholder="è¯·éæ©å½å±é¨é¨" /> |
| | | placeholder="è¯·éæ©å½å±é¨é¨" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¾å"> |
| | | <el-upload class="avatar-uploader" :action="uploadAction" :show-file-list="false" |
| | |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="个人ç
§ç"> |
| | | <el-upload class="avatar-uploader" :action="uploadAction" :show-file-list="false" |
| | | :headers="upload.headers" accept=".png, .jpg, .jpeg, .gif" :on-error="handleUploadError1" |
| | | :on-success="handleUploadSuccess1" :before-upload="handleBeforeUpload1"> |
| | | :headers="upload.headers" accept=".png, .jpg, .jpeg, .gif" :on-error="handleUploadError1" |
| | | :on-success="handleUploadSuccess1" :before-upload="handleBeforeUpload1"> |
| | | <img v-if="form.pictureUrl" :src="javaApi + '/img/' + form.pictureUrl" class="avatar" alt=""> |
| | | <i v-else class="el-icon-plus avatar-uploader-icon"></i> |
| | | </el-upload> |
| | |
| | | resetUserPwd, |
| | | changeUserStatus, |
| | | deptTreeSelect, |
| | | selectCompaniesList, selectSimpleList, addPersonUser, uploadFile, selectRoleList, selectCustomEnum, addDepartment |
| | | selectCompaniesList, |
| | | selectSimpleList, |
| | | addPersonUser, |
| | | uploadFile, |
| | | selectRoleList, |
| | | selectCustomEnum, |
| | | addDepartment |
| | | } from "@/api/system/user"; |
| | | import {optionSelect} from '@/api/system/post' |
| | | import { getToken } from "@/utils/auth"; |
| | | import Treeselect from "@riophae/vue-treeselect"; |
| | | import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
| | |
| | | dateRange: [], |
| | | // å²ä½é项 |
| | | postOptions: [], |
| | | //åä½é项 |
| | | companyOptions:[], |
| | | // è§è²é项 |
| | | roleOptions: [], |
| | | // 表ååæ° |
| | |
| | | this.reset(); |
| | | this.open = true; |
| | | selectCustomEnum().then(res => { |
| | | this.postOptions = res.data; |
| | | this.companyOptions = res.data; |
| | | }) |
| | | getUser().then(response => { |
| | | this.roleOptions = response.roles; |
| | | this.postOptions = response.posts |
| | | this.title = "æ·»å ç¨æ·"; |
| | | }); |
| | | }, |
| | |
| | | handleUpdate(row) { |
| | | this.reset(); |
| | | selectCustomEnum().then(res => { |
| | | this.postOptions = res.data; |
| | | this.companyOptions = res.data; |
| | | }) |
| | | const userId = row.userId || this.ids; |
| | | getUser(userId).then(response => { |
| | |
| | | this.form.password = '' |
| | | this.roleOptions = response.roles; |
| | | this.$set(this.form, "roleIds", response.roleIds); |
| | | this.postOptions = response.posts |
| | | this.$set(this.form, "postIds", response.postIds); |
| | | this.open = true; |
| | | this.title = "ä¿®æ¹ç¨æ·"; |
| | | }); |