src/views/performance/class/index.vue
@@ -22,8 +22,8 @@
        </div>
      </div>
      <div class="search_thing" style="padding-left: 30px">
        <el-button size="small" @click="refresh()">重 置</el-button>
        <el-button size="small" type="primary" @click="refreshTable()">查 询</el-button>
        <el-button size="mini" type="primary" @click="refreshTable()">查 询</el-button>
        <el-button size="mini" @click="refresh()">重置</el-button>
      </div>
      <div class="search_thing btns" style="padding-left: 30px">
        <el-button size="small" type="primary" v-if="checkPermi(['performance:class:time'])"
@@ -101,18 +101,12 @@
                <el-dropdown trigger="click" placement="bottom" @command="(e) => handleCommand(e, m)"
                  :disabled="!checkPermi(['performance:class:edit'])"
                  style="width: 100%; height: 100%; cursor: pointer">
                  <div class="work-box" :class="{
                    type0: m.shift === '0',
                    type1: m.shift === '1',
                    type2: m.shift === '2',
                    type3: m.shift === '3',
                    type4: m.shift === '4',
                    type5: m.shift === '5',
                    type6: m.shift === '6',
                  }">
                    <span style="cursor: pointer" :style="`opacity: ${getShiftByDic(m.shift) == '无' ? 0 : 1
                      };`">{{ getShiftByDic(m.shift) }}</span>
                  </div>
                  <el-tooltip :disabled="!m.annotationText" :content="m.annotationText">
                    <el-tag @contextmenu.prevent.native="handleContextMenu(m,$event)" class="work-box" :type="getDictTypeByShift(m.shift)">{{ getShiftByDic(m.shift) }}</el-tag>
                  </el-tooltip>
                  <i v-if="m.checkinResult==='success'" class="el-icon-success" style="position: relative;top:-20px;color:#67c23a;"></i>
                  <i v-else-if="m.checkinResult==='fail'" class="el-icon-warning" style="position: relative;top:-20px;color:#f56c6c;"></i>
                  <svg v-if="m.annotationText" style="position: relative;top:-62px;left:31px;" t="1772437700487" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6193" width="12" height="12"><path d="M751.228537 117.332567c-1.023063 7.672974-1.470653 15.601715-1.278829 23.466514l1.278829 41.434062-32.418317 25.768406L473.466862 402.639333l-34.656268 27.494825-42.137418-13.747412a332.495559 332.495559 0 0 0-270.280524 28.965478l193.742604 194.637785 49.107037 49.362802 14.51471 14.642593 193.99837 194.829609a331.21673 331.21673 0 0 0 29.732776-271.559353l-13.747413-42.137418 27.494825-34.656268 194.509902-245.535182 25.768406-32.354375 41.434062 1.278829 4.220136 0.127883c6.522028 0 13.044057-0.44759 19.438202-1.406712l-155.377732-155.24985zM734.539817 0c9.719101 0 19.566085 3.644663 27.111177 11.189754l251.034146 250.650499a38.236989 38.236989 0 0 1-5.946555 59.081903 219.255244 219.255244 0 0 1-119.570518 35.359623c-2.301892 0-4.539843 0-6.841736-0.127882L685.752488 601.689078a413.253615 413.253615 0 0 1-71.742311 388.764038 39.451877 39.451877 0 0 1-58.378547 2.941307l-235.752139-236.775202L64.497325 1012.193211a37.277867 37.277867 0 1 1-52.623816-52.7517l255.510048-255.57399L31.631418 467.092319a39.451877 39.451877 0 0 1 3.197072-58.378548 411.399313 411.399313 0 0 1 258.771063-91.244454c43.480188 0 86.832494 6.905677 128.586263 20.461265l245.407299-194.573843A218.871596 218.871596 0 0 1 702.56909 17.264192a37.981223 37.981223 0 0 1 31.970727-17.264192z" fill="#f56c6c" p-id="6194"></path></svg>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item v-for="(n, j) in classType" :key="'h' + j" :command="n.dictValue">{{ n.dictLabel
                      }}</el-dropdown-item>
@@ -203,6 +197,13 @@
      style="margin-top: 10px; text-align: right; margin-right: 30px">
    </el-pagination>
    <ul v-show="showMenu"
        class="contextmenu"
        :style="{left:menuX+'px',top:menuY+'px'}"
        @click.stop>
      <li @click="editAnnotation()">编辑批注</li>
      <li class="divider"></li>
    </ul>
    <el-dialog title="时间配置" :visible.sync="configTimeVisible" width="620px">
      <div v-loading="configTimeVisibleLoading" style="min-height: 200px">
        <div v-for="(item, index) in timeQuery">
@@ -319,6 +320,7 @@
  obtainItemParameterList,
  update,
  selectUserCondition,
  editAnnotationText
} from "@/api/performance/class";
export default {
  name: 'Class',
@@ -395,7 +397,7 @@
      },
      list: [],
      currentPage: 1, // 当前页
      pageSize: 6, // 一页10条
      pageSize: 20, // 一页10条
      total: 0,
      pageLoading: false, // 组件loading的展示,默认为true
      finishLoding: false, // 加载完成,显示已经没有更多了
@@ -406,31 +408,17 @@
      configTimeVisibleLoading: false, // 时间配置弹框loading
      timeTypeList: [],
      timeQuery: [],
      showMenu: false,
      menuX: 0,
      menuY: 0,
      selectedTarget: null,
    };
  },
  watch: {
    // 'query.year'(val){
    //   this.monthList = []
    //   if(val.getFullYear()==new Date().getFullYear()){
    //     for(let i=new Date().getMonth()+1;i>0;i--){
    //       this.monthList.push(i)
    //     }
    //   }else{
    //     for (let i=12;i>0;i--) {
    //       this.monthList.push(i)
    //     }
    //   }
    //   this.monthList.reverse()
    // },
    // 'query.month'(val){
    //   if(!val){
    //     this.currentPage = 1;
    //     this.yearList = []
    //     this.initYear()
    //   }
    // }
  },
  mounted() {
    document.addEventListener('click', this.handleClickOutside)
    this.selectEnumByCategory();
    this.obtainItemParameterList();
    this.getUsers();
@@ -444,9 +432,65 @@
      this.monthList.push(i);
    }
    this.monthList.reverse();
    // this.getPower();
  },
  destroyed() {
    document.removeEventListener('click', this.handleClickOutside)
  },
  methods: {
    handleContextMenu(target,e) {
      // 阻止浏览器默认右键菜单
      e.preventDefault()
      const menuMinWidth = 105
      const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
      const offsetWidth = this.$el.offsetWidth // container width
      const maxLeft = offsetWidth - menuMinWidth // left boundary
      const left = e.clientX - offsetLeft + 15 // 15: margin right
      if (left > maxLeft) {
        this.menuX = maxLeft
      } else {
        this.menuX = left
      }
      this.menuY = e.clientY - 60
      // 显示菜单
      this.selectedTarget = target
      this.showMenu = true
    },
    editAnnotation() {
      // 点击菜单后关闭菜单
      this.showMenu = false
      if(this.selectedTarget && !this.selectedTarget.shift){
        this.$message.warning('请先选择班次')
        return
      }
      this.$prompt('', '编辑批注', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputType:'textarea',
        inputPlaceholder:'填写批注内容',
        inputPattern: /^.{0,100}$/,
        inputErrorMessage: '最大输入100个字符'
      }).then(({ value }) => {
        editAnnotationText({
          id:this.selectedTarget.id,
          annotationText:value
        }).then(res=>{
          this.refreshTable()
          this.$message.success("提交成功")
        })
      }).catch(() => { });
    },
    handleClickOutside() {
      this.showMenu = false
    },
    getDictTypeByShift(e) {
      let obj = this.classType.find((m) => m.dictValue == e);
      if (obj) {
        return obj.listClass;
      }
      return "";
    },
    refresh() {
      this.list = [];
      this.yearList = [];
@@ -530,7 +574,6 @@
        laboratory: this.query.laboratory,
      }).then((res) => {
        this.pageLoading = false;
        if (res.code == 201) return;
        this.total = res.data.page.total;
        this.list = res.data.page.records.map((item) => {
          for (let key in item.monthlyAttendance) {
@@ -541,6 +584,7 @@
          }
          return item;
        });
        console.log(this.list)
        let headerList = res.data.headerList;
        this.weeks = [];
        headerList.forEach((item) => {
@@ -551,7 +595,9 @@
          };
          this.weeks.push(obj);
        });
      });
      }).catch(() => {
        this.pageLoading = false;
      })
    },
    initYear() {
      this.pageLoading = true;
@@ -564,7 +610,6 @@
        laboratory: this.query.laboratory,
      }).then((res) => {
        this.pageLoading = false;
        if (res.code == 201) return;
        this.total = res.data.total;
        this.yearList = res.data.records.map((item) => {
          for (let key in item.year) {
@@ -624,7 +669,6 @@
      })
        .then((res) => {
          this.loading = false;
          if (res.code == 201) return;
          this.$message.success("操作成功");
          this.schedulingVisible = false;
          this.schedulingQuery = {
@@ -649,7 +693,6 @@
      this.configTimeVisibleLoading = true;
      list()
        .then((res) => {
          if (res.code == 201) return;
          if (res.data.length > 0) {
            res.data.forEach((item) => {
              item.isEdit = false;
@@ -701,14 +744,12 @@
        // 编辑
        newObj.id = item.id;
        shiftUpdate(newObj).then((res) => {
          if (res.code == 201) return;
          this.$message.success("操作成功");
          this.getTimeList();
        });
      } else {
        // 新增
        shiftAdd(newObj).then((res) => {
          if (res.code == 201) return;
          this.$message.success("操作成功");
          this.getTimeList();
        });
@@ -719,7 +760,6 @@
        shiftRemove({
          id: item.id,
        }).then((res) => {
          if (res.code == 201) return;
          this.$message.success("操作成功");
          this.getTimeList();
        });
@@ -801,17 +841,13 @@
          id: m.id,
          shift: e,
        }).then((res) => {
          if (res.code == 201) return;
          this.$message.success("操作成功");
          m.shift = e;
        });
      }
    },
    getUsers() {
      selectUserCondition().then((res) => {
        if (res.code === 201) {
          return;
        }
      selectUserCondition({ type: 1 }).then((res) => {
        let arr = res.data;
        this.personList = arr;
      });
@@ -833,17 +869,9 @@
};
</script>
<style scoped>
<style scoped lang="scss">
.class-page {
  padding: 10px;
}
.form_title {
  height: 36px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  font-weight: 800;
}
.search {
@@ -990,83 +1018,10 @@
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-around;
  background: #edeff2;
  justify-content: center;
  border-radius: 8px 8px 8px 8px;
  color: #999;
  font-size: 14px;
}
.work-box.type0 {
  background: rgba(58, 123, 250, 0.15);
  color: #3a7bfa !important;
}
.work-box.type0 span {
  color: #3a7bfa !important;
}
.work-box.type1 {
  background: #e3dcfe;
  color: #635998 !important;
}
.work-box.type1 span {
  color: #635998 !important;
}
.work-box.type2 {
  background: #fae2ca;
  color: #bc8d5e !important;
}
.work-box.type2 span {
  color: #bc8d5e !important;
}
.work-box.type3 {
  background: #e1f3d8;
  color: #67c23a !important;
}
.work-box.type3 span {
  color: #67c23a !important;
}
.work-box.type4 {
  background: #fde2e2;
  color: #f56c6c !important;
}
.work-box.type4 span {
  color: #f56c6c !important;
}
.work-box.type5 {
  background: #ff46c145;
  color: #ff46c0 !important;
}
.work-box.type5 span {
  color: #ff46c0 !important;
}
.work-box.type6 {
  background: #00036418;
  color: #000464 !important;
}
.work-box.type6 span {
  color: #000464 !important;
}
.work-box-left {
  display: flex;
  justify-content: center;
  flex-direction: column;
  line-height: 24px;
}
.content-user {
  width: 100%;
  height: 70px;
@@ -1128,4 +1083,27 @@
  flex-direction: column;
  justify-content: center;
}
/* 自定义右键菜单样式 */
.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
  li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
    &:hover {
      background: #eee;
    }
  }
}
</style>