瀏覽代碼

值班员工作台

CzRger 1 年之前
父節點
當前提交
044e1d35ee

+ 6 - 0
src/api/modules/workbench.ts

@@ -14,3 +14,9 @@ export const zbyWorkbenchCheckWeek = (params: any) => handle({
   method: 'get',
   params
 })
+//  值班员 > 中间日历
+export const zbyWorkbenchCheckCalendar = (params: any) => handle({
+  url: `/${suffix}/workbench/check/calendar`,
+  method: 'post',
+  params
+})

+ 3 - 3
src/store/modules/app.ts

@@ -32,6 +32,7 @@ const state = {
 	signInfo: null,
 	dailyInfo: null,
 	weeklyInfo: null,
+	projectFirstDate: new Date('2023-11-24 00:00:00')
 }
 
 const getters = {
@@ -44,9 +45,8 @@ const getters = {
 	yearWeeks: (state) => {
 		const arr: any = []
 		const map = new Map()
-		const firstDate = new Date('2023-11-24 00:00:00')
 		let index = 0
-		for (let year = firstDate.getFullYear(); year <= new Date(state.timestamp).getFullYear(); year++) {
+		for (let year = state.projectFirstDate.getFullYear(); year <= new Date(state.timestamp).getFullYear(); year++) {
 			let num = 1
 			let firstWeeklyDate = new Date(year, 0, 1)
 			while (firstWeeklyDate.getDay() !== state.weeklySubmitDay) {
@@ -55,7 +55,7 @@ const getters = {
 			let start = new Date(firstWeeklyDate.getTime() - Handle.oneDayTime * 6)
 			while (new Date(start).getTime() < new Date(year + 1, 0, 1).getTime()) {
 				const end = new Date(start).getTime() + Handle.oneDayTime * 6
-				if (end >= firstDate.getTime() && end <= state.timestamp) {
+				if (end >= state.projectFirstDate.getTime() && end <= state.timestamp) {
 					const obj = {
 						index: index,
 						date: [new Date(start), new Date(end)],

+ 8 - 0
src/store/modules/dictionary.ts

@@ -12,6 +12,14 @@ const state = {
       ['2', '#F9741B'],
       ['3', '#F8EA9A'],
       ['4', '#E5004F'],
+  ]),
+  dailyStatusColor: new Map([
+      ['1', '#3EFFBB'],
+      ['2', '#E5004F'],
+  ]),
+  weeklyStatusColor: new Map([
+      ['1', '#3EFFBB'],
+      ['2', '#E5004F'],
   ])
 }
 

+ 3 - 36
src/views/staging/common/handle.ts

@@ -1,3 +1,5 @@
+import {YMD} from "@/utils/util";
+
 export const formatDate = (d) => {
   const _date = new Date(d)
   const Y = _date.getFullYear()
@@ -49,6 +51,7 @@ export const getMonthCalendarData = (d, fD, selectMonth = null) => {
     const t = new Date(i)
     const obj: any = {
       date: t,
+      dateStr: YMD(t),
       dayStr: t.getDate(),
       tom: getYMDTime(t) > getYMDTime(d)
     }
@@ -59,50 +62,14 @@ export const getMonthCalendarData = (d, fD, selectMonth = null) => {
     } else if (getYMDTime(t) === getYMDTime(d)) {
       obj.today = true // 是传入的当前日期
     }
-    // mock-start
-    if (t.getDate() + 1 === new Date(d).getDate()) {
-      obj.isSign = false
-      obj.signType = '1'  //  1-缺勤,2-迟到,3-早退,4-缺卡
-    }
-    if (t.getDate() + 2 === new Date(d).getDate()) {
-      obj.isSign = false
-      obj.signType = '2'  //  1-缺勤,2-迟到,3-早退,4-缺卡
-    }
-    if (t.getDate() + 3 === new Date(d).getDate()) {
-      obj.isSign = false
-      obj.signType = '3'  //  1-缺勤,2-迟到,3-早退,4-缺卡
-    }
-    if (t.getDate() + 4 === new Date(d).getDate()) {
-      obj.isSign = false
-      obj.signType = '4'  //  1-缺勤,2-迟到,3-早退,4-缺卡
-    }
-    if (t.getDate() + 5 === new Date(d).getDate()) {
-      obj.isSign = true
-    }
-    if (t.getDate() + 6 === new Date(d).getDate()) {
-      obj.isSign = false
-    }
-    if (t.getDate() + 3 === new Date(d).getDate()) {
-      obj.isDaily = true
-    }
-    if (t.getDate() + 4 === new Date(d).getDate()) {
-      obj.isDaily = false
-    }
-    // mock-end
     w.push(obj)
     if (w.length === 7) {
       const wObj: any = {
         calendar: w
       }
-      if (w.some(v => v.today)) {
-        wObj.isWeekly = false
-      }
       arr.push(wObj)
       w = []
     }
   }
-  // mock-start
-  arr[0].isWeekly = true
-  // mock-end
   return arr
 }

+ 0 - 1
src/views/staging/zbgly/right/attendance-com.vue

@@ -117,7 +117,6 @@ export default defineComponent({
     })
     const handleButtonClick = (val) => {
       if (val.value === '4') {
-        console.log(val)
         state.showTimeDialog = true
       }
     }

+ 153 - 56
src/views/staging/zby/center/calendar.vue

@@ -1,12 +1,21 @@
 <template>
-  <div class="calendar-main">
+  <div class="calendar-main" v-loading="loading">
     <div class="month-select">
       <div class="show-block __hover" @click="ref_date.handleOpen()">
-        <img class="select-last __hover" src="@/views/staging/common/title-triangle.png" @click.stop="switchMonth(false)"/>
+        <div class="select-last __hover" @click.stop="pageLastShowCpt ? switchMonth(false) : undefined">
+          <img v-if="pageLastShowCpt" src="@/views/staging/common/title-triangle.png"/>
+        </div>
         <div class="month">{{new Date(selectMonth).getFullYear()}}年{{new Date(selectMonth).getMonth() + 1}}月</div>
-        <img class="select-next __hover" src="@/views/staging/common/title-triangle.png" @click.stop="switchMonth(true)"/>
+        <div class="select-next __hover" @click.stop="pageNextShowCpt ? switchMonth(true) : undefined">
+          <img v-if="pageNextShowCpt" src="@/views/staging/common/title-triangle.png"/>
+        </div>
       </div>
-      <el-date-picker ref="ref_date" v-model="selectMonth" type="month"/>
+      <el-date-picker
+          ref="ref_date"
+          v-model="selectMonth"
+          type="month"
+          :disabled-date="(d) => new Date($util.YM(d)).getTime() > new Date($store.state.app.timestamp).getTime() || new Date($util.YM(d)).getTime() < new Date($util.YM($store.state.app.projectFirstDate)).getTime()"
+      />
     </div>
     <div class="week-head">
       <template v-for="item in getWeekCN(startWeek)">
@@ -14,42 +23,40 @@
       </template>
     </div>
     <div class="week-body">
-      <template v-for="week in calendarCpt">
+      <template v-for="week in calendarWithInfoCpt">
         <div class="week-block">
           <div class="week-block-head">
             <template v-for="item in week.calendar">
               <div class="wbh-content">
                 <div class="day" :class="{last: item.last, will: item.will, today: item.today}">{{item.dayStr}}</div>
                 <div class="info" :class="{tom: item.tom}">
-                  <div>
+                  <div class="sign">
                     签卡
-                    <template v-if="$util.isValue(item.isSign)">
-                      <template v-if="item.isSign">
-                        <SvgIcon name="true" color="#01C869" size="14"/>
+                    <template v-if="$util.isValue(item.signInStatus)">
+                      <template v-if="item.signInStatus === '1'">
+                        <SvgIcon name="true" :color="$store.state.dictionary.signStatusColor.get(item.signInStatus)" size="14"/>
+                      </template>
+                      <template v-else>
+                        <SvgIcon name="tips" :color="$store.state.dictionary.signStatusColor.get(item.signInStatus)" size="14"/>
+                      </template>
+                    </template>
+                    <template v-if="$util.isValue(item.signOutStatus)">
+                      <template v-if="item.signOutStatus === '1'">
+                        <SvgIcon name="true" :color="$store.state.dictionary.signStatusColor.get(item.signOutStatus)" size="14"/>
                       </template>
                       <template v-else>
-                        <SvgIcon name="tips" :color="
-                          item.signType === '1' ?
-                           '#E72524' :
-                           (item.signType === '2' ?
-                           '#F9741B' :
-                           (item.signType === '3' ?
-                           '#F8EA9A' :
-                           (item.signType === '4' ?
-                           '#36485b' :
-                           '#E72524'))
-                        )" size="14"/>
+                        <SvgIcon name="tips" :color="$store.state.dictionary.signStatusColor.get(item.signOutStatus)" size="14"/>
                       </template>
                     </template>
                   </div>
-                  <div>
+                  <div class="daily">
                     日报
-                    <template v-if="$util.isValue(item.isDaily)">
-                      <template v-if="item.isDaily">
-                        <img src="@/assets/images/business/calendar-true.png"/>
+                    <template v-if="$util.isValue(item.dailyStatus)">
+                      <template v-if="item.dailyStatus === '1'">
+                        <SvgIcon name="true" :color="$store.state.dictionary.dailyStatusColor.get(item.dailyStatus)" size="14"/>
                       </template>
                       <template v-else>
-                        <img src="@/assets/images/business/calendar-false.png"/>
+                        <SvgIcon name="tips" :color="$store.state.dictionary.dailyStatusColor.get(item.dailyStatus)" size="14"/>
                       </template>
                     </template>
                   </div>
@@ -58,9 +65,9 @@
             </template>
           </div>
           <div class="week-block-weekly">
-            <div class="value" :style="`color: ${week.isWeekly ? '#01C869' : '#E72524'}`">
-              <template v-if="$util.isValue(week.isWeekly)">
-                {{week.isWeekly ? '周报已提交' : '周报未提交'}}
+            <div class="value" :style="`color: ${$store.state.dictionary.weeklyStatusColor.get(week.weeklyStatus)}`">
+              <template v-if="$util.isValue(week.weeklyStatus)">
+                {{week.weeklyStatus === '1' ? '周报已提交' : '周报未提交'}}
               </template>
             </div>
           </div>
@@ -70,21 +77,20 @@
     <div class="week-tips">
       <div class="sign">
         签卡:
-        <div class="green"/>正常
-        <div class="red"/>缺勤
-        <div class="orange"/>迟到
-        <div class="yellow"/>早退
-        <div class="gray"/>缺卡
+        <div :style="`background-color: ${$store.state.dictionary.signStatusColor.get('1')};`"/>正常
+        <div :style="`background-color: ${$store.state.dictionary.signStatusColor.get('2')};`"/>迟到
+        <div :style="`background-color: ${$store.state.dictionary.signStatusColor.get('3')};`"/>早退
+        <div :style="`background-color: ${$store.state.dictionary.signStatusColor.get('4')};`"/>缺卡
       </div>
       <div class="daily">
         日志:
-        <div class="green"/>已提交
-        <div class="red"/>未提交
+        <div :style="`background-color: ${$store.state.dictionary.dailyStatusColor.get('1')};`"/>已提交
+        <div :style="`background-color: ${$store.state.dictionary.dailyStatusColor.get('2')};`"/>未提交
       </div>
       <div class="weekly">
         周报:
-        <div class="green"/>已提交
-        <div class="red"/>未提交
+        <div :style="`background-color: ${$store.state.dictionary.weeklyStatusColor.get('1')};`"/>已提交
+        <div :style="`background-color: ${$store.state.dictionary.weeklyStatusColor.get('2')};`"/>未提交
       </div>
     </div>
   </div>
@@ -106,6 +112,7 @@ import {
 import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import * as Handle from "@/views/staging/common/handle";
+import {ElMessage} from "element-plus";
 
 export default defineComponent({
   name: '',
@@ -120,10 +127,42 @@ export default defineComponent({
       startWeek: store.state.app.weekStart,
       timestamp: JSON.parse(JSON.stringify(store.state.app.timestamp)),
       selectMonth: JSON.parse(JSON.stringify(store.state.app.timestamp)),
+      loading: false,
+      calendarInfo: {
+        signIn: new Map(),
+        signOut: new Map(),
+        daily: new Map(),
+        weekly: new Map(),
+      }
     })
     const calendarCpt = computed(() => {
       return Handle.getMonthCalendarData(state.timestamp, state.startWeek, state.selectMonth)
     })
+    const calendarWithInfoCpt = computed(() => {
+      const arr: any = []
+      calendarCpt.value.forEach(w => {
+        w.calendar.forEach(d => {
+          //  周报提交状态
+          if (state.calendarInfo.weekly.has(d.dateStr)) {
+            w.weeklyStatus = state.calendarInfo.weekly.get(d.dateStr)
+          }
+          //  日志提交状态
+          if (state.calendarInfo.daily.has(d.dateStr)) {
+            d.dailyStatus = state.calendarInfo.daily.get(d.dateStr)
+          }
+          //  签到状态
+          if (state.calendarInfo.signIn.has(d.dateStr)) {
+            d.signInStatus = state.calendarInfo.signIn.get(d.dateStr)
+          }
+          //  签退状态
+          if (state.calendarInfo.signOut.has(d.dateStr)) {
+            d.signOutStatus = state.calendarInfo.signOut.get(d.dateStr)
+          }
+        })
+        arr.push(w)
+      })
+      return arr
+    })
     const calendarCptLength = computed(() => {
       return calendarCpt.value.length
     })
@@ -145,6 +184,12 @@ export default defineComponent({
       return weekArray
     }
     const ref_date = ref()
+    const pageLastShowCpt = computed(() => {
+      return new Date(that.$util.YM(state.selectMonth)).getTime() > new Date(that.$util.YM(store.state.app.projectFirstDate)).getTime()
+    })
+    const pageNextShowCpt = computed(() => {
+      return new Date(that.$util.YM(state.selectMonth)).getTime() < new Date(that.$util.YM(store.state.app.timestamp)).getTime()
+    })
     const switchMonth = (isNext) => {
       const sm = new Date(state.selectMonth)
       const first = new Date(sm.getFullYear(), sm.getMonth(), 1)
@@ -157,13 +202,69 @@ export default defineComponent({
         state.selectMonth = new Date(last.getFullYear(), last.getMonth(), 1)
       }
     }
+    const getCalendarInfo = () => {
+      state.loading = true
+      state.calendarInfo = {
+        signIn: new Map(),
+        signOut: new Map(),
+        daily: new Map(),
+        weekly: new Map(),
+      }
+      that.$api.zbyWorkbenchCheckCalendar({
+        deptId: store.state.app.userInfo.dept.id,
+        times: calendarCpt.value.map(v => {
+          return {
+            beginTime: v.calendar[0].dateStr,
+            endTime: v.calendar[v.calendar.length - 1].dateStr,
+          }
+        })
+      }).then(res => {
+        if (res.code === 200 && res.data) {
+          res.data.dateList?.forEach(v => {
+            if (new Date(that.$util.YMD(v.date)) <= new Date(that.$util.YMD(store.state.app.timestamp)) && new Date(that.$util.YMD(v.date)) >= new Date(that.$util.YMD(store.state.app.projectFirstDate))) {
+              //  日志提交情况
+              state.calendarInfo.daily.set(v.date, v.logStatus)
+              //  签到情况
+              if (v.signInfoStatus?.inStatus) {
+                state.calendarInfo.signIn.set(v.date, v.signInfoStatus.inStatus)
+              }
+              //  签退情况
+              if (v.signInfoStatus?.outStatus) {
+                state.calendarInfo.signOut.set(v.date, v.signInfoStatus.outStatus)
+              }
+            }
+          })
+          //  周报提交情况
+          for (const [k, v] of Object.entries(res.data?.weekMap)) {
+            if (that.$util.isValue(v)) {
+              if (new Date(that.$util.YMD(k)) <= new Date(that.$util.YMD(store.state.app.timestamp)) && new Date(that.$util.YMD(k)) >= new Date(that.$util.YMD(store.state.app.projectFirstDate))) {
+                state.calendarInfo.weekly.set(k, v)
+              }
+            }
+          }
+        } else {
+          ElMessage.error(res.message)
+        }
+        state.loading = false
+      }).catch(() => {
+        state.loading = false
+      })
+    }
+    watch(() => state.selectMonth, (n) => {
+      getCalendarInfo()
+    }, {
+      immediate: true
+    })
     return {
       ...toRefs(state),
       getWeekCN,
       ref_date,
       switchMonth,
       calendarCpt,
-      calendarCptLength
+      calendarWithInfoCpt,
+      calendarCptLength,
+      pageLastShowCpt,
+      pageNextShowCpt,
     }
   },
 })
@@ -198,6 +299,10 @@ export default defineComponent({
       .select-last, .select-next {
         width: 11px;
         height: 23px;
+        >img {
+          width: 100%;
+          height: 100%;
+        }
       }
       .select-last {
         transform: rotate(180deg);
@@ -284,8 +389,15 @@ export default defineComponent({
               padding-left: 6px;
               display: flex;
               align-items: center;
-              >img, .svg-icon {
-                margin-left: 8px;
+              &.sign {
+                .svg-icon {
+                  margin-left: 2px;
+                }
+              }
+              &.daily {
+                .svg-icon {
+                  margin-left: 8px;
+                }
               }
             }
           }
@@ -323,27 +435,12 @@ export default defineComponent({
     >div {
       display: flex;
       align-items: center;
-      .green, .red, .orange, .yellow, .gray {
+      >div {
         width: 6px;
         height: 6px;
         border-radius: 50%;
         margin: 0 6px 0 10px;
       }
-      .green {
-        background-color: #3EFFBB;
-      }
-      .red {
-        background-color: #E5004F;
-      }
-      .orange {
-        background-color: #F9741B;
-      }
-      .yellow {
-        background-color: #F8EA9A;
-      }
-      .gray {
-        background-color: #36485b;
-      }
     }
     .daily {
       margin: 0 52px;

+ 11 - 15
src/views/staging/zby/center/index.vue

@@ -12,11 +12,11 @@
           <img src="@/assets/images/business/operation-sign.png"/>
         </div>
         <div class="label">
-          <template v-if="isSignCpt">
-            班打卡
+          <template v-if="!$store.state.app.signInfo?.id">
+            班打卡
           </template>
           <template v-else>
-            班打卡
+            班打卡
           </template>
         </div>
       </div>
@@ -116,9 +116,6 @@ export default defineComponent({
       }
       state.showWeeklyDetail = true
     }
-    const isSignCpt = computed(() => {
-      return store.state.app.signInfo?.id
-    })
     const onSign = () => {
       const sign = (msg) => {
         that.$api.signIn().then(res => {
@@ -131,8 +128,10 @@ export default defineComponent({
         }).catch(() => {
         })
       }
-      if (!isSignCpt.value) {
-        if (state.tools.now > state.tools.signStart) {
+      if (!store.state.app.signInfo?.id) {
+        if (state.tools.now < state.tools.signStart) {
+          sign('签到成功!')
+        } else {
           ElMessageBox.confirm(`当前已过签到时间,是否继续签到?`, "提示", {
             confirmButtonText: "确定",
             cancelButtonText: "取消",
@@ -140,11 +139,11 @@ export default defineComponent({
           }).then(() => {
             sign('签到成功!')
           }).catch(() => {})
-        } else {
-          sign('签到成功!')
         }
       } else {
-        if (state.tools.now < state.tools.signEnd) {
+        if (state.tools.now > state.tools.signEnd) {
+          sign('签退成功!')
+        } else {
           ElMessageBox.confirm(`当前未到签退时间,是否继续签退?`, "提示", {
             confirmButtonText: "确定",
             cancelButtonText: "取消",
@@ -152,8 +151,6 @@ export default defineComponent({
           }).then(() => {
             sign('签退成功!')
           }).catch(() => {})
-        } else {
-          sign('签退成功!')
         }
       }
     }
@@ -170,13 +167,12 @@ export default defineComponent({
       if (store.getters['app/isWeeklyDay'] && !store.state.app.weeklyInfo?.id) {
         str.push('未提交周报')
       }
-      return `您还${str.join('/')},请尽快完成操作`
+      return str.length > 0 ? `您还${str.join('/')},请尽快完成操作` : ''
     })
     return {
       ...toRefs(state),
       onDaily,
       onWeekly,
-      isSignCpt,
       onSign,
       tipsCpt
     }

+ 14 - 8
src/views/staging/zby/center/statistic.vue

@@ -14,7 +14,7 @@
             v-model="dateValue.selectDay"
             value-format="YYYY-MM-DD"
             @change="handleDay"
-            :disabled-date="(d) => new Date($util.YMD(d)).getTime() > new Date(tempToday).getTime()"
+            :disabled-date="(d) => new Date($util.YMD(d)).getTime() > new Date($util.YMD(tempToday)).getTime() || new Date($util.YMD(d)).getTime() < new Date($util.YMD($store.state.app.projectFirstDate)).getTime()"
         />
         <el-select
             v-if="dateType === 'week'"
@@ -36,7 +36,7 @@
             type="month"
             value-format="YYYY-MM"
             @change="handleMonth"
-            :disabled-date="(d) => new Date($util.YM(d)).getTime() > new Date(tempToday).getTime()"
+            :disabled-date="(d) => new Date($util.YM(d)).getTime() > new Date($util.YM(tempToday)).getTime() || new Date($util.YM(d)).getTime() < new Date($util.YM($store.state.app.projectFirstDate)).getTime()"
         />
       </div>
       <div class="page">
@@ -47,8 +47,8 @@
           <template v-if="dateType === 'day'">
             <template v-for="item in dateCalendar.day">
               <div class="page-content-item __hover"
-                   :class="{today: item.isToday, active: dateValue.selectDay === item.selectValue}"
-                   @click="onDayClick(item)"
+                   :class="{today: item.isToday, active: dateValue.selectDay === item.selectValue, disabled: item.disabled}"
+                   @click="item.disabled ? undefined : onDayClick(item)"
               >{{item.str}}</div>
             </template>
           </template>
@@ -63,8 +63,8 @@
           <template v-if="dateType === 'month'">
             <template v-for="item in dateCalendar.month">
               <div class="page-content-item __hover"
-                   :class="{today: item.isToday, active: dateValue.selectMonth === item.selectValue}"
-                   @click="onMonthClick(item)"
+                   :class="{today: item.isToday, active: dateValue.selectMonth === item.selectValue, disabled: item.disabled}"
+                   @click="item.disabled ? undefined : onMonthClick(item)"
               >{{item.str}}</div>
             </template>
           </template>
@@ -412,11 +412,11 @@ export default defineComponent({
     })
     const pageLastShowCpt = computed(() => {
       let flag = false
-      if (state.dateType === 'day' && state.dateCalendar.day.length > 0) {
+      if (state.dateType === 'day' && state.dateCalendar.day.length > 0 && state.dateCalendar.day.every(v => !v.disabled)) {
         flag = true
       } else if (state.dateType === 'week' && state.dateCalendar.week.length > 0 && store.getters['app/yearWeeks'].list.length > 0) {
         flag = state.dateCalendar.week[0].index > 0
-      } else if (state.dateType === 'month' && state.dateCalendar.month.length > 0) {
+      } else if (state.dateType === 'month' && state.dateCalendar.month.length > 0 && state.dateCalendar.month.every(v => !v.disabled)) {
         flag = true
       }
       return flag
@@ -470,6 +470,7 @@ export default defineComponent({
       for (let i = 6; i >= 0; i--) {
         const d = new Date(new Date(lastDate).getTime() - oneDayTime * i)
         arr.push({
+          disabled: new Date(that.$util.YMD(d)).getTime() < new Date(that.$util.YMD(store.state.app.projectFirstDate)).getTime(),
           str: d.getDate(),
           date: d,
           selectValue: that.$util.YMD(d),
@@ -496,6 +497,7 @@ export default defineComponent({
       for (let i = 6; i >= 0; i--) {
         const d = new Date(new Date(lastDate).getFullYear(), new Date(lastDate).getMonth() - i, 1)
         arr.push({
+          disabled: new Date(that.$util.YM(d)).getTime() < new Date(that.$util.YM(store.state.app.projectFirstDate)).getTime(),
           str: (d.getMonth() + 1) + '月',
           date: d,
           selectValue: that.$util.YM(d),
@@ -825,6 +827,10 @@ export default defineComponent({
             box-shadow: inset 0px 0px 20px 3px #2EB8FF;
             background-color: rgba(0, 133, 247, 0.25);
           }
+          &.disabled {
+            opacity: 0.3;
+            cursor: not-allowed;
+          }
         }
       }
     }