Explorar el Código

完善系统管理

Michael Wang hace 4 años
padre
commit
8c8eb31e2d

+ 1 - 0
package.json

@@ -24,6 +24,7 @@
     "crypto-js": "^4.0.0",
     "element-ui": "^2.13.2",
     "js-cookie": "^2.2.1",
+    "js-md5": "^0.7.3",
     "lodash-es": "^4.17.15",
     "moment": "^2.27.0",
     "query-string": "^6.13.1",

+ 6 - 4
src/api/system-info.js

@@ -1,10 +1,12 @@
 import { httpApp } from "@/plugins/axiosIndex";
 import { object2QueryString } from "@/utils/utils";
 
-export function uploadFile({ file }) {
+export function uploadFile({ file, md5 }) {
+  const form = new FormData();
+  form.append("file", file);
   return httpApp.post(
-    "/api/admin/user/query?" + object2QueryString({ type: "frontend" }),
-    { file: file },
-    { headers: { "Content-Type": "multipart/form-data" } }
+    "/api/admin/sys/file/upload?" + object2QueryString({ type: "frontend" }),
+    form,
+    { headers: { "Content-Type": "multipart/form-data", md5: md5 } }
   );
 }

+ 38 - 0
src/api/system-org.js

@@ -15,3 +15,41 @@ export function searchOrgs({
   );
   return httpApp.post("/api/admin/org/query?" + object2QueryString(data));
 }
+
+export function toggleEnableOrg({ id, enable }) {
+  return httpApp.post("/api/admin/org/enable", { id, enable });
+}
+
+export function searchOrg(id) {
+  return httpApp.post("/api/admin/sys/org/query?" + object2QueryString({ id }));
+}
+
+export function saveOrg({
+  id = "",
+  name = "",
+  code = "",
+  contactName = "",
+  contactPhone = "",
+  logo = null,
+  enableSimulate = 0,
+  enableMonitorRecord = 0,
+  enableLiveness = 0,
+  enable = 0,
+}) {
+  const data = pickBy(
+    {
+      id,
+      name,
+      code,
+      contactName,
+      contactPhone,
+      // logo,
+      enableSimulate,
+      enableMonitorRecord,
+      enableLiveness,
+      enable,
+    },
+    (v) => v !== ""
+  );
+  return httpApp.post("/api/admin/org/save", { ...data, logo });
+}

+ 2 - 1
src/features/Login/Login.vue

@@ -7,7 +7,7 @@
         在线考试管理系统
       </h2> -->
       <div class="form-container">
-        <div>
+        <div class="text-center">
           <img :src="schoolLogo" class="school-logo" alt="学校logo" />
           <div class="text-center title">在线考试平台后台管理系统</div>
         </div>
@@ -258,6 +258,7 @@ export default {
   text-align: center;
   height: 60px;
   width: 200px;
+  object-fit: cover;
 }
 .title {
   color: #626a82;

+ 3 - 3
src/features/examwork/InvigilateManagement/InvigilateManagement.vue

@@ -56,7 +56,7 @@
     </div>
 
     <InvigilateManagementDialog
-      ref="userDialog"
+      ref="theDialog"
       :user="selectedUser"
       @reload="searchForm"
     />
@@ -119,11 +119,11 @@ export default {
     },
     add() {
       this.selectedUser = {};
-      this.$refs.userDialog.openDialog();
+      this.$refs.theDialog.openDialog();
     },
     edit(user) {
       this.selectedUser = user;
-      this.$refs.userDialog.openDialog();
+      this.$refs.theDialog.openDialog();
     },
   },
 };

+ 2 - 2
src/features/examwork/StudentManagement/StudentManagement.vue

