Browse Source

添加URLLIST

guicheng 8 months ago
parent
commit
bfb5bf61dc

+ 2 - 1
src/api/apiResult.ts

@@ -2,12 +2,13 @@
  * @Author: Gui
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: Please set LastEditors
- * @LastEditTime: 2024-01-03 14:17:14
+ * @LastEditTime: 2024-03-13 17:38:40
  * @Description: kxs files
  * @filePath:
  */
 export type dataResult = {
   status: String;
   message?: String;
+  info?: any;
   data: any;
 };

+ 1 - 1
src/api/utils.ts

@@ -7,4 +7,4 @@
  * @filePath:
  */
 export const baseUrlApi = (url: string) =>
-  `http://mpadminap.kexiaoshuang.com${url}`;
+  `http://test.mpadminap.kexiaoshuang.com${url}`;

+ 38 - 0
src/utils/getUrl/CryptoJS.js

@@ -0,0 +1,38 @@
+/*
+ * @Author: Gui
+ * @Date: 2023-07-04 11:59:05
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2023-07-20 13:34:57
+ * @Description: kxs files
+ * @filePath:
+ */
+import CryptoJS from "crypto-js";
+
+const ShakeDownEncrypt = function (message) {
+  const keyHex = CryptoJS.enc.Utf8.parse("kexiaoshuang.com/Secret");
+  const ivHex = CryptoJS.enc.Utf8.parse("ap.kexiaoshuang.com");
+  const srcs = CryptoJS.enc.Utf8.parse(message);
+  const encrypted = CryptoJS.TripleDES.encrypt(srcs, keyHex, {
+    iv: ivHex,
+    mode: CryptoJS.mode.CBC,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  return encrypted.toString();
+};
+const ShakeDownDecrypt = function (message) {
+  if (!message) {
+    return message;
+  }
+  const keyHex = CryptoJS.enc.Utf8.parse("kexiaoshuang.com/Secret");
+  const ivHex = CryptoJS.enc.Utf8.parse("ap.kexiaoshuang.com");
+  const base64 = CryptoJS.enc.Base64.parse(message);
+  const src = CryptoJS.enc.Base64.stringify(base64);
+  const decrypt = CryptoJS.TripleDES.decrypt(src, keyHex, {
+    iv: ivHex,
+    mode: CryptoJS.mode.CBC,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
+  return decryptedStr.toString();
+};
+export { ShakeDownEncrypt, ShakeDownDecrypt };

+ 50 - 0
src/utils/getUrl/PublicLib.js

@@ -0,0 +1,50 @@
+/*
+ * @Author:
+ * @Date: 2023-12-28 18:10:02
+ * @LastEditors:
+ * @LastEditTime: 2024-03-13 14:44:25
+ * @Description: kxs files
+ * @filePath:
+ */
+import Cookies from "./cookie";
+import { ShakeDownEncrypt, ShakeDownDecrypt } from "./CryptoJS";
+
+var PublicLib = {
+  putCookieInfo: function (option, val) {
+    let Key,
+      Value,
+      Type = 1,
+      Conf;
+    if (!option.Key) {
+      Key = option;
+      Value = val;
+    } else {
+      Key = option.Key;
+      Value = option.Value;
+      Type = option.Type;
+      Conf = option.Conf;
+    }
+    Cookies.set(Key, ShakeDownEncrypt(JSON.stringify(Value)), Type, Conf);
+  },
+
+  getCookieInfo: function (option) {
+    let Key, Type, Conf;
+    if (!option.Key) {
+      Key = option;
+    } else {
+      Key = option.Key;
+      Type = option.Type;
+      Conf = option.Conf;
+    }
+    if (Type == 3) {
+      return new Promise(async (resolve, reject) => {
+        resolve(
+          JSON.parse(ShakeDownDecrypt(await Cookies.get(Key, Type, Conf)))
+        );
+      });
+    } else {
+      return JSON.parse(ShakeDownDecrypt(Cookies.get(Key, Type, Conf)));
+    }
+  }
+};
+export default PublicLib;

+ 185 - 0
src/utils/getUrl/cookie.js

@@ -0,0 +1,185 @@
+class indexedDb {
+  constructor(dbName, version, storeName) {
+    this.dbName = dbName;
+    this.version = version;
+    this.storeName = storeName;
+    this.indexdbrequest = window.indexedDB.open(dbName, version);
+    this.db;
+    this.indexdbrequest.onsuccess = this.onsuccess;
+    this.indexdbrequest.onerror = this.onerror;
+    this.indexdbrequest.onupgradeneeded = this.onupgradeneeded;
+  };
+  onsuccess =  (event) => {
+    this.db = event.target.result; // 数据库对象
+  }
+  onerror =  (event) => {
+    console.log('indexdb error :',event)
+  }
+  onupgradeneeded =  (event) => {
+    // 数据库创建或升级的时候会触发
+    this.db = event.target.result; // 数据库对象
+    let objectStore;
+    if (!this.db.objectStoreNames.contains(this.storeName)) {
+      objectStore = this.db.createObjectStore(this.storeName, { keyPath: "id" }); // 创建表
+      // objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段
+    }
+  }
+  // 添加数据
+  addData(data) {
+    return new Promise((resolve, reject) => {
+      try{
+        const req = this.db
+                    .transaction([this.storeName], "readwrite") // 事务对象 指定表格名称和操作模式("只读"或"读写")
+                    .objectStore(this.storeName) // 仓库对象
+                    .add(data);
+        // 操作成功
+        req.onsuccess = function (event) {
+            resolve({code: 200, success: true, data: req.result, msg: '数据添加成功!'})
+        }
+        // 操作失败
+        req.onerror = function (event) {
+            let data = {code: -1, success: false, data: null, msg: '数据添加失败!'}
+            resolve(data)
+        }
+      }catch(err){
+        resolve({code: -1, success: false, data: null, msg: '数据获取失败!'})
+      }
+    })
+  }
+
+  // 根据id获取数据
+  getDataByKey(key) {
+    return new Promise((resolve, reject) => {
+      try{
+        const req = this.db
+                    .transaction([this.storeName])
+                    .objectStore(this.storeName)
+                    .get(key);
+        // 操作成功
+        req.onsuccess = function (event) {
+          resolve({code: 200, success: true, data: req.result, msg: '数据获取成功!'})
+        }
+        // 操作失败
+        req.onerror = function (event) {
+          resolve({code: -1, success: false, data: null, msg: '数据获取失败!'})
+        }
+      }catch(err){
+        resolve({code: -1, success: false, data: {}, msg: '数据获取失败!'})
+      }
+    })
+  }
+
+  // 根据id修改数据
+  updateDBfunction (data) {
+    return new Promise((resolve, reject) => {
+      try{
+        const req = this.db
+                    .transaction([this.storeName], 'readwrite')
+                    .objectStore(this.storeName)
+                    .put(data)
+        // 操作成功
+        req.onsuccess = function (event) {
+          resolve({code: 200, success: true, data: null, msg: '数据更新成功!'})
+        }
+        // 操作失败
+        req.onerror = function (event) {
+          resolve({code: -1, success: false, data: null, msg: '数据更新失败!'})
+        }
+      }catch(err){
+        resolve({code: -1, success: false, data: null, msg: '数据获取失败!'})
+      }
+    })
+  }
+
+  // 根据id删除数据
+  deleteDB(id) {
+    return new Promise((resolve, reject) => {
+      try{
+      let req = this.db
+        .transaction([this.storeName], "readwrite")
+        .objectStore(this.storeName)
+        .delete(id);
+        // 操作成功
+        req.onsuccess = function (event) {
+            resolve({code: 200, success: true, data: null, msg: '数据删除成功!'})
+        }
+        // 操作失败
+        req.onerror = function (event) {
+            let data = {code: -1, success: false, data: null, msg: '数据删除失败!'}
+            resolve(data)
+        }
+      }catch(err){
+        resolve({code: -1, success: false, data: null, msg: '数据获取失败!'})
+      }
+    })
+  }
+}
+const local = {
+  get:function(e){
+    return localStorage.getItem(e);
+  },
+  set:function(key,val){
+    localStorage.setItem(key,val);
+  }
+};
+
+const cookie = {
+  get:function(name) {
+    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
+    if (arr = document.cookie.match(reg)) return unescape(arr[2]);
+    else return null;
+  },
+  set:function(name, value,date = 30) {
+    var Days = date; // 设置有效期
+    var exp = new Date();
+    exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
+    document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
+  },
+  del: function delCookie(name) { 
+    var exp = new Date();
+    exp.setTime(exp.getTime() - 1);
+    var cval = getCookie(name);
+    if (cval != null) document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
+  },
+};
+
+export default {
+  get:function(name,type = 1,conf = {dbname:'dbname',version:1,table:'cookies'}) {
+    switch(type){
+      case 1:
+      return cookie.get(name);
+      case 2:
+      return local.get(name);
+      case 3:
+        return new Promise((resolve, reject) => {
+        const db = new indexedDb(conf.dbname,conf.version,conf.table);
+        setTimeout(async ()=>{
+          const res = await db.getDataByKey(name);
+          resolve(res.data && res.data.data ? res.data.data : null); 
+        },50);
+      });
+    }
+  },
+  set:function(name, value,type = 1,conf = {dbname:'dbname',version:1,table:'cookies'}) {
+    switch(type){
+      case 1:
+      return cookie.set(name,value);
+      case 2:
+      return local.set(name,value);
+      case 3:
+        return new Promise(async (resolve, reject) => {
+        const db = await new indexedDb(conf.dbname,conf.version,conf.table);
+        setTimeout(async ()=>{
+          const res = await db.getDataByKey(name);
+          if(res.data){
+            const updata = await db.updateDBfunction({data:value,'id':name});
+            resolve(updata.data);
+          }else{
+            const adddata = await db.addData({data:value,'id':name});
+            resolve(adddata.data);
+          }
+        },500);
+      });
+    }
+  },
+}

+ 137 - 0
src/utils/getUrl/getUrl.js

@@ -0,0 +1,137 @@
+/*
+ * @Author:
+ * @Date: 2024-01-04 15:04:20
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2024-03-13 17:30:17
+ * @Description: kxs files
+ * @filePath:
+ */
+import axios from "axios";
+import PublicLib from "./PublicLib";
+import CryptoJS from "crypto-js";
+var request = axios.create({
+  // 请求超时时间
+  timeout: 5000
+});
+
+// 加密函数
+const encryptByDES = function (message) {
+  var keyHex = CryptoJS.enc.Utf8.parse("&L^kg4N9");
+  var ivHex = CryptoJS.enc.Utf8.parse("&L^kg4N9");
+  const encrypted = CryptoJS.DES.encrypt(message, keyHex, {
+    iv: ivHex,
+    mode: CryptoJS.mode.CBC,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  return encrypted.toString();
+};
+
+// 请求方法
+const postRequest = (url, params) => {
+  console.log("请求参数:", params);
+  let param = new URLSearchParams();
+  param.append("value", encryptByDES(JSON.stringify(params)));
+  return request({
+    url,
+    method: "post",
+    headers: {
+      "Content-Type": "application/x-www-form-urlencoded"
+    },
+    data: param
+  });
+};
+
+// 更新本地URL列表
+const putURL = list => {
+  PublicLib.putCookieInfo({
+    Key: "URL_INTERFACE",
+    Value: list,
+    Type: 3,
+    Conf: { dbname: "PROJECT_INTERFACE", version: 1, table: "INTERFACE_List" }
+  });
+};
+
+// 获取本地URL列表
+const getURL = () => {
+  return PublicLib.getCookieInfo({
+    Key: "URL_INTERFACE",
+    Type: 3,
+    Conf: { dbname: "PROJECT_INTERFACE", version: 1, table: "INTERFACE_List" }
+  });
+};
+
+// URL列表资源
+const getAllPlate = () => {
+  return new Promise(async (resolve, reject) => {
+    postRequest("http://test.config.kexiaoshuang.com/api/apiinfo/groups", {
+      key: "kxs#2024"
+    })
+      .then(async res => {
+        resolve(res.data.data);
+      })
+      .catch(err => {
+        throw Error(err);
+      });
+  });
+};
+
+// 比对版本号且做更新
+const getGroupUrl = async (checkPlate = []) => {
+  return new Promise(async (resolve, reject) => {
+    const URLLIST = (await getURL()) || {};
+    let parameters = { userId: 1, groups: []  };
+    if (checkPlate.length == 0) {
+      checkPlate = await getAllPlate();
+    }
+    parameters.groups = checkPlate.map(item => {
+      return {
+        name: item,
+        version: URLLIST && URLLIST[item] ? URLLIST[item].groupVersion : 0
+      };
+    });
+    const timer = setTimeout(() => {
+      resolve(URLLIST);
+      throw Error(
+        "GET URLLIST FAIL, BECAUSE INTERFACE IS TIMEOUT, NOW RETURN LOCAL URLLIST"
+      );
+    }, 5000);
+    postRequest(
+      "http://test.config.kexiaoshuang.com/api/apiinfo/list",
+      parameters
+    )
+      .then(async res => {
+        clearTimeout(timer);
+        if (Object.keys(URLLIST).length === 0) {
+          putURL(res.data.data);
+          resolve(res.data.data);
+        } else {
+          if (res.data.status == "1") {
+            // 全部接口循环读取更新
+            const onlineurl = res.data.data;
+            for (let key in onlineurl) {
+              if (
+                URLLIST[key] &&
+                onlineurl[key].groupVersion > URLLIST[key].groupVersion
+              ) {
+                URLLIST[key] = onlineurl[key];
+                console.log("更新列表:", key);
+                putURL(URLLIST);
+              }
+            }
+            resolve(URLLIST);
+          } else {
+            resolve(URLLIST);
+            throw Error(
+              "GET URLLIST FAIL, BECAUSE INTERFACE STATUS IS ERROR, NOW RETURN LOCAL URLLIST"
+            );
+          }
+        }
+      })
+      .catch(err => {
+        resolve(URLLIST);
+        throw Error(err);
+      });
+  });
+};
+
+export { getGroupUrl };

+ 32 - 33
src/utils/http/index.ts

@@ -2,7 +2,7 @@
  * @Author: Gui
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: Please set LastEditors
- * @LastEditTime: 2023-07-26 16:38:24
+ * @LastEditTime: 2024-03-13 17:37:52
  * @Description: kxs files
  * @filePath:
  */
@@ -95,40 +95,40 @@ class PureHttp {
         return whiteList.some(v => config.url.indexOf(v) > -1)
           ? config
           : new Promise(resolve => {
-              const data = getToken();
-              if (data) {
-                const now = new Date().getTime();
-                const expired = parseInt(data.expires) - now <= 0;
-                if (expired) {
-                  if (!PureHttp.isRefreshing) {
-                    PureHttp.isRefreshing = true;
-                    // token过期刷新
-                    // apiToken
-                    // apiTokenExpiredDate
-                    // refreshToken
-                    useUserStoreHook()
-                      .handRefreshToken({ refreshToken: data.refreshToken })
-                      .then(res => {
-                        const token = res.data.apiToken;
-                        config.headers["Authorization"] = formatToken(token);
-                        PureHttp.requests.forEach(cb => cb(token));
-                        PureHttp.requests = [];
-                      })
-                      .finally(() => {
-                        PureHttp.isRefreshing = false;
-                      });
-                  }
-                  resolve(PureHttp.retryOriginalRequest(config));
-                } else {
-                  config.headers["Authorization"] = formatToken(
-                    data.accessToken
-                  );
-                  resolve(config);
+            const data = getToken();
+            if (data) {
+              const now = new Date().getTime();
+              const expired = parseInt(data.expires) - now <= 0;
+              if (expired) {
+                if (!PureHttp.isRefreshing) {
+                  PureHttp.isRefreshing = true;
+                  // token过期刷新
+                  // apiToken
+                  // apiTokenExpiredDate
+                  // refreshToken
+                  useUserStoreHook()
+                    .handRefreshToken({ refreshToken: data.refreshToken })
+                    .then(res => {
+                      const token = res.data.apiToken;
+                      config.headers["Authorization"] = formatToken(token);
+                      PureHttp.requests.forEach(cb => cb(token));
+                      PureHttp.requests = [];
+                    })
+                    .finally(() => {
+                      PureHttp.isRefreshing = false;
+                    });
                 }
+                resolve(PureHttp.retryOriginalRequest(config));
               } else {
+                config.headers["Authorization"] = formatToken(
+                  data.accessToken
+                );
                 resolve(config);
               }
-            });
+            } else {
+              resolve(config);
+            }
+          });
       },
       error => {
         return Promise.reject(error);
@@ -188,7 +188,7 @@ class PureHttp {
   public request<T>(
     method: RequestMethods,
     url: string,
-    param?: AxiosRequestConfig,
+    param?: any,
     axiosConfig?: PureHttpRequestConfig
   ): Promise<T> {
     const config = {
@@ -196,7 +196,6 @@ class PureHttp {
       url,
       ...param,
       headers: {
-        // 	'Access-Control-Allow-Origin':'*'
         "Content-Type": "application/x-www-form-urlencoded"
       },
       ...axiosConfig

+ 7 - 1
src/views/Template/template/components/add/index.vue

@@ -2,7 +2,7 @@
  * @Author: 
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: Please set LastEditors
- * @LastEditTime: 2024-03-08 17:43:01
+ * @LastEditTime: 2024-03-13 17:45:49
  * @Description: kxs files
  * @filePath: 
 -->
@@ -17,6 +17,12 @@ import { inject, ref } from "vue";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { postUserList } from "@/api/system";
 import { ElMessage, ElMessageBox } from "element-plus";
+import { http } from "@/utils/http";
+import { dataResult } from "@/api/apiResult";
+// 获取URLLIST
+import { getGroupUrl } from "@/utils/getUrl/getUrl"
+// 获取当前板块接口列表
+const UserUrl = await getGroupUrl(['User']);
 import Upload from "@iconify-icons/ri/upload-2-fill"
 import Close from "@iconify-icons/ri/close-fill"
 const props = defineProps<{

+ 13 - 9
src/views/Template/template/components/edit/index.vue

@@ -2,7 +2,7 @@
  * @Author: 
  * @Date: 2023-03-01 19:20:44
  * @LastEditors: Please set LastEditors
- * @LastEditTime: 2024-03-08 18:01:37
+ * @LastEditTime: 2024-03-13 18:00:16
  * @Description: kxs files
  * @filePath: 
 -->
@@ -19,6 +19,12 @@ import { postUserList } from "@/api/system";
 import { ElMessage, ElMessageBox } from "element-plus";
 import Upload from "@iconify-icons/ri/upload-2-fill"
 import Close from "@iconify-icons/ri/close-fill"
+import { http } from "@/utils/http";
+import { dataResult } from "@/api/apiResult";
+// 获取URLLIST
+import { getGroupUrl } from "@/utils/getUrl/getUrl"
+// 获取当前板块接口列表
+const UserUrl = await getGroupUrl(['User']);
 const props = defineProps<{
   editVisible: {
     type: Boolean;
@@ -29,7 +35,8 @@ const props = defineProps<{
     default: 50;
   };
   formData: {
-    type: Object;
+    id: any;
+    type: any;
     default: {};
   };
 }>();
@@ -50,7 +57,7 @@ const optionList = [
 const activeId = ref('1')
 // 提交函数
 const submit = async () => {
-  const { status, info }: any = await postUserList(UpdateForm.value);
+  const { status, info }: any = http.request<dataResult>(UserUrl.User.userSearch.method, UserUrl.User.userSearch.url, UpdateForm.value);
   if (status === "1") {
     ElMessage({
       message: "修改成功",
@@ -126,14 +133,11 @@ const openVisible = async () => {
     //- 无选项卡模板
     el-form(:model='UpdateForm' label-position="right" label-width="100px")
       el-form-item(label='账户名称' prop="RealName")
-        el-input(v-model='UpdateForm.RealName' autocomplete='off' class="!w-[230px]"
-          placeholder="请输入账户名称")
+        el-input(v-model='UpdateForm.RealName' autocomplete='off' class="!w-[230px]" placeholder="请输入账户名称")
       el-form-item(label='用户名' prop="AdminName")
-        el-input(v-model='UpdateForm.AdminName' autocomplete='off' class="!w-[230px]"
-          placeholder="请输入用户名")
+        el-input(v-model='UpdateForm.AdminName' autocomplete='off' class="!w-[230px]" placeholder="请输入用户名")
       el-form-item(label='密码' prop="PassWord")
-        el-input(v-model='UpdateForm.PassWord' autocomplete='off' class="!w-[230px]"
-          placeholder="请输入密码")
+        el-input(v-model='UpdateForm.PassWord' autocomplete='off' class="!w-[230px]" placeholder="请输入密码")
       el-form-item(label="角色:", prop="RoleId")
         el-select(
           v-model="UpdateForm.RoleId",

+ 28 - 3
src/views/Template/template/hook.tsx

@@ -2,11 +2,35 @@ import { getRoleList } from "@/api/system";
 import { type PaginationProps } from "@pureadmin/table";
 import { ElMessage, ElMessageBox } from "element-plus";
 import { reactive, ref, computed, onMounted } from "vue";
-
+// 获取URLLIST
+import { getGroupUrl } from "@/utils/getUrl/getUrl"
+import { http } from "@/utils/http";
+import { dataResult } from "@/api/apiResult";
+// 获取当前板块接口列表
+const UserUrl = await getGroupUrl(['User']);
 export function useUser() {
+  // 搜索表单参数
   let form = reactive({
     Name: ""
   });
+  // 级联选择器参数
+  const optionList = ref([{
+    value: 'resource', label: 'Resource',
+    children: [
+      {
+        value: 'axure',
+        label: 'Axure Components',
+      },
+      {
+        value: 'sketch',
+        label: 'Sketch Templates',
+      },
+      {
+        value: 'docs',
+        label: 'Design Documentation',
+      },
+    ],
+  }])
   const dataList = ref([]);
   const loading = ref(false);
   const dialogAddVisible = ref(false);
@@ -65,7 +89,7 @@ export function useUser() {
       });
     };
     loading.value = true;
-    const { data, other }: any = await getRoleList({ ...form, page_size: pagination.pageSize, page_num: pagination.currentPage });
+    const { data, other }: any = http.request<dataResult>(UserUrl.User.userSearch.method, UserUrl.User.userSearch.url, { ...form, page_size: pagination.pageSize, page_num: pagination.currentPage });
     dataList.value = data;
     pagination.total = other.Count;
     setTimeout(() => {
@@ -88,7 +112,7 @@ export function useUser() {
         type: "warning"
       }
     ).then(async () => {
-      const { status, info } = await deleteUserList({ SysAdminId: row.Id });
+      const { status, info } = await http.request<dataResult>(UserUrl.User.userDelete.method, UserUrl.User.userDelete.url, { SysAdminId: row.Id });
       if (status === "1") {
         ElMessage({
           message: "删除成功",
@@ -132,5 +156,6 @@ export function useUser() {
     addVisible,
     editVisible,
     editFormData,
+    optionList,
   };
 }

+ 46 - 2
src/views/Template/template/index.vue

@@ -33,6 +33,7 @@ const {
   addVisible,
   editVisible,
   editFormData,
+  optionList,
 } = useUser();
 // 关闭修改
 const closeEditVisible = () => {
@@ -58,13 +59,28 @@ provide('closeAddVisible', closeAddVisible)
       :rules="rules",
       class="w-[99/100]"
     )
-      el-form-item(label="搜索内容:", prop="searchMain")
+      el-form-item(label="搜索内容:", prop="searchMain")
         el-input(
           v-model="form.searchMain",
           placeholder="请输入搜索内容",
           clearable,
           class="!w-[230px]"
         )
+      el-form-item(label="级联选择框:", prop="searchMain")
+        el-cascader(
+          v-model="form.searchMain" 
+          :options="optionList" 
+          class="!w-[230px]"
+          clearable)
+      el-form-item(label="时间选择器:", prop="searchMain")
+        el-date-picker(
+          v-model="form.searchMain"
+          type="daterange"
+          class="!w-[230px]"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+          :default-value="[new Date(2010, 9, 1), new Date(2010, 10, 1)]"
+        )
       el-form-item
         el-button(
           type="primary",
@@ -131,4 +147,32 @@ provide('closeAddVisible', closeAddVisible)
                     
 </template>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+:deep(.el-dropdown-menu__item i) {
+  margin: 0;
+}
+
+:deep(.el-form-item__label) {
+  font-weight: 700;
+}
+
+:deep(.el-pagination) {
+  flex-flow: wrap;
+}
+
+:deep(.is-draggable) {
+  max-height: 80vh;
+  overflow: auto;
+}
+
+:deep(.el-dialog__header) {
+  position: sticky;
+  top: 0;
+  z-index: 2;
+  background: #fff;
+}
+
+:deep(.el-descriptions__header) {
+  margin: 16px 0 !important;
+}
+</style>

+ 7 - 7
src/views/login/index.vue

@@ -180,7 +180,7 @@ watch(imgCode, value => {
             </el-dropdown-item>
           </el-dropdown-menu>
         </template>
-      </el-dropdown> -->
+</el-dropdown> -->
     </div>
     <div class="login-container">
       <div class="img">
@@ -200,12 +200,12 @@ watch(imgCode, value => {
           <el-form v-if="currentPage === 0" ref="ruleFormRef" :model="ruleForm" :rules="loginRules" size="large">
             <Motion :delay="100">
               <el-form-item :rules="[
-                {
-                  required: true,
-                  message: transformI18n($t('login.usernameReg')),
-                  trigger: 'blur'
-                }
-              ]" prop="username">
+          {
+            required: true,
+            message: transformI18n($t('login.usernameReg')),
+            trigger: 'blur'
+          }
+        ]" prop="username">
                 <el-input clearable v-model="ruleForm.username" :placeholder="t('login.username')"
                   :prefix-icon="useRenderIcon(User)" />
               </el-form-item>