Browse Source

自訂名單:整理模塊, 刪除名單, 複製範例提示框功能

Louise lin 2 năm trước cách đây
mục cha
commit
6e826eb95f

+ 2 - 206
HiTeachCC/ClientApp/src/assets/css/Board.less

@@ -245,14 +245,14 @@
       padding: 10px;
       text-align: left;
       background-color: #fcfcfc;
-      max-height: 130px;
+      height: 150px;
       overflow: auto;
       .list-stu{
         font-size: 14px;
       }
       .list-info{
         text-align: center;
-        margin-top: 10%;
+        margin-top: 20%;
         color: gray;
         font-size: 14px;
       }
@@ -390,7 +390,6 @@
     }
   }
 }
-
 .closebtn {
   cursor: pointer;
   position: absolute;
@@ -650,209 +649,6 @@ svg {
     }
   }
 }
-.editmemberlist-view{
-  position: fixed;
-  display: block;
-  width: 100%;
-  background-color: rgba(0, 0, 0, 0.8);
-  // border-radius: 5px;
-  color: black;
-  height: 100%;
-  z-index: 1016;
-
-  .addmember-card{
-    text-align: left !important;
-  }
-  .closebtn {
-    cursor: pointer;
-    position:absolute;
-    top: -12px;
-    right:-10px;
-    width: 30px;
-    height: 30px;
-    line-height: 27px;
-    background-color: #d8d8d8;
-    text-align: center;
-    border-radius: 50%;
-    z-index: 1017;
-  }
-  
-  .closebtn img {
-    width: 80%;
-  }
-  .editmemberlist-card {
-    top: 8%;
-    max-width: 500px;
-    transition: 0.5s;
-    position: relative;
-    left: 50%;
-    transform: translateX(-50%);
-    background-color: #ededed;
-    font-weight: bolder;
-    padding: 20px 20px 10px 20px;
-    border-radius: 5px;
-    box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
-    z-index: 1002;
-    text-align: center;
-    .memberlist-wrap {
-      display: flex;
-      background-color: #fcfcfc;
-      border-width: 2px;
-      border-radius: 4px;
-      border: 1px solid #ccc !important;
-      margin:10px 5px;
-      
-      .listitems {
-        flex:1;
-        .listitem-light{
-          color: blue;
-          border: 1px solid blue !important;
-          border-bottom: 1px solid blue !important;
-        }
-        .listitem {
-          width: 100%;
-          cursor: pointer;
-          display: inline-block !important;
-          background-color: #fcfcfc;
-          border-width: 2px;
-          border: 1px solid transparent ;
-          border-bottom: 1px solid #ccc ;
-          padding: 5px;
-          font-size: 16px;
-          &:hover {
-            // background-color: darken(#fcfcfc, 10%);
-            color: blue;
-            border: 1px solid blue !important;
-          }
-        }
-      }
-      .listDetail {
-        background-color: #fcfcfc;
-        border-width: 2px;
-        border-radius: 4px;
-        border-left: 1px solid #ccc !important;
-        flex: 1;
-        padding: 10px;
-        text-align: left;
-        background-color: #fcfcfc;
-        overflow: auto;
-        .list-stu{
-          font-size: 14px;
-        }
-        .list-info{
-          text-align: center;
-          margin-top: 10%;
-          color: gray;
-          font-size: 14px;
-        }
-      }
-     
-    }
-    .editmemberlist-title {
-      font-size: 20px;
-      color: #3d3d3d;
-      text-align: left;
-      margin-left:5px;
-    }
-    .editmemberlist-rightbtns{
-      position: absolute;
-      right:15px;
-      top:10px;
-      *{
-        display: inline-block;
-        &:hover{
-          fill: blue !important;
-          stroke:blue !important;
-        }
-      }
-      .delete-btn{
-        padding:10px;
-        font-size: 20px;
-        fill:black;
-        cursor: pointer;
-      }
-      .add-btn{
-        padding:10px;
-        font-size: 20px;
-        stroke:black;
-        cursor: pointer;
-      }
-    }
-    .add-title{
-      font-size: 16px;
-      color: #3d3d3d;
-      text-align: left;
-      margin-left:5px;
-      padding: 5px;
-      border-radius: 4px;
-      border: 1px solid #ccc;
-      &:focus{
-        border: 2px solid blue;
-      }
-    }
-    .addmember-area{
-      background-color: #fff;
-      margin:10px 5px;
-      display: flex;
-      .left-part{
-        flex: 1;
-      }
-      .right-part{
-        flex: 1;
-        width: 100%;
-      }
-      textarea{
-        font-size: 14px;
-        border: 1px solid #ccc;
-        padding: 5px;
-        &:focus{
-          border: 2px solid blue;
-        }
-      }
-    }
-    .editmemberlist-empty{
-      background-color: #fff;
-      color: #3d3d3d;
-      border-radius: 5px;
-      padding:20px;
-      margin:10px 5px;
-      cursor: pointer;
-      .add-icon{
-        stroke: #3d3d3d;
-        font-size: 40px;
-        margin: 10px;;
-      }
-    }
-    .editmemberlistbtn-group {
-      display: flex;
-      align-items: center;
-      .editmemberlist-disabledBtn{
-        cursor: not-allowed !important;
-        color: rgba(128, 128, 128, 0.3) !important;
-        background-color: #d8d8d8 !important;
-        &:hover {
-          color: rgba(128, 128, 128, 0.3);
-       
-        }
-      }
-      .editmemberlist-btn {
-        cursor: pointer;
-        flex: 1;
-        white-space: nowrap;
-        padding: 5px 10px;
-        margin: 10px 5px;
-        border-radius: 5px;
-        text-align: center;
-        background-color: #d8d8d8;
-        &:first-child , &:nth-child(2){
-          color: white;
-          background-color: @btn-color;
-        }
-        
-      }
-    }
-  }
-}
 
 
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6 - 0
HiTeachCC/ClientApp/src/assets/icons/svg/question.svg


