|
@@ -0,0 +1,434 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ class="modify-marker-question"
|
|
|
+ :visible.sync="modalIsShow"
|
|
|
+ append-to-body
|
|
|
+ top="20px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ :show-close="false"
|
|
|
+ @opened="visibleChange"
|
|
|
+ >
|
|
|
+ <div slot="title"></div>
|
|
|
+
|
|
|
+ <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-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="userChange"
|
|
|
+ >
|
|
|
+ {{ 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.label }}
|
|
|
+ </el-tag>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="questions" label="选择评卷题目:">
|
|
|
+ <div class="marker-paper-struct">
|
|
|
+ <div
|
|
|
+ v-for="mainItem in paperStructs"
|
|
|
+ :key="mainItem.mainId"
|
|
|
+ class="struct-item"
|
|
|
+ >
|
|
|
+ <div class="struct-header box-justify">
|
|
|
+ <h4>{{ mainItem.mainNumber }}、{{ mainItem.mainTitle }}</h4>
|
|
|
+ <el-checkbox
|
|
|
+ v-model="mainItem.selected"
|
|
|
+ title="全选"
|
|
|
+ @change="checked => selectQuestionAll(checked, mainItem)"
|
|
|
+ ></el-checkbox>
|
|
|
+ </div>
|
|
|
+ <div class="struct-questions">
|
|
|
+ <el-checkbox
|
|
|
+ v-for="question in mainItem.children"
|
|
|
+ :key="question.id"
|
|
|
+ v-model="question.selected"
|
|
|
+ :disabled="question.disabled"
|
|
|
+ @change="questionChange"
|
|
|
+ >
|
|
|
+ {{ question.subNumber }}
|
|
|
+ </el-checkbox>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </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 { organizationList } from "../../base/api";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "modify-marker-question",
|
|
|
+ props: {
|
|
|
+ instance: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ },
|
|
|
+ disabledQuestionIds: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ paperStructure: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ const usersValidator = (rule, value, callback) => {
|
|
|
+ if (!this.selectedUserIds.length) {
|
|
|
+ callback(new Error("请选择评卷员"));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const questionsValidator = (rule, value, callback) => {
|
|
|
+ if (!this.selectedQuestionIds.length) {
|
|
|
+ callback(new Error("请选择试题"));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ modalIsShow: false,
|
|
|
+ filterLabel: "",
|
|
|
+ orgUsers: [],
|
|
|
+ userTree: [],
|
|
|
+ userList: [],
|
|
|
+ selectedUsers: [],
|
|
|
+ selectedUserIds: [],
|
|
|
+ selectedQuestions: [],
|
|
|
+ selectedQuestionIds: [],
|
|
|
+ paperStructs: [],
|
|
|
+ defaultProps: {
|
|
|
+ children: "children",
|
|
|
+ label: "label"
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ users: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ validator: usersValidator,
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ questions: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ validator: questionsValidator,
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getOrgData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ visibleChange() {
|
|
|
+ this.parseStructs();
|
|
|
+ this.filterLabel = "";
|
|
|
+ this.selectedUsers = this.instance.markers;
|
|
|
+ this.selectedQuestions = this.instance.questions;
|
|
|
+ this.selectedUserIds = this.selectedUsers.map(item => item.id);
|
|
|
+ this.selectedQuestionIds = this.selectedQuestions.map(item => item.id);
|
|
|
+ this.labelChange();
|
|
|
+ },
|
|
|
+ cancel() {
|
|
|
+ this.modalIsShow = false;
|
|
|
+ },
|
|
|
+ open() {
|
|
|
+ this.modalIsShow = true;
|
|
|
+ },
|
|
|
+ // user
|
|
|
+ async getOrgData() {
|
|
|
+ const data = await organizationList();
|
|
|
+ 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,
|
|
|
+ selected: false,
|
|
|
+ isUser: true
|
|
|
+ };
|
|
|
+ return nuser;
|
|
|
+ });
|
|
|
+ nitem.children = [...nitem.children, ...users];
|
|
|
+ }
|
|
|
+ return nitem;
|
|
|
+ });
|
|
|
+ };
|
|
|
+ this.orgUsers = parseUser(data);
|
|
|
+ this.userTree = this.orgUsers;
|
|
|
+ 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.userTree = this.orgUsers;
|
|
|
+ } else {
|
|
|
+ const escapeRegexpString = (value = "") =>
|
|
|
+ String(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
|
+ const reg = new RegExp(escapeRegexpString(this.filterLabel), "i");
|
|
|
+
|
|
|
+ this.userTree = this.userList.filter(item => reg.test(item.name));
|
|
|
+ }
|
|
|
+ this.$refs.UserTree.setCheckedKeys(this.selectedUserIds);
|
|
|
+ },
|
|
|
+ selectNodeAll(checked, data) {
|
|
|
+ let userIds = [];
|
|
|
+ const getUserIds = list => {
|
|
|
+ list.forEach(item => {
|
|
|
+ item.selected = checked;
|
|
|
+ if (item.children && item.children.length) {
|
|
|
+ getUserIds(item.children);
|
|
|
+ } else {
|
|
|
+ if (item.isUser) userIds.push(item.userId);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ getUserIds(data.children);
|
|
|
+
|
|
|
+ userIds.forEach(userId => {
|
|
|
+ const userPos = this.selectedUserIds.indexOf(userId);
|
|
|
+ const includeUser = userPos !== -1;
|
|
|
+ if (checked) {
|
|
|
+ if (!includeUser) this.selectedUserIds.push(userId);
|
|
|
+ } else {
|
|
|
+ if (includeUser) {
|
|
|
+ this.selectedUserIds.splice(userPos, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ this.$refs.UserTree.setCheckedKeys(this.selectedUserIds);
|
|
|
+ this.updateSelectedUsersFromUserIds();
|
|
|
+
|
|
|
+ this.$refs.modalFormRef.validateField("users");
|
|
|
+ },
|
|
|
+ updateSelectedUsersFromUserIds() {
|
|
|
+ this.selectedUsers = this.userList.filter(user =>
|
|
|
+ this.selectedUserIds.includes(user.id)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ userChange() {
|
|
|
+ if (this.filterLabel) {
|
|
|
+ let prevSelectUserIds = this.selectedUsers.map(item => item.id);
|
|
|
+ const prevUserListSelectUserIds = this.userTree
|
|
|
+ .filter(user => prevSelectUserIds.includes(user.id))
|
|
|
+ .map(user => user.id);
|
|
|
+ const selectedUsers = this.$refs.UserTree.getCheckedNodes(true);
|
|
|
+ const sIds = selectedUsers.map(user => user.id);
|
|
|
+ const prevDeletedUserIds = prevUserListSelectUserIds.filter(
|
|
|
+ uid => !sIds.includes(uid)
|
|
|
+ );
|
|
|
+ this.selectedUsers = this.selectedUsers.filter(
|
|
|
+ user => !prevDeletedUserIds.includes(user.id)
|
|
|
+ );
|
|
|
+ prevSelectUserIds = this.selectedUsers.map(item => item.id);
|
|
|
+
|
|
|
+ selectedUsers.forEach(user => {
|
|
|
+ if (prevSelectUserIds.includes(user.id)) return;
|
|
|
+ const nuser = {
|
|
|
+ id: user.id,
|
|
|
+ name: user.name,
|
|
|
+ label: `${user.name}(${user.orgName})`
|
|
|
+ };
|
|
|
+ this.selectedUsers.push(nuser);
|
|
|
+ });
|
|
|
+ this.selectedUserIds = this.selectedUsers.map(item => item.id);
|
|
|
+ } else {
|
|
|
+ const selectedUsers = this.$refs.UserTree.getCheckedNodes(true);
|
|
|
+ this.selectedUsers = selectedUsers.map(user => {
|
|
|
+ const nuser = {
|
|
|
+ id: user.id,
|
|
|
+ name: user.name,
|
|
|
+ label: `${user.name}(${user.orgName})`
|
|
|
+ };
|
|
|
+ return nuser;
|
|
|
+ });
|
|
|
+ this.selectedUserIds = this.selectedUsers.map(item => item.id);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 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");
|
|
|
+ },
|
|
|
+ // question
|
|
|
+ parseStructs() {
|
|
|
+ this.selectedQuestionIds = this.instance.questions.map(q => q.id);
|
|
|
+ let paperStructs = [];
|
|
|
+ let struct = null;
|
|
|
+ this.paperStructure.forEach(item => {
|
|
|
+ if (item.isMainFirstSub) {
|
|
|
+ if (struct) paperStructs.push(struct);
|
|
|
+ struct = {
|
|
|
+ mainId: item.mainId,
|
|
|
+ mainTitle: item.mainTitle,
|
|
|
+ mainNumber: item.mainNumber,
|
|
|
+ selected: false,
|
|
|
+ children: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+ struct.children.push({
|
|
|
+ ...item,
|
|
|
+ disabled: this.disabledQuestionIds.includes(item.id),
|
|
|
+ selected: this.selectedQuestionIds.includes(item.id)
|
|
|
+ });
|
|
|
+ });
|
|
|
+ if (struct) paperStructs.push(struct);
|
|
|
+ this.paperStructs = paperStructs;
|
|
|
+ },
|
|
|
+ selectQuestionAll(checked, mainItem) {
|
|
|
+ mainItem.children.forEach(q => {
|
|
|
+ if (!q.disabled) q.selected = checked;
|
|
|
+ });
|
|
|
+ this.questionChange();
|
|
|
+ },
|
|
|
+ updateSelectedQuestions() {
|
|
|
+ let selectedQuestions = [];
|
|
|
+ let selectedQuestionIds = [];
|
|
|
+ this.paperStructs.forEach(s => {
|
|
|
+ s.children.forEach(q => {
|
|
|
+ if (q.selected && !q.disabled) {
|
|
|
+ selectedQuestions.push(q);
|
|
|
+ selectedQuestionIds.push(q.id);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.selectedQuestions = selectedQuestions;
|
|
|
+ this.selectedQuestionIds = selectedQuestionIds;
|
|
|
+ },
|
|
|
+ questionChange() {
|
|
|
+ this.updateSelectedQuestions();
|
|
|
+ this.$refs.modalFormRef.validateField("questions");
|
|
|
+ },
|
|
|
+ // confirm
|
|
|
+ async confirm() {
|
|
|
+ const valid = await this.$refs.modalFormRef.validate().catch(() => {});
|
|
|
+ if (!valid) return;
|
|
|
+
|
|
|
+ let datas = { ...this.instance };
|
|
|
+ datas.markers = this.selectedUsers;
|
|
|
+ datas.questions = this.selectedQuestions;
|
|
|
+ this.$emit("modified", datas);
|
|
|
+ this.cancel();
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|