zhangjie 1 an în urmă
părinte
comite
93b8392cb2

+ 1 - 1
src/api/rootOrgPage.ts

@@ -20,7 +20,7 @@ export function updateRootOrg(params: {
   // code: string;
   // name: string;
   // enable: boolean;
-  id:number;
+  id: number;
   domainName: string;
 }) {
   return httpApp.post("/api/ess/root/org/update", params);

+ 12 - 0
src/assets/svgs/file.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>icon-选取文件</title>
+    <g id="超管" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="04.01-授权管理" transform="translate(-116, -458)">
+            <g id="icon-选取文件" transform="translate(116, 458)">
+                <rect id="folder-open-(Background)" opacity="0" x="0" y="0" width="16" height="16"></rect>
+                <path d="M6.4285717,2.74395752 L8.5,4.39467525 L13.5,4.39467525 L13.5,3.39467514 L8.84971762,3.39467514 L6.77828932,1.74395752 L2.5,1.74395752 L2.5,2.74395752 L6.4285717,2.74395752 Z M1.5,5.39465761 L1.5,13.0000305 C1.5,13.5523157 1.9477157,14.0000305 2.5,14.0000305 L13.5,14.0000305 C14.0522852,14.0000305 14.5,13.55231 14.5,13.0000257 L14.5,7.04537106 C14.5,6.49308634 14.0522852,6.04537106 13.5,6.04537106 L8.17485857,6.04537106 L6.10343027,4.39465332 L2.5,4.39465809 C1.94771576,4.39465809 1.5,4.84237242 1.5,5.39465761 Z M5.75371265,5.39465332 L7.82514095,7.04537106 L13.5,7.04537106 L13.5,13.0000257 L2.5,13.0000305 L2.5,5.39465761 L5.75371265,5.39465332 Z" id="folder-open" fill="#595959"></path>
+            </g>
+        </g>
+    </g>
+</svg>

+ 34 - 0
src/components/StatusTag.vue

@@ -0,0 +1,34 @@
+<template>
+  <a-tag :bordered="false" :color="theme">{{ label }}</a-tag>
+</template>
+
+<script setup lang="ts">
+import { computed } from "vue";
+import $filters from "@/filters";
+
+const configs = {
+  enable: {
+    themeDict: { true: "success", false: "danger" },
+    valFilter: $filters.booleanEnableDisableFilter,
+  },
+};
+type ConfigKeyType = keyof typeof configs;
+
+function getConfig(type: ConfigKeyType) {
+  return configs[type] || { themeDict: {}, valFilter: (val) => val };
+}
+
+const props = defineProps({
+  value: { type: [Boolean, String, Number], default: "" },
+  type: { type: String },
+});
+
+const { themeDict, valFilter } = getConfig(props.type as ConfigKeyType);
+
+const theme = computed(() => {
+  return themeDict[props.value];
+});
+const label = computed(() => {
+  return valFilter(props.value as any);
+});
+</script>

+ 96 - 81
src/features/authManagement/AuthManagement.vue

@@ -1,84 +1,85 @@
 <template>
-  <div>
-    <div class="tw-bg-white tw-p-5 tw-rounded-xl tw-mb-5">
-      <h3 class="section-title">授权信息</h3>
-      <div>
-        <a-form :labelCol="{ style: { width: '150px' } }">
-          <a-form-item label="当前信息" style="margin-bottom: 5px">
-            <span>{{ info.activation }}</span>
-          </a-form-item>
-          <a-form-item label="人数限制" style="margin-bottom: 5px">
-            <span>{{ info.maxCount }}</span>
-          </a-form-item>
-          <a-form-item label="当前人数" style="margin-bottom: 5px">
-            <span>{{ info.onlineCount }}</span>
-          </a-form-item>
-          <a-form-item label="过期时间" style="margin-bottom: 5px">
-            <span>{{ info.expire }}</span>
-          </a-form-item>
-          <a-form-item label="授权模式" style="margin-bottom: 5px">
-            <span>{{ info.type }}</span>
-          </a-form-item>
-        </a-form>
-      </div>
-    </div>
-
-    <div class="tw-bg-white tw-p-5 tw-rounded-xl">
-      <a-form :labelCol="{ style: { width: '150px' } }" style="width: 600px">
-        <a-form-item label="授权模式">
-          <a-select v-model:value="authForm.authType" style="width: 200px">
-            <a-select-option value="ONLINE">在线激活</a-select-option>
-            <a-select-option value="OFFLINE">离线激活</a-select-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item
-          v-show="authForm.authType == 'ONLINE'"
-          label="密匙"
-          prop="accessKey"
-        >
-          <a-input
-            v-model:value="authForm.accessKey"
-            :maxlength="255"
-            allowClear
-          />
-        </a-form-item>
-        <a-form-item
-          v-show="authForm.authType == 'ONLINE'"
-          label="密钥"
-          prop="accessSecret"
+  <a-card title="授权信息">
+    <a-form class="tiny" :labelCol="{ style: { width: '72px' } }">
+      <a-form-item label="当前信息">
+        <a-tag :bordered="false" :color="info.auth ? 'success' : 'default'">{{
+          info.activation
+        }}</a-tag>
+      </a-form-item>
+      <a-form-item label="人数限制">
+        <span>{{ info.maxCount }}</span>
+      </a-form-item>
+      <a-form-item label="当前人数">
+        <span>{{ info.onlineCount }}</span>
+      </a-form-item>
+      <a-form-item label="过期时间">
+        <span>{{ info.expire }}</span>
+      </a-form-item>
+      <a-form-item label="授权模式">
+        <span>{{ info.type }}</span>
+      </a-form-item>
+    </a-form>
+  </a-card>
+  <a-card title="授权设置">
+    <a-form :labelCol="{ style: { width: '72px' } }" style="width: 600px">
+      <a-form-item label="授权模式">
+        <a-select v-model:value="authForm.authType" style="width: 120px">
+          <a-select-option value="ONLINE">在线激活</a-select-option>
+          <a-select-option value="OFFLINE">离线激活</a-select-option>
+        </a-select>
+      </a-form-item>
+      <a-form-item
+        v-show="authForm.authType == 'ONLINE'"
+        label="密匙"
+        prop="accessKey"
+      >
+        <a-input
+          v-model:value="authForm.accessKey"
+          :maxlength="255"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item
+        v-show="authForm.authType == 'ONLINE'"
+        label="密钥"
+        prop="accessSecret"
+      >
+        <a-input
+          v-model:value="authForm.accessSecret"
+          :maxlength="255"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item v-show="authForm.authType == 'OFFLINE'" label="授权文件">
+        <a-upload
+          accept=".lic"
+          :before-upload="customRequest"
+          :showUploadList="false"
+          :disabled="loading"
         >
-          <a-input
-            v-model:value="authForm.accessSecret"
-            :maxlength="255"
-            allowClear
-          />
-        </a-form-item>
-        <a-form-item
-          v-show="authForm.authType == 'OFFLINE'"
-          label="导入授权文件"
+          <a-button>
+            <template #icon>
+              <svg-icon name="file"></svg-icon>
+            </template>
+            选择文件
+          </a-button>
+        </a-upload>
+      </a-form-item>
+      <a-form-item v-if="authForm.authType == 'OFFLINE'" label="硬件信息">
+        <a-button :loading="loading" @click="exportFile">
+          <template #icon>
+            <svg-icon name="export"></svg-icon>
+          </template>
+          导出信息
+        </a-button>
+      </a-form-item>
+      <a-form-item v-else>
+        <a-button type="primary" :loading="loading" @click="submitForm"
+          >保存</a-button
         >
-          <a-upload
-            accept=".lic"
-            :customRequest="customRequest"
-            :showUploadList="false"
-          >
-            <a-button type="primary">选择文件</a-button>
-          </a-upload>
-        </a-form-item>
-        <a-form-item v-if="authForm.authType == 'OFFLINE'" label="硬件信息">
-          <a-button type="primary" @click="exportFile">导出硬件信息</a-button>
-        </a-form-item>
-        <a-form-item v-else>
-          <a-button
-            style="margin-left: 150px"
-            type="primary"
-            @click="submitForm"
-            >保存</a-button
-          >
-        </a-form-item>
-      </a-form>
-    </div>
-  </div>
+      </a-form-item>
+    </a-form>
+  </a-card>
 </template>
 
 <script setup lang="ts">
@@ -90,6 +91,7 @@ import {
 import { message } from "ant-design-vue";
 import { onMounted, reactive } from "vue";
 import { downloadFileURL } from "@/utils/utils";
+import useLoading from "@/hooks/loading";
 
 interface InfoType {
   activation: string;
@@ -97,6 +99,7 @@ interface InfoType {
   type: string;
   maxCount: string;
   onlineCount: number;
+  auth: boolean;
 }
 
 interface AuthFormType {
@@ -111,6 +114,7 @@ let info: InfoType = reactive({
   type: "",
   maxCount: "",
   onlineCount: 0,
+  auth: false,
 });
 
 let authForm: AuthFormType = reactive({
@@ -122,9 +126,11 @@ let authForm: AuthFormType = reactive({
 onMounted(async () => {
   await fetchData();
 });
+const { loading, setLoading } = useLoading();
 
 async function fetchData() {
   const res = await getAuthInfo();
+  info.auth = res.data.auth;
   if (res.data.auth == true) {
     info.activation = "已授权";
     if (info.activation == "已授权" && !res.data.expireTime) {
@@ -143,21 +149,30 @@ async function fetchData() {
     info.activation = "未授权";
   }
 }
+
 async function submitForm() {
-  await onlineAuth(authForm);
+  if (loading.value) return;
+  setLoading(true);
+  await onlineAuth(authForm).catch(() => {});
+  setLoading(false);
   void message.success("操作成功");
 }
 
 // offline-auth
 async function customRequest(data: { file: File }) {
+  setLoading(true);
   let formData = new FormData();
   formData.append("file", data.file);
-  await offlineAuth(formData);
+  await offlineAuth(formData).catch(() => {});
+  setLoading(false);
   void message.success("上传成功!");
   await fetchData();
 }
 
 async function exportFile() {
-  await downloadFileURL("/api/ess/system/auth/device/info");
+  if (loading.value) return;
+  setLoading(true);
+  await downloadFileURL("/api/ess/system/auth/device/info").catch(() => {});
+  setLoading(false);
 }
 </script>

+ 2 - 0
src/features/login/Login.vue

@@ -57,6 +57,8 @@ import type { Rule } from "ant-design-vue/es/form";
 import type { FormInstance } from "ant-design-vue";
 const store = useMainStore();
 
+store.resetInfo();
+
 let rootOrgId = $(useRouteQuery("rootOrgId"));
 const router = useRouter();
 if (!rootOrgId) {

+ 31 - 16
src/features/rootOrg/RootOrg.vue

@@ -1,19 +1,31 @@
 <template>
   <div class="part-box">
-    <a-button style="float: right" @click="handleRootOrgSync">同步</a-button>
+    <a-space class="part-action" :size="12">
+      <a-button type="text" @click="handleRootOrgSync">
+        <template #icon>
+          <svg-icon name="add"></svg-icon>
+        </template>
+        同步
+      </a-button>
+    </a-space>
 
     <a-table
+      class="page-table"
       rowKey="code"
       :columns="columns"
       :data-source="data"
       :pagination="false"
     >
-      <template #enable="{ text }"> </template>
+      <template #enable="{ record }">
+        <status-tag :value="record.enable" type="enable"></status-tag>
+      </template>
       <template #action="{ record }">
-        <span>
-          <a-button @click="showModal(record)">编辑</a-button>
-          <a-button @click="editRootOrgSettings(record.id)">特殊设置</a-button>
-        </span>
+        <div class="action-cell">
+          <a-button type="text" @click="showModal(record)">编辑</a-button>
+          <a-button type="text" @click="editRootOrgSettings(record.id)"
+            >特殊设置</a-button
+          >
+        </div>
       </template>
     </a-table>
 
@@ -22,6 +34,7 @@
       title="学校信息页"
       okText="确定"
       cancelText="取消"
+      :width="438"
       @ok="handleOk"
     >
       <a-form :labelCol="{ span: 5 }">
@@ -48,14 +61,10 @@
 <script setup lang="ts">
 import { getRootOrgList, syncRootOrg, updateRootOrg } from "@/api/rootOrgPage";
 import router from "@/router";
-import { useMainStore } from "@/store";
 import { RootOrg } from "@/types";
 import { message } from "ant-design-vue";
 import { ref, onMounted, reactive } from "vue";
 
-const store = useMainStore();
-store.currentLocation = "基础管理 / 学校管理";
-
 let code = $ref("");
 let name = $ref("");
 let enable = $ref(undefined as undefined | boolean);
@@ -88,25 +97,30 @@ const columns = [
   {
     title: "学校名称",
     dataIndex: "name",
-    width: 150,
-  },
-  {
-    title: "状态",
-    dataIndex: "enable",
-    slots: { customRender: "enable" },
+    minWidth: 150,
   },
   {
     title: "学校域名",
     dataIndex: "domainName",
+    minWidth: 150,
   },
   {
     title: "更新时间",
     dataIndex: "updateTime",
+    width: 180,
+  },
+  {
+    title: "状态",
+    dataIndex: "enable",
+    slots: { customRender: "enable" },
+    width: 120,
   },
   {
     title: "操作",
     key: "action",
     slots: { customRender: "action" },
+    fixed: "right",
+    width: 140,
   },
 ];
 
@@ -133,6 +147,7 @@ const handleOk = async () => {
 };
 
 const rootOrgObj = reactive({
+  id: 0,
   code: "",
   name: "",
   enable: true,

+ 2 - 3
src/features/userManagement/UserManagement.vue

@@ -95,7 +95,7 @@
           <!-- <a>{{ record.rootOrgName }}({{ record.rootOrgCode }})</a> -->
         </template>
         <template #enable="{ text }">
-          <a>{{ $filters.booleanEnableDisableFilter(text) }}</a>
+          <status-tag :value="text" type="enable"></status-tag>
         </template>
         <template #action="{ record }">
           <div class="action-cell">
@@ -218,7 +218,6 @@ import { message, Modal } from "ant-design-vue";
 import { watch, onMounted, ref, reactive, toRaw, h } from "vue";
 
 const store = useMainStore();
-store.currentLocation = "基础管理 / 用户管理";
 
 let rootOrgId = $ref<null | number>(null);
 let role = $ref(undefined as unknown as string);
@@ -293,7 +292,7 @@ const columns = [
     title: "状态",
     dataIndex: "enable",
     slots: { customRender: "enable" },
-    width: 60,
+    width: 100,
   },
   {
     title: "创建时间",

+ 0 - 2
src/main.ts

@@ -19,7 +19,6 @@ import roundNumber from "@/directives/roundNumber";
 import numberToPercent from "@/directives/numberToPercent";
 
 import ECharts from "./plugins/echarts";
-import SvgIcon from "./components/SvgIcon.vue";
 
 import store from "./store";
 
@@ -28,7 +27,6 @@ app.use(router);
 app.use(store);
 app.config.globalProperties.$filters = filters;
 
-app.component("SvgIcon", SvgIcon);
 app.component("VChart", ECharts);
 app.directive("round-number", roundNumber);
 app.directive("number-to-percent", numberToPercent);

+ 3 - 0
src/store/main.ts

@@ -49,6 +49,9 @@ const useMainStore = defineStore("main", {
       setToken(res.token);
       setSessionId(res.identity);
     },
+    resetInfo() {
+      this.$reset();
+    },
   },
   persist: {
     storage: sessionStorage,

+ 33 - 0
src/styles/ant-custom.less

@@ -30,6 +30,19 @@
 .ant-btn + .ant-btn {
   margin-left: 8px;
 }
+.ant-btn {
+  .svg-icon {
+    margin-right: 3px;
+    margin-top: -2px;
+  }
+}
+.ant-btn-default {
+  &:hover {
+    .svg-icon use {
+      fill: var(--color-primary);
+    }
+  }
+}
 
 // ant-modal
 .ant-modal {
@@ -53,3 +66,23 @@
     margin: 0;
   }
 }
+
+// .ant-card
+.ant-card {
+  margin-bottom: 16px;
+  .ant-card-head {
+    padding: 0 16px;
+  }
+  .ant-card-body {
+    padding: 16px;
+  }
+}
+
+// .ant-form
+.ant-form {
+  &.tiny {
+    .ant-form-item {
+      margin: 0;
+    }
+  }
+}

+ 0 - 5
src/styles/base.less

@@ -103,11 +103,6 @@
 .part-action {
   .ant-btn-text {
     padding: 5px 8px;
-
-    .svg-icon {
-      margin-right: 3px;
-      margin-top: -2px;
-    }
   }
   .ant-divider {
     margin: 0;