zhangjie 1 жил өмнө
parent
commit
b24c325b11

+ 3 - 3
src/modules/mark/components/ModifyMarkSetting.vue

@@ -44,9 +44,9 @@
           >
           </el-date-picker>
         </el-form-item>
-        <el-form-item label="小助手原卷:">
+        <!-- <el-form-item label="小助手原卷:">
           <el-checkbox v-model="modalForm.sheetView"></el-checkbox>
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label="评卷是否显示客观分:">
           <el-checkbox v-model="modalForm.showObjectScore"></el-checkbox>
         </el-form-item>
@@ -124,7 +124,7 @@ const initModalForm = {
   markMode: "",
   markStartTime: "",
   markEndTime: "",
-  sheetView: "",
+  // sheetView: "",
   showObjectScore: "",
   autoScroll: "",
   passScore: 60,

+ 9 - 8
src/modules/mark/components/markDetail/MarkDetailMarker.vue

@@ -156,12 +156,12 @@
       :ids="curIds"
       @modified="getList"
     ></modify-marker-task-count>
-    <!-- SelectUserDialog -->
-    <select-user-dialog
-      ref="SelectUserDialog"
-      :userLimitCount="0"
+    <!-- ModifyMarkerBind -->
+    <modify-marker-bind
+      ref="ModifyMarkerBind"
+      :courseCode="baseInfo.courseCode"
       @modified="markerSelected"
-    ></select-user-dialog>
+    ></modify-marker-bind>
   </div>
 </template>
 
@@ -175,7 +175,7 @@ import {
   markMarkerBind,
 } from "../../api";
 import ModifyMarkerTaskCount from "./ModifyMarkerTaskCount.vue";
-import SelectUserDialog from "../../../base/components/SelectUserDialog.vue";
+import ModifyMarkerBind from "./ModifyMarkerBind.vue";
 
 export default {
   name: "mark-detail-marker",
@@ -187,7 +187,7 @@ export default {
       },
     },
   },
