Browse Source

我的日程

lxf 2 năm trước cách đây
mục cha
commit
2c15722963
2 tập tin đã thay đổi với 317 bổ sung32 xóa
  1. 26 0
      src/utils/date.js
  2. 291 32
      src/views/oa/work/schedule/index.vue

+ 26 - 0
src/utils/date.js

@@ -0,0 +1,26 @@
+// 获取日期范围内所有日期
+export function getMonthBetween(starDay, endDay) {
+  var arr = [];
+  var dates = [];
+  // 设置两个日期UTC时间
+  var db = new Date(starDay);
+  var de = new Date(endDay);
+  // 获取两个日期GTM时间
+  var s = db.getTime() - 24 * 60 * 60 * 1000;
+  var d = de.getTime() - 24 * 60 * 60 * 1000;
+  // 获取到两个日期之间的每一天的毫秒数
+  for (var i = s; i <= d; ) {
+    i = i + 24 * 60 * 60 * 1000;
+    arr.push(parseInt(i));
+  }
+  // 获取每一天的时间  YY-MM-DD
+  for (var j in arr) {
+    var time = new Date(arr[j]);
+    var year = time.getFullYear(time);
+    var mouth = time.getMonth() + 1 >= 10 ? time.getMonth() + 1 : "0" + (time.getMonth() + 1);
+    var day = time.getDate() >= 10 ? time.getDate() : "0" + time.getDate();
+    var YYMMDD = year + "-" + mouth + "-" + day;
+    dates.push(YYMMDD);
+  }
+  return dates;
+}

+ 291 - 32
src/views/oa/work/schedule/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="outer-layer">
     <div class="schedule-left">
-      <div class="title commons-title" style="margin-bottom: 0">我的日程</div>
+      <div class="commons-title" style="margin-bottom: 0">我的日程</div>
       <div style="margin-top: 16px">
         <el-input v-model="sourceList.pagination.keyword" placeholder="请输入关键词" class="input-with-select" clearable>
           <template #append>
@@ -26,8 +26,24 @@
         </el-menu>
       </div>
       <div style="margin-top: 16px; font-size: 20px; font-weight: 700">
-        <span>{{ day }}</span>
-        <span style="margin-left: 16px">{{ calculationWeek(day, "yyyy年MM月DD日") }}</span>
+        <span>{{ moment(today).format("yyyy年MM月DD日") }}</span>
+        <span style="margin-left: 16px">{{ calculationWeek(moment(today).format("yyyy年MM月DD日"), "yyyy年MM月DD日") }}</span>
+      </div>
+      <div v-for="(item, index) in selectData" :key="index" style="display: flex; margin-top: 16px">
+        <div style="width: 30px">
+          <div :style="'width: 14px; height: 14px; border-radius: 50px; margin-top: 4px; background-color: ' + item.color"></div>
+        </div>
+        <div style="width: calc(100% -0px)">
+          <div>
+            <span>{{ moment(item.startDate.substr(5, 16), "MM-DD HH:mm:ss").format("MM月DD日 HH:mm") }}</span>
+            <span> - </span>
+            <span>{{ moment(item.endDate.substr(5, 16), "MM-DD HH:mm:ss").format("MM月DD日 HH:mm") }}</span>
+          </div>
+          <div style="margin: 16px 0">
+            <div>{{ item.title }}</div>
+          </div>
+          <div style="margin: 16px 0" v-html="getStyle(item.remark)" v-if="item.remark"></div>
+        </div>
       </div>
     </div>
     <div class="schedule-right">
@@ -52,24 +68,50 @@
         </el-row>
       </div>
       <div class="schedule-bottom">
-        <el-calendar v-model="date" ref="calendar">
+        <el-calendar v-model="today" ref="calendar">
           <template #date-cell="{ data }">
             <div>
               <div :class="'title ' + (data.isSelected ? 'is-selected' : '')" :style="data.isSelected ? '  background-color: #eeeeee;' : ''">
                 <span :class="data.isSelected ? 'select-title' : ''">{{ data.day.substr(8, 10) }}</span>
