Selaa lähdekoodia

Merge commit 'refs/pull/510/head' of https://gitee.com/zuohuaijun/Admin.NET into next

zuohuaijun 3 vuotta sitten
vanhempi
commit
8e688e12c2

+ 24 - 24
Admin.NET/Admin.NET.Application/Configuration/App.json

@@ -1,29 +1,29 @@
 {
-    "$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
+  "$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
 
-    "Urls": "https://*:5005",
+  //"Urls": "https://*:5005",
 
-    "AllowedHosts": "*",
+  "AllowedHosts": "*",
 
-    "AppSettings": {
-        "InjectSpecificationDocument": true // 生产环境是否开启Swagger
-    },
-    "DynamicApiControllerSettings": {
-        "LowercaseRoute": false,
-        "KeepName": true,
-        "AsLowerCamelCase": true // 小驼峰路由路径
-    },
-    "FriendlyExceptionSettings": {
-        "DefaultErrorMessage": "系统异常,请联系管理员",
-        "ThrowBah": true,
-        "LogError": false // 是否输出异常日志,默认true
-    },
-    "LocalizationSettings": {
-        "SupportedCultures": [ "zh-CN", "en-US" ], // 语言列表
-        "DefaultCulture": "zh-CN" // 默认语言
-    },
-    "CorsAccessorSettings": {
-        "WithExposedHeaders": [ "Content-Disposition" ], // 如果前端不代理且是axios请求
-        "SignalRSupport": true // 启用 SignalR 跨域支持
-    }
+  "AppSettings": {
+    "InjectSpecificationDocument": true // 生产环境是否开启Swagger
+  },
+  "DynamicApiControllerSettings": {
+    "LowercaseRoute": false,
+    "KeepName": true,
+    "AsLowerCamelCase": true // 小驼峰路由路径
+  },
+  "FriendlyExceptionSettings": {
+    "DefaultErrorMessage": "系统异常,请联系管理员",
+    "ThrowBah": true,
+    "LogError": false // 是否输出异常日志,默认true
+  },
+  "LocalizationSettings": {
+    "SupportedCultures": [ "zh-CN", "en-US" ], // 语言列表
+    "DefaultCulture": "zh-CN" // 默认语言
+  },
+  "CorsAccessorSettings": {
+    "WithExposedHeaders": [ "Content-Disposition" ], // 如果前端不代理且是axios请求
+    "SignalRSupport": true // 启用 SignalR 跨域支持
+  }
 }

+ 9 - 9
Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs

@@ -327,7 +327,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Name = className + "Management",
             Type = MenuTypeEnum.Menu,
             Path = pPath + "/" + className.ToLower(),
-            Component = "/main/" + className + "/index",
+            Component = "/main/" + className[..1].ToLower() + className[1..] + "/index",
         };
         {   // 如果之前存在那么就删除本级和下级
             var list = await _db.Queryable<SysMenu>().Where(e => e.Title == menuType1.Title && e.Type == menuType1.Type).ToListAsync();
@@ -353,7 +353,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Pid = pid1,
             Title = busName + "查询",
             Type = MenuTypeEnum.Btn,
-            Permission = className + ":page",
+            Permission = className[..1].ToLower() + className[1..] + ":page",
         };
 
         // 按钮-detail
@@ -362,7 +362,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Pid = pid1,
             Title = busName + "详情",
             Type = MenuTypeEnum.Btn,
-            Permission = className + ":detail",
+            Permission = className[..1].ToLower() + className[1..] + ":detail",
         };
 
         // 按钮-add
@@ -371,7 +371,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Pid = pid1,
             Title = busName + "增加",
             Type = MenuTypeEnum.Btn,
-            Permission = className + ":add",
+            Permission = className[..1].ToLower() + className[1..] + ":add",
         };
 
         // 按钮-delete
@@ -380,7 +380,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Pid = pid1,
             Title = busName + "删除",
             Type = MenuTypeEnum.Btn,