+ 526 - 0
HiTeachCC/ClientApp/src/components/EditMemberList.vue

@@ -0,0 +1,526 @@
+<template>
+  <div class="editmemberlist-view" v-show="showEditMemberList">
+    <div class="editmemberlist-card" v-show="!showAddMemberList">
+      <div class="closebtn" @click="closeEditMemberList()"><img src="@/statics/iconsvg/interaction/Close.svg" class="q-icon" /></div>
+      <p class="editmemberlist-title">{{ "自訂學生名單" }}</p>
+
+      <!--選單控制按鈕-->
+      <div class="editmemberlist-rightbtns" v-show="$parent.testMemberlist.length > 0">
+        <div class="add-btn" @click="openAddMemberList()"><svg-icon icon-class="new-page" /></div>
+        <div class="delete-btn" @click="deleteMemberList()"><svg-icon icon-class="trash-alt-solid" /></div>
+      </div>
+
+      <div class="editmemberlist-empty" v-show="$parent.testMemberlist.length == 0">
+        <div @click="openAddMemberList()"><svg-icon icon-class="new-page" class="add-icon" /><br />創建名單</div>
+      </div>
+      <div class="memberlist-wrap" v-if="$parent.testMemberlist.length > 0">
+        <div class="listitems">
+          <div class="listitem" v-for="(list, index) in $parent.testMemberlist" :key="list.listName + index" @click="setCurrentMemberList(list)" :class="{ 'listitem-light': $parent.currentMemberList.listID == list.listID }">
+            {{ list.listName }}
+          </div>
+        </div>
+        <div class="listDetail" :style="{ 'min-height': tableHeight + 'px' }">
+          <Table :fixed-header="true" v-show="Object.keys($parent.currentMemberList).length >= 0" :height="tableHeight" :no-data-text="`<p>點選左側列表檢視名單</p>`" :columns="columns1" :data="$parent.currentMemberList.list"></Table>
+        </div>
+      </div>
+      <!-- <div class="editmemberlistbtn-group">
+          <div class="editmemberlist-btn"  v-show="testMemberlist.length!==0">{{ '儲存' }}</div>
+          <div class="editmemberlist-btn" @click="closeEditMemberList()">{{ $t("board['取消']") }}</div>
+        </div> -->
+    </div>
+    <div class="editmemberlist-card addmember-card" v-show="showAddMemberList">
+      <div v-show="showEditHint">
+        <div class="edit-tooltip-triangle"></div>
+        <div class="edit-tooltip">
+          <div class="close-btn" @click="showEditHint=false"><svg-icon icon-class="Close" /></div>
+          <p v-html="hintInfo"></p>
+          <div class="tooltip-btn" @click="useSampleList()">複製範例</div>
+        </div>
+      </div>
+
+      <input type="text" class="add-title" v-model="currentEditMemberListName" placeholder="新建的學生名單..." />
+      <div class="example-btn" @click="showEditHint = !showEditHint"><svg-icon icon-class="question" /></div>
+      <div class="addmember-area">
+        <textarea class="left-part" v-model="addmemberlisttext" name="addmember" id="" cols="30" rows="10" placeholder="輸入名單資料..."></textarea>
+        <div class="right-part">
+          <Table :fixed-header="true" :height="tableHeight" :no-data-text="`<p>暫無資料</p>`" :columns="columns1" :data="tempAddMemberList" :row-class-name="hintBugRow"></Table>
+        </div>
+      </div>
+      <div v-show="addMemberListErrMsg.length > 0" class="errmsg">
+        <div v-for="text in addMemberListErrMsg" :key="text">
+          {{ text }}
+        </div>
+      </div>
+      <div v-show="showAddMemberAutoSeatIDMsg" class="hintmsg">
+        {{ "無法辨識座號規則,系統採自動編號" }}
+      </div>
+      <div class="editmemberlistbtn-group">
+        <div class="editmemberlist-btn" @click="checkAddMemberList()">{{ "預覽" }}</div>
+        <div class="editmemberlist-btn" @click="saveTestMemberList()" :class="{ 'editmemberlist-disabledBtn': addMemberListErrMsg.length > 0 || currentEditMemberListName == '' || addmemberlisttext == '' || tempAddMemberList.length == 0 }">{{ "儲存預覽表格" }}</div>
+        <div class="editmemberlist-btn" @click="showAddMemberList = false">{{ $t("board['取消']") }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import SvgIcon from "../views/SvgIcon.vue";
+export default {
+  components: { SvgIcon },
+  name: "EditMemberList",
+  data() {
+    return {
+      hintInfo: `輸入名單小技巧<br><br>名單的格式為:
+        姓名, 座號 <br>(座號可省略,如有填寫則須每列都填寫)<br><br>
+        限制<br>
+        姓名:字數長度50以內<br>
+        座號:不能重複數字,應小於1000
+         <br><br>    
+        範例 <br>
+        王大明, 1,<br>
+        張小凡, 2,<br>
+        陳士軒, 3,<br>`,
+      showEditMemberList: false,
+      showAddMemberList: false,
+      currentEditMemberListName: "",
+      addmemberlisttext: "",
+      columns1: [
+        {
+          title: "姓名",
+          key: "memberName",
+          sortable: true,
+        },
+        {
+          title: "座號",
+          key: "seatID",
+          sortable: true,
+        },
+      ],
+      tempAddMemberList: [],
+      addMemberListErrMsg: [],
+      showAddMemberAutoSeatIDMsg: false,
+      addMemberListErrRow: [], // 存放預覽有問題的行數
+      editMemberListMode: "Init", //Init or Menu
+      showEditHint: false,
+    };
+  },
+  computed: {
+    tableHeight() {
+      return window.innerHeight * 0.5 < 250 ? 250 : window.innerHeight * 0.5;
+    },
+  },
+  methods: {
+    setCurrentMemberList(list) {
+      this.$parent.currentMemberList = list;
+      this.memberList = Object.keys(this.$parent.currentMemberList).length == 0 ? [] : this.$parent.currentMemberList.list;
+      this.verifyMode = Object.keys(this.$parent.currentMemberList).length == 0 ? "Dynamic" : "Fixed";
+      console.log(this.memberList);
+    },
+    openEditMemberListAtInit() {
+      this.editMemberListMode = "Init";
+      this.showEditMemberList = true;
+    },
+    openEditMemberList() {
+      console.log("開名單");
+      this.editMemberListMode = "Menu";
+      this.showEditMemberList = true;
+      this.Hishow = false;
+    },
+    openAddMemberList() {
+      this.showAddMemberList = true;
+      this.tempAddMemberList = [];
+      this.addMemberListErrRow = [];
+      this.addMemberListErrMsg = [];
+      this.currentEditMemberListName = "自訂名單" + (this.$parent.testMemberlist.length + 1);
+      this.currentEditMemberList = {};
+      this.addmemberlisttext = "";
+      this.showAddMemberAutoSeatIDMsg = false;
+    },
+    closeEditMemberList() {
+      this.showEditMemberList = false;
+      this.showAddMemberList = false;
+    },
+    hasDuplicates(arr) {
+      return arr.some((x) => arr.indexOf(x) !== arr.lastIndexOf(x));
+    },
+    setAddMemberErrMsg(Msg) {
+      if (this.addMemberListErrMsg.indexOf(Msg) == -1) {
+        this.addMemberListErrMsg.push(Msg);
+      }
+    },
+    hasNonNumeric(str) {
+      return /[^0-9]/.test(str); //匹配除了 0 到 9 的数字以外的任何字符
+    },
+    checkAddMemberList() {
+      this.tempAddMemberList = [];
+      this.addMemberListErrRow = [];
+      this.addMemberListErrMsg = [];
+      let data = this.addmemberlisttext
+        .replaceAll("\n", ",")
+        .split(",")
+        .filter((item) => item != "");
+      data = data.map((item) => item.trim());
+      let isAutoSeatID = false;
+      this.showAddMemberAutoSeatIDMsg = false;
+      //檢測座號是否皆為數字,部分有部分沒有就直接自動編號
+      if (data.length % 2 == 1) {
+        isAutoSeatID = true;
+      } else {
+        data.forEach((item, index) => {
+          const pointIndex = item.indexOf(".");
+          const zeroIndex = item.indexOf("0");
+          if (index % 2 == 1 && (zeroIndex == 0 || pointIndex != -1 || this.hasNonNumeric(item))) {
+            //座號第一位數字非0、不可帶有小數點、須為數字
+            isAutoSeatID = true;
+          }
+        });
+      }
+      // console.log(isAutoSeatID,'isAutoSeatID')
+      if (!isAutoSeatID) {
+        //檢測座號是否重複
+        const seatIDs = data.filter((item, index) => index % 2 == 1);
+        // console.log(seatIDs)
+        if (this.hasDuplicates(seatIDs)) {
+          this.setAddMemberErrMsg("帶有重複座號");
+
+          let firstAppearID = [];
+          seatIDs.forEach((id, index) => {
+            const itemIndex = firstAppearID.findIndex((item) => item.id == id);
+            if (itemIndex == -1) firstAppearID.push({ id: id, count: 1, index: index });
+            else {
+              seatIDs.forEach((subId) => {
+                if (id == subId) {
+                  this.addMemberListErrRow.push(index);
+                }
+              });
+            }
+          });
+          // console.log(firstAppearID)
+        }
+        data.forEach((item, index) => {
+          //檢測座號是否<=999
+          // console.log(index%2)
+          if (index % 2 == 1 && parseInt(item) > 999) {
+            this.setAddMemberErrMsg("座號應設置於1-999");
+            this.addMemberListErrRow.push(parseInt(index / 2));
+          }
+          if (index % 2 == 1 && !isNaN(parseInt(item))) {
+            this.tempAddMemberList.push({
+              seatID: item,
+              memberID: this.tempAddMemberList.length,
+              memberName: data[index - 1],
+            });
+          }
+        });
+      } else {
+        this.showAddMemberAutoSeatIDMsg = true;
+        data.forEach((item, index) => {
+          if (item) {
+            this.tempAddMemberList.push({
+              seatID: index + 1,
+              memberID: this.tempAddMemberList.length,
+              memberName: data[index],
+            });
+          }
+        });
+      }
+    },
+    saveTestMemberList() {
+      if (this.addMemberListErrMsg.length === 0 && this.addmemberlisttext != "" && this.tempAddMemberList.length != 0) {
+        this.$parent.testMemberlist.push({
+          listName: this.currentEditMemberListName,
+          list: this.tempAddMemberList,
+          listID: new Date().getTime(),
+        });
+        this.editMemberListMode == "Init" ? this.closeEditMemberList() : (this.showAddMemberList = false);
+        this.$parent.currentMemberList = this.$parent.testMemberlist[this.$parent.testMemberlist.length - 1];
+      }
+    },
+    useSampleList() {
+      this.addmemberlisttext = `王大明, 1,\n張小凡, 2,\n陳士軒, 3,\n`;
+    },
+    deleteMemberList() {
+      const deleteIndex = this.$parent.testMemberlist.findIndex((list) => list.listID === this.$parent.currentMemberList.listID);
+      this.$parent.testMemberlist.splice(deleteIndex, 1);
+    },
+    hintBugRow(row, index) {
+      // console.log(this.addMemberListErrRow,index)
+      if (this.addMemberListErrRow.indexOf(index) != -1) {
+        return "demo-table-info-row";
+      }
+      return "";
+    },
+  },
+};
+</script>
+
+<style lang="less">
+@import "../assets/css/color.less";
+.ivu-table .demo-table-info-row td {
+  background-color: pink;
+}
+
+.editmemberlist-view {
+  position: relative;
+  position: fixed;
+  display: block;
+  width: 100%;
+  background-color: rgba(0, 0, 0, 0.8);
+  // border-radius: 5px;
+  color: black;
+  height: 100%;
+  z-index: 1016;
+  .close-btn{
+    cursor: pointer;
+    font-size: 16px;
+    color: #3d3d3d;
+    position: absolute;
+    right:10px;
+    top:5px;
+  }
+  .example-btn {
+    position: absolute;
+    right: 20px;
+    top: 15px;
+    cursor: pointer;
+    font-size: 30px;
+    color: #3d3d3d;
+  }
+  .tooltip-btn {
+    display: inline-block;
+    padding: 10px;
+    color: white;
+    background-color: @btn-color;
+    cursor: pointer;
+    white-space: nowrap;
+    padding: 5px 10px;
+    margin: 10px 5px;
+    border-radius: 5px;
+    text-align: center;
+  }
+  .edit-tooltip {
+    position: absolute;
+    display: inline-block;
+    background-color: rgb(254, 255, 183);
+    color: black;
+    width: 65%;
+    top: 65px;
+    right: -14%;
+    text-align: left;
+    padding: 10px;
+    border-radius: 4px;
+    box-shadow: 0 2px 10px rgba(112, 112, 112, 0.5);
+    z-index: 999;
+  }
+  .edit-tooltip-triangle {
+    width: 0;
+    height: 0;
+    border-style: solid;
+    border-width: 0 15px 15px 15px;
+    border-color: transparent transparent rgb(254, 255, 183) transparent;
+    line-height: 0px;
+    position: absolute;
+    top: 50px;
+    right: 5%;
+    z-index: 1000;
+  }
+
+  .addmember-card {
+    text-align: left !important;
+  }
+  .closebtn {
+    cursor: pointer;
+    position: absolute;
+    top: -12px;
+    right: -10px;
+    width: 30px;
+    height: 30px;
+    line-height: 27px;
+    background-color: #d8d8d8;
+    text-align: center;
+    border-radius: 50%;
+    z-index: 1017;
+  }
+
+  .closebtn img {
+    width: 80%;
+  }
+  .editmemberlist-card {
+    top: 8%;
+    max-width: 500px;
+    transition: 0.5s;
+    position: relative;
+    left: 50%;
+    transform: translateX(-50%);
+    background-color: #ededed;
+    font-weight: bolder;
+    padding: 20px 20px 10px 20px;
+    border-radius: 5px;
+    box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
+    z-index: 1002;
+    text-align: center;
+    .errmsg {
+      margin-left: 6px;
+      color: red;
+    }
+    .hintmsg {
+      margin-left: 6px;
+      color: blue;
+    }
+    .memberlist-wrap {
+      display: flex;
+      background-color: #fcfcfc;
+      border-width: 2px;
+      border-radius: 4px;
+
+      margin: 10px 5px;
+      .listitems {
+        flex: 1;
+        border: 1px solid #ccc !important;
+        .listitem-light {
+          color: blue;
+          border: 1px solid blue !important;
+          border-bottom: 1px solid blue !important;
+        }
+        .listitem {
+          width: 100%;
+          cursor: pointer;
+          display: inline-block !important;
+          background-color: #fcfcfc;
+          border-width: 2px;
+          border: 1px solid transparent;
+          border-bottom: 1px solid #ccc;
+          padding: 5px;
+          font-size: 16px;
+          &:hover {
+            // background-color: darken(#fcfcfc, 10%);
+            color: blue;
+            border: 1px solid blue !important;
+          }
+        }
+      }
+      .listDetail {
+        background-color: #fcfcfc;
+        border-width: 2px;
+        border-radius: 4px;
+
+        flex: 1;
+        text-align: left;
+        background-color: #fcfcfc;
+        overflow: auto;
+        .list-stu {
+          font-size: 14px;
+        }
+        .list-info {
+          text-align: center;
+          margin-top: 10%;
+          color: gray;
+          font-size: 14px;
+        }
+      }
+    }
+    .editmemberlist-title {
+      font-size: 20px;
+      color: #3d3d3d;
+      text-align: left;
+      margin-left: 5px;
+    }
+    .editmemberlist-rightbtns {
+      position: absolute;
+      right: 15px;
+      top: 10px;
+      * {
+        display: inline-block;
+        &:hover {
+          fill: blue !important;
+          stroke: blue !important;
+        }
+      }
+      .delete-btn {
+        padding: 10px;
+        font-size: 20px;
+        fill: black;
+        cursor: pointer;
+      }
+      .add-btn {
+        padding: 10px;
+        font-size: 20px;
+        stroke: black;
+        cursor: pointer;
+      }
+    }
+    .add-title {
+      font-size: 16px;
+      color: #3d3d3d;
+      text-align: left;
+      margin-left: 5px;
+      padding: 5px;
+      border-radius: 4px;
+      border: 1px solid #ccc;
+      &:focus {
+        border: 2px solid blue;
+      }
+    }
+    .addmember-area {
+      background-color: #fff;
+      margin: 10px 5px;
+      display: flex;
+      .left-part {
+        flex: 1;
+      }
+      .right-part {
+        flex: 1;
+        width: 100%;
+      }
+      textarea {
+        font-size: 14px;
+        border: 1px solid #ccc;
+        padding: 5px;
+        &:focus {
+          border: 2px solid blue;
+        }
+      }
+    }
+    .editmemberlist-empty {
+      background-color: #fff;
+      color: #3d3d3d;
+      border-radius: 5px;
+      padding: 20px;
+      margin: 10px 5px;
+      cursor: pointer;
+      .add-icon {
+        stroke: #3d3d3d;
+        font-size: 40px;
+        margin: 10px;
+      }
+    }
+    .editmemberlistbtn-group {
+      display: flex;
+      align-items: center;
+      .editmemberlist-disabledBtn {
+        cursor: not-allowed !important;
+        color: rgba(128, 128, 128, 0.3) !important;
+        background-color: #d8d8d8 !important;
+        &:hover {
+          color: rgba(128, 128, 128, 0.3);
+        }
+      }
+      .editmemberlist-btn {
+        cursor: pointer;
+        flex: 1;
+        white-space: nowrap;
+        padding: 5px 10px;
+        margin: 10px 5px;
+        border-radius: 5px;
+        text-align: center;
+        background-color: #d8d8d8;
+        &:first-child,
+        &:nth-child(2) {
+          color: white;
+          background-color: @btn-color;
+        }
+      }
+    }
+  }
+}
+</style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3643 - 3866
HiTeachCC/ClientApp/src/views/Board.vue