-                <span style="position: absolute; right: 4px; top: 4px; font-size: 14px; color: black">4条</span>
-              </div>
-              <div :class="data.isSelected ? 'is-selected' : ''" style="text-align: center; height: 18px; line-height: 18px">
-                {{ data.day.substr(8, 10) }}
-              </div>
-              <div :class="data.isSelected ? 'is-selected' : ''" style="text-align: center; height: 18px; line-height: 18px">
-                {{ data.day.substr(8, 10) }}
+                <span style="position: absolute; right: 4px; top: 4px; font-size: 14px; color: black" v-if="judgeDay(data.day)">
+                  {{ dateList[data.day].length }}条
+                </span>
               </div>
-              <div :class="data.isSelected ? 'is-selected' : ''" style="text-align: center; height: 18px; line-height: 18px">
-                {{ data.day.substr(8, 10) }}
-              </div>
-              <div :class="data.isSelected ? 'is-selected' : ''" style="text-align: center; height: 18px; line-height: 18px">
-                {{ data.day.substr(8, 10) }}
+              <div v-if="judgeDay(data.day)">
+                <div v-for="(item, index) in dateList[data.day]" :key="index">
+                  <el-popover placement="right" :width="400" trigger="hover">
+                    <template #reference>
+                      <div class="line-class" :style="getColor(item)">
+                        <span style="font-size: 12px; margin-left: 8px; color: black">{{ item.title }}</span>
+                      </div>
+                    </template>
+                    <div>
+                      <el-form :model="item" label-width="80px" style="margin-top: 18px">
+                        <el-form-item label="主题:">
+                          <span>{{ item.title }}</span>
+                        </el-form-item>
+                        <el-form-item label="时间:">
+                          <div>
+                            <span v-if="item.startDate">{{ moment(item.startDate.substr(5, 16), "MM-DD HH:mm:ss").format("MM月DD日 HH:mm") }}</span>
+                            <span> - </span>
+                            <span v-if="item.endDate">{{ moment(item.endDate.substr(5, 16), "MM-DD HH:mm:ss").format("MM月DD日 HH:mm") }}</span>
+                          </div>
+                        </el-form-item>
+                        <el-form-item label="颜色:">
+                          <div :style="' width: 24px; height: 24px; border-radius: 50px; margin-top: 2px; background-color: ' + item.color">
+                            <el-icon style="color: #fff; font-size: 20px; margin: 2px 0 0 2px"><Check /></el-icon>
+                          </div>
+                        </el-form-item>
+                        <el-form-item label="提醒:">
+                          <span>{{ getLabel(item.noticeType, noticeType) }}</span>
+                        </el-form-item>
+                      </el-form>
+                      <div style="border-top: 1px solid #ccc; text-align: center; padding-top: 16px">
+                        <el-button type="primary" @click="clickDetail(item)" text>查看详情</el-button>
+                      </div>
+                    </div>
+                  </el-popover>
+                </div>
               </div>
             </div>
           </template>
@@ -163,6 +205,41 @@
         <el-button type="primary" @click="clickSubmit()" size="large">确 定</el-button>
       </template>
     </el-dialog>
