Browse Source

数据权限: 添加和删除

Michael Wang 4 years ago
parent
commit
6e578fa0b8

+ 57 - 0
src/components/ExamTypeSelect.vue

@@ -0,0 +1,57 @@
+<template>
+  <el-select
+    v-model="selected"
+    class="size-select"
+    placeholder="请选择"
+    @change="select"
+    :style="styles"
+    clearable
+  >
+    <el-option
+      v-for="item in optionList"
+      :key="item.code"
+      :label="item.name"
+      :value="item.code"
+    >
+      <span>{{ item.name }}</span>
+    </el-option>
+  </el-select>
+</template>
+
+<script>
+import { EXAM_TYPE_SELECT } from "@/constants/constants";
+export default {
+  name: "ExamTypeSelect",
+  props: {
+    value: {
+      type: String,
+      default: ""
+    },
+    options: { type: Array, default: () => null },
+    styles: { type: String }
+  },
+  data() {
+    return {
+      optionList: this.options || EXAM_TYPE_SELECT,
+      selected: ""
+    };
+  },
+  async created() {},
+  watch: {
+    value: {
+      immediate: true,
+      handler(val) {
+        this.selected = val;
+      }
+    }
+  },
+  methods: {
+    select() {
+      this.$emit("input", this.selected);
+      this.$emit("change", this.selected);
+    }
+  }
+};
+</script>
+
+<style></style>

+ 57 - 0
src/components/LevelTypeSelect.vue

@@ -0,0 +1,57 @@
+<template>
+  <el-select
+    v-model="selected"
+    class="size-select"
+    placeholder="请选择"
+    @change="select"
+    :style="styles"
+    clearable
+  >
+    <el-option
+      v-for="item in optionList"
+      :key="item.code"
+      :label="item.name"
+      :value="item.code"
+    >
+      <span>{{ item.name }}</span>
+    </el-option>
+  </el-select>
+</template>
+
+<script>
+import { LEVEL_TYPE_SELECT } from "@/constants/constants";
+export default {
+  name: "ExamTypeSelect",
+  props: {
+    value: {
+      type: String,
+      default: ""
+    },
+    options: { type: Array, default: () => null },
+    styles: { type: String }
+  },
+  data() {
+    return {
+      optionList: this.options || LEVEL_TYPE_SELECT,
+      selected: ""
+    };
+  },
+  async created() {},
+  watch: {
+    value: {
+      immediate: true,
+      handler(val) {
+        this.selected = val;
+      }
+    }
+  },
+  methods: {
+    select() {
+      this.$emit("input", this.selected);
+      this.$emit("change", this.selected);
+    }
+  }
+};
+</script>
+
+<style></style>

+ 38 - 0
src/components/registerComponents.js

@@ -0,0 +1,38 @@
+import Vue from "vue";
+// import upperFirst from "lodash/upperFirst";
+// import camelCase from "lodash/camelCase";
+
+const requireComponent = require.context(
+  // The relative path of the components folder
+  "./",
+  // Whether or not to look in subfolders
+  false,
+  // The regular expression used to match base component filenames
+  /[A-Z]\w+\.(vue|js)$/
+);
+
+requireComponent.keys().forEach(fileName => {
+  // Get component config
+  const componentConfig = requireComponent(fileName);
+
+  // Get PascalCase name of component
+  const componentName =
+    // upperFirst(
+    //   camelCase(
+    // Gets the file name regardless of folder depth
+    fileName
+      .split("/")
+      .pop()
+      .replace(/\.\w+$/, "");
+  //   )
+  // );
+
+  // Register component globally
+  Vue.component(
+    componentName,
+    // Look for the component options on `.default`, which will
+    // exist if the component was exported with `export default`,
+    // otherwise fall back to module's root.
+    componentConfig.default || componentConfig
+  );
+});

+ 18 - 0
src/constants/constants.js

@@ -19,6 +19,24 @@ export const EXAM_TYPE = [
   { label: "印刷", value: "PRINT_EXAM" }
 ];
 