-            Permission = className + ":delete",
+            Permission = className[..1].ToLower() + className[1..] + ":delete",
         };
 
         // 按钮-edit
@@ -389,7 +389,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             Pid = pid1,
             Title = busName + "编辑",
             Type = MenuTypeEnum.Btn,
-            Permission = className + ":edit",
+            Permission = className[..1].ToLower() + className[1..] + ":edit",
         };
 
         var menuList = new List<SysMenu>() { menuType2, menuType2_1, menuType2_2, menuType2_3, menuType2_4 };
@@ -428,9 +428,9 @@ public class SysCodeGenService : IDynamicApiController, ITransient
         var outputPath = Path.Combine(backendPath, "Dto", input.TableName + "Output.cs");
         var viewPath = Path.Combine(backendPath, "Dto", input.TableName + "Dto.cs");
         var frontendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "views", "main");
-        var indexPath = Path.Combine(frontendPath, input.TableName, "index.vue");
-        var formModalPath = Path.Combine(frontendPath, input.TableName, "component", "editDialog.vue");
-        var apiJsPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "api", "main", input.TableName + ".ts");
+        var indexPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "index.vue");//
+        var formModalPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "component", "editDialog.vue");
+        var apiJsPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "api", "main", input.TableName[..1].ToLower() + input.TableName[1..] + ".ts");
 
         return new List<string>()
         {

+ 2 - 2
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Entity.cs.vm

@@ -7,8 +7,8 @@ namespace Admin.NET.Application.Entity
      /// <summary>
      /// @(@Model.Description)
      /// </summary>
-      [SugarTable("@(@Model.TableName)","@(@Model.Description)"))]
-      [Tenant(@(@Model.ConfigId)]
+      [SugarTable("@(@Model.TableName)","@(@Model.Description)")]
+      [Tenant("@(@Model.ConfigId)")]
       public class @(@Model.EntityName) @Model.BaseClassName
       {
 @foreach (var column in Model.TableField){

+ 6 - 6
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Manage.js.vm

@@ -1,14 +1,14 @@
 import request from '/@@/utils/request';
 enum Api {
-  Add@(@Model.ClassName) = '/@(@Model.ClassName)/add',
-  Delete@(@Model.ClassName) = '/@(@Model.ClassName)/delete',
-  Update@(@Model.ClassName) = '/@(@Model.ClassName)/edit',
-  Get@(@Model.ClassName)Page = '/@(@Model.ClassName)/page',
+  Add@(@Model.ClassName) = '/@(@Model.LowerClassName)/add',
+  Delete@(@Model.ClassName) = '/@(@Model.LowerClassName)/delete',
+  Update@(@Model.ClassName) = '/@(@Model.LowerClassName)/edit',
+  Get@(@Model.ClassName)Page = '/@(@Model.LowerClassName)/page',
   @foreach (var column in Model.TableField){
 if(@column.EffectType == "fk"){
-  @:Get@(@column.FkEntityName)Dropdown = '/@(@Model.ClassName)/@(@column.FkEntityName)Dropdown',
+  @:Get@(@column.FkEntityName)Dropdown = '/@(@Model.LowerClassName)/@(@column.FkEntityName)Dropdown',
 }else if(@column.EffectType == "ApiTreeSelect"){
-  @:Get@(@column.FkEntityName)Tree = '/@(@Model.ClassName)/@(@column.FkEntityName)Tree',
+  @:Get@(@column.FkEntityName)Tree = '/@(@Model.LowerClassName)/@(@column.FkEntityName)Tree',
 }
 }
 }

+ 8 - 8
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm

@@ -20,7 +20,7 @@ public class @(@Model.ClassName)Service : IDynamicApiController, ITransient
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [HttpGet("/@Model.ClassName/page")]
+    [HttpGet("/@Model.LowerClassName/page")]
     public async Task<dynamic> Page([FromQuery] @(@Model.ClassName)Input input)
     {
         var query= _rep.Context.Queryable<@(@Model.ClassName)>()
@@ -80,7 +80,7 @@ if (@column.QueryWhether == "Y"){
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [HttpPost("/@Model.ClassName/add")]
+    [HttpPost("/@Model.LowerClassName/add")]
     public async Task Add(Add@(@Model.ClassName)Input input)
     {
         var entity = input.Adapt<@(@Model.ClassName)>();
@@ -92,7 +92,7 @@ if (@column.QueryWhether == "Y"){
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [HttpPost("/@Model.ClassName/delete")]
+    [HttpPost("/@Model.LowerClassName/delete")]
     public async Task Delete(Delete@(@Model.ClassName)Input input)
     {
 @foreach (var column in Model.TableField){
@@ -108,7 +108,7 @@ if (@column.ColumnKey == "True"){
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [HttpPost("/@Model.ClassName/edit")]
+    [HttpPost("/@Model.LowerClassName/edit")]
     public async Task Update(Update@(@Model.ClassName)Input input)
     {
         var entity = input.Adapt<@(@Model.ClassName)>();
@@ -120,7 +120,7 @@ if (@column.ColumnKey == "True"){
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [HttpGet("/@Model.ClassName/detail")]
+    [HttpGet("/@Model.LowerClassName/detail")]
     public async Task<@(@Model.ClassName)> Get([FromQuery] Querye@(@Model.ClassName)Input input)
     {
 @foreach (var column in Model.TableField){
@@ -135,14 +135,14 @@ if (@column.ColumnKey == "True"){
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [HttpGet("/@Model.ClassName/list")]
+    [HttpGet("/@Model.LowerClassName/list")]
     public async Task<dynamic> List([FromQuery] @(@Model.ClassName)Input input)
     {
         return await _rep.AsQueryable().ToListAsync();
     }
 @foreach (var column in Model.TableField){
 if(@column.EffectType == "fk"){
-    @:[HttpGet("/@(@Model.ClassName)/@(@column.FkEntityName)Dropdown")]
+    @:[HttpGet("/@(@Model.LowerClassName)/@(@column.FkEntityName)Dropdown")]
     @:public async Task<dynamic> @(@column.FkEntityName)Dropdown()
     @:{
         @:return await _rep.Context.Queryable<@(@column.FkEntityName)>()
@@ -159,7 +159,7 @@ if(@column.EffectType == "fk"){
 
 @foreach (var column in Model.TableField){
 if(@column.EffectType == "ApiTreeSelect"){
-    @:[HttpGet("/@(@Model.ClassName)/@(@column.FkEntityName)Tree")]
+    @:[HttpGet("/@(@Model.LowerClassName)/@(@column.FkEntityName)Tree")]
     @:public async Task<dynamic> @(@column.FkEntityName)Tree()
     @:{
         @:return await _rep.Context.Queryable<@(@column.FkEntityName)TreeOutput>().ToTreeAsync(u => u.Children, u => u.@(@column.PidColumn), 0);

+ 38 - 39
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/editDialog.vue.vm

@@ -1,6 +1,6 @@
 <template>
-	<div class="@(@Model.ClassName)-container">
-    <el-dialog v-model="isShowDialog" :title="props.title" :width="700" draggable>
+	<div class="@(@Model.LowerClassName)-container">
+		<el-dialog v-model="isShowDialog" :title="props.title" :width="700" draggable="">
 			<el-form :model="ruleForm" ref="ruleFormRef" size="default" label-width="100px" :rules="rules">
 				<el-row :gutter="35">
 					@foreach (var column in Model.TableField){
@@ -24,7 +24,7 @@
 					}else if(@column.EffectType == "Input"){
 					@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						@:<el-form-item label="@column.ColumnComment" prop="@(@column.LowerColumnName)">
-							@:<el-input v-model="ruleForm.@(@column.LowerColumnName)" placeholder="请输入@(@column.ColumnComment)" clearable=""/>
+							@:<el-input v-model="ruleForm.@(@column.LowerColumnName)" placeholder="请输入@(@column.ColumnComment)" clearable="" />
 							@:
 						</el-form-item>
 						@:
@@ -32,7 +32,7 @@
 					}else if(@column.EffectType == "InputNumber"){
 					@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						@:<el-form-item label="@column.ColumnComment" prop="@(@column.LowerColumnName)">
-							@:<el-input-number v-model="ruleForm.@(@column.LowerColumnName)" placeholder="请输入@(@column.ColumnComment)" clearable=""/>
+							@:<el-input-number v-model="ruleForm.@(@column.LowerColumnName)" placeholder="请输入@(@column.ColumnComment)" clearable="" />
 							@:
 						</el-form-item>
 						@:
@@ -40,7 +40,7 @@
 					}else if(@column.EffectType == "InputTextArea"){
 					@:<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
 						@:<el-form-item label="@column.ColumnComment" prop="@(@column.LowerColumnName)">
-							@:<el-input v-model="ruleForm.@(@column.LowerColumnName)" placeholder="请输入@(@column.ColumnComment)" type="textarea" clearable=""/>
+							@:<el-input v-model="ruleForm.@(@column.LowerColumnName)" placeholder="请输入@(@column.ColumnComment)" type="textarea" clearable="" />
 							@:
 						</el-form-item>
 						@:
@@ -78,7 +78,7 @@
 					}else if(@column.EffectType == "DatePicker"){
 					@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						@:<el-form-item label="@column.ColumnComment" prop="@(@column.LowerColumnName)">
-							@:<el-date-picker v-model="ruleForm.@(@column.LowerColumnName)" type="date" placeholder="@(@column.ColumnComment)"  />
+							@:<el-date-picker v-model="ruleForm.@(@column.LowerColumnName)" type="date" placeholder="@(@column.ColumnComment)" />
 							@:
 						</el-form-item>
 						@:
@@ -88,9 +88,9 @@
 					}else{
 
 					}
-        }
-      }
-    }
+					}
+					}
+					}
 				</el-row>
 			</el-form>
 			<template #footer="">
@@ -104,34 +104,34 @@
 </template>
 
 <script lang="ts" setup>
-import { ref } from "vue";
-import { ElMessage } from "element-plus";
-import type { FormRules } from "element-plus";
-import { add@(@Model.ClassName), update@(@Model.ClassName) } from "/@@/api/main/@(@Model.ClassName)";
-@foreach (var column in Model.TableField){
-  if(@column.EffectType == "fk"){
-    @:import { get@(@column.FkEntityName)Dropdown } from '/@@/api/main/@(@Model.ClassName)';
-  }
-}
-@foreach (var column in Model.TableField){
-  if(@column.EffectType == "Select"){
-    @:import { getDictDataDropdown } from '/@@/api/system/admin';
-  }
-}
-//父级传递来的参数
-var props = defineProps({
-  title: {
-    type: String,
-    default: "",
-  },
-});
-//父级传递来的函数,用于回调
-const emit = defineEmits(["reloadTable"]);
-const ruleFormRef = ref();
-const isShowDialog = ref(false);
-const ruleForm = ref<any>({});
-//自行删除非必填规则
-const rules = ref<FormRules>({
+	import { ref } from "vue";
+	import { ElMessage } from "element-plus";
+	import type { FormRules } from "element-plus";
+	import { add@(@Model.ClassName), update@(@Model.ClassName) } from "/@@/api/main/@(@Model.LowerClassName)";
+	@foreach (var column in Model.TableField){
+	if(@column.EffectType == "fk"){
+	@:import { get@(@column.FkEntityName)Dropdown } from '/@@/api/main/@(@Model.LowerClassName)';
+	}
+	}
+	@foreach (var column in Model.TableField){
+	if(@column.EffectType == "Select"){
+	@:import { getDictDataDropdown } from '/@@/api/system/admin';
+	}
+	}
+	//父级传递来的参数
+	var props = defineProps({
+	title: {
+	type: String,
+	default: "",
+	},
+	});
+	//父级传递来的函数,用于回调
+	const emit = defineEmits(["reloadTable"]);
+	const ruleFormRef = ref();
+	const isShowDialog = ref(false);
+	const ruleForm = ref<any>({});
+		//自行删除非必填规则
+		const rules = ref<FormRules>({
   @foreach (var column in Model.TableField){
     if(@column.EffectType == "Input" || @column.EffectType == "InputNumber" ||@column.EffectType == "InputTextArea"){
   @:@column.LowerColumnName: [{required: true, message: '请输入@(@column.ColumnComment)!', trigger: 'blur',},],
@@ -141,7 +141,6 @@ const rules = ref<FormRules>({
   }
 });
 
-
 // 打开弹窗
 const openDialog = (row: any) => {
   ruleForm.value = row;
@@ -181,4 +180,4 @@ const submit = async () => {
 
 //将属性或者函数暴露给父组件
 defineExpose({ openDialog });
-</script>
+</script>

+ 9 - 9
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm

@@ -1,5 +1,5 @@
 <template>
-	<div class="@(@Model.ClassName)-container">
+	<div class="@(@Model.LowerClassName)-container">
 		<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
 			@if(Model.QueryWhetherList.Count > 0){
 			@:<el-form :model="queryParams" ref="queryForm" :inline="true">
@@ -56,8 +56,8 @@
           @:<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
           @:<div style="text-align:right">
           @:<el-button icon="ele-Refresh" @@click="() => queryParams = {}"> 重置 </el-button>
-          @:<el-button type="primary" icon="ele-Search" @@click="handleQuery" v-auth="'@(@Model.ClassName):page'"> 查询 </el-button>
-          @:<el-button icon="ele-Plus" @@click="openAdd@(@Model.ClassName)" v-auth="'@(@Model.ClassName):add'"> 新增 </el-button>
+          @:<el-button type="primary" icon="ele-Search" @@click="handleQuery" v-auth="'@(@Model.LowerClassName):page'"> 查询 </el-button>
+          @:<el-button icon="ele-Plus" @@click="openAdd@(@Model.ClassName)" v-auth="'@(@Model.LowerClassName):add'"> 新增 </el-button>
           @:</div>
           @:</el-col>
       @:</el-row>
@@ -107,10 +107,10 @@
 				}
 				}
 				}
-				<el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('@(@Model.ClassName):edit') || auth('@(@Model.ClassName):delete')">
+				<el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('@(@Model.LowerClassName):edit') || auth('@(@Model.LowerClassName):delete')">
 					<template #default="scope">
-						<el-button icon="ele-Edit" size="small" text="" type="primary" @@click="openEdit@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.ClassName):edit'"> 编辑 </el-button>
-						<el-button icon="ele-Delete" size="small" text="" type="primary" @@click="del@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.ClassName):delete'"> 删除 </el-button>
+						<el-button icon="ele-Edit" size="small" text="" type="primary" @@click="openEdit@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.LowerClassName):edit'"> 编辑 </el-button>
+						<el-button icon="ele-Delete" size="small" text="" type="primary" @@click="del@(@Model.ClassName)(scope.row)" v-auth="'@(@Model.LowerClassName):delete'"> 删除 </el-button>
 					</template>
 				</el-table-column>
 			</el-table>
@@ -140,11 +140,11 @@ import { ElMessageBox, ElMessage } from "element-plus";
 import { auth } from '/@@/utils/authFunction';
 import { formatDate } from '/@@/utils/formatTime';
 
-import editDialog from '/@@/views/main/@(@Model.ClassName)/component/editDialog.vue'
-import { get@(@Model.ClassName)PageList, delete@(@Model.ClassName) } from '/@@/api/main/@(@Model.ClassName)';
+import editDialog from '/@@/views/main/@(@Model.LowerClassName)/component/editDialog.vue'
+import { get@(@Model.ClassName)PageList, delete@(@Model.ClassName) } from '/@@/api/main/@(@Model.LowerClassName)';
 	@foreach (var column in Model.QueryWhetherList){
 	if(@column.EffectType == "fk"){
-	@:import { get@(@column.FkEntityName)Dropdown } from '/@@/api/main/@(@Model.ClassName)';
+	@:import { get@(@column.FkEntityName)Dropdown } from '/@@/api/main/@(@Model.LowerClassName)';
 	}
 	}
 	@foreach (var column in Model.QueryWhetherList){

+ 164 - 25
Web/src/utils/request.ts

@@ -1,20 +1,74 @@
-import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { Session } from '/@/utils/storage';
+import axios, { AxiosInstance } from 'axios';
+import { ElMessage } from 'element-plus';
+import { Local, Session } from '/@/utils/storage';
 
 // 配置新建一个 axios 实例
-const service: AxiosInstance = axios.create({
-	baseURL: import.meta.env.VITE_API_URL,
+export const service = axios.create({
+	baseURL: import.meta.env.VITE_API_URL as any,
 	timeout: 50000,
 	headers: { 'Content-Type': 'application/json' },
 });
 
+// token 键定义
+export const accessTokenKey = 'access-token';
+export const refreshAccessTokenKey = `x-${accessTokenKey}`;
+
+// 获取 token
+export const getToken = () => {
+	return Local.get(accessTokenKey);
+};
+
+// 清除 token
+export const clearAccessTokens = () => {
+	Local.remove(accessTokenKey);
+	Local.remove(refreshAccessTokenKey);
+
+	// 清除其他
+	Session.clear();
+
+	// 刷新浏览器
+	window.location.reload();
+};
+
+// axios 默认实例
+export const axiosInstance: AxiosInstance = axios;
+
 // 添加请求拦截器
 service.interceptors.request.use(
-	(config: AxiosRequestConfig) => {
-		// 在发送请求之前做些什么 token
-		if (Session.get('token')) {
-			config.headers!['Authorization'] = `${Session.get('token')}`;
+	(config) => {
+		// // 在发送请求之前做些什么 token
+		// if (Session.get('token')) {
+		// 	(<any>config.headers).common['Authorization'] = `${Session.get('token')}`;
+		// }
+
+		// 获取本地的 token
+		const accessToken = Local.get(accessTokenKey);
+		if (accessToken) {
+			// 将 token 添加到请求报文头中
+			config.headers!['Authorization'] = `Bearer ${accessToken}`;
+
+			// 判断 accessToken 是否过期
+			const jwt: any = decryptJWT(accessToken);
+			const exp = getJWTDate(jwt.exp as number);
+
+			// token 已经过期
+			if (new Date() >= exp) {
+				// 获取刷新 token
+				const refreshAccessToken = Local.get(refreshAccessTokenKey);
+
+				// 携带刷新 token
+				if (refreshAccessToken) {
+					config.headers!['X-Authorization'] = `Bearer ${refreshAccessToken}`;
+				}
+			}
+			// debugger
+			// get请求映射params参数
+			if (config.method?.toLowerCase() === 'get' && config.data) {
+				let url = config.url + '?' + tansParams(config.data);
+				url = url.slice(0, -1);
+				config.data = {};
+				config.url = url;
+			}
 		}
 		return config;
 	},
@@ -26,24 +80,61 @@ service.interceptors.request.use(
 
 // 添加响应拦截器
 service.interceptors.response.use(
-	(response) => {
-		// 对响应数据做点什么
-		const res = response.data;
-		if (res.code && res.code !== 0) {
-			// `token` 过期或者账号已在别处登录
-			if (res.code === 401 || res.code === 4001) {
-				Session.clear(); // 清除浏览器全部临时缓存
-				window.location.href = '/'; // 去登录页
-				ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
-					.then(() => {})
-					.catch(() => {});
-			}
-			return Promise.reject(service.interceptors.response);
-		} else {
-			return response.data;
+	(res) => {
+		// 获取状态码和返回数据
+		var status = res.status;
+		var serve = res.data;
+
+		// 处理 401
+		if (status === 401) {
+			clearAccessTokens();
+		}
+
+		// 处理未进行规范化处理的
+		if (status >= 400) {
+			throw new Error(res.statusText || 'Request Error.');
+		}
+
+		// 处理规范化结果错误
+		if (serve && serve.hasOwnProperty('errors') && serve.errors) {
+			throw new Error(JSON.stringify(serve.errors || 'Request Error.'));
+		}
+
+		// 读取响应报文头 token 信息
+		var accessToken = res.headers[accessTokenKey];
+		var refreshAccessToken = res.headers[refreshAccessTokenKey];
+
+		// 判断是否是无效 token
+		if (accessToken === 'invalid_token') {
+			clearAccessTokens();
+		}
+		// 判断是否存在刷新 token,如果存在则存储在本地
+		else if (refreshAccessToken && accessToken && accessToken !== 'invalid_token') {
+			Local.set(accessTokenKey, accessToken);
+			Local.set(refreshAccessTokenKey, refreshAccessToken);
 		}
+
+		// 响应拦截及自定义处理
+		if (serve.code === 401) {
+			clearAccessTokens();
+		} else if (serve.code === undefined) {
+			return Promise.resolve(res);
+		} else if (serve.code !== 200) {
+			var message = JSON.stringify(serve.message);
+			ElMessage.error(message);
+			throw new Error(message);
+		}
+
+		return res;
 	},
 	(error) => {
+		// 处理响应错误
+		if (error.response) {
+			if (error.response.status === 401) {
+				clearAccessTokens();
+			}
+		}
+
 		// 对响应错误做点什么
 		if (error.message.indexOf('timeout') != -1) {
 			ElMessage.error('网络超时');
@@ -53,9 +144,57 @@ service.interceptors.response.use(
 			if (error.response.data) ElMessage.error(error.response.statusText);
 			else ElMessage.error('接口路径找不到');
 		}
+
 		return Promise.reject(error);
 	}
 );
 
+/**
+ *  参数处理
+ * @param {*} params  参数
+ */
+export function tansParams(params: any) {
+	let result = '';
+	for (const propName of Object.keys(params)) {
+		const value = params[propName];
+		var part = encodeURIComponent(propName) + '=';
+		if (value !== null && value !== '' && typeof value !== 'undefined') {
+			if (typeof value === 'object') {
+				for (const key of Object.keys(value)) {
+					if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') {
+						let params = propName + '[' + key + ']';
+						var subPart = encodeURIComponent(params) + '=';
+						result += subPart + encodeURIComponent(value[key]) + '&';
+					}
+				}
+			} else {
+				result += part + encodeURIComponent(value) + '&';
+			}
+		}
+	}
+	return result;
+}
+
+/**
+ * 解密 JWT token 的信息
+ * @param token jwt token 字符串
+ * @returns <any>object
+ */
+export function decryptJWT(token: string): any {
+	token = token.replace(/_/g, '/').replace(/-/g, '+');
+	var json = decodeURIComponent(escape(window.atob(token.split('.')[1])));
+	return JSON.parse(json);
+}
+
+/**
+ * 将 JWT 时间戳转换成 Date
+ * @description 主要针对 `exp`,`iat`,`nbf`
+ * @param timestamp 时间戳
+ * @returns Date 对象
+ */
+export function getJWTDate(timestamp: number): Date {
+	return new Date(timestamp * 1000);
+}
+
 // 导出 axios 实例
-export default service;
+export default service;