+
+    <el-drawer v-model="drawer" :title="getDrawerTitle()" :direction="direction">
+      <div style="padding-top: 18px; border-top: 1px solid #ccc">
+        <el-form :model="item" label-width="80px" style="margin: 20px">
+          <el-form-item label="主题:">
+            <span>{{ scheduleDetails.title }}</span>
+          </el-form-item>
+          <el-form-item label="时间:">
+            <div>
+              <span v-if="scheduleDetails.startDate">{{ moment(scheduleDetails.startDate.substr(5, 16), "MM-DD HH:mm:ss").format("MM月DD日 HH:mm") }}</span>
+              <span> - </span>
+              <span v-if="scheduleDetails.endDate">{{ moment(scheduleDetails.endDate.substr(5, 16), "MM-DD HH:mm:ss").format("MM月DD日 HH:mm") }}</span>
+            </div>
+          </el-form-item>
+          <el-form-item label="颜色:">
+            <div :style="' width: 24px; height: 24px; border-radius: 50px; margin-top: 2px; background-color: ' + scheduleDetails.color">
+              <el-icon style="color: #fff; font-size: 20px; margin: 2px 0 0 2px"><Check /></el-icon>
+            </div>
+          </el-form-item>
+          <el-form-item label="参与人:">
+            <div style="display: flex; flex-wrap: wrap" v-if="scheduleDetails.participantList && scheduleDetails.participantList.length > 0">
+              <span v-for="(item, index) in scheduleDetails.participantList" :key="index" style="margin-right: 16px; margin-bottom: 8px">
+                {{ getLabel(item.participantId, userList) }}
+              </span>
+            </div>
+          </el-form-item>
+          <el-form-item label="提醒:">
+            <span>{{ getLabel(scheduleDetails.noticeType, noticeType) }}</span>
+          </el-form-item>
+          <el-form-item label="具体描述:">
+            <div v-html="getStyle(scheduleDetails.remark)" v-if="scheduleDetails.remark"></div>
+          </el-form-item>
+        </el-form>
+      </div>
+    </el-drawer>
   </div>
 </template>
 
@@ -173,6 +250,7 @@ import moment from "moment";
 import byForm from "@/components/byForm/index";
 import useUserStore from "@/store/modules/user";
 import { ElMessage } from "element-plus";