+// for exam type select
+export const EXAM_TYPE_SELECT = [
+  { code: "TRADITION", name: "传统" },
+  { code: "ONLINE", name: "网考" },
+  { code: "PRACTICE", name: "练习" },
+  { code: "OFFLINE", name: "离线" },
+  { code: "ONLINE_HOMEWORK", name: "在线作业" },
+  { code: "PRINT_EXAM", name: "印刷" }
+];
+
+// for level type select
+export const LEVEL_TYPE_SELECT = [
+  { code: "ZSB", name: "专升本" },
+  { code: "GQZ", name: "高起专" },
+  { code: "GQB", name: "高起本" },
+  { code: "ALL", name: "不限" }
+];
+
 //试卷类型
 export const PAPER_TYPE = [
   "A",

+ 11 - 0
src/filters/filters.js

@@ -1,2 +1,13 @@
 import "../modules/questions/filters/filters";
 import "../modules/marking/filters/filters";
+import Vue from "vue";
+import { LEVEL_TYPE_SELECT } from "@/constants/constants";
+
+// 课程层次过滤器
+Vue.filter("levelTypeFilter", function(val) {
+  for (let examType of LEVEL_TYPE_SELECT) {
+    if (examType.code === val) {
+      return examType.name;
+    }
+  }
+});

+ 1 - 0
src/main.js

@@ -3,6 +3,7 @@ import App from "./App.vue";
 import router from "./router";
 import store from "./store";
 // import "./registerServiceWorker";
+import "./components/registerComponents";
 import "./plugins/element.js";
 import "./plugins/axios";
 import "./plugins/vueAwesome";

+ 57 - 16
src/modules/basic/view/data_previllege.vue

@@ -13,9 +13,7 @@
             label-position="right"
           >
             <div style="margin-bottom: 10px;">
-              <el-button type="primary" size="small" @click="savePrevillegeExam"
-                >保 存</el-button
-              >
+              <el-button type="primary" size="small">保 存</el-button>
               <el-button
                 type="primary"
                 size="small"
@@ -37,7 +35,7 @@
                       size="small"
                       type="danger"
                       icon="el-icon-delete"
-                      @click="deleteBatchExam"
+                      @click="deleteBatch('Exam')"
                       :disabled="noBatchSelectedExam"
                       >删除</el-button
                     >
@@ -45,7 +43,7 @@
                       size="small"
                       type="primary"
                       icon="el-icon-plus"
-                      @click="deleteBatchExam"
+                      @click="addExam"
                       >添加</el-button
                     >
                   </div>
@@ -104,7 +102,7 @@
                       size="small"
                       type="danger"
                       icon="el-icon-delete"
-                      @click="deleteBatchCourse"
+                      @click="deleteBatch('Course')"
                       :disabled="noBatchSelectedCourse"
                       >删除</el-button
                     >
@@ -112,7 +110,7 @@
                       size="small"
                       type="primary"
                       icon="el-icon-plus"
-                      @click="deleteBatchCourse"
+                      @click="addCourse"
                       >添加</el-button
                     >
                   </div>
@@ -176,7 +174,7 @@
                       size="small"
                       type="danger"
                       icon="el-icon-delete"
-                      @click="deleteBatchOrg"
+                      @click="deleteBatch('Org')"
                       :disabled="noBatchSelectedOrg"
                       >删除</el-button
                     >
@@ -184,7 +182,7 @@
                       size="small"
                       type="primary"
                       icon="el-icon-plus"
-                      @click="deleteBatchOrg"
+                      @click="addOrg"
                       >添加</el-button
                     >
                   </div>
@@ -235,6 +233,21 @@
         </div>
       </div>
     </section>
+    <DataPrevillegeAddExamDialog
+      ref="addExamDialog"
+      :userId="userId"
+      @reload="init"
+    />
+    <DataPrevillegeAddCourseDialog
+      ref="addCourseDialog"
+      :userId="userId"
+      @reload="init"
+    />
+    <DataPrevillegeAddOrgDialog
+      ref="addOrgDialog"
+      :userId="userId"
+      @reload="init"
+    />
   </div>
 </template>
 
@@ -243,11 +256,17 @@ import { mapState } from "vuex";
 import { CORE_API } from "@/constants/constants.js";
 import LinkTitlesCustom from "@/components/LinkTitlesCustom.vue";
 import { object2QueryString } from "@/utils/utils";
+import DataPrevillegeAddExamDialog from "./data_previllege_add_exam";
+import DataPrevillegeAddCourseDialog from "./data_previllege_add_course";
+import DataPrevillegeAddOrgDialog from "./data_previllege_add_org";
 
 export default {
   name: "DataPrevillege",
   components: {
-    LinkTitlesCustom
+    LinkTitlesCustom,
+    DataPrevillegeAddExamDialog,
+    DataPrevillegeAddCourseDialog,
+    DataPrevillegeAddOrgDialog
   },
   data() {
     return {
@@ -386,12 +405,34 @@ export default {
         this.form["defaultStatus" + type] = !enabled;
       }
     },
-    savePrevillegeExam() {},
-    deleteBatchExam() {},
-    savePrevillegeCourse() {},
-    deleteBatchCourse() {},
-    savePrevillegeOrg() {},
-    deleteBatchOrg() {}
+    addExam() {
+      this.$refs.addExamDialog.openDialog();
+    },
+    async deleteBatch(type) {
+      const ids = this.$refs["table" + type].selection.map(v => v.id).join();
+      try {
+        await this.$httpWithMsg.post(
+          CORE_API +
+            "/user/data/rule/delete?" +
+            object2QueryString({
+              ids
+            })
+        );
+        this.$notify({
+          type: "success",
+          message: "删除成功"
+        });
+        await this.init();
+      } catch (error) {
+        console.log(error);
+      }
+    },
+    addCourse() {
+      this.$refs.addCourseDialog.openDialog();
+    },
+    addOrg() {
+      this.$refs.addOrgDialog.openDialog();
+    }
   },
   async created() {
     this.userId = this.$route.params.userId;

+ 186 - 0
src/modules/basic/view/data_previllege_add_course.vue

@@ -0,0 +1,186 @@
+<template>
+  <el-dialog
+    ref="dialog"
+    title="添加课程"
+    width="700px"
+    :visible.sync="visible"
+    @close="closeDialog"
+  >
+    <el-form
+      :model="form"
+      ref="form"
+      :rules="rules"
+      :inline="true"
+      label-position="right"
+      label-width="80px"
+    >
+      <el-row>
+        <el-form-item label="课程名称">
+          <el-input placeholder="请输入课程名称" v-model="form.name" />
+        </el-form-item>
+        <el-form-item label="课程层次">
+          <LevelTypeSelect v-model="form.levelType"></LevelTypeSelect>
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-search"
+            @click="search"
+          >
+            查询
+          </el-button>
+        </el-form-item>
+      </el-row>
+
+      <el-row>
+        <div>
+          <el-table
+            ref="table"
+            :data="tableData"
+            border
+            resizable
+            stripe
+            style="width: 100%;"
+          >
+            <el-table-column type="selection" width="40" />
+            <el-table-column width="85" label="课程ID">
+              <span slot-scope="scope">{{ scope.row.id }}</span>
+            </el-table-column>
+            <el-table-column width="200" label="课程代码">
+              <span slot-scope="scope">{{ scope.row.code }}</span>
+            </el-table-column>
+            <el-table-column label="课程名称">
+              <span slot-scope="scope">{{ scope.row.name }}</span>
+            </el-table-column>
+            <el-table-column width="100" label="课程层次">
+              <span slot-scope="scope">{{
+                scope.row.level | levelTypeFilter
+              }}</span>
+            </el-table-column>
+          </el-table>
+          <div class="page pull-right">
+            <el-pagination
+              v-if="paginationShow"
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              :page-sizes="[10, 20, 50, 100, 200, 300]"
+              @size-change="handleSizeChange"
+              layout="total, sizes, prev, pager, next, jumper"
+              :total="total"
+            />
+          </div>
+        </div>
+        <div style="margin-bottom: 20px"></div>
+      </el-row>
+
+      <el-row class="d-flex justify-content-center mt-2">
+        <el-button type="primary" @click="submitForm" :loading="loading"
+          >确 定</el-button
+        >
+        <el-button @click="closeDialog">取 消</el-button>
+      </el-row>
+    </el-form>
+  </el-dialog>
+</template>
+
+<script>
+import { CORE_API } from "@/constants/constants";
+export default {
+  name: "DataPrevillegeAddCourseDialog",
+  props: {
+    userId: String
+  },
+  data() {
+    return {
+      visible: false,
+      form: {
+        name: "",
+        levelType: ""
+      },
+      rules: {},
+      loading: false,
+      paginationShow: false,
+      tableData: [],
+      noBatchSelected: true,
+      currentPage: 1,
+      pageSize: 10,
+      total: 10
+    };
+  },
+  methods: {
+    async search() {
+      var param = new URLSearchParams(this.form);
+      var url =
+        CORE_API +
+        "/course/coursePage/" +
+        (this.currentPage - 1) +
+        "/" +
+        this.pageSize +
+        "?" +
+        param;
+      this.loading = true;
+      return this.$httpWithMsg.get(url).then(response => {
+        this.tableData = response.data.content;
+        this.total = response.data.total;
+        this.loading = false;
+        this.paginationShow = true;
+      });
+    },
+    async openDialog() {
+      this.visible = true;
+      try {
+        await this.search();
+      } catch (error) {
+        console.log(error);
+        this.$notify({ type: "error", title: "获取课程列表失败" });
+      }
+    },
+    closeDialog() {
+      this.visible = false;
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.search();
+    },
+    async submitForm() {
+      try {
+        await this.$refs.form.validate();
+      } catch (error) {
+        console.log("校验失败", error);
+        return;
+      }
+
+      const refIds = this.$refs.table.selection.map(v => v.id);
+      console.log(refIds);
+      if (refIds.length === 0) {
+        this.$notify({ type: "warning", message: "请先选择一行或多行" });
+        return;
+      }
+
+      this.$httpWithMsg.post(CORE_API + "/user/data/rule/add", {
+        refIds,
+        type: "COURSE",
+        userId: this.userId
+      });
+      try {
+        this.loading = true;
+        // await saveActivity(data);
+        this.$emit("reload");
+        this.$notify({ title: "保存成功", type: "success" });
+        this.closeDialog();
+      } finally {
+        this.loading = false;
+      }
+    }
+  }
+};
+</script>
+
+<style></style>

+ 186 - 0
src/modules/basic/view/data_previllege_add_exam.vue

@@ -0,0 +1,186 @@
+<template>
+  <el-dialog
+    ref="dialog"
+    title="添加考试"
+    width="700px"
+    :visible.sync="visible"
+    @close="closeDialog"
+  >
+    <el-form
+      :model="form"
+      ref="form"
+      :rules="rules"
+      :inline="true"
+      label-position="right"
+      label-width="80px"
+    >
+      <el-row>
+        <el-form-item label="考试名称">
+          <el-input placeholder="请输入考试名称" v-model="form.name" />
+        </el-form-item>
+        <el-form-item label="考试类型">
+          <ExamTypeSelect v-model="form.examType"></ExamTypeSelect>
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-search"
+            @click="search"
+          >
+            查询
+          </el-button>
+        </el-form-item>
+      </el-row>
+
+      <el-row>
+        <div>
+          <el-table
+            ref="table"
+            :data="tableData"
+            border
+            resizable
+            stripe
+            style="width: 100%;"
+          >
+            <el-table-column type="selection" width="40" />
+            <el-table-column width="85" label="考试ID">
+              <span slot-scope="scope">{{ scope.row.id }}</span>
+            </el-table-column>
+            <el-table-column width="200" label="考试代码">
+              <span slot-scope="scope">{{ scope.row.code }}</span>
+            </el-table-column>
+            <el-table-column label="考试名称">
+              <span slot-scope="scope">{{ scope.row.name }}</span>
+            </el-table-column>
+            <el-table-column width="100" label="考试类型">
+              <span slot-scope="scope">{{
+                scope.row.examType | examTypeFilter
+              }}</span>
+            </el-table-column>
+          </el-table>
+          <div class="page pull-right">
+            <el-pagination
+              v-if="paginationShow"
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              :page-sizes="[10, 20, 50, 100, 200, 300]"
+              @size-change="handleSizeChange"
+              layout="total, sizes, prev, pager, next, jumper"
+              :total="total"
+            />
+          </div>
+        </div>
+        <div style="margin-bottom: 20px"></div>
+      </el-row>
+
+      <el-row class="d-flex justify-content-center mt-2">
+        <el-button type="primary" @click="submitForm" :loading="loading"
+          >确 定</el-button
+        >
+        <el-button @click="closeDialog">取 消</el-button>
+      </el-row>
+    </el-form>
+  </el-dialog>
+</template>
+
+<script>
+import { CORE_API, EXAM_WORK_API } from "@/constants/constants";
+export default {
+  name: "DataPrevillegeAddExamDialog",
+  props: {
+    userId: String
+  },
+  data() {
+    return {
+      visible: false,
+      form: {
+        name: "",
+        examType: ""
+      },
+      rules: {},
+      loading: false,
+      paginationShow: false,
+      tableData: [],
+      noBatchSelected: true,
+      currentPage: 1,
+      pageSize: 10,
+      total: 10
+    };
+  },
+  methods: {
+    async search() {
+      var param = new URLSearchParams(this.form);
+      var url =
+        EXAM_WORK_API +
+        "/exam/queryPage/" +
+        (this.currentPage - 1) +
+        "/" +
+        this.pageSize +
+        "?" +
+        param;
+      this.loading = true;
+      return this.$httpWithMsg.get(url).then(response => {
+        this.tableData = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+        this.paginationShow = true;
+      });
+    },
+    async openDialog() {
+      this.visible = true;
+      try {
+        await this.search();
+      } catch (error) {
+        console.log(error);
+        this.$notify({ type: "error", title: "获取考试列表失败" });
+      }
+    },
+    closeDialog() {
+      this.visible = false;
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.search();
+    },
+    async submitForm() {
+      try {
+        await this.$refs.form.validate();
+      } catch (error) {
+        console.log("校验失败", error);
+        return;
+      }
+
+      const refIds = this.$refs.table.selection.map(v => v.id);
+      console.log(refIds);
+      if (refIds.length === 0) {
+        this.$notify({ type: "warning", message: "请先选择一行或多行" });
+        return;
+      }
+
+      this.$httpWithMsg.post(CORE_API + "/user/data/rule/add", {
+        refIds,
+        type: "EXAM",
+        userId: this.userId
+      });
+      try {
+        this.loading = true;
+        // await saveActivity(data);
+        this.$emit("reload");
+        this.$notify({ title: "保存成功", type: "success" });
+        this.closeDialog();
+      } finally {
+        this.loading = false;
+      }
+    }
+  }
+};
+</script>
+
+<style></style>

+ 188 - 0
src/modules/basic/view/data_previllege_add_org.vue

@@ -0,0 +1,188 @@
+<template>
+  <el-dialog
+    ref="dialog"
+    title="添加中心"
+    width="700px"
+    :visible.sync="visible"
+    @close="closeDialog"
+  >
+    <el-form
+      :model="form"
+      ref="form"
+      :rules="rules"
+      :inline="true"
+      label-position="right"
+      label-width="80px"
+    >
+      <el-row>
+        <el-form-item label="中心名称">
+          <el-input placeholder="请输入中心名称" v-model="form.name" />
+        </el-form-item>
+        <el-form-item label="中心代码">
+          <el-input placeholder="请输入中心代码" v-model="form.code" />
+        </el-form-item>
+        <!-- <el-form-item label="负责人">
+          <el-input placeholder="请输入中心名称" v-model="form.contact" />
+        </el-form-item> -->
+        <el-form-item>
+          <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-search"
+            @click="search"
+          >
+            查询
+          </el-button>
+        </el-form-item>
+      </el-row>
+
+      <el-row>
+        <div>
+          <el-table
+            ref="table"
+            :data="tableData"
+            border
+            resizable
+            stripe
+            style="width: 100%;"
+          >
+            <el-table-column type="selection" width="40" />
+            <el-table-column width="85" label="中心ID">
+              <span slot-scope="scope">{{ scope.row.id }}</span>
+            </el-table-column>
+            <el-table-column width="200" label="中心代码">
+              <span slot-scope="scope">{{ scope.row.code }}</span>
+            </el-table-column>
+            <el-table-column label="中心名称">
+              <span slot-scope="scope">{{ scope.row.name }}</span>
+            </el-table-column>
+            <el-table-column width="100" label="负责人">
+              <span slot-scope="scope">{{ scope.row.contacts }}</span>
+            </el-table-column>
+          </el-table>
+          <div class="page pull-right">
+            <el-pagination
+              v-if="paginationShow"
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              :page-sizes="[10, 20, 50, 100, 200, 300]"
+              @size-change="handleSizeChange"
+              layout="total, sizes, prev, pager, next, jumper"
+              :total="total"
+            />
+          </div>
+        </div>
+        <div style="margin-bottom: 20px"></div>
+      </el-row>
+
+      <el-row class="d-flex justify-content-center mt-2">
+        <el-button type="primary" @click="submitForm" :loading="loading"
+          >确 定</el-button
+        >
+        <el-button @click="closeDialog">取 消</el-button>
+      </el-row>
+    </el-form>
+  </el-dialog>
+</template>
+
+<script>
+import { CORE_API } from "@/constants/constants";
+export default {
+  name: "DataPrevillegeAddOrgDialog",
+  props: {
+    userId: String
+  },
+  data() {
+    return {
+      visible: false,
+      form: {
+        parentId: this.$store.state.user.rootOrgId,
+        name: "",
+        code: ""
+      },
+      rules: {},
+      loading: false,
+      paginationShow: false,
+      tableData: [],
+      noBatchSelected: true,
+      currentPage: 1,
+      pageSize: 10,
+      total: 10
+    };
+  },
+  methods: {
+    async search() {
+      var param = new URLSearchParams(this.form);
+      var url =
+        CORE_API +
+        "/org/subOrgPage/" +
+        (this.currentPage - 1) +
+        "/" +
+        this.pageSize +
+        "?" +
+        param;
+      this.loading = true;
+      return this.$httpWithMsg.get(url).then(response => {
+        this.tableData = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+        this.paginationShow = true;
+      });
+    },
+    async openDialog() {
+      this.visible = true;
+      try {
+        await this.search();
+      } catch (error) {
+        console.log(error);
+        this.$notify({ type: "error", title: "获取中心列表失败" });
+      }
+    },
+    closeDialog() {
+      this.visible = false;
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+      this.search();
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.search();
+    },
+    async submitForm() {
+      try {
+        await this.$refs.form.validate();
+      } catch (error) {
+        console.log("校验失败", error);
+        return;
+      }
+
+      const refIds = this.$refs.table.selection.map(v => v.id);
+      console.log(refIds);
+      if (refIds.length === 0) {
+        this.$notify({ type: "warning", message: "请先选择一行或多行" });
+        return;
+      }
+
+      this.$httpWithMsg.post(CORE_API + "/user/data/rule/add", {
+        refIds,
+        type: "ORG",
+        userId: this.userId
+      });
+      try {
+        this.loading = true;
+        // await saveActivity(data);
+        this.$emit("reload");
+        this.$notify({ title: "保存成功", type: "success" });
+        this.closeDialog();
+      } finally {
+        this.loading = false;
+      }
+    }
+  }
+};
+</script>
+
+<style></style>