Ver código fonte

管理人员左侧日历

CzRger 1 ano atrás
pai
commit
080586a111

BIN
src/assets/images/business/calendar-false.png


BIN
src/assets/images/business/calendar-true.png


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

@@ -54,7 +54,7 @@ const actions = {
 		})
 		})
 	},
 	},
 	LOAD_TIMESTAMP({ commit }: any) {
 	LOAD_TIMESTAMP({ commit }: any) {
-		const date = new Date()
+		const date = new Date('2023-07-16')
 		commit('SET_TIMESTAMP', date)
 		commit('SET_TIMESTAMP', date)
 	},
 	},
 }
 }

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

@@ -8,7 +8,7 @@ export const formatDate = (d) => {
   return `${Y}/${M}/${D} ${H}:${m}`;
   return `${Y}/${M}/${D} ${H}:${m}`;
 }
 }
 
 
-export const getMonthCalendarData = (d, fD) => {
+export const getMonthCalendarData = (d, fD, selectMonth = null) => {
   const getFirstDateOfWeek = (fDate, firstDayOfWeek) => {
   const getFirstDateOfWeek = (fDate, firstDayOfWeek) => {
     const day = fDate.getDay();
     const day = fDate.getDay();
     const diff = (day < firstDayOfWeek ? 7 : 0) + day - firstDayOfWeek;
     const diff = (day < firstDayOfWeek ? 7 : 0) + day - firstDayOfWeek;
@@ -21,8 +21,15 @@ export const getMonthCalendarData = (d, fD) => {
     const lastDate = new Date(lDate.getFullYear(), lDate.getMonth(), lDate.getDate() + (6 - diff));
     const lastDate = new Date(lDate.getFullYear(), lDate.getMonth(), lDate.getDate() + (6 - diff));
     return lastDate;
     return lastDate;
   }
   }
+  const getYMDTime = (date) => {
+    const _date = new Date(date)
+    const Y = _date.getFullYear()
+    const M = _date.getMonth() + 1
+    const D = _date.getDate()
+    return new Date(`${Y}-${M}-${D}`).getTime()
+  }
   const oneDayTime = 1000 * 60 * 60 * 24
   const oneDayTime = 1000 * 60 * 60 * 24
-  const _date = new Date(d)
+  const _date = selectMonth ? new Date(selectMonth) : new Date(d)
   // d的月份有几天
   // d的月份有几天
   const monthDaysTotal = new Date(_date.getFullYear(), _date.getMonth() + 1, 0).getDate()
   const monthDaysTotal = new Date(_date.getFullYear(), _date.getMonth() + 1, 0).getDate()
   // d的月份的第一天
   // d的月份的第一天
@@ -34,8 +41,48 @@ export const getMonthCalendarData = (d, fD) => {
   // 日历最后一天
   // 日历最后一天
   const wholeLastDay = getLastDateOfWeek(monthLastDate, fD)
   const wholeLastDay = getLastDateOfWeek(monthLastDate, fD)
   const arr: any = []
   const arr: any = []
+  let w: any = []
   for (let i = wholeFirstDay.getTime(); i <= wholeLastDay.getTime(); i += oneDayTime) {
   for (let i = wholeFirstDay.getTime(); i <= wholeLastDay.getTime(); i += oneDayTime) {
-    arr.push(new Date(i).getDay() + '-' + new Date(i).getDate())
+    const t = new Date(i)
+    const obj: any = {
+      date: t,
+      dayStr: t.getDate()
+    }
+    if (getYMDTime(t) < monthFirstDate.getTime()) {
+      obj.last = true //  是补全的日历过去时间
+    } else if (getYMDTime(t) > monthLastDate.getTime()) {
+      obj.will = true //  是补全的日历未来时间
+    } else if (getYMDTime(t) === getYMDTime(d)) {
+      obj.today = true // 是传入的当前日期
+    }
+    // mock-start
+    if (t.getDate() + 1 === new Date(d).getDate()) {
+      obj.isSign = true
+    }
+    if (t.getDate() + 2 === 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
   return arr
 }
 }

+ 2 - 2
src/views/staging/zbgly/index.vue

@@ -62,11 +62,11 @@ export default defineComponent({
   flex-direction: column;
   flex-direction: column;
   .calendar-main {
   .calendar-main {
     width: 100%;
     width: 100%;
-    height: calc(100% / 3 * 2);
   }
   }
   .analysis-main {
   .analysis-main {
+    flex: 1;
     width: 100%;
     width: 100%;
-    height: calc(100% / 3);
+    overflow: hidden;
   }
   }
 }
 }
 .staging-right {
 .staging-right {

+ 227 - 12
src/views/staging/zbgly/left/calendar-com.vue

@@ -7,12 +7,71 @@
       <div class="more">查看更多》</div>
       <div class="more">查看更多》</div>
     </template>
     </template>
     <div class="main">
     <div class="main">
-      <template v-for="item in getWeekCN(startWeek)">
-        <div class="item">{{item}}</div>
-      </template>
-      <template v-for="item in Handle.getMonthCalendarData($store.state.app.timestamp, startWeek)">
-        <div class="item">{{item}}</div>
-      </template>
+      <div class="week-head">
+        <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="month">{{new Date(selectMonth).getMonth() + 1}}</div>
+            <div class="unit">/月</div>
+            <img class="select-next __hover" src="@/views/staging/common/title-triangle.png" @click.stop="switchMonth(true)"/>
+          </div>
+          <el-date-picker ref="ref_date" v-model="selectMonth" type="month"/>
+        </div>
+        <div class="none"/>
+        <template v-for="item in getWeekCN(startWeek)">
+          <div class="week-cn">{{item}}</div>
+        </template>
+      </div>
+      <div class="week-body">
+        <template v-for="week in calendarCpt">
+          <div class="week-block">
+            <div class="week-block-head">
+              <div class="none"></div>
+              <template v-for="item in week.calendar">
+                <div class="day" :class="{last: item.last, will: item.will, today: item.today}">{{item.dayStr}}</div>
+              </template>
+            </div>
+            <div class="week-block-sign">
+              <div class="label">签卡</div>
+              <template v-for="item in week.calendar">
+                <div class="item">
+                  <template v-if="$util.isValue(item.isSign)">
+                    <template v-if="item.isSign">
+                      <img src="@/assets/images/business/calendar-true.png"/>
+                    </template>
+                    <template v-else>
+                      <img src="@/assets/images/business/calendar-false.png"/>
+                    </template>
+                  </template>
+                </div>
+              </template>
+            </div>
+            <div class="week-block-daily">
+              <div class="label">日报</div>
+              <template v-for="item in week.calendar">
+                <div class="item">
+                  <template v-if="$util.isValue(item.isDaily)">
+                    <template v-if="item.isDaily">
+                      <img src="@/assets/images/business/calendar-true.png"/>
+                    </template>
+                    <template v-else>
+                      <img src="@/assets/images/business/calendar-false.png"/>
+                    </template>
+                  </template>
+                </div>
+              </template>
+            </div>
+            <div class="week-block-weekly">
+              <div class="label">周报</div>
+              <div class="value" :style="`color: ${week.isWeekly ? '#01C869' : '#E72524'}`">
+                <template v-if="$util.isValue(week.isWeekly)">
+                  {{week.isWeekly ? '(已提交)' : '(未提交)'}}
+                </template>
+              </div>
+            </div>
+          </div>
+        </template>
+      </div>
     </div>
     </div>
   </BaseBlockCom>
   </BaseBlockCom>
 </template>
 </template>
@@ -50,7 +109,15 @@ export default defineComponent({
     const state = reactive({
     const state = reactive({
       Handle: Handle,
       Handle: Handle,
       deptId: '',
       deptId: '',
-      startWeek: 0
+      startWeek: 0,
+      timestamp: JSON.parse(JSON.stringify(store.state.app.timestamp)),
+      selectMonth: JSON.parse(JSON.stringify(store.state.app.timestamp)),
+    })
+    const calendarCpt = computed(() => {
+      return Handle.getMonthCalendarData(state.timestamp, state.startWeek, state.selectMonth)
+    })
+    const calendarCptLength = computed(() => {
+      return calendarCpt.value.length
     })
     })
     const getWeekCN = (xq) => {
     const getWeekCN = (xq) => {
       const m = new Map([
       const m = new Map([
@@ -69,12 +136,28 @@ export default defineComponent({
       }
       }
       return weekArray
       return weekArray
     }
     }
-
+    const ref_date = ref()
+    const switchMonth = (isNext) => {
+      const sm = new Date(state.selectMonth)
+      const first = new Date(sm.getFullYear(), sm.getMonth(), 1)
+      const oneDayTime = 1000 * 60 * 60 * 24
+      if (isNext) {
+        const next = new Date(first.getTime() + oneDayTime * 40)
+        state.selectMonth = new Date(next.getFullYear(), next.getMonth(), 1)
+      } else {
+        const last = new Date(first.getTime() - oneDayTime)
+        state.selectMonth = new Date(last.getFullYear(), last.getMonth(), 1)
+      }
+    }
     onMounted(() => {
     onMounted(() => {
     })
     })
     return {
     return {
       ...toRefs(state),
       ...toRefs(state),
-      getWeekCN
+      getWeekCN,
+      ref_date,
+      switchMonth,
+      calendarCpt,
+      calendarCptLength
     }
     }
   },
   },
 })
 })
@@ -89,8 +172,140 @@ export default defineComponent({
   margin-right: 10px;
   margin-right: 10px;
 }
 }
 .main {
 .main {
-  display: grid;
-  grid-template-columns: repeat(7, 1fr);
-  row-gap: 10px;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  $headH: 30px;
+  $dayH: 24px;
+  .week-head {
+    margin-top: 6px;
+    display: grid;
+    grid-template-columns: repeat(8, 1fr);
+    height: $headH;
+    font-size: 12px;
+    font-family: Source Han Sans CN;
+    font-weight: bold;
+    color: #FFFFFF;
+    position: relative;
+    .week-cn {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .month-select {
+      width: calc(100% / 8 - 2px);
+      height: calc(#{$headH} + #{$dayH});
+      position: absolute;
+      :deep(.el-date-editor--month) {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        visibility: hidden;
+        z-index: 1;
+      }
+      .show-block {
+        width: 100%;
+        height: 100%;
+        position: absolute;
+        top: 0;
+        left: 0;
+        z-index: 2;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        background-color: rgba(0, 133, 247, 0.1);
+        .select-last, .select-next {
+          position: absolute;
+          width: 7px;
+          height: 15px;
+        }
+        .select-last {
+          left: -5px;
+          transform: rotate(180deg);
+        }
+        .select-next {
+          right: -5px;
+        }
+        .month {
+          font-size: 28px;
+          font-family: Source Han Sans CN;
+          font-weight: bold;
+          color: #FFFFFF;
+          line-height: 30px;
+        }
+        .unit {
+          font-size: 12px;
+          font-family: Microsoft YaHei;
+          font-weight: 400;
+          color: #FFFFFF;
+        }
+      }
+    }
+  }
+  .week-body {
+    flex: 1;
+    display: grid;
+    grid-template-rows: repeat(v-bind(calendarCptLength), 90px);
+    margin-bottom: 10px;
+    .week-block {
+      margin-top: 2px;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      .week-block-head, .week-block-sign, .week-block-daily, .week-block-weekly {
+        display: grid;
+        grid-template-columns: repeat(8, 1fr);
+      }
+      .week-block-head {
+        height: $dayH;
+        .day {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          background-color: rgba(0, 133, 247, 0.25);
+          margin: 0 1px;
+          font-size: 14px;
+          font-family: Microsoft YaHei;
+          font-weight: 400;
+          color: #FFFFFF;
+          &.last, &.will {
+            background-color: rgba(0, 133, 247, 0.1);
+            color: rgba(255, 255, 255, 0.4);
+          }
+          &.today {
+            border: 2px solid;
+            border-image: linear-gradient(0deg, #4FACFE, #00F2FE) 10 10;
+            box-shadow: inset 0px 0px 20px 3px #2EB8FF;
+          }
+        }
+      }
+      .week-block-sign, .week-block-daily, .week-block-weekly {
+        height: 20px;
+        background-color: rgba(0, 133, 247, 0.1);
+        margin-top: 2px;
+        font-size: 12px;
+        font-family: Microsoft YaHei;
+        font-weight: 400;
+        color: rgba(255, 255, 255, 0.7);
+        >div {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+        }
+      }
+      .week-block-weekly {
+        .value {
+          grid-column: span 7;
+          display: flex;
+          justify-content: flex-end;
+          margin-right: 10px;
+        }
+      }
+    }
+  }
 }
 }
 </style>
 </style>

+ 26 - 5
src/views/staging/zbgly/left/trend-analysis-chart.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <div class="chart-main">
+  <div class="chart-main" ref="ref_main">
     <div class="chart-ref" ref="ref_chart"/>
     <div class="chart-ref" ref="ref_chart"/>
     <div class="legend">
     <div class="legend">
       <div class="green">
       <div class="green">
@@ -23,7 +23,7 @@ import {
   getCurrentInstance,
   getCurrentInstance,
   ComponentInternalInstance,
   ComponentInternalInstance,
   toRefs,
   toRefs,
-  nextTick
+  nextTick, onUnmounted
 } from 'vue'
 } from 'vue'
 import {useStore} from 'vuex'
 import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import {useRouter, useRoute} from 'vue-router'
@@ -37,8 +37,12 @@ export default defineComponent({
     const router = useRouter();
     const router = useRouter();
     const route = useRoute();
     const route = useRoute();
     const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
     const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
-    const state = reactive({})
+    const state = reactive({
+      resizeObserver: <any>null,
+      chart: <any>null
+    })
     const ref_chart = ref();
     const ref_chart = ref();
+    const ref_main = ref();
     const initChart = () => {
     const initChart = () => {
       const chart = echarts.init(ref_chart.value);
       const chart = echarts.init(ref_chart.value);
       const yStyle = {
       const yStyle = {
@@ -193,13 +197,30 @@ export default defineComponent({
         ]
         ]
       };
       };
       chart.setOption(option);
       chart.setOption(option);
+      // window.onresize = () => {
+      //   chart && chart.resize()
+      // }
+      state.resizeObserver = new ResizeObserver((entries) => {
+        for (const entry of entries) {
+          chart && chart.resize()
+        }
+      })
+      state.resizeObserver.observe(ref_main.value);
+      return chart
     }
     }
     onMounted(() => {
     onMounted(() => {
-      initChart()
+      nextTick(() => {
+        state.chart = initChart()
+      })
+      return () => {
+        state.resizeObserver?.unobserve(ref_main?.value)
+        state.resizeObserver?.disconnect()
+      }
     })
     })
     return {
     return {
       ...toRefs(state),
       ...toRefs(state),
-      ref_chart
+      ref_chart,
+      ref_main
     }
     }
   },
   },
 })
 })