+import * as date from "@/utils/date.js";
 
 const { proxy } = getCurrentInstance();
 const sourceList = ref({
@@ -188,9 +266,11 @@ const sourceList = ref({
   },
 });
 const menuDefault = ref(2);
-const day = ref(moment().format("yyyy年MM月DD日"));
+// const day = ref(moment().format("yyyy年MM月DD日"));
 const month = ref(moment().format("yyyy年MM月"));
 const status = ref("0");
+const dateList = ref({});
+const selectData = ref([]);
 const tableStatus = ref([
   {
     label: "月",
@@ -201,16 +281,17 @@ const tableStatus = ref([
     value: "1",
   },
 ]);
-const date = ref(moment().format("yyyy-MM-DD"));
+const today = ref(moment().format("yyyy-MM-DD"));
 const calendar = ref();
 watch(
-  () => date.value,
+  () => today.value,
   (newValue) => {
     if (month.value !== moment(newValue).format("yyyy年MM月")) {
       month.value = moment(newValue).format("yyyy年MM月");
       console.log("date-change");
       getList();
     }
+    getSelectDayList();
   }
 );
 const selectDate = (val) => {
@@ -234,11 +315,130 @@ const getList = async () => {
   sourceList.value.pagination.startDate = moment(month.value, "yyyy年MM月").format("yyyy-MM-DD");
   sourceList.value.pagination.endDate = moment(moment(month.value, "yyyy年MM月").add(+1, "month").add(-1, "days").calendar()).format("yyyy-MM-DD");
   console.log("getList", sourceList.value.pagination);
+  dateList.value = {};
   proxy.post("/scheduleInfo/page", sourceList.value.pagination).then((res) => {
-    console.log(res);
-    // sourceList.value.data = res.rows;
+    let list = date.getMonthBetween(sourceList.value.pagination.startDate, sourceList.value.pagination.endDate);
+    if (list && list.length > 0) {
+      list.map((item) => {
+        dateList.value[item] = [];
+      });
+    }
+    let dataArr = [];
+    if (res.rows && res.rows.length > 0) {
+      for (let i = 0; i < res.rows.length; i++) {
+        let rowDate = date.getMonthBetween(res.rows[i].startDate.substr(0, 10), res.rows[i].endDate.substr(0, 10));
+        dataArr.push({
+          list: [],
+        });
+        for (let j = 0; j < rowDate.length; j++) {
+          dataArr[i].list.push({
+            ...res.rows[i],
+            date: rowDate[j],
+          });
+        }
+      }
+      var alreadyExisted = [];
+      for (var i = 0; i < dataArr.length; i++) {
+        if (dataArr[i].list.length > 0) {
+          var status = true;
+          for (var j = 0; j < 9; j++) {
+            var status2 = true;
+            for (var k = 0; k < dataArr[i].list.length; k++) {
+              if (alreadyExisted.indexOf(dataArr[i].list[k].date + "-" + j) !== -1) {
+                status2 = false;
+                break;
+              }
+            }
+            if (status2) {
+              for (var l = 0; l < dataArr[i].list.length; l++) {
+                alreadyExisted.push(dataArr[i].list[l].date + "-" + j);
+                for (var n = 0; n < j + 1; n++) {
+                  if (n !== j) {
+                    if (!dateList.value[dataArr[i].list[l].date]) {
+                      dateList.value[dataArr[i].list[l].date] = [];
+                    }
+                    if (!dateList.value[dataArr[i].list[l].date][n]) {
+                      dateList.value[dataArr[i].list[l].date].push({});
+                    }
+                  } else {
+                    if (!dateList.value[dataArr[i].list[l].date]) {
+                      dateList.value[dataArr[i].list[l].date] = [];
+                    }
+                    dateList.value[dataArr[i].list[l].date][j] = dataArr[i].list[l];
+                  }
+                }
+              }
+              status = false;
+              break;
+            }
+          }
+          if (status) {
+            for (var m = 0; m < dataArr[i].list.length; m++) {
+              if (!dateList.value[dataArr[i].list[m].date]) {
+                dateList.value[dataArr[i].list[m].date] = [];
+              }
+              if (!dateList.value[dataArr[i].list[m].date][0]) {
+                dateList.value[dataArr[i].list[m].date][0] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][1]) {
+                dateList.value[dataArr[i].list[m].date][1] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][2]) {
+                dateList.value[dataArr[i].list[m].date][2] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][3]) {
+                dateList.value[dataArr[i].list[m].date][3] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][4]) {
+                dateList.value[dataArr[i].list[m].date][4] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][5]) {
+                dateList.value[dataArr[i].list[m].date][5] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][6]) {
+                dateList.value[dataArr[i].list[m].date][6] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][7]) {
+                dateList.value[dataArr[i].list[m].date][7] = {};
+              }
+              if (!dateList.value[dataArr[i].list[m].date][8]) {
+                dateList.value[dataArr[i].list[m].date][8] = {};
+              }
+              dateList.value[dataArr[i].list[m].date].push(dataArr[i].list[m]);
+            }
+          }
+        }
+      }
+    }
   });
 };
+const getStyle = (text) => {
+  if (text) {
+    return text.replace(/\n|\r\n/g, "<br>");
+  } else {
+    return "";
+  }
+};
+const getSelectDayList = () => {
+  let queryParam = JSON.parse(JSON.stringify(sourceList.value.pagination));
+  queryParam.startDate = moment(today.value).format("yyyy-MM-DD");
+  queryParam.endDate = moment(today.value).format("yyyy-MM-DD");
+  if (menuDefault.value === 1) {
+    queryParam.createUser = useUserStore().user.userId;
+    queryParam.participantId = "";
+  } else if (menuDefault.value === 2) {
+    queryParam.createUser = useUserStore().user.userId;
+    queryParam.participantId = useUserStore().user.userId;
+  } else if (menuDefault.value === 3) {
+    queryParam.createUser = "";
+    queryParam.participantId = useUserStore().user.userId;
+  }
+  console.log("getSelectDayList", queryParam);
+  proxy.post("/scheduleInfo/page", queryParam).then((res) => {
+    selectData.value = res.rows;
+  });
+};
+getSelectDayList();
 const clickToday = () => {
   console.log("clickToday", sourceList.value.pagination);
 };