@@ -127,11 +127,11 @@ export default {
     },
     add() {
       this.selectedUser = {};
-      this.$refs.userDialog.openDialog();
+      this.$refs.theDialog.openDialog();
     },
     edit(user) {
       this.selectedUser = user;
-      this.$refs.userDialog.openDialog();
+      this.$refs.theDialog.openDialog();
     },
     async toggleEnableStudent(user) {
       await toggleEnableStudent({

+ 33 - 4
src/features/system/OrgManagement/OrgManagement.vue

@@ -11,7 +11,7 @@
         <StateSelect v-model="form.enableState"></StateSelect>
       </el-form-item>
       <el-button @click="searchForm">查询</el-button>
-      <el-button>新增</el-button>
+      <el-button @click="add">新增</el-button>
       <!-- <el-button>导入</el-button> -->
     </el-form>
 
@@ -50,6 +50,14 @@
           <el-button size="mini" type="primary" plain @click="edit(scope.row)">
             <i class="el-icon-edit"></i> 编辑
           </el-button>
+          <el-button
+            size="mini"
+            type="primary"
+            plain
+            @click="toggleEnableOrg(scope.row)"
+          >
+            {{ scope.row.enable ? "禁用" : "启用" }}
+          </el-button>
         </div>
       </el-table-column>
     </el-table>
@@ -64,17 +72,22 @@
         :total="total"
       />
     </div>
+    <OrgManagementDialog
+      ref="theDialog"
+      :org="selectedOrg"
+      @reload="searchForm"
+    />
   </div>
 </template>
 
 <script>
-import StateSelect from "@/components/StateSelect";
-import { searchOrgs } from "../../../api/system-org";
+import { searchOrgs, toggleEnableOrg } from "../../../api/system-org";
+import OrgManagementDialog from "./OrgManagementDialog";
 
 export default {
   name: "OrgManagement",
   components: {
-    StateSelect,
+    OrgManagementDialog,
   },
   data() {
     return {
@@ -87,6 +100,7 @@ export default {
       currentPage: 1,
       pageSize: 10,
       total: 10,
+      selectedOrg: {},
     };
   },
   async created() {},
@@ -111,6 +125,21 @@ export default {
       this.currentPage = 1;
       this.searchForm();
     },
+    add() {
+      this.selectedOrg = {};
+      this.$refs.theDialog.openDialog();
+    },
+    edit(org) {
+      this.selectedOrg = org;
+      this.$refs.theDialog.openDialog();
+    },
+    async toggleEnableOrg(org) {
+      await toggleEnableOrg({
+        id: org.id,
+        enable: org.enable === 0 ? 1 : 0,
+      });
+      this.searchForm();
+    },
   },
 };
 </script>

+ 164 - 0
src/features/system/OrgManagement/OrgManagementDialog.vue

@@ -0,0 +1,164 @@
+<template>
+  <el-dialog
+    ref="dialog"
+    :title="(isEdit ? '编辑' : '新增') + '机构'"
+    width="480px"
+    :visible.sync="visible"
+    @close="closeDialog"
+  >
+    <el-form
+      :model="form"
+      ref="form"
+      :rules="rules"
+      label-position="right"
+      label-width="140px"
+    >
+      <el-row>
+        <el-form-item label="机构名称" prop="name">
+          <el-input
+            class="pull_length"
+            v-model="form.name"
+            placeholder="机构名称"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="机构编码" prop="code">
+          <el-input
+            class="pull_length"
+            v-model="form.code"
+            placeholder="机构编码"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="负责人" prop="contactName">
+          <el-input
+            class="pull_length"
+            v-model="form.contactName"
+            placeholder="负责人"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="联系方式" prop="contactPhone">
+          <el-input
+            class="pull_length"
+            v-model="form.contactPhone"
+            placeholder="联系方式"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="logo" prop="logo">
+          <UploadFile v-model="form.logo" />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="是否启用模考" prop="enableSimulate">
+          <el-radio-group class="pull_right_sm" v-model="form.enableSimulate">
+            <el-radio :label="1">启用</el-radio>
+            <el-radio :label="0">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="是否视频转录" prop="enableMonitorRecord">
+          <el-radio-group
+            class="pull_right_sm"
+            v-model="form.enableMonitorRecord"
+          >
+            <el-radio :label="1">启用</el-radio>
+            <el-radio :label="0">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="是否使用活体检测" prop="enableLiveness">
+          <el-radio-group class="pull_right_sm" v-model="form.enableLiveness">
+            <el-radio :label="1">启用</el-radio>
+            <el-radio :label="0">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="状态" prop="enable">
+          <el-radio-group class="pull_right_sm" v-model="form.enable">
+            <el-radio :label="1">启用</el-radio>
+            <el-radio :label="0">禁用</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-row>
+      <el-row class="d-flex justify-content-center">
+        <el-button type="primary" @click="submitForm">保 存</el-button>
+        <el-button @click="closeDialog">取 消</el-button>
+      </el-row>
+    </el-form>
+  </el-dialog>
+</template>
+
+<script>
+import { searchOrg, saveOrg } from "@/api/system-org";
+import UploadFile from "./UploadFile";
+export default {
+  name: "OrgManagementDialog",
+  props: {
+    org: Object,
+  },
+  components: { UploadFile },
+  computed: {
+    isEdit() {
+      return this.org.id;
+    },
+  },
+  data() {
+    return {
+      visible: false,
+      form: {},
+      rules: {},
+    };
+  },
+  watch: {
+    org: {
+      immediate: true,
+      handler: async function () {
+        if (this.isEdit) {
+          const res = await searchOrg(this.org.id);
+          this.form = res.data.data.records[0];
+        } else {
+          this.form = {
+            name: "",
+            code: "",
+            contactName: "",
+            contactPhone: "",
+            logo: null,
+            enableSimulate: 0,
+            enableMonitorRecord: 0,
+            enableLiveness: 0,
+            enable: 0,
+          };
+        }
+      },
+    },
+  },
+  methods: {
+    openDialog() {
+      this.visible = true;
+    },
+    closeDialog() {
+      this.visible = false;
+    },
+    async submitForm() {
+      let data = this.form;
+      if (this.isEdit) {
+        data = { ...data, id: this.org.id };
+      }
+      await saveOrg(data);
+      this.$emit("reload");
+      this.closeDialog();
+    },
+  },
+};
+</script>
+
+<style></style>

+ 82 - 0
src/features/system/OrgManagement/UploadFile.vue

@@ -0,0 +1,82 @@
+<template>
+  <el-upload
+    ref="upload"
+    class="upload-demo"
+    action="/api/placeholder"
+    accept=".jpg,.png"
+    :on-preview="handlePreview"
+    :on-remove="handleRemove"
+    :file-list="fileList"
+    :before-upload="beforeUpload"
+    list-type="picture"
+  >
+    <el-button size="small" type="primary">点击上传</el-button>
+    <div slot="tip" class="el-upload__tip">
+      只能上传jpg/png文件,且不超过500kb
+    </div>
+  </el-upload>
+</template>
+
+<script>
+import MD5 from "js-md5";
+import { uploadFile } from "@/api/system-info";
+
+export default {
+  props: { value: String },
+  data() {
+    return {
+      fileList: [
+        {
+          name: "",
+          url: this.value || "",
+        },
+      ],
+    };
+  },
+  watch: {
+    value: {
+      immediate: true,
+      handler(v) {
+        this.fileList[0].url = v;
+      },
+    },
+  },
+  methods: {
+    handleRemove(file, fileList) {
+      console.log(file, fileList);
+      const url = "";
+      this.fileList[0].url = url;
+      this.$emit("input", url);
+      this.$emit("change", url);
+    },
+    handlePreview(file) {
+      console.log(file);
+    },
+    async beforeUpload(file) {
+      console.log(file);
+      async function blobToArray(blob) {
+        return new Promise((resolve) => {
+          var reader = new FileReader();
+          reader.addEventListener("loadend", function () {
+            // reader.result contains the contents of blob as a typed array
+            resolve(reader.result);
+          });
+          reader.readAsArrayBuffer(blob);
+        });
+      }
+      const ab = await blobToArray(file);
+      const md5 = MD5(ab);
+
+      const res = await uploadFile({ file, md5 });
+      console.log(res);
+      const url = res.data.data.url;
+      this.fileList[0].url = url;
+      this.$emit("input", url);
+      this.$emit("change", url);
+      // return Promise.reject("stop upload");
+    },
+  },
+};
+</script>
+
+<style></style>

+ 11 - 11
src/features/system/UserManagement/UserManagement.vue

@@ -60,14 +60,14 @@
           <el-button size="mini" type="primary" plain @click="edit(scope.row)">
             编辑
           </el-button>
-          <el-button
-            size="mini"
-            type="primary"
-            plain
-            @click="resetUserPassword(scope.row)"
+          <el-popconfirm
+            title="确定将此用户密码重置为 123456 吗?"
+            @onConfirm="resetUserPassword(scope.row)"
           >
-            重置密码
-          </el-button>
+            <el-button slot="reference" size="mini" type="primary" plain>
+              重置密码
+            </el-button>
+          </el-popconfirm>
           <el-button
             size="mini"
             type="primary"
@@ -92,7 +92,7 @@
     </div>
 
     <UserManagementDialog
-      ref="userDialog"
+      ref="theDialog"
       :user="selectedUser"
       @reload="searchForm"
     />
@@ -160,11 +160,11 @@ export default {
     },
     add() {
       this.selectedUser = {};
-      this.$refs.userDialog.openDialog();
+      this.$refs.theDialog.openDialog();
     },
     edit(user) {
       this.selectedUser = user;
-      this.$refs.userDialog.openDialog();
+      this.$refs.theDialog.openDialog();
     },
     async toggleEnableUser(user) {
       await toggleEnableUser({
@@ -178,7 +178,7 @@ export default {
         id: user.id,
         password: "123456",
       });
-      this.searchForm();
+      this.$notify({ type: "success", title: "重置成功" });
     },
   },
 };

+ 5 - 0
yarn.lock

@@ -6794,6 +6794,11 @@ js-cookie@^2.2.1:
   resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
   integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
 
+js-md5@^0.7.3:
+  version "0.7.3"
+  resolved "https://registry.npm.taobao.org/js-md5/download/js-md5-0.7.3.tgz#b4f2fbb0b327455f598d6727e38ec272cd09c3f2"
+  integrity sha1-tPL7sLMnRV9ZjWcn447Ccs0Jw/I=
+
 js-message@1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15"