-  components: { ModifyMarkerTaskCount, SelectUserDialog },
+  components: { ModifyMarkerTaskCount, ModifyMarkerBind },
   data() {
     return {
       filter: {
@@ -205,6 +205,7 @@ export default {
       questions: [],
       multipleSelection: [],
       downloading: false,
+      userParams: {},
     };
   },
   mounted() {
@@ -256,7 +257,7 @@ export default {
         paperNumber: this.baseInfo.paperNumber,
         groupNumber: this.filter.groupNumber,
       };
-      this.$refs.SelectUserDialog.open();
+      this.$refs.ModifyMarkerBind.open();
     },
     async markerSelected(users) {
       if (!users.length) return;

+ 315 - 49
src/modules/mark/components/markDetail/ModifyMarkerBind.vue

@@ -1,99 +1,365 @@
 <template>
   <el-dialog
+    class="modify-marker-bind modify-marker-question"
     :visible.sync="modalIsShow"
+    append-to-body
+    top="10px"
+    width="900px"
     title="绑定评卷员"
-    top="10vh"
-    width="448px"
     :close-on-click-modal="false"
     :close-on-press-escape="false"
-    append-to-body
+    :show-close="false"
     @opened="visibleChange"
   >
-    <el-form ref="modalFormComp" :model="modalForm" :rules="rules">
-      <el-form-item prop="userIds" label="评卷员:">
-        <el-select
-          v-model="modalForm.userIds"
-          placeholder="评卷员"
-          multiple
-          clearable
-        >
-          <el-option v-for="user in userList" :key="user.id" :value="user.id">{{
-            user.name
-          }}</el-option>
-        </el-select>
-      </el-form-item>
-    </el-form>
-    <div slot="footer">
-      <el-button type="primary" :loading="isSubmit" @click="submit"
-        >确认</el-button
-      >
+    <el-row type="flex" :gutter="10">
+      <el-col :span="12">
+        <div class="marker-box">
+          <div class="user-title">评卷员</div>
+          <div class="user-search">
+            <el-input
+              v-model="filterLabel"
+              placeholder="请输入评卷员名称"
+              clearable
+              size="mini"
+              prefix-icon="el-icon-search"
+              @input="labelChange"
+            ></el-input>
+          </div>
+          <div class="user-types">
+            <div
+              :class="['user-type', { 'is-active': userType === 'org' }]"
+              @click="switchUserType('org')"
+            >
+              组织架构
+            </div>
+            <div
+              :class="['user-type', { 'is-active': userType === 'course' }]"
+              @click="switchUserType('course')"
+            >
+              课程
+            </div>
+          </div>
+          <div class="user-tree">
+            <el-tree
+              ref="UserTree"
+              :data="userTree"
+              node-key="id"
+              :default-checked-keys="selectedUserIds"
+              :props="defaultProps"
+              default-expand-all
+            >
+              <span class="custom-tree-node" slot-scope="{ node, data }">
+                <el-checkbox
+                  v-if="data.isUser"
+                  v-model="node.checked"
+                  @change="(val) => userChange(val, data)"
+                >
+                  {{ node.label }}
+                </el-checkbox>
+                <span v-else>{{ node.label }}</span>
+                <div title="全选" @click.stop>
+                  <el-checkbox
+                    v-if="!data.isUser && data.children.length"
+                    v-model="data.selected"
+                    @change="(checked) => selectNodeAll(checked, data)"
+                  ></el-checkbox>
+                </div>
+              </span>
+            </el-tree>
+          </div>
+        </div>
+      </el-col>
+      <el-col :span="12">
+        <div class="marker-box marker-box-uq">
+          <el-form
+            ref="modalFormRef"
+            :rules="rules"
+            :model="{}"
+            label-width="100px"
+            label-position="top"
+          >
+            <el-form-item prop="users" label="已选评卷员:">
+              <el-tag
+                v-for="user in selectedUsers"
+                :key="user.id"
+                closable
+                :disable-transitions="false"
+                @close="toDeleteUser(user)"
+              >
+                {{ user.name }}({{ user.orgName }})
+              </el-tag>
+            </el-form-item>
+          </el-form>
+        </div>
+      </el-col>
+    </el-row>
+
+    <div class="marker-footer">
+      <el-button type="primary" @click="confirm">确认</el-button>
       <el-button @click="cancel">取消</el-button>
     </div>
+
+    <div slot="footer"></div>
   </el-dialog>
 </template>
 
 <script>
-import { markMarkerBind } from "../../api";
+import { deepCopy } from "@/plugins/utils";
+import { organizationList } from "../../../base/api";
 
 export default {
-  name: "modify-marker-bind",
+  name: "modify-mark-group",
   props: {
-    data: {
+    instance: {
       type: Object,
       default() {
         return {};
       },
     },
+    courseCode: {
+      type: String,
+      default: "",
+    },
   },
   data() {
+    const usersValidator = (rule, value, callback) => {
+      if (!this.selectedUserIds.length) {
+        callback(new Error("请选择评卷员"));
+      } else {
+        callback();
+      }
+    };
+
     return {
-      isSubmit: false,
       modalIsShow: false,
-      modalForm: { userIds: [] },
+      filterLabel: "",
+      userType: "course",
+      courseUsers: [],
+      orgUsers: [],
+      userTree: [],
       userList: [],
+      selectedUsers: [],
+      selectedUserIds: [],
+      defaultProps: {
+        children: "children",
+        label: "label",
+      },
       rules: {
-        userIds: [
+        users: [
           {
             required: true,
-            validator: (rule, value, callback) => {
-              if (!value || !value.length) {
-                return callback(new Error(`请选择评卷员`));
-              }
-              callback();
-            },
+            validator: usersValidator,
             trigger: "change",
           },
         ],
       },
     };
   },
+  mounted() {
+    this.getOrgData();
+  },
   methods: {
     visibleChange() {
-      this.modalForm = { userIds: [] };
-      this.$nextTick(() => {
-        this.$refs.modalFormComp.clearValidate();
-      });
+      this.filterLabel = "";
+      this.userType = "course";
+      this.selectedUsers = [];
+      this.selectedUserIds = [];
+      this.labelChange();
     },
     cancel() {
       this.modalIsShow = false;
+      this.$emit("cancel");
     },
     open() {
       this.modalIsShow = true;
     },
-    async submit() {
-      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
-      if (!valid) return;
+    // user
+    switchUserType(type) {
+      this.filterLabel = "";
+      this.userType = type;
 
-      if (this.isSubmit) return;
-      this.isSubmit = true;
+      this.userTree =
+        type === "org" ? deepCopy(this.orgUsers) : deepCopy(this.courseUsers);
+      this.$refs.UserTree.setCheckedKeys(this.selectedUserIds);
+    },
+    async getOrgData() {
+      let params = {
+        specialPrivilege: "MARKER",
+      };
+      if (this.courseCode) params.courseCode = this.courseCode;
+      const data = await organizationList(params);
+      this.parseUserData(data);
+      this.getUserList();
+    },
+    parseUserData(data) {
+      const parseUser = (list) => {
+        return list.map((item) => {
+          // org
+          let nitem = {
+            id: item.id,
+            label: item.name,
+            isUser: false,
+            selected: false,
+            children: [],
+          };
+
+          if (item["children"] && item["children"].length) {
+            nitem.children = [...nitem.children, ...parseUser(item.children)];
+          }
+          // user
+          if (item["sysUserList"] && item["sysUserList"].length) {
+            let sysUserList = item.sysUserList;
+            const users = sysUserList.map((user) => {
+              const nuser = {
+                id: user.id,
+                userId: user.id,
+                label: user.realName,
+                name: user.realName,
+                orgName: item.name,
+                loginName: user.loginName,
+                selected: false,
+                isUser: true,
+              };
+              return nuser;
+            });
+            nitem.children = [...nitem.children, ...users];
+          }
 
-      const datas = { ...this.modalForm, ...this.data };
-      const res = await markMarkerBind(datas).catch(() => {});
-      this.isSubmit = false;
-      if (!res) return;
-      this.$message.success("绑定成功!");
-      this.cancel();
-      this.$emit("modified");
+          if (item["courseUserList"] && item["courseUserList"].length) {
+            nitem.courseUserList = item.courseUserList.map((user) => {
+              return {
+                id: user.id,
+                userId: user.id,
+                label: user.realName,
+                name: user.realName,
+                orgName: user.orgName,
+                loginName: user.loginName,
+                selected: false,
+                isUser: true,
+              };
+            });
+          }
+          return nitem;
+        });
+      };
+      this.orgUsers = parseUser(data);
+      this.userTree = deepCopy(this.orgUsers);
+      if (this.courseCode && this.orgUsers[0].courseUserList) {
+        this.courseUsers = deepCopy(this.orgUsers[0].courseUserList);
+      }
+      this.getUserList();
+    },
+    getUserList() {
+      let userList = [];
+      const fetchUser = (users) => {
+        users.forEach((item) => {
+          if (item["children"] && item["children"].length) {
+            fetchUser(item.children);
+          } else {
+            if (item.isUser) {
+              let nitem = { ...item };
+              nitem.label = `${nitem.name}(${nitem.orgName})`;
+              userList.push(nitem);
+            }
+          }
+        });
+      };
+      fetchUser(this.orgUsers);
+
+      this.userList = userList;
+    },
+    labelChange() {
+      if (!this.filterLabel) {
+        this.switchUserType(this.userType);
+      } else {
+        const escapeRegexpString = (value = "") =>
+          String(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
+        const reg = new RegExp(escapeRegexpString(this.filterLabel), "i");
+
+        if (this.userType === "org") {
+          this.userTree = this.userList.filter((item) => reg.test(item.name));
+        } else {
+          this.userTree = this.courseUsers.filter((item) =>
+            reg.test(item.name)
+          );
+        }
+      }
+      this.$refs.UserTree.setCheckedKeys(this.selectedUserIds);
+    },
+    selectNodeAll(checked, data) {
+      let users = [];
+      const getUserIds = (list) => {
+        list.forEach((item) => {
+          item.selected = checked;
+          if (item.children && item.children.length) {
+            getUserIds(item.children);
+          } else {
+            if (item.isUser) users.push(item);
+          }
+        });
+      };
+      getUserIds(data.children);
+
+      const userIds = users.map((u) => u.id);
+      const selectedUserIds = this.selectedUsers.map((item) => item.id);
+
+      let deleteUserIds = [];
+      userIds.forEach((userId, uindex) => {
+        const userPos = selectedUserIds.indexOf(userId);
+        const includeUser = userPos !== -1;
+        if (checked) {
+          if (!includeUser) this.selectedUsers.push(users[uindex]);
+        } else {
+          if (includeUser) {
+            deleteUserIds.push(userId);
+          }
+        }
+      });
+      this.selectedUsers = this.selectedUsers.filter(
+        (u) => !deleteUserIds.includes(u.id)
+      );
+      this.selectedUserIds = this.selectedUsers.map((item) => item.id);
+      this.$refs.UserTree.setCheckedKeys(this.selectedUserIds);
+      this.$refs.modalFormRef.validateField("users");
+    },
+    updateSelectedUsersFromUserIds() {
+      this.selectedUsers = this.userList.filter((user) =>
+        this.selectedUserIds.includes(user.id)
+      );
+    },
+    userChange(checked, user) {
+      if (checked) {
+        this.selectedUsers.push(user);
+      } else {
+        this.selectedUsers = this.selectedUsers.filter(
+          (item) => item.id !== user.id
+        );
+      }
+      this.selectedUserIds = this.selectedUsers.map((item) => item.id);
+      this.$refs.modalFormRef.validateField("users");
+    },
+    toDeleteUser(user) {
+      const pos = this.selectedUsers.findIndex((item) => item.id === user.id);
+      this.selectedUsers.splice(pos, 1);
+      this.selectedUserIds = this.selectedUsers.map((item) => item.id);
+      this.$refs.UserTree.setCheckedKeys(this.selectedUserIds);
+      this.$refs.modalFormRef.validateField("users");
+    },
+    // confirm
+    async confirm() {
+      const valid = await this.$refs.modalFormRef.validate().catch(() => {});
+      if (!valid) return;
+
+      this.$emit(
+        "modified",
+        this.selectedUsers.map((item) => {
+          return {
+            id: item.id,
+            name: item.name,
+          };
+        })
+      );
+      this.modalIsShow = false;
     },
   },
 };

+ 1 - 0
src/modules/mark/components/markParam/MarkParamGroup.vue

@@ -272,6 +272,7 @@ export default {
         markers: [],
         pictureConfigs: [],
         questions: [],
+        isNew: true,
       };
       this.$refs.ModifyMarkGroup.open();
     },

+ 19 - 11
src/modules/mark/components/markParam/ModifyMarkGroup.vue

@@ -211,6 +211,7 @@
 import { deepCopy } from "../../../../plugins/utils";
 import { organizationList } from "../../../base/api";
 import { SCORE_POLICY_TYPE } from "@/constants/enumerate";
+import { omit } from "lodash";
 
 export default {
   name: "modify-mark-group",
@@ -319,6 +320,11 @@ export default {
       },
     };
   },
+  computed: {
+    isEdit() {
+      return !this.instance.isNew;
+    },
+  },
   mounted() {
     this.getOrgData();
   },
@@ -630,16 +636,18 @@ export default {
       const valid2 = await this.$refs.modalFormRef.validate().catch(() => {});
       if (!valid1 || !valid2) return;
 
-      const changed = this.checkDataChange();
-      if (changed) {
-        const confirm = await this.$confirm(
-          `保存后分组关联所有评卷任务都将删除,并生成新的分组任务!`,
-          "提示",
-          {
-            type: "warning",
-          }
-        ).catch(() => {});
-        if (confirm !== "confirm") return;
+      if (this.isEdit) {
+        const changed = this.checkDataChange();
+        if (changed) {
+          const confirm = await this.$confirm(
+            `保存后分组关联所有评卷任务都将删除,并生成新的分组任务!`,
+            "提示",
+            {
+              type: "warning",
+            }
+          ).catch(() => {});
+          if (confirm !== "confirm") return;
+        }
       }
 
       let datas = Object.assign({}, this.instance, this.rowInfo);
@@ -665,7 +673,7 @@ export default {
       ) {
         datas.pictureConfigs = [];
       }
-      this.$emit("modified", datas);
+      this.$emit("modified", omit(datas, ["isNew"]));
       this.modalIsShow = false;
     },
   },