@@ -336,15 +536,13 @@ const predefineColors = ref([
   "#ffd700",
   "#90ee90",
   "#00ced1",
+  "#00e0ff",
   "#1e90ff",
   "#c71585",
-  "#ff4500ad",
-  "#ff7800",
-  "#fad400",
-  "#90f09080",
-  "#00babd",
-  "#1f93ffba",
-  "#c7158577",
+  "#8c00ff",
+  "#ff00f2",
+  "#00ff32",
+  "#b9ff00",
 ]);
 const formConfig = computed(() => {
   return [
@@ -419,6 +617,9 @@ const newSchedule = () => {
 };
 const clickSubmit = () => {
   schedule.value.handleSubmit(() => {
+    if (formData.data.startDate > formData.data.endDate) {
+      return ElMessage("结束时间不能小于开始时间");
+    }
     loadingDialog.value = true;
     let data = JSON.parse(JSON.stringify(formData.data));
     if (data.participantList && data.participantList.length > 0) {
@@ -436,6 +637,7 @@ const clickSubmit = () => {
         });
         openSchedule.value = false;
         getList();
+        getSelectDayList();
       },
       (err) => {
         console.log(err);
@@ -444,6 +646,44 @@ const clickSubmit = () => {
     );
   });
 };
+const judgeDay = (day) => {
+  return dateList.value[day] && dateList.value[day].length > 0;
+};
+const getColor = (item) => {
+  let text = "background-color: " + item.color + "6b;";
+  if (item.startDate && item.date === item.startDate.substr(0, 10)) {
+    text += " border-left: 5px solid " + item.color;
+  }
+  return text;
+};
+const getLabel = (val, list) => {
+  let text = "";
+  if (list && list.length > 0) {
+    let data = list.filter((item) => item.value == val);
+    if (data && data.length > 0) {
+      text = data[0].label;
+    }
+  }
+  return text;
+};
+const scheduleDetails = ref({});
+const drawer = ref(false);
+const direction = ref("rtl");
+const getDrawerTitle = () => {
+  let title = "";
+  if (scheduleDetails.value.date) {
+    title += moment(scheduleDetails.value.date).format("MM月DD日");
+    title = title + " " + proxy.calculationWeek(moment(scheduleDetails.value.date).format("MM月DD日"), "MM月DD日");
+  }
+  return title;
+};
+const clickDetail = (item) => {
+  proxy.post("/scheduleInfo/detail", { id: item.id }).then((res) => {
+    scheduleDetails.value = res;
+    scheduleDetails.value.date = item.date;
+    drawer.value = true;
+  });
+};
 </script>
 
 <style lang="scss" scoped>
@@ -475,6 +715,16 @@ const clickSubmit = () => {
       &::-webkit-scrollbar {
         width: 0px;
       }
+
+      .line-class {
+        height: 18px;
+        line-height: 18px;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        -o-text-overflow: ellipsis;
+        margin: 1px 0;
+      }
     }
   }
 }
@@ -492,22 +742,23 @@ const clickSubmit = () => {
 }
 ::v-deep(.el-calendar-table .el-calendar-day) {
   padding: 0;
-  min-height: calc((100vh - 100px - 40px - 92px - 50px - 40px) / 6);
+  height: calc((100vh - 100px - 40px - 92px - 50px - 40px) / 6);
+  overflow-y: hidden;
 }
 .is-selected {
   color: #1989fa;
 }
 .title {
   text-align: center;
-  height: 30px;
-  line-height: 22px;
+  height: 24px;
+  line-height: 18px;
   position: relative;
   padding: 4px;
   .select-title {
     border-radius: 50px;
     background-color: #1989fa;
     color: #eee;
-    padding: 4px;
+    padding: 2px;
   }
 }
 ::v-deep(.radio-color .el-radio) {
@@ -523,4 +774,12 @@ const clickSubmit = () => {
     border-radius: 50px;
   }
 }
+::v-deep(.el-drawer__title) {
+  font-size: 24px;
+  font-weight: 700;
+  color: black;
+}
+::v-deep(.el-drawer__body) {
+  padding: 0 !important;
+}
 </style>