feat: login
This commit is contained in:
@@ -1,20 +1,20 @@
|
||||
// https://umijs.org/config/
|
||||
|
||||
import { join } from 'node:path';
|
||||
import { defineConfig } from '@umijs/max';
|
||||
import defaultSettings from './defaultSettings';
|
||||
import proxy from './proxy';
|
||||
import { join } from "node:path";
|
||||
import { defineConfig } from "@umijs/max";
|
||||
import defaultSettings from "./defaultSettings";
|
||||
import proxy from "./proxy";
|
||||
|
||||
import routes from './routes';
|
||||
import routes from "./routes";
|
||||
|
||||
const { UMI_ENV = 'dev' } = process.env;
|
||||
const { UMI_ENV = "dev" } = process.env;
|
||||
|
||||
/**
|
||||
* @name 使用公共路径
|
||||
* @description 部署时的路径,如果部署在非根目录下,需要配置这个变量
|
||||
* @doc https://umijs.org/docs/api/config#publicpath
|
||||
*/
|
||||
const PUBLIC_PATH: string = '/';
|
||||
const PUBLIC_PATH: string = "/";
|
||||
|
||||
export default defineConfig({
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ export default defineConfig({
|
||||
* @name layout 插件
|
||||
* @doc https://umijs.org/docs/max/layout-menu
|
||||
*/
|
||||
title: 'Ant Design Pro',
|
||||
title: "Ant Design Pro",
|
||||
layout: {
|
||||
locale: true,
|
||||
...defaultSettings,
|
||||
@@ -94,8 +94,8 @@ export default defineConfig({
|
||||
* @doc https://umijs.org/docs/max/moment2dayjs
|
||||
*/
|
||||
moment2dayjs: {
|
||||
preset: 'antd',
|
||||
plugins: ['duration'],
|
||||
preset: "antd",
|
||||
plugins: ["duration"],
|
||||
},
|
||||
/**
|
||||
* @name 国际化插件
|
||||
@@ -103,7 +103,7 @@ export default defineConfig({
|
||||
*/
|
||||
locale: {
|
||||
// default zh-CN
|
||||
default: 'zh-CN',
|
||||
default: "zh-CN",
|
||||
antd: true,
|
||||
// default true, when it is true, will use `navigator.language` overwrite default
|
||||
baseNavigator: true,
|
||||
@@ -119,7 +119,7 @@ export default defineConfig({
|
||||
theme: {
|
||||
cssVar: true,
|
||||
token: {
|
||||
fontFamily: 'AlibabaSans, sans-serif',
|
||||
fontFamily: "AlibabaSans, sans-serif",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -142,10 +142,10 @@ export default defineConfig({
|
||||
*/
|
||||
headScripts: [
|
||||
// 解决首次加载时白屏的问题
|
||||
{ src: join(PUBLIC_PATH, 'scripts/loading.js'), async: true },
|
||||
{ src: join(PUBLIC_PATH, "scripts/loading.js"), async: true },
|
||||
],
|
||||
//================ pro 插件配置 =================
|
||||
presets: ['umi-presets-pro'],
|
||||
presets: ["umi-presets-pro"],
|
||||
/**
|
||||
* @name openAPI 插件的配置
|
||||
* @description 基于 openapi 的规范生成serve 和mock,能减少很多样板代码
|
||||
@@ -154,20 +154,19 @@ export default defineConfig({
|
||||
openAPI: [
|
||||
{
|
||||
requestLibPath: "import { request } from '@umijs/max'",
|
||||
// 或者使用在线的版本
|
||||
// schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
|
||||
schemaPath: join(__dirname, 'oneapi.json'),
|
||||
|
||||
schemaPath: join(__dirname, "oneapi/prodapi.json"),
|
||||
mock: false,
|
||||
projectName: "prodApi",
|
||||
},
|
||||
{
|
||||
requestLibPath: "import { request } from '@umijs/max'",
|
||||
schemaPath:
|
||||
'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
|
||||
projectName: 'swagger',
|
||||
},
|
||||
// {schemaPath: "./docs/apifox-api.json",
|
||||
// requestLibPath: "import { request } from '@umijs/max'",
|
||||
// schemaPath: join(__dirname, "oneapi.json"),
|
||||
// projectName: "login",
|
||||
// },
|
||||
],
|
||||
mock: {
|
||||
include: ['mock/**/*', 'src/pages/**/_mock.ts'],
|
||||
include: ["mock/**/*", "src/pages/**/_mock.ts"],
|
||||
},
|
||||
/**
|
||||
* @name 是否开启 mako
|
||||
@@ -179,6 +178,6 @@ export default defineConfig({
|
||||
requestRecord: {},
|
||||
exportStatic: {},
|
||||
define: {
|
||||
'process.env.CI': process.env.CI,
|
||||
"process.env.CI": process.env.CI,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ProLayoutProps } from '@ant-design/pro-components';
|
||||
import type { ProLayoutProps } from "@ant-design/pro-components";
|
||||
|
||||
/**
|
||||
* @name
|
||||
@@ -7,18 +7,18 @@ const Settings: ProLayoutProps & {
|
||||
pwa?: boolean;
|
||||
logo?: string;
|
||||
} = {
|
||||
navTheme: 'light',
|
||||
navTheme: "light",
|
||||
// 拂晓蓝
|
||||
colorPrimary: '#1890ff',
|
||||
layout: 'mix',
|
||||
contentWidth: 'Fluid',
|
||||
colorPrimary: "#1890ff",
|
||||
layout: "mix",
|
||||
contentWidth: "Fluid",
|
||||
fixedHeader: false,
|
||||
fixSiderbar: true,
|
||||
colorWeak: false,
|
||||
title: 'Ant Design Pro',
|
||||
title: "tashow - 管理后台",
|
||||
pwa: true,
|
||||
logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
|
||||
iconfontUrl: '',
|
||||
logo: "https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg",
|
||||
iconfontUrl: "",
|
||||
token: {
|
||||
// 参见ts声明,demo 见文档,通过token 修改样式
|
||||
//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F
|
||||
|
||||
@@ -1,593 +0,0 @@
|
||||
{
|
||||
"openapi": "3.0.1",
|
||||
"info": {
|
||||
"title": "Ant Design Pro",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://localhost:8000/"
|
||||
},
|
||||
{
|
||||
"url": "https://localhost:8000/"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/api/currentUser": {
|
||||
"get": {
|
||||
"tags": ["api"],
|
||||
"description": "获取当前的用户",
|
||||
"operationId": "currentUser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CurrentUser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/api/login/captcha": {
|
||||
"post": {
|
||||
"description": "发送验证码",
|
||||
"operationId": "getFakeCaptcha",
|
||||
"tags": ["login"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "phone",
|
||||
"in": "query",
|
||||
"description": "手机号",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/FakeCaptcha"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login/outLogin": {
|
||||
"post": {
|
||||
"description": "登录接口",
|
||||
"operationId": "outLogin",
|
||||
"tags": ["login"],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/api/login/account": {
|
||||
"post": {
|
||||
"tags": ["login"],
|
||||
"description": "登录接口",
|
||||
"operationId": "login",
|
||||
"requestBody": {
|
||||
"description": "登录系统",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/LoginParams"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/LoginResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codegen-request-body-name": "body"
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/api/notices": {
|
||||
"summary": "getNotices",
|
||||
"description": "NoticeIconItem",
|
||||
"get": {
|
||||
"tags": ["api"],
|
||||
"operationId": "getNotices",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NoticeIconList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/rule": {
|
||||
"get": {
|
||||
"tags": ["rule"],
|
||||
"description": "获取规则列表",
|
||||
"operationId": "rule",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "current",
|
||||
"in": "query",
|
||||
"description": "当前的页码",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "pageSize",
|
||||
"in": "query",
|
||||
"description": "页面的容量",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RuleList"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["rule"],
|
||||
"description": "新建规则",
|
||||
"operationId": "addRule",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RuleListItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": ["rule"],
|
||||
"description": "新建规则",
|
||||
"operationId": "updateRule",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RuleListItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["rule"],
|
||||
"description": "删除规则",
|
||||
"operationId": "removeRule",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/swagger": {
|
||||
"x-swagger-pipe": "swagger_raw"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"CurrentUser": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"userid": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"signature": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"group": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"notifyCount": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"unreadCount": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"access": {
|
||||
"type": "string"
|
||||
},
|
||||
"geographic": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"province": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"city": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"LoginResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"currentAuthority": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PageParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"current": {
|
||||
"type": "number"
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RuleListItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"disabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"href": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"desc": {
|
||||
"type": "string"
|
||||
},
|
||||
"callNo": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"status": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"format": "datetime"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string",
|
||||
"format": "datetime"
|
||||
},
|
||||
"progress": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RuleList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RuleListItem"
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"description": "列表的内容总数",
|
||||
"format": "int32"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FakeCaptcha": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"LoginParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"autoLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ErrorResponse": {
|
||||
"required": ["errorCode"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"errorCode": {
|
||||
"type": "string",
|
||||
"description": "业务约定的错误码"
|
||||
},
|
||||
"errorMessage": {
|
||||
"type": "string",
|
||||
"description": "业务上的错误信息"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"description": "业务上的请求是否成功"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NoticeIconList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NoticeIconItem"
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"description": "列表的内容总数",
|
||||
"format": "int32"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NoticeIconItemType": {
|
||||
"title": "NoticeIconItemType",
|
||||
"description": "已读未读列表的枚举",
|
||||
"type": "string",
|
||||
"properties": {},
|
||||
"enum": ["notification", "message", "event"]
|
||||
},
|
||||
"NoticeIconItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"extra": {
|
||||
"type": "string",
|
||||
"format": "any"
|
||||
},
|
||||
"key": { "type": "string" },
|
||||
"read": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"datetime": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"extensions": {
|
||||
"x-is-enum": true
|
||||
},
|
||||
"$ref": "#/components/schemas/NoticeIconItemType"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
config/oneapi/orderapi.json
Normal file
0
config/oneapi/orderapi.json
Normal file
6627
config/oneapi/prodapi.json
Normal file
6627
config/oneapi/prodapi.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,33 +11,33 @@
|
||||
*/
|
||||
export default {
|
||||
// 如果需要自定义本地开发服务器 请取消注释按需调整
|
||||
// dev: {
|
||||
// // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
|
||||
// '/api/': {
|
||||
// // 要代理的地址
|
||||
// target: 'https://preview.pro.ant.design',
|
||||
// // 配置了这个可以从 http 代理到 https
|
||||
// // 依赖 origin 的功能可能需要这个,比如 cookie
|
||||
// changeOrigin: true,
|
||||
// },
|
||||
// },
|
||||
dev: {
|
||||
// localhost:8000/api/** -> https://preview.pro.ant.design/api/**
|
||||
"/admin-api/": {
|
||||
// 要代理的地址
|
||||
target: "http://192.168.1.114:48080",
|
||||
// 配置了这个可以从 http 代理到 https
|
||||
// 依赖 origin 的功能可能需要这个,比如 cookie
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @name 详细的代理配置
|
||||
* @doc https://github.com/chimurai/http-proxy-middleware
|
||||
*/
|
||||
test: {
|
||||
// localhost:8000/api/** -> https://preview.pro.ant.design/api/**
|
||||
'/api/': {
|
||||
target: 'https://proapi.azurewebsites.net',
|
||||
"/api/": {
|
||||
target: "https://proapi.azurewebsites.net",
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^': '' },
|
||||
pathRewrite: { "^": "" },
|
||||
},
|
||||
},
|
||||
pre: {
|
||||
'/api/': {
|
||||
target: 'your pre url',
|
||||
"/api/": {
|
||||
target: "your pre url",
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^': '' },
|
||||
pathRewrite: { "^": "" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,52 +12,52 @@
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: '/user',
|
||||
path: "/user",
|
||||
layout: false,
|
||||
routes: [
|
||||
{
|
||||
name: 'login',
|
||||
path: '/user/login',
|
||||
component: './user/login',
|
||||
name: "login",
|
||||
path: "/user/login",
|
||||
component: "./user/login",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/welcome',
|
||||
name: 'welcome',
|
||||
icon: 'smile',
|
||||
component: './Welcome',
|
||||
path: "/welcome",
|
||||
name: "welcome",
|
||||
icon: "smile",
|
||||
component: "./Welcome",
|
||||
},
|
||||
{
|
||||
path: '/admin',
|
||||
name: 'admin',
|
||||
icon: 'crown',
|
||||
access: 'canAdmin',
|
||||
path: "/admin",
|
||||
name: "admin",
|
||||
icon: "crown",
|
||||
access: "canAdmin",
|
||||
routes: [
|
||||
{
|
||||
path: '/admin',
|
||||
redirect: '/admin/sub-page',
|
||||
path: "/admin",
|
||||
redirect: "/admin/sub-page",
|
||||
},
|
||||
{
|
||||
path: '/admin/sub-page',
|
||||
name: 'sub-page',
|
||||
component: './Admin',
|
||||
path: "/admin/sub-page",
|
||||
name: "sub-page",
|
||||
component: "./Admin",
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// name: 'list.table-list',
|
||||
// icon: 'table',
|
||||
// path: '/list',
|
||||
// component: './table-list',
|
||||
// },
|
||||
{
|
||||
name: 'list.table-list',
|
||||
icon: 'table',
|
||||
path: '/list',
|
||||
component: './table-list',
|
||||
path: "/",
|
||||
redirect: "/welcome",
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/welcome',
|
||||
},
|
||||
{
|
||||
component: '404',
|
||||
component: "404",
|
||||
layout: false,
|
||||
path: './*',
|
||||
path: "./*",
|
||||
},
|
||||
];
|
||||
|
||||
12
package.json
12
package.json
@@ -37,22 +37,26 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@ant-design/pro-components": "^2.8.9",
|
||||
"antd": "^5.26.4",
|
||||
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
||||
"antd": "^5.26.4",
|
||||
"antd-style": "^3.7.0",
|
||||
"classnames": "^2.5.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"jsencrypt": "^3.5.4",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
"react-dom": "^19.1.0",
|
||||
"web-storage-cache": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/pro-cli": "^3.3.0",
|
||||
"@biomejs/biome": "^2.1.1",
|
||||
"@commitlint/cli": "^19.8.1",
|
||||
"@commitlint/config-conventional": "^19.8.1",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@types/express": "^5.0.3",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/node": "^24.0.13",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
@@ -68,9 +72,7 @@
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.6.3",
|
||||
"umi-presets-pro": "^2.0.3",
|
||||
"umi-serve": "^1.9.11",
|
||||
"@biomejs/biome": "^2.1.1",
|
||||
"@types/node": "^24.0.13"
|
||||
"umi-serve": "^1.9.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
|
||||
39
pnpm-lock.yaml
generated
39
pnpm-lock.yaml
generated
@@ -29,12 +29,18 @@ importers:
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.18
|
||||
jsencrypt:
|
||||
specifier: ^3.5.4
|
||||
version: 3.5.4
|
||||
react:
|
||||
specifier: ^19.1.0
|
||||
version: 19.1.1
|
||||
react-dom:
|
||||
specifier: ^19.1.0
|
||||
version: 19.1.1(react@19.1.1)
|
||||
web-storage-cache:
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
devDependencies:
|
||||
'@ant-design/pro-cli':
|
||||
specifier: ^3.3.0
|
||||
@@ -6624,6 +6630,9 @@ packages:
|
||||
canvas:
|
||||
optional: true
|
||||
|
||||
jsencrypt@3.5.4:
|
||||
resolution: {integrity: sha512-kNjfYEMNASxrDGsmcSQh/rUTmcoRfSUkxnAz+MMywM8jtGu+fFEZ3nJjHM58zscVnwR0fYmG9sGkTDjqUdpiwA==}
|
||||
|
||||
jsesc@2.5.2:
|
||||
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -10737,6 +10746,9 @@ packages:
|
||||
wcwidth@1.0.1:
|
||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||
|
||||
web-storage-cache@1.1.1:
|
||||
resolution: {integrity: sha512-D0MieGooOs8RpsrK+vnejXnvh4OOv/+lTFB35JRkJJQt+uOjPE08XpaE0QBLMTRu47B1KGT/Nq3Gbag3Orinzw==}
|
||||
|
||||
web-streams-polyfill@3.3.3:
|
||||
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -14812,7 +14824,7 @@ snapshots:
|
||||
|
||||
'@types/history@5.0.0':
|
||||
dependencies:
|
||||
history: 4.10.1
|
||||
history: 5.3.0
|
||||
|
||||
'@types/hoist-non-react-statics@3.3.7(@types/react@19.1.12)':
|
||||
dependencies:
|
||||
@@ -14917,7 +14929,7 @@ snapshots:
|
||||
'@types/history': 4.7.11
|
||||
'@types/react': 19.1.12
|
||||
'@types/react-router': 5.1.20
|
||||
redux: 3.7.2
|
||||
redux: 4.2.1
|
||||
|
||||
'@types/react-router@5.1.20':
|
||||
dependencies:
|
||||
@@ -15247,7 +15259,7 @@ snapshots:
|
||||
'@svgr/core': 6.5.1
|
||||
'@umijs/bundler-utils': 4.4.12
|
||||
'@umijs/utils': 4.4.12
|
||||
'@vitejs/plugin-react': 4.0.0(vite@4.5.2(@types/node@24.3.1)(less@4.4.1)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0))
|
||||
'@vitejs/plugin-react': 4.0.0(vite@4.5.2(@types/node@24.3.1)(less@4.1.3)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0))
|
||||
core-js: 3.34.0
|
||||
less: 4.1.3
|
||||
postcss-preset-env: 7.5.0(postcss@8.5.6)
|
||||
@@ -15934,13 +15946,13 @@ snapshots:
|
||||
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
|
||||
optional: true
|
||||
|
||||
'@vitejs/plugin-react@4.0.0(vite@4.5.2(@types/node@24.3.1)(less@4.4.1)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0))':
|
||||
'@vitejs/plugin-react@4.0.0(vite@4.5.2(@types/node@24.3.1)(less@4.1.3)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.4
|
||||
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4)
|
||||
react-refresh: 0.14.2
|
||||
vite: 4.5.2(@types/node@24.3.1)(less@4.4.1)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0)
|
||||
vite: 4.5.2(@types/node@24.3.1)(less@4.1.3)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -20412,6 +20424,8 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
jsencrypt@3.5.4: {}
|
||||
|
||||
jsesc@2.5.2: {}
|
||||
|
||||
jsesc@3.0.2: {}
|
||||
@@ -25430,19 +25444,6 @@ snapshots:
|
||||
sugarss: 2.0.0
|
||||
terser: 5.44.0
|
||||
|
||||
vite@4.5.2(@types/node@24.3.1)(less@4.4.1)(lightningcss@1.22.1)(sugarss@2.0.0)(terser@5.44.0):
|
||||
dependencies:
|
||||
esbuild: 0.18.20
|
||||
postcss: 8.5.6
|
||||
rollup: 3.29.5
|
||||
optionalDependencies:
|
||||
'@types/node': 24.3.1
|
||||
fsevents: 2.3.3
|
||||
less: 4.4.1
|
||||
lightningcss: 1.22.1
|
||||
sugarss: 2.0.0
|
||||
terser: 5.44.0
|
||||
|
||||
vm-browserify@1.1.2: {}
|
||||
|
||||
w3c-xmlserializer@5.0.0:
|
||||
@@ -25476,6 +25477,8 @@ snapshots:
|
||||
dependencies:
|
||||
defaults: 1.0.4
|
||||
|
||||
web-storage-cache@1.1.1: {}
|
||||
|
||||
web-streams-polyfill@3.3.3: {}
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { UserVO } from "./services/login/types";
|
||||
|
||||
/**
|
||||
* @see https://umijs.org/docs/max/access#access
|
||||
* */
|
||||
export default function access(
|
||||
initialState: { currentUser?: API.CurrentUser } | undefined,
|
||||
initialState: { currentUser?: UserVO } | undefined
|
||||
) {
|
||||
const { currentUser } = initialState ?? {};
|
||||
return {
|
||||
canAdmin: currentUser && currentUser.access === 'admin',
|
||||
canAdmin: currentUser && currentUser.username === "admin",
|
||||
};
|
||||
}
|
||||
|
||||
58
src/app.tsx
58
src/app.tsx
@@ -1,39 +1,39 @@
|
||||
import { LinkOutlined } from '@ant-design/icons';
|
||||
import type { Settings as LayoutSettings } from '@ant-design/pro-components';
|
||||
import { SettingDrawer } from '@ant-design/pro-components';
|
||||
import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
|
||||
import { history, Link } from '@umijs/max';
|
||||
import React from 'react';
|
||||
import { LinkOutlined } from "@ant-design/icons";
|
||||
import type { Settings as LayoutSettings } from "@ant-design/pro-components";
|
||||
import { SettingDrawer } from "@ant-design/pro-components";
|
||||
import type { RequestConfig, RunTimeLayoutConfig } from "@umijs/max";
|
||||
import { history, Link } from "@umijs/max";
|
||||
import React from "react";
|
||||
import {
|
||||
AvatarDropdown,
|
||||
AvatarName,
|
||||
Footer,
|
||||
Question,
|
||||
SelectLang,
|
||||
} from '@/components';
|
||||
import { currentUser as queryCurrentUser } from '@/services/ant-design-pro/api';
|
||||
import defaultSettings from '../config/defaultSettings';
|
||||
import { errorConfig } from './requestErrorConfig';
|
||||
import '@ant-design/v5-patch-for-react-19';
|
||||
} from "@/components";
|
||||
import { getInfo } from "@/services/login";
|
||||
import type { UserVO, TokenType } from "@/services/login/types";
|
||||
import defaultSettings from "../config/defaultSettings";
|
||||
import { errorConfig } from "./requestErrorConfig";
|
||||
import "@ant-design/v5-patch-for-react-19";
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
const isDev = process.env.NODE_ENV === "development";
|
||||
const isDevOrTest = isDev || process.env.CI;
|
||||
const loginPath = '/user/login';
|
||||
const loginPath = "/user/login";
|
||||
|
||||
/**
|
||||
* @see https://umijs.org/docs/api/runtime-config#getinitialstate
|
||||
* */
|
||||
export async function getInitialState(): Promise<{
|
||||
settings?: Partial<LayoutSettings>;
|
||||
currentUser?: API.CurrentUser;
|
||||
currentUser?: { user: UserVO };
|
||||
loading?: boolean;
|
||||
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
|
||||
fetchUserInfo?: () => Promise<{ user: UserVO } | undefined>;
|
||||
}> {
|
||||
const fetchUserInfo = async () => {
|
||||
// history.push(loginPath);
|
||||
try {
|
||||
const msg = await queryCurrentUser({
|
||||
skipErrorHandler: true,
|
||||
});
|
||||
const msg = await getInfo();
|
||||
return msg.data;
|
||||
} catch (_error) {
|
||||
history.push(loginPath);
|
||||
@@ -43,8 +43,8 @@ export async function getInitialState(): Promise<{
|
||||
// 如果不是登录页面,执行
|
||||
const { location } = history;
|
||||
if (
|
||||
![loginPath, '/user/register', '/user/register-result'].includes(
|
||||
location.pathname,
|
||||
![loginPath, "/user/register", "/user/register-result"].includes(
|
||||
location.pathname
|
||||
)
|
||||
) {
|
||||
const currentUser = await fetchUserInfo();
|
||||
@@ -71,14 +71,14 @@ export const layout: RunTimeLayoutConfig = ({
|
||||
<SelectLang key="SelectLang" />,
|
||||
],
|
||||
avatarProps: {
|
||||
src: initialState?.currentUser?.avatar,
|
||||
src: initialState?.currentUser?.user.avatar,
|
||||
title: <AvatarName />,
|
||||
render: (_, avatarChildren) => (
|
||||
<AvatarDropdown>{avatarChildren}</AvatarDropdown>
|
||||
),
|
||||
},
|
||||
waterMarkProps: {
|
||||
content: initialState?.currentUser?.name,
|
||||
content: initialState?.currentUser?.user.nickname,
|
||||
},
|
||||
footerRender: () => <Footer />,
|
||||
onPageChange: () => {
|
||||
@@ -90,22 +90,22 @@ export const layout: RunTimeLayoutConfig = ({
|
||||
},
|
||||
bgLayoutImgList: [
|
||||
{
|
||||
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
|
||||
src: "https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr",
|
||||
left: 85,
|
||||
bottom: 100,
|
||||
height: '303px',
|
||||
height: "303px",
|
||||
},
|
||||
{
|
||||
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
|
||||
src: "https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr",
|
||||
bottom: -68,
|
||||
right: -45,
|
||||
height: '303px',
|
||||
height: "303px",
|
||||
},
|
||||
{
|
||||
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
|
||||
src: "https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
width: '331px',
|
||||
width: "331px",
|
||||
},
|
||||
],
|
||||
links: isDevOrTest
|
||||
@@ -151,6 +151,6 @@ export const layout: RunTimeLayoutConfig = ({
|
||||
* @doc https://umijs.org/docs/max/request#配置
|
||||
*/
|
||||
export const request: RequestConfig = {
|
||||
baseURL: isDev ? '' : 'https://proapi.azurewebsites.net',
|
||||
baseURL: isDev ? "" : "https://proapi.azurewebsites.net",
|
||||
...errorConfig,
|
||||
};
|
||||
|
||||
@@ -2,15 +2,15 @@ import {
|
||||
LogoutOutlined,
|
||||
SettingOutlined,
|
||||
UserOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { history, useModel } from '@umijs/max';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Spin } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import React from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { outLogin } from '@/services/ant-design-pro/api';
|
||||
import HeaderDropdown from '../HeaderDropdown';
|
||||
} from "@ant-design/icons";
|
||||
import { history, useModel } from "@umijs/max";
|
||||
import type { MenuProps } from "antd";
|
||||
import { Spin } from "antd";
|
||||
import { createStyles } from "antd-style";
|
||||
import React from "react";
|
||||
import { flushSync } from "react-dom";
|
||||
import { loginOut } from "@/services/login";
|
||||
import HeaderDropdown from "../HeaderDropdown";
|
||||
|
||||
export type GlobalHeaderRightProps = {
|
||||
menu?: boolean;
|
||||
@@ -18,23 +18,23 @@ export type GlobalHeaderRightProps = {
|
||||
};
|
||||
|
||||
export const AvatarName = () => {
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const { initialState } = useModel("@@initialState");
|
||||
const { currentUser } = initialState || {};
|
||||
return <span className="anticon">{currentUser?.name}</span>;
|
||||
return <span className="anticon">{currentUser?.user.nickname}</span>;
|
||||
};
|
||||
|
||||
const useStyles = createStyles(({ token }) => {
|
||||
return {
|
||||
action: {
|
||||
display: 'flex',
|
||||
height: '48px',
|
||||
marginLeft: 'auto',
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
padding: '0 8px',
|
||||
cursor: 'pointer',
|
||||
display: "flex",
|
||||
height: "48px",
|
||||
marginLeft: "auto",
|
||||
overflow: "hidden",
|
||||
alignItems: "center",
|
||||
padding: "0 8px",
|
||||
cursor: "pointer",
|
||||
borderRadius: token.borderRadius,
|
||||
'&:hover': {
|
||||
"&:hover": {
|
||||
backgroundColor: token.colorBgTextHover,
|
||||
},
|
||||
},
|
||||
@@ -49,29 +49,29 @@ export const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({
|
||||
* 退出登录,并且将当前的 url 保存
|
||||
*/
|
||||
const loginOut = async () => {
|
||||
await outLogin();
|
||||
await loginOut();
|
||||
const { search, pathname } = window.location;
|
||||
const urlParams = new URL(window.location.href).searchParams;
|
||||
const searchParams = new URLSearchParams({
|
||||
redirect: pathname + search,
|
||||
});
|
||||
/** 此方法会跳转到 redirect 参数所在的位置 */
|
||||
const redirect = urlParams.get('redirect');
|
||||
const redirect = urlParams.get("redirect");
|
||||
// Note: There may be security issues, please note
|
||||
if (window.location.pathname !== '/user/login' && !redirect) {
|
||||
if (window.location.pathname !== "/user/login" && !redirect) {
|
||||
history.replace({
|
||||
pathname: '/user/login',
|
||||
pathname: "/user/login",
|
||||
search: searchParams.toString(),
|
||||
});
|
||||
}
|
||||
};
|
||||
const { styles } = useStyles();
|
||||
|
||||
const { initialState, setInitialState } = useModel('@@initialState');
|
||||
const { initialState, setInitialState } = useModel("@@initialState");
|
||||
|
||||
const onMenuClick: MenuProps['onClick'] = (event) => {
|
||||
const onMenuClick: MenuProps["onClick"] = (event) => {
|
||||
const { key } = event;
|
||||
if (key === 'logout') {
|
||||
if (key === "logout") {
|
||||
flushSync(() => {
|
||||
setInitialState((s) => ({ ...s, currentUser: undefined }));
|
||||
});
|
||||
@@ -99,7 +99,7 @@ export const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({
|
||||
|
||||
const { currentUser } = initialState;
|
||||
|
||||
if (!currentUser || !currentUser.name) {
|
||||
if (!currentUser || !currentUser.user.nickname) {
|
||||
return loading;
|
||||
}
|
||||
|
||||
@@ -107,24 +107,24 @@ export const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({
|
||||
...(menu
|
||||
? [
|
||||
{
|
||||
key: 'center',
|
||||
key: "center",
|
||||
icon: <UserOutlined />,
|
||||
label: '个人中心',
|
||||
label: "个人中心",
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
key: "settings",
|
||||
icon: <SettingOutlined />,
|
||||
label: '个人设置',
|
||||
label: "个人设置",
|
||||
},
|
||||
{
|
||||
type: 'divider' as const,
|
||||
type: "divider" as const,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
key: 'logout',
|
||||
key: "logout",
|
||||
icon: <LogoutOutlined />,
|
||||
label: '退出登录',
|
||||
label: "退出登录",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
39
src/hooks/web/useCache.ts
Normal file
39
src/hooks/web/useCache.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 配置浏览器本地存储的方式,可直接存储对象数组。
|
||||
*/
|
||||
|
||||
import WebStorageCache from "web-storage-cache";
|
||||
|
||||
type CacheType = "localStorage" | "sessionStorage";
|
||||
|
||||
export const CACHE_KEY = {
|
||||
// 用户相关
|
||||
ROLE_ROUTERS: "roleRouters",
|
||||
USER: "user",
|
||||
// 系统设置
|
||||
IS_DARK: "isDark",
|
||||
LANG: "lang",
|
||||
THEME: "theme",
|
||||
LAYOUT: "layout",
|
||||
DICT_CACHE: "dictCache",
|
||||
// 登录表单
|
||||
LoginForm: "loginForm",
|
||||
TenantId: "tenantId",
|
||||
};
|
||||
|
||||
export const useCache = (type: CacheType = "localStorage") => {
|
||||
const wsCache: WebStorageCache = new WebStorageCache({
|
||||
storage: type,
|
||||
});
|
||||
|
||||
return {
|
||||
wsCache,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteUserCache = () => {
|
||||
const { wsCache } = useCache();
|
||||
wsCache.delete(CACHE_KEY.USER);
|
||||
wsCache.delete(CACHE_KEY.ROLE_ROUTERS);
|
||||
// 注意,不要清理 LoginForm 登录表单
|
||||
};
|
||||
@@ -1,80 +1,80 @@
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
type ActionType,
|
||||
ModalForm,
|
||||
ProFormText,
|
||||
ProFormTextArea,
|
||||
} from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
|
||||
import { Button, message } from 'antd';
|
||||
import type { FC } from 'react';
|
||||
import { addRule } from '@/services/ant-design-pro/api';
|
||||
// import { PlusOutlined } from '@ant-design/icons';
|
||||
// import {
|
||||
// type ActionType,
|
||||
// ModalForm,
|
||||
// ProFormText,
|
||||
// ProFormTextArea,
|
||||
// } from '@ant-design/pro-components';
|
||||
// import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
|
||||
// import { Button, message } from 'antd';
|
||||
// import type { FC } from 'react';
|
||||
// import { addRule } from '@/services/ant-design-pro/api';
|
||||
|
||||
interface CreateFormProps {
|
||||
reload?: ActionType['reload'];
|
||||
}
|
||||
// interface CreateFormProps {
|
||||
// reload?: ActionType['reload'];
|
||||
// }
|
||||
|
||||
const CreateForm: FC<CreateFormProps> = (props) => {
|
||||
const { reload } = props;
|
||||
// const CreateForm: FC<CreateFormProps> = (props) => {
|
||||
// const { reload } = props;
|
||||
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
/**
|
||||
* @en-US International configuration
|
||||
* @zh-CN 国际化配置
|
||||
* */
|
||||
const intl = useIntl();
|
||||
// const [messageApi, contextHolder] = message.useMessage();
|
||||
// /**
|
||||
// * @en-US International configuration
|
||||
// * @zh-CN 国际化配置
|
||||
// * */
|
||||
// const intl = useIntl();
|
||||
|
||||
const { run, loading } = useRequest(addRule, {
|
||||
manual: true,
|
||||
onSuccess: () => {
|
||||
messageApi.success('Added successfully');
|
||||
reload?.();
|
||||
},
|
||||
onError: () => {
|
||||
messageApi.error('Adding failed, please try again!');
|
||||
},
|
||||
});
|
||||
// const { run, loading } = useRequest(addRule, {
|
||||
// manual: true,
|
||||
// onSuccess: () => {
|
||||
// messageApi.success('Added successfully');
|
||||
// reload?.();
|
||||
// },
|
||||
// onError: () => {
|
||||
// messageApi.error('Adding failed, please try again!');
|
||||
// },
|
||||
// });
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
<ModalForm
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.searchTable.createForm.newRule',
|
||||
defaultMessage: 'New rule',
|
||||
})}
|
||||
trigger={
|
||||
<Button type="primary" icon={<PlusOutlined />}>
|
||||
<FormattedMessage id="pages.searchTable.new" defaultMessage="New" />
|
||||
</Button>
|
||||
}
|
||||
width="400px"
|
||||
modalProps={{ okButtonProps: { loading } }}
|
||||
onFinish={async (value) => {
|
||||
await run({ data: value as API.RuleListItem });
|
||||
// return (
|
||||
// <>
|
||||
// {contextHolder}
|
||||
// <ModalForm
|
||||
// title={intl.formatMessage({
|
||||
// id: 'pages.searchTable.createForm.newRule',
|
||||
// defaultMessage: 'New rule',
|
||||
// })}
|
||||
// trigger={
|
||||
// <Button type="primary" icon={<PlusOutlined />}>
|
||||
// <FormattedMessage id="pages.searchTable.new" defaultMessage="New" />
|
||||
// </Button>
|
||||
// }
|
||||
// width="400px"
|
||||
// modalProps={{ okButtonProps: { loading } }}
|
||||
// onFinish={async (value) => {
|
||||
// await run({ data: value as API.RuleListItem });
|
||||
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
<ProFormText
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.ruleName"
|
||||
defaultMessage="Rule name is required"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
width="md"
|
||||
name="name"
|
||||
/>
|
||||
<ProFormTextArea width="md" name="desc" />
|
||||
</ModalForm>
|
||||
</>
|
||||
);
|
||||
};
|
||||
// return true;
|
||||
// }}
|
||||
// >
|
||||
// <ProFormText
|
||||
// rules={[
|
||||
// {
|
||||
// required: true,
|
||||
// message: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.ruleName"
|
||||
// defaultMessage="Rule name is required"
|
||||
// />
|
||||
// ),
|
||||
// },
|
||||
// ]}
|
||||
// width="md"
|
||||
// name="name"
|
||||
// />
|
||||
// <ProFormTextArea width="md" name="desc" />
|
||||
// </ModalForm>
|
||||
// </>
|
||||
// );
|
||||
// };
|
||||
|
||||
export default CreateForm;
|
||||
// export default CreateForm;
|
||||
|
||||
@@ -1,251 +1,251 @@
|
||||
import {
|
||||
ProFormDateTimePicker,
|
||||
ProFormRadio,
|
||||
ProFormSelect,
|
||||
ProFormText,
|
||||
ProFormTextArea,
|
||||
StepsForm,
|
||||
} from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
|
||||
import { Modal, message } from 'antd';
|
||||
import React, { cloneElement, useCallback, useState } from 'react';
|
||||
import { updateRule } from '@/services/ant-design-pro/api';
|
||||
// import {
|
||||
// ProFormDateTimePicker,
|
||||
// ProFormRadio,
|
||||
// ProFormSelect,
|
||||
// ProFormText,
|
||||
// ProFormTextArea,
|
||||
// StepsForm,
|
||||
// } from '@ant-design/pro-components';
|
||||
// import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
|
||||
// import { Modal, message } from 'antd';
|
||||
// import React, { cloneElement, useCallback, useState } from 'react';
|
||||
// import { updateRule } from '@/services/ant-design-pro/api';
|
||||
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.RuleListItem>;
|
||||
// export type FormValueType = {
|
||||
// target?: string;
|
||||
// template?: string;
|
||||
// type?: string;
|
||||
// time?: string;
|
||||
// frequency?: string;
|
||||
// } & Partial<API.RuleListItem>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
trigger?: React.ReactElement<any>;
|
||||
onOk?: () => void;
|
||||
values: Partial<API.RuleListItem>;
|
||||
};
|
||||
// export type UpdateFormProps = {
|
||||
// trigger?: React.ReactElement<any>;
|
||||
// onOk?: () => void;
|
||||
// values: Partial<API.RuleListItem>;
|
||||
// };
|
||||
|
||||
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
|
||||
const { onOk, values, trigger } = props;
|
||||
// const UpdateForm: React.FC<UpdateFormProps> = (props) => {
|
||||
// const { onOk, values, trigger } = props;
|
||||
|
||||
const intl = useIntl();
|
||||
// const intl = useIntl();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
// const [open, setOpen] = useState(false);
|
||||
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
// const [messageApi, contextHolder] = message.useMessage();
|
||||
|
||||
const { run } = useRequest(updateRule, {
|
||||
manual: true,
|
||||
onSuccess: () => {
|
||||
messageApi.success('Configuration is successful');
|
||||
onOk?.();
|
||||
},
|
||||
onError: () => {
|
||||
messageApi.error('Configuration failed, please try again!');
|
||||
},
|
||||
});
|
||||
// const { run } = useRequest(updateRule, {
|
||||
// manual: true,
|
||||
// onSuccess: () => {
|
||||
// messageApi.success('Configuration is successful');
|
||||
// onOk?.();
|
||||
// },
|
||||
// onError: () => {
|
||||
// messageApi.error('Configuration failed, please try again!');
|
||||
// },
|
||||
// });
|
||||
|
||||
const onCancel = useCallback(() => {
|
||||
setOpen(false);
|
||||
}, []);
|
||||
// const onCancel = useCallback(() => {
|
||||
// setOpen(false);
|
||||
// }, []);
|
||||
|
||||
const onOpen = useCallback(() => {
|
||||
setOpen(true);
|
||||
}, []);
|
||||
// const onOpen = useCallback(() => {
|
||||
// setOpen(true);
|
||||
// }, []);
|
||||
|
||||
const onFinish = useCallback(
|
||||
async (values?: any) => {
|
||||
await run({ data: values });
|
||||
// const onFinish = useCallback(
|
||||
// async (values?: any) => {
|
||||
// await run({ data: values });
|
||||
|
||||
onCancel();
|
||||
},
|
||||
[onCancel, run],
|
||||
);
|
||||
// onCancel();
|
||||
// },
|
||||
// [onCancel, run],
|
||||
// );
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
{trigger
|
||||
? cloneElement(trigger, {
|
||||
onClick: onOpen,
|
||||
})
|
||||
: null}
|
||||
<StepsForm
|
||||
stepsProps={{
|
||||
size: 'small',
|
||||
}}
|
||||
stepsFormRender={(dom, submitter) => {
|
||||
return (
|
||||
<Modal
|
||||
width={640}
|
||||
styles={{
|
||||
body: {
|
||||
padding: '32px 40px 48px',
|
||||
},
|
||||
}}
|
||||
destroyOnHidden
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleConfig',
|
||||
defaultMessage: '规则配置',
|
||||
})}
|
||||
open={open}
|
||||
footer={submitter}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
{dom}
|
||||
</Modal>
|
||||
);
|
||||
}}
|
||||
onFinish={onFinish}
|
||||
>
|
||||
<StepsForm.StepForm
|
||||
initialValues={values}
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.basicConfig',
|
||||
defaultMessage: '基本信息',
|
||||
})}
|
||||
>
|
||||
<ProFormText
|
||||
name="name"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleName.nameLabel',
|
||||
defaultMessage: '规则名称',
|
||||
})}
|
||||
width="md"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.updateForm.ruleName.nameRules"
|
||||
defaultMessage="请输入规则名称!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
name="desc"
|
||||
width="md"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleDesc.descLabel',
|
||||
defaultMessage: '规则描述',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleDesc.descPlaceholder',
|
||||
defaultMessage: '请输入至少五个字符',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.updateForm.ruleDesc.descRules"
|
||||
defaultMessage="请输入至少五个字符的规则描述!"
|
||||
/>
|
||||
),
|
||||
min: 5,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</StepsForm.StepForm>
|
||||
<StepsForm.StepForm
|
||||
initialValues={{
|
||||
target: '0',
|
||||
template: '0',
|
||||
}}
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleProps.title',
|
||||
defaultMessage: '配置规则属性',
|
||||
})}
|
||||
>
|
||||
<ProFormSelect
|
||||
name="target"
|
||||
width="md"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.object',
|
||||
defaultMessage: '监控对象',
|
||||
})}
|
||||
valueEnum={{
|
||||
0: '表一',
|
||||
1: '表二',
|
||||
}}
|
||||
/>
|
||||
<ProFormSelect
|
||||
name="template"
|
||||
width="md"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleProps.templateLabel',
|
||||
defaultMessage: '规则模板',
|
||||
})}
|
||||
valueEnum={{
|
||||
0: '规则模板一',
|
||||
1: '规则模板二',
|
||||
}}
|
||||
/>
|
||||
<ProFormRadio.Group
|
||||
name="type"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.ruleProps.typeLabel',
|
||||
defaultMessage: '规则类型',
|
||||
})}
|
||||
options={[
|
||||
{
|
||||
value: '0',
|
||||
label: '强',
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: '弱',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</StepsForm.StepForm>
|
||||
<StepsForm.StepForm
|
||||
initialValues={{
|
||||
type: '1',
|
||||
frequency: 'month',
|
||||
}}
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.schedulingPeriod.title',
|
||||
defaultMessage: '设定调度周期',
|
||||
})}
|
||||
>
|
||||
<ProFormDateTimePicker
|
||||
name="time"
|
||||
width="md"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.schedulingPeriod.timeLabel',
|
||||
defaultMessage: '开始时间',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.updateForm.schedulingPeriod.timeRules"
|
||||
defaultMessage="请选择开始时间!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormSelect
|
||||
name="frequency"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.searchTable.updateForm.object',
|
||||
defaultMessage: '监控对象',
|
||||
})}
|
||||
width="md"
|
||||
valueEnum={{
|
||||
month: '月',
|
||||
week: '周',
|
||||
}}
|
||||
/>
|
||||
</StepsForm.StepForm>
|
||||
</StepsForm>
|
||||
</>
|
||||
);
|
||||
};
|
||||
// return (
|
||||
// <>
|
||||
// {contextHolder}
|
||||
// {trigger
|
||||
// ? cloneElement(trigger, {
|
||||
// onClick: onOpen,
|
||||
// })
|
||||
// : null}
|
||||
// <StepsForm
|
||||
// stepsProps={{
|
||||
// size: 'small',
|
||||
// }}
|
||||
// stepsFormRender={(dom, submitter) => {
|
||||
// return (
|
||||
// <Modal
|
||||
// width={640}
|
||||
// styles={{
|
||||
// body: {
|
||||
// padding: '32px 40px 48px',
|
||||
// },
|
||||
// }}
|
||||
// destroyOnHidden
|
||||
// title={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleConfig',
|
||||
// defaultMessage: '规则配置',
|
||||
// })}
|
||||
// open={open}
|
||||
// footer={submitter}
|
||||
// onCancel={onCancel}
|
||||
// >
|
||||
// {dom}
|
||||
// </Modal>
|
||||
// );
|
||||
// }}
|
||||
// onFinish={onFinish}
|
||||
// >
|
||||
// <StepsForm.StepForm
|
||||
// initialValues={values}
|
||||
// title={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.basicConfig',
|
||||
// defaultMessage: '基本信息',
|
||||
// })}
|
||||
// >
|
||||
// <ProFormText
|
||||
// name="name"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleName.nameLabel',
|
||||
// defaultMessage: '规则名称',
|
||||
// })}
|
||||
// width="md"
|
||||
// rules={[
|
||||
// {
|
||||
// required: true,
|
||||
// message: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.updateForm.ruleName.nameRules"
|
||||
// defaultMessage="请输入规则名称!"
|
||||
// />
|
||||
// ),
|
||||
// },
|
||||
// ]}
|
||||
// />
|
||||
// <ProFormTextArea
|
||||
// name="desc"
|
||||
// width="md"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleDesc.descLabel',
|
||||
// defaultMessage: '规则描述',
|
||||
// })}
|
||||
// placeholder={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleDesc.descPlaceholder',
|
||||
// defaultMessage: '请输入至少五个字符',
|
||||
// })}
|
||||
// rules={[
|
||||
// {
|
||||
// required: true,
|
||||
// message: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.updateForm.ruleDesc.descRules"
|
||||
// defaultMessage="请输入至少五个字符的规则描述!"
|
||||
// />
|
||||
// ),
|
||||
// min: 5,
|
||||
// },
|
||||
// ]}
|
||||
// />
|
||||
// </StepsForm.StepForm>
|
||||
// <StepsForm.StepForm
|
||||
// initialValues={{
|
||||
// target: '0',
|
||||
// template: '0',
|
||||
// }}
|
||||
// title={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleProps.title',
|
||||
// defaultMessage: '配置规则属性',
|
||||
// })}
|
||||
// >
|
||||
// <ProFormSelect
|
||||
// name="target"
|
||||
// width="md"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.object',
|
||||
// defaultMessage: '监控对象',
|
||||
// })}
|
||||
// valueEnum={{
|
||||
// 0: '表一',
|
||||
// 1: '表二',
|
||||
// }}
|
||||
// />
|
||||
// <ProFormSelect
|
||||
// name="template"
|
||||
// width="md"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleProps.templateLabel',
|
||||
// defaultMessage: '规则模板',
|
||||
// })}
|
||||
// valueEnum={{
|
||||
// 0: '规则模板一',
|
||||
// 1: '规则模板二',
|
||||
// }}
|
||||
// />
|
||||
// <ProFormRadio.Group
|
||||
// name="type"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.ruleProps.typeLabel',
|
||||
// defaultMessage: '规则类型',
|
||||
// })}
|
||||
// options={[
|
||||
// {
|
||||
// value: '0',
|
||||
// label: '强',
|
||||
// },
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '弱',
|
||||
// },
|
||||
// ]}
|
||||
// />
|
||||
// </StepsForm.StepForm>
|
||||
// <StepsForm.StepForm
|
||||
// initialValues={{
|
||||
// type: '1',
|
||||
// frequency: 'month',
|
||||
// }}
|
||||
// title={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.schedulingPeriod.title',
|
||||
// defaultMessage: '设定调度周期',
|
||||
// })}
|
||||
// >
|
||||
// <ProFormDateTimePicker
|
||||
// name="time"
|
||||
// width="md"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.schedulingPeriod.timeLabel',
|
||||
// defaultMessage: '开始时间',
|
||||
// })}
|
||||
// rules={[
|
||||
// {
|
||||
// required: true,
|
||||
// message: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.updateForm.schedulingPeriod.timeRules"
|
||||
// defaultMessage="请选择开始时间!"
|
||||
// />
|
||||
// ),
|
||||
// },
|
||||
// ]}
|
||||
// />
|
||||
// <ProFormSelect
|
||||
// name="frequency"
|
||||
// label={intl.formatMessage({
|
||||
// id: 'pages.searchTable.updateForm.object',
|
||||
// defaultMessage: '监控对象',
|
||||
// })}
|
||||
// width="md"
|
||||
// valueEnum={{
|
||||
// month: '月',
|
||||
// week: '周',
|
||||
// }}
|
||||
// />
|
||||
// </StepsForm.StepForm>
|
||||
// </StepsForm>
|
||||
// </>
|
||||
// );
|
||||
// };
|
||||
|
||||
export default UpdateForm;
|
||||
// export default UpdateForm;
|
||||
|
||||
@@ -1,330 +1,330 @@
|
||||
import type {
|
||||
ActionType,
|
||||
ProColumns,
|
||||
ProDescriptionsItemProps,
|
||||
} from '@ant-design/pro-components';
|
||||
import {
|
||||
FooterToolbar,
|
||||
PageContainer,
|
||||
ProDescriptions,
|
||||
ProTable,
|
||||
} from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
|
||||
import { Button, Drawer, Input, message } from 'antd';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import { removeRule, rule } from '@/services/ant-design-pro/api';
|
||||
import CreateForm from './components/CreateForm';
|
||||
import UpdateForm from './components/UpdateForm';
|
||||
// import type {
|
||||
// ActionType,
|
||||
// ProColumns,
|
||||
// ProDescriptionsItemProps,
|
||||
// } from '@ant-design/pro-components';
|
||||
// import {
|
||||
// FooterToolbar,
|
||||
// PageContainer,
|
||||
// ProDescriptions,
|
||||
// ProTable,
|
||||
// } from '@ant-design/pro-components';
|
||||
// import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
|
||||
// import { Button, Drawer, Input, message } from 'antd';
|
||||
// import React, { useCallback, useRef, useState } from 'react';
|
||||
// import { removeRule, rule } from '@/services/ant-design-pro/api';
|
||||
// import CreateForm from './components/CreateForm';
|
||||
// import UpdateForm from './components/UpdateForm';
|
||||
|
||||
const TableList: React.FC = () => {
|
||||
const actionRef = useRef<ActionType | null>(null);
|
||||
// const TableList: React.FC = () => {
|
||||
// const actionRef = useRef<ActionType | null>(null);
|
||||
|
||||
const [showDetail, setShowDetail] = useState<boolean>(false);
|
||||
const [currentRow, setCurrentRow] = useState<API.RuleListItem>();
|
||||
const [selectedRowsState, setSelectedRows] = useState<API.RuleListItem[]>([]);
|
||||
// const [showDetail, setShowDetail] = useState<boolean>(false);
|
||||
// const [currentRow, setCurrentRow] = useState<API.RuleListItem>();
|
||||
// const [selectedRowsState, setSelectedRows] = useState<API.RuleListItem[]>([]);
|
||||
|
||||
/**
|
||||
* @en-US International configuration
|
||||
* @zh-CN 国际化配置
|
||||
* */
|
||||
const intl = useIntl();
|
||||
// /**
|
||||
// * @en-US International configuration
|
||||
// * @zh-CN 国际化配置
|
||||
// * */
|
||||
// const intl = useIntl();
|
||||
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
// const [messageApi, contextHolder] = message.useMessage();
|
||||
|
||||
const { run: delRun, loading } = useRequest(removeRule, {
|
||||
manual: true,
|
||||
onSuccess: () => {
|
||||
setSelectedRows([]);
|
||||
actionRef.current?.reloadAndRest?.();
|
||||
// const { run: delRun, loading } = useRequest(removeRule, {
|
||||
// manual: true,
|
||||
// onSuccess: () => {
|
||||
// setSelectedRows([]);
|
||||
// actionRef.current?.reloadAndRest?.();
|
||||
|
||||
messageApi.success('Deleted successfully and will refresh soon');
|
||||
},
|
||||
onError: () => {
|
||||
messageApi.error('Delete failed, please try again');
|
||||
},
|
||||
});
|
||||
// messageApi.success('Deleted successfully and will refresh soon');
|
||||
// },
|
||||
// onError: () => {
|
||||
// messageApi.error('Delete failed, please try again');
|
||||
// },
|
||||
// });
|
||||
|
||||
const columns: ProColumns<API.RuleListItem>[] = [
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.updateForm.ruleName.nameLabel"
|
||||
defaultMessage="Rule name"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'name',
|
||||
render: (dom, entity) => {
|
||||
return (
|
||||
<a
|
||||
onClick={() => {
|
||||
setCurrentRow(entity);
|
||||
setShowDetail(true);
|
||||
}}
|
||||
>
|
||||
{dom}
|
||||
</a>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.titleDesc"
|
||||
defaultMessage="Description"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'desc',
|
||||
valueType: 'textarea',
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.titleCallNo"
|
||||
defaultMessage="Number of service calls"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'callNo',
|
||||
sorter: true,
|
||||
hideInForm: true,
|
||||
renderText: (val: string) =>
|
||||
`${val}${intl.formatMessage({
|
||||
id: 'pages.searchTable.tenThousand',
|
||||
defaultMessage: ' 万 ',
|
||||
})}`,
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.titleStatus"
|
||||
defaultMessage="Status"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'status',
|
||||
hideInForm: true,
|
||||
valueEnum: {
|
||||
0: {
|
||||
text: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.nameStatus.default"
|
||||
defaultMessage="Shut down"
|
||||
/>
|
||||
),
|
||||
status: 'Default',
|
||||
},
|
||||
1: {
|
||||
text: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.nameStatus.running"
|
||||
defaultMessage="Running"
|
||||
/>
|
||||
),
|
||||
status: 'Processing',
|
||||
},
|
||||
2: {
|
||||
text: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.nameStatus.online"
|
||||
defaultMessage="Online"
|
||||
/>
|
||||
),
|
||||
status: 'Success',
|
||||
},
|
||||
3: {
|
||||
text: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.nameStatus.abnormal"
|
||||
defaultMessage="Abnormal"
|
||||
/>
|
||||
),
|
||||
status: 'Error',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.titleUpdatedAt"
|
||||
defaultMessage="Last scheduled time"
|
||||
/>
|
||||
),
|
||||
sorter: true,
|
||||
dataIndex: 'updatedAt',
|
||||
valueType: 'dateTime',
|
||||
renderFormItem: (item, { defaultRender, ...rest }, form) => {
|
||||
const status = form.getFieldValue('status');
|
||||
if (`${status}` === '0') {
|
||||
return false;
|
||||
}
|
||||
if (`${status}` === '3') {
|
||||
return (
|
||||
<Input
|
||||
{...rest}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.searchTable.exception',
|
||||
defaultMessage: 'Please enter the reason for the exception!',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return defaultRender(item);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.titleOption"
|
||||
defaultMessage="Operating"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
render: (_, record) => [
|
||||
<UpdateForm
|
||||
trigger={
|
||||
<a>
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.config"
|
||||
defaultMessage="Configuration"
|
||||
/>
|
||||
</a>
|
||||
}
|
||||
key="config"
|
||||
onOk={actionRef.current?.reload}
|
||||
values={record}
|
||||
/>,
|
||||
<a key="subscribeAlert" href="https://procomponents.ant.design/">
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.subscribeAlert"
|
||||
defaultMessage="Subscribe to alerts"
|
||||
/>
|
||||
</a>,
|
||||
],
|
||||
},
|
||||
];
|
||||
// const columns: ProColumns<API.RuleListItem>[] = [
|
||||
// {
|
||||
// title: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.updateForm.ruleName.nameLabel"
|
||||
// defaultMessage="Rule name"
|
||||
// />
|
||||
// ),
|
||||
// dataIndex: 'name',
|
||||
// render: (dom, entity) => {
|
||||
// return (
|
||||
// <a
|
||||
// onClick={() => {
|
||||
// setCurrentRow(entity);
|
||||
// setShowDetail(true);
|
||||
// }}
|
||||
// >
|
||||
// {dom}
|
||||
// </a>
|
||||
// );
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.titleDesc"
|
||||
// defaultMessage="Description"
|
||||
// />
|
||||
// ),
|
||||
// dataIndex: 'desc',
|
||||
// valueType: 'textarea',
|
||||
// },
|
||||
// {
|
||||
// title: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.titleCallNo"
|
||||
// defaultMessage="Number of service calls"
|
||||
// />
|
||||
// ),
|
||||
// dataIndex: 'callNo',
|
||||
// sorter: true,
|
||||
// hideInForm: true,
|
||||
// renderText: (val: string) =>
|
||||
// `${val}${intl.formatMessage({
|
||||
// id: 'pages.searchTable.tenThousand',
|
||||
// defaultMessage: ' 万 ',
|
||||
// })}`,
|
||||
// },
|
||||
// {
|
||||
// title: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.titleStatus"
|
||||
// defaultMessage="Status"
|
||||
// />
|
||||
// ),
|
||||
// dataIndex: 'status',
|
||||
// hideInForm: true,
|
||||
// valueEnum: {
|
||||
// 0: {
|
||||
// text: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.nameStatus.default"
|
||||
// defaultMessage="Shut down"
|
||||
// />
|
||||
// ),
|
||||
// status: 'Default',
|
||||
// },
|
||||
// 1: {
|
||||
// text: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.nameStatus.running"
|
||||
// defaultMessage="Running"
|
||||
// />
|
||||
// ),
|
||||
// status: 'Processing',
|
||||
// },
|
||||
// 2: {
|
||||
// text: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.nameStatus.online"
|
||||
// defaultMessage="Online"
|
||||
// />
|
||||
// ),
|
||||
// status: 'Success',
|
||||
// },
|
||||
// 3: {
|
||||
// text: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.nameStatus.abnormal"
|
||||
// defaultMessage="Abnormal"
|
||||
// />
|
||||
// ),
|
||||
// status: 'Error',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.titleUpdatedAt"
|
||||
// defaultMessage="Last scheduled time"
|
||||
// />
|
||||
// ),
|
||||
// sorter: true,
|
||||
// dataIndex: 'updatedAt',
|
||||
// valueType: 'dateTime',
|
||||
// renderFormItem: (item, { defaultRender, ...rest }, form) => {
|
||||
// const status = form.getFieldValue('status');
|
||||
// if (`${status}` === '0') {
|
||||
// return false;
|
||||
// }
|
||||
// if (`${status}` === '3') {
|
||||
// return (
|
||||
// <Input
|
||||
// {...rest}
|
||||
// placeholder={intl.formatMessage({
|
||||
// id: 'pages.searchTable.exception',
|
||||
// defaultMessage: 'Please enter the reason for the exception!',
|
||||
// })}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
// return defaultRender(item);
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: (
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.titleOption"
|
||||
// defaultMessage="Operating"
|
||||
// />
|
||||
// ),
|
||||
// dataIndex: 'option',
|
||||
// valueType: 'option',
|
||||
// render: (_, record) => [
|
||||
// <UpdateForm
|
||||
// trigger={
|
||||
// <a>
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.config"
|
||||
// defaultMessage="Configuration"
|
||||
// />
|
||||
// </a>
|
||||
// }
|
||||
// key="config"
|
||||
// onOk={actionRef.current?.reload}
|
||||
// values={record}
|
||||
// />,
|
||||
// <a key="subscribeAlert" href="https://procomponents.ant.design/">
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.subscribeAlert"
|
||||
// defaultMessage="Subscribe to alerts"
|
||||
// />
|
||||
// </a>,
|
||||
// ],
|
||||
// },
|
||||
// ];
|
||||
|
||||
/**
|
||||
* Delete node
|
||||
* @zh-CN 删除节点
|
||||
*
|
||||
* @param selectedRows
|
||||
*/
|
||||
const handleRemove = useCallback(
|
||||
async (selectedRows: API.RuleListItem[]) => {
|
||||
if (!selectedRows?.length) {
|
||||
messageApi.warning('请选择删除项');
|
||||
// /**
|
||||
// * Delete node
|
||||
// * @zh-CN 删除节点
|
||||
// *
|
||||
// * @param selectedRows
|
||||
// */
|
||||
// const handleRemove = useCallback(
|
||||
// async (selectedRows: API.RuleListItem[]) => {
|
||||
// if (!selectedRows?.length) {
|
||||
// messageApi.warning('请选择删除项');
|
||||
|
||||
return;
|
||||
}
|
||||
// return;
|
||||
// }
|
||||
|
||||
await delRun({
|
||||
data: {
|
||||
key: selectedRows.map((row) => row.key),
|
||||
},
|
||||
});
|
||||
},
|
||||
[delRun, messageApi.warning],
|
||||
);
|
||||
// await delRun({
|
||||
// data: {
|
||||
// key: selectedRows.map((row) => row.key),
|
||||
// },
|
||||
// });
|
||||
// },
|
||||
// [delRun, messageApi.warning],
|
||||
// );
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
{contextHolder}
|
||||
<ProTable<API.RuleListItem, API.PageParams>
|
||||
headerTitle={intl.formatMessage({
|
||||
id: 'pages.searchTable.title',
|
||||
defaultMessage: 'Enquiry form',
|
||||
})}
|
||||
actionRef={actionRef}
|
||||
rowKey="key"
|
||||
search={{
|
||||
labelWidth: 120,
|
||||
}}
|
||||
toolBarRender={() => [
|
||||
<CreateForm key="create" reload={actionRef.current?.reload} />,
|
||||
]}
|
||||
request={rule}
|
||||
columns={columns}
|
||||
rowSelection={{
|
||||
onChange: (_, selectedRows) => {
|
||||
setSelectedRows(selectedRows);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
{selectedRowsState?.length > 0 && (
|
||||
<FooterToolbar
|
||||
extra={
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.chosen"
|
||||
defaultMessage="Chosen"
|
||||
/>{' '}
|
||||
<a style={{ fontWeight: 600 }}>{selectedRowsState.length}</a>{' '}
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.item"
|
||||
defaultMessage="项"
|
||||
/>
|
||||
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.totalServiceCalls"
|
||||
defaultMessage="Total number of service calls"
|
||||
/>{' '}
|
||||
{selectedRowsState.reduce(
|
||||
(pre, item) => pre + (item.callNo ?? 0),
|
||||
0,
|
||||
)}{' '}
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.tenThousand"
|
||||
defaultMessage="万"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
loading={loading}
|
||||
onClick={() => {
|
||||
handleRemove(selectedRowsState);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.batchDeletion"
|
||||
defaultMessage="Batch deletion"
|
||||
/>
|
||||
</Button>
|
||||
<Button type="primary">
|
||||
<FormattedMessage
|
||||
id="pages.searchTable.batchApproval"
|
||||
defaultMessage="Batch approval"
|
||||
/>
|
||||
</Button>
|
||||
</FooterToolbar>
|
||||
)}
|
||||
// return (
|
||||
// <PageContainer>
|
||||
// {contextHolder}
|
||||
// <ProTable<API.RuleListItem, API.PageParams>
|
||||
// headerTitle={intl.formatMessage({
|
||||
// id: 'pages.searchTable.title',
|
||||
// defaultMessage: 'Enquiry form',
|
||||
// })}
|
||||
// actionRef={actionRef}
|
||||
// rowKey="key"
|
||||
// search={{
|
||||
// labelWidth: 120,
|
||||
// }}
|
||||
// toolBarRender={() => [
|
||||
// <CreateForm key="create" reload={actionRef.current?.reload} />,
|
||||
// ]}
|
||||
// request={rule}
|
||||
// columns={columns}
|
||||
// rowSelection={{
|
||||
// onChange: (_, selectedRows) => {
|
||||
// setSelectedRows(selectedRows);
|
||||
// },
|
||||
// }}
|
||||
// />
|
||||
// {selectedRowsState?.length > 0 && (
|
||||
// <FooterToolbar
|
||||
// extra={
|
||||
// <div>
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.chosen"
|
||||
// defaultMessage="Chosen"
|
||||
// />{' '}
|
||||
// <a style={{ fontWeight: 600 }}>{selectedRowsState.length}</a>{' '}
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.item"
|
||||
// defaultMessage="项"
|
||||
// />
|
||||
//
|
||||
// <span>
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.totalServiceCalls"
|
||||
// defaultMessage="Total number of service calls"
|
||||
// />{' '}
|
||||
// {selectedRowsState.reduce(
|
||||
// (pre, item) => pre + (item.callNo ?? 0),
|
||||
// 0,
|
||||
// )}{' '}
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.tenThousand"
|
||||
// defaultMessage="万"
|
||||
// />
|
||||
// </span>
|
||||
// </div>
|
||||
// }
|
||||
// >
|
||||
// <Button
|
||||
// loading={loading}
|
||||
// onClick={() => {
|
||||
// handleRemove(selectedRowsState);
|
||||
// }}
|
||||
// >
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.batchDeletion"
|
||||
// defaultMessage="Batch deletion"
|
||||
// />
|
||||
// </Button>
|
||||
// <Button type="primary">
|
||||
// <FormattedMessage
|
||||
// id="pages.searchTable.batchApproval"
|
||||
// defaultMessage="Batch approval"
|
||||
// />
|
||||
// </Button>
|
||||
// </FooterToolbar>
|
||||
// )}
|
||||
|
||||
<Drawer
|
||||
width={600}
|
||||
open={showDetail}
|
||||
onClose={() => {
|
||||
setCurrentRow(undefined);
|
||||
setShowDetail(false);
|
||||
}}
|
||||
closable={false}
|
||||
>
|
||||
{currentRow?.name && (
|
||||
<ProDescriptions<API.RuleListItem>
|
||||
column={2}
|
||||
title={currentRow?.name}
|
||||
request={async () => ({
|
||||
data: currentRow || {},
|
||||
})}
|
||||
params={{
|
||||
id: currentRow?.name,
|
||||
}}
|
||||
columns={columns as ProDescriptionsItemProps<API.RuleListItem>[]}
|
||||
/>
|
||||
)}
|
||||
</Drawer>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
// <Drawer
|
||||
// width={600}
|
||||
// open={showDetail}
|
||||
// onClose={() => {
|
||||
// setCurrentRow(undefined);
|
||||
// setShowDetail(false);
|
||||
// }}
|
||||
// closable={false}
|
||||
// >
|
||||
// {currentRow?.name && (
|
||||
// <ProDescriptions<API.RuleListItem>
|
||||
// column={2}
|
||||
// title={currentRow?.name}
|
||||
// request={async () => ({
|
||||
// data: currentRow || {},
|
||||
// })}
|
||||
// params={{
|
||||
// id: currentRow?.name,
|
||||
// }}
|
||||
// columns={columns as ProDescriptionsItemProps<API.RuleListItem>[]}
|
||||
// />
|
||||
// )}
|
||||
// </Drawer>
|
||||
// </PageContainer>
|
||||
// );
|
||||
// };
|
||||
|
||||
export default TableList;
|
||||
// export default TableList;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,397 +1,283 @@
|
||||
import {
|
||||
AlipayCircleOutlined,
|
||||
AlipayOutlined,
|
||||
LockOutlined,
|
||||
MobileOutlined,
|
||||
TaobaoCircleOutlined,
|
||||
TaobaoOutlined,
|
||||
UserOutlined,
|
||||
WeiboCircleOutlined,
|
||||
} from '@ant-design/icons';
|
||||
WeiboOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import {
|
||||
LoginForm,
|
||||
LoginFormPage,
|
||||
ProConfigProvider,
|
||||
ProFormCaptcha,
|
||||
ProFormCheckbox,
|
||||
ProFormText,
|
||||
} from '@ant-design/pro-components';
|
||||
import {
|
||||
FormattedMessage,
|
||||
Helmet,
|
||||
SelectLang,
|
||||
useIntl,
|
||||
useModel,
|
||||
} from '@umijs/max';
|
||||
import { Alert, App, Tabs } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import React, { useState } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { Footer } from '@/components';
|
||||
import { login } from '@/services/ant-design-pro/api';
|
||||
import { getFakeCaptcha } from '@/services/ant-design-pro/login';
|
||||
import Settings from '../../../../config/defaultSettings';
|
||||
} from "@ant-design/pro-components";
|
||||
import { Button, Divider, Space, Tabs, message, theme } from "antd";
|
||||
import type { CSSProperties } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
const useStyles = createStyles(({ token }) => {
|
||||
return {
|
||||
action: {
|
||||
marginLeft: '8px',
|
||||
color: 'rgba(0, 0, 0, 0.2)',
|
||||
fontSize: '24px',
|
||||
verticalAlign: 'middle',
|
||||
cursor: 'pointer',
|
||||
transition: 'color 0.3s',
|
||||
'&:hover': {
|
||||
color: token.colorPrimaryActive,
|
||||
},
|
||||
},
|
||||
lang: {
|
||||
width: 42,
|
||||
height: 42,
|
||||
lineHeight: '42px',
|
||||
position: 'fixed',
|
||||
right: 16,
|
||||
borderRadius: token.borderRadius,
|
||||
':hover': {
|
||||
backgroundColor: token.colorBgTextHover,
|
||||
},
|
||||
},
|
||||
container: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
overflow: 'auto',
|
||||
backgroundImage:
|
||||
"url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
|
||||
backgroundSize: '100% 100%',
|
||||
},
|
||||
};
|
||||
});
|
||||
type LoginType = "phone" | "account";
|
||||
|
||||
const ActionIcons = () => {
|
||||
const { styles } = useStyles();
|
||||
|
||||
return (
|
||||
<>
|
||||
<AlipayCircleOutlined
|
||||
key="AlipayCircleOutlined"
|
||||
className={styles.action}
|
||||
/>
|
||||
<TaobaoCircleOutlined
|
||||
key="TaobaoCircleOutlined"
|
||||
className={styles.action}
|
||||
/>
|
||||
<WeiboCircleOutlined
|
||||
key="WeiboCircleOutlined"
|
||||
className={styles.action}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
const iconStyles: CSSProperties = {
|
||||
color: "rgba(0, 0, 0, 0.2)",
|
||||
fontSize: "18px",
|
||||
verticalAlign: "middle",
|
||||
cursor: "pointer",
|
||||
};
|
||||
|
||||
const Lang = () => {
|
||||
const { styles } = useStyles();
|
||||
|
||||
const Page = () => {
|
||||
const [loginType, setLoginType] = useState<LoginType>("phone");
|
||||
const { token } = theme.useToken();
|
||||
return (
|
||||
<div className={styles.lang} data-lang>
|
||||
{SelectLang && <SelectLang />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const LoginMessage: React.FC<{
|
||||
content: string;
|
||||
}> = ({ content }) => {
|
||||
return (
|
||||
<Alert
|
||||
<div
|
||||
style={{
|
||||
marginBottom: 24,
|
||||
backgroundColor: "white",
|
||||
height: "100vh",
|
||||
}}
|
||||
message={content}
|
||||
type="error"
|
||||
showIcon
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Login: React.FC = () => {
|
||||
const [userLoginState, setUserLoginState] = useState<API.LoginResult>({});
|
||||
const [type, setType] = useState<string>('account');
|
||||
const { initialState, setInitialState } = useModel('@@initialState');
|
||||
const { styles } = useStyles();
|
||||
const { message } = App.useApp();
|
||||
const intl = useIntl();
|
||||
|
||||
const fetchUserInfo = async () => {
|
||||
const userInfo = await initialState?.fetchUserInfo?.();
|
||||
if (userInfo) {
|
||||
flushSync(() => {
|
||||
setInitialState((s) => ({
|
||||
...s,
|
||||
currentUser: userInfo,
|
||||
}));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (values: API.LoginParams) => {
|
||||
try {
|
||||
// 登录
|
||||
const msg = await login({ ...values, type });
|
||||
if (msg.status === 'ok') {
|
||||
const defaultLoginSuccessMessage = intl.formatMessage({
|
||||
id: 'pages.login.success',
|
||||
defaultMessage: '登录成功!',
|
||||
});
|
||||
message.success(defaultLoginSuccessMessage);
|
||||
await fetchUserInfo();
|
||||
const urlParams = new URL(window.location.href).searchParams;
|
||||
window.location.href = urlParams.get('redirect') || '/';
|
||||
return;
|
||||
}
|
||||
console.log(msg);
|
||||
// 如果失败去设置用户错误信息
|
||||
setUserLoginState(msg);
|
||||
} catch (error) {
|
||||
const defaultLoginFailureMessage = intl.formatMessage({
|
||||
id: 'pages.login.failure',
|
||||
defaultMessage: '登录失败,请重试!',
|
||||
});
|
||||
console.log(error);
|
||||
message.error(defaultLoginFailureMessage);
|
||||
}
|
||||
};
|
||||
const { status, type: loginType } = userLoginState;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Helmet>
|
||||
<title>
|
||||
{intl.formatMessage({
|
||||
id: 'menu.login',
|
||||
defaultMessage: '登录页',
|
||||
})}
|
||||
{Settings.title && ` - ${Settings.title}`}
|
||||
</title>
|
||||
</Helmet>
|
||||
<Lang />
|
||||
<div
|
||||
style={{
|
||||
flex: '1',
|
||||
padding: '32px 0',
|
||||
>
|
||||
<LoginFormPage
|
||||
backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp"
|
||||
logo="https://github.githubassets.com/favicons/favicon.png"
|
||||
backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr"
|
||||
title="Github"
|
||||
containerStyle={{
|
||||
backgroundColor: "rgba(0, 0, 0,0.65)",
|
||||
backdropFilter: "blur(4px)",
|
||||
}}
|
||||
>
|
||||
<LoginForm
|
||||
contentStyle={{
|
||||
minWidth: 280,
|
||||
maxWidth: '75vw',
|
||||
}}
|
||||
logo={<img alt="logo" src="/logo.svg" />}
|
||||
title="Ant Design"
|
||||
subTitle={intl.formatMessage({
|
||||
id: 'pages.layouts.userLayout.title',
|
||||
})}
|
||||
initialValues={{
|
||||
autoLogin: true,
|
||||
}}
|
||||
actions={[
|
||||
<FormattedMessage
|
||||
key="loginWith"
|
||||
id="pages.login.loginWith"
|
||||
defaultMessage="其他登录方式"
|
||||
/>,
|
||||
<ActionIcons key="icons" />,
|
||||
]}
|
||||
onFinish={async (values) => {
|
||||
await handleSubmit(values as API.LoginParams);
|
||||
}}
|
||||
>
|
||||
<Tabs
|
||||
activeKey={type}
|
||||
onChange={setType}
|
||||
centered
|
||||
items={[
|
||||
{
|
||||
key: 'account',
|
||||
label: intl.formatMessage({
|
||||
id: 'pages.login.accountLogin.tab',
|
||||
defaultMessage: '账户密码登录',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'mobile',
|
||||
label: intl.formatMessage({
|
||||
id: 'pages.login.phoneLogin.tab',
|
||||
defaultMessage: '手机号登录',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{status === 'error' && loginType === 'account' && (
|
||||
<LoginMessage
|
||||
content={intl.formatMessage({
|
||||
id: 'pages.login.accountLogin.errorMessage',
|
||||
defaultMessage: '账户或密码错误(admin/ant.design)',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{type === 'account' && (
|
||||
<>
|
||||
<ProFormText
|
||||
name="username"
|
||||
fieldProps={{
|
||||
size: 'large',
|
||||
prefix: <UserOutlined />,
|
||||
}}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.login.username.placeholder',
|
||||
defaultMessage: '用户名: admin or user',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.login.username.required"
|
||||
defaultMessage="请输入用户名!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText.Password
|
||||
name="password"
|
||||
fieldProps={{
|
||||
size: 'large',
|
||||
prefix: <LockOutlined />,
|
||||
}}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.login.password.placeholder',
|
||||
defaultMessage: '密码: ant.design',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.login.password.required"
|
||||
defaultMessage="请输入密码!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{status === 'error' && loginType === 'mobile' && (
|
||||
<LoginMessage content="验证码错误" />
|
||||
)}
|
||||
{type === 'mobile' && (
|
||||
<>
|
||||
<ProFormText
|
||||
fieldProps={{
|
||||
size: 'large',
|
||||
prefix: <MobileOutlined />,
|
||||
}}
|
||||
name="mobile"
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.login.phoneNumber.placeholder',
|
||||
defaultMessage: '手机号',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.login.phoneNumber.required"
|
||||
defaultMessage="请输入手机号!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
pattern: /^1\d{10}$/,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.login.phoneNumber.invalid"
|
||||
defaultMessage="手机号格式错误!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormCaptcha
|
||||
fieldProps={{
|
||||
size: 'large',
|
||||
prefix: <LockOutlined />,
|
||||
}}
|
||||
captchaProps={{
|
||||
size: 'large',
|
||||
}}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'pages.login.captcha.placeholder',
|
||||
defaultMessage: '请输入验证码',
|
||||
})}
|
||||
captchaTextRender={(timing, count) => {
|
||||
if (timing) {
|
||||
return `${count} ${intl.formatMessage({
|
||||
id: 'pages.getCaptchaSecondText',
|
||||
defaultMessage: '获取验证码',
|
||||
})}`;
|
||||
}
|
||||
return intl.formatMessage({
|
||||
id: 'pages.login.phoneLogin.getVerificationCode',
|
||||
defaultMessage: '获取验证码',
|
||||
});
|
||||
}}
|
||||
name="captcha"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="pages.login.captcha.required"
|
||||
defaultMessage="请输入验证码!"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
onGetCaptcha={async (phone) => {
|
||||
const result = await getFakeCaptcha({
|
||||
phone,
|
||||
});
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
message.success('获取验证码成功!验证码为:1234');
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
marginBottom: 24,
|
||||
}}
|
||||
>
|
||||
<ProFormCheckbox noStyle name="autoLogin">
|
||||
<FormattedMessage
|
||||
id="pages.login.rememberMe"
|
||||
defaultMessage="自动登录"
|
||||
/>
|
||||
</ProFormCheckbox>
|
||||
<a
|
||||
subTitle="全球最大的代码托管平台"
|
||||
activityConfig={{
|
||||
style: {
|
||||
boxShadow: "0px 0px 8px rgba(0, 0, 0, 0.2)",
|
||||
color: token.colorTextHeading,
|
||||
borderRadius: 8,
|
||||
backgroundColor: "rgba(255,255,255,0.25)",
|
||||
backdropFilter: "blur(4px)",
|
||||
},
|
||||
title: "活动标题,可配置图片",
|
||||
subTitle: "活动介绍说明文字",
|
||||
action: (
|
||||
<Button
|
||||
size="large"
|
||||
style={{
|
||||
float: 'right',
|
||||
borderRadius: 20,
|
||||
background: token.colorBgElevated,
|
||||
color: token.colorPrimary,
|
||||
width: 120,
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="pages.login.forgotPassword"
|
||||
defaultMessage="忘记密码"
|
||||
/>
|
||||
</a>
|
||||
去看看
|
||||
</Button>
|
||||
),
|
||||
}}
|
||||
actions={
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Divider plain>
|
||||
<span
|
||||
style={{
|
||||
color: token.colorTextPlaceholder,
|
||||
fontWeight: "normal",
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
其他登录方式
|
||||
</span>
|
||||
</Divider>
|
||||
<Space align="center" size={24}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
height: 40,
|
||||
width: 40,
|
||||
border: "1px solid " + token.colorPrimaryBorder,
|
||||
borderRadius: "50%",
|
||||
}}
|
||||
>
|
||||
<AlipayOutlined style={{ ...iconStyles, color: "#1677FF" }} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
height: 40,
|
||||
width: 40,
|
||||
border: "1px solid " + token.colorPrimaryBorder,
|
||||
borderRadius: "50%",
|
||||
}}
|
||||
>
|
||||
<TaobaoOutlined style={{ ...iconStyles, color: "#FF6A10" }} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
height: 40,
|
||||
width: 40,
|
||||
border: "1px solid " + token.colorPrimaryBorder,
|
||||
borderRadius: "50%",
|
||||
}}
|
||||
>
|
||||
<WeiboOutlined style={{ ...iconStyles, color: "#1890ff" }} />
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
</LoginForm>
|
||||
</div>
|
||||
<Footer />
|
||||
}
|
||||
>
|
||||
<Tabs
|
||||
centered
|
||||
activeKey={loginType}
|
||||
onChange={(activeKey) => setLoginType(activeKey as LoginType)}
|
||||
>
|
||||
<Tabs.TabPane key={"account"} tab={"账号密码登录"} />
|
||||
<Tabs.TabPane key={"phone"} tab={"手机号登录"} />
|
||||
</Tabs>
|
||||
{loginType === "account" && (
|
||||
<>
|
||||
<ProFormText
|
||||
name="username"
|
||||
fieldProps={{
|
||||
size: "large",
|
||||
prefix: (
|
||||
<UserOutlined
|
||||
style={{
|
||||
color: token.colorText,
|
||||
}}
|
||||
className={"prefixIcon"}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
placeholder={"用户名: admin or user"}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名!",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText.Password
|
||||
name="password"
|
||||
fieldProps={{
|
||||
size: "large",
|
||||
prefix: (
|
||||
<LockOutlined
|
||||
style={{
|
||||
color: token.colorText,
|
||||
}}
|
||||
className={"prefixIcon"}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
placeholder={"密码: ant.design"}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码!",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{loginType === "phone" && (
|
||||
<>
|
||||
<ProFormText
|
||||
fieldProps={{
|
||||
size: "large",
|
||||
prefix: (
|
||||
<MobileOutlined
|
||||
style={{
|
||||
color: token.colorText,
|
||||
}}
|
||||
className={"prefixIcon"}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
name="mobile"
|
||||
placeholder={"手机号"}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入手机号!",
|
||||
},
|
||||
{
|
||||
pattern: /^1\d{10}$/,
|
||||
message: "手机号格式错误!",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormCaptcha
|
||||
fieldProps={{
|
||||
size: "large",
|
||||
prefix: (
|
||||
<LockOutlined
|
||||
style={{
|
||||
color: token.colorText,
|
||||
}}
|
||||
className={"prefixIcon"}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
captchaProps={{
|
||||
size: "large",
|
||||
}}
|
||||
placeholder={"请输入验证码"}
|
||||
captchaTextRender={(timing, count) => {
|
||||
if (timing) {
|
||||
return `${count} ${"获取验证码"}`;
|
||||
}
|
||||
return "获取验证码";
|
||||
}}
|
||||
name="captcha"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "请输入验证码!",
|
||||
},
|
||||
]}
|
||||
onGetCaptcha={async () => {
|
||||
message.success("获取验证码成功!验证码为:1234");
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
marginBlockEnd: 24,
|
||||
}}
|
||||
>
|
||||
<ProFormCheckbox noStyle name="autoLogin">
|
||||
自动登录
|
||||
</ProFormCheckbox>
|
||||
<a
|
||||
style={{
|
||||
float: "right",
|
||||
}}
|
||||
>
|
||||
忘记密码
|
||||
</a>
|
||||
</div>
|
||||
</LoginFormPage>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
||||
export default () => {
|
||||
return (
|
||||
<ProConfigProvider dark>
|
||||
<Page />
|
||||
</ProConfigProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
// @ts-ignore
|
||||
import { startMock } from '@@/requestRecordMock';
|
||||
import { TestBrowser } from '@@/testBrowser';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import React, { act } from 'react';
|
||||
|
||||
const waitTime = (time: number = 100) => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
}, time);
|
||||
});
|
||||
};
|
||||
|
||||
let server: {
|
||||
close: () => void;
|
||||
};
|
||||
|
||||
describe('Login Page', () => {
|
||||
beforeAll(async () => {
|
||||
server = await startMock({
|
||||
port: 8000,
|
||||
scene: 'login',
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
server?.close();
|
||||
});
|
||||
|
||||
it('should show login form', async () => {
|
||||
const historyRef = React.createRef<any>();
|
||||
const rootContainer = render(
|
||||
<TestBrowser
|
||||
historyRef={historyRef}
|
||||
location={{
|
||||
pathname: '/user/login',
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
await rootContainer.findAllByText('Ant Design');
|
||||
|
||||
act(() => {
|
||||
historyRef.current?.push('/user/login');
|
||||
});
|
||||
|
||||
expect(
|
||||
rootContainer.baseElement?.querySelector('.ant-pro-form-login-desc')
|
||||
?.textContent,
|
||||
).toBe(
|
||||
'Ant Design is the most influential web design specification in Xihu district',
|
||||
);
|
||||
|
||||
expect(rootContainer.asFragment()).toMatchSnapshot();
|
||||
|
||||
rootContainer.unmount();
|
||||
});
|
||||
|
||||
it('should login success', async () => {
|
||||
const historyRef = React.createRef<any>();
|
||||
const rootContainer = render(
|
||||
<TestBrowser
|
||||
historyRef={historyRef}
|
||||
location={{
|
||||
pathname: '/user/login',
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
await rootContainer.findAllByText('Ant Design');
|
||||
|
||||
const userNameInput = await rootContainer.findByPlaceholderText(
|
||||
'Username: admin or user',
|
||||
);
|
||||
|
||||
act(() => {
|
||||
fireEvent.change(userNameInput, { target: { value: 'admin' } });
|
||||
});
|
||||
|
||||
const passwordInput = await rootContainer.findByPlaceholderText(
|
||||
'Password: ant.design',
|
||||
);
|
||||
|
||||
act(() => {
|
||||
fireEvent.change(passwordInput, { target: { value: 'ant.design' } });
|
||||
});
|
||||
|
||||
await (await rootContainer.findByText('Login')).click();
|
||||
|
||||
// 等待接口返回结果
|
||||
await waitTime(5000);
|
||||
|
||||
await rootContainer.findAllByText('Ant Design Pro');
|
||||
|
||||
expect(rootContainer.asFragment()).toMatchSnapshot();
|
||||
|
||||
await waitTime(2000);
|
||||
|
||||
rootContainer.unmount();
|
||||
});
|
||||
});
|
||||
@@ -1,94 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** 获取当前的用户 GET /api/currentUser */
|
||||
export async function currentUser(options?: { [key: string]: any }) {
|
||||
return request<{
|
||||
data: API.CurrentUser;
|
||||
}>('/api/currentUser', {
|
||||
method: 'GET',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 退出登录接口 POST /api/login/outLogin */
|
||||
export async function outLogin(options?: { [key: string]: any }) {
|
||||
return request<Record<string, any>>('/api/login/outLogin', {
|
||||
method: 'POST',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 登录接口 POST /api/login/account */
|
||||
export async function login(body: API.LoginParams, options?: { [key: string]: any }) {
|
||||
return request<API.LoginResult>('/api/login/account', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 此处后端没有提供注释 GET /api/notices */
|
||||
export async function getNotices(options?: { [key: string]: any }) {
|
||||
return request<API.NoticeIconList>('/api/notices', {
|
||||
method: 'GET',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取规则列表 GET /api/rule */
|
||||
export async function rule(
|
||||
params: {
|
||||
// query
|
||||
/** 当前的页码 */
|
||||
current?: number;
|
||||
/** 页面的容量 */
|
||||
pageSize?: number;
|
||||
},
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<API.RuleList>('/api/rule', {
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 更新规则 PUT /api/rule */
|
||||
export async function updateRule(options?: { [key: string]: any }) {
|
||||
return request<API.RuleListItem>('/api/rule', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
method: 'update',
|
||||
...(options || {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** 新建规则 POST /api/rule */
|
||||
export async function addRule(options?: { [key: string]: any }) {
|
||||
return request<API.RuleListItem>('/api/rule', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
method: 'post',
|
||||
...(options || {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除规则 DELETE /api/rule */
|
||||
export async function removeRule(options?: { [key: string]: any }) {
|
||||
return request<Record<string, any>>('/api/rule', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
method: 'delete',
|
||||
...(options || {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** 发送验证码 POST /api/login/captcha */
|
||||
export async function getFakeCaptcha(
|
||||
params: {
|
||||
// query
|
||||
/** 手机号 */
|
||||
phone?: string;
|
||||
},
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<API.FakeCaptcha>('/api/login/captcha', {
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
101
src/services/ant-design-pro/typings.d.ts
vendored
101
src/services/ant-design-pro/typings.d.ts
vendored
@@ -1,101 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
|
||||
declare namespace API {
|
||||
type CurrentUser = {
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
userid?: string;
|
||||
email?: string;
|
||||
signature?: string;
|
||||
title?: string;
|
||||
group?: string;
|
||||
tags?: { key?: string; label?: string }[];
|
||||
notifyCount?: number;
|
||||
unreadCount?: number;
|
||||
country?: string;
|
||||
access?: string;
|
||||
geographic?: {
|
||||
province?: { label?: string; key?: string };
|
||||
city?: { label?: string; key?: string };
|
||||
};
|
||||
address?: string;
|
||||
phone?: string;
|
||||
};
|
||||
|
||||
type LoginResult = {
|
||||
status?: string;
|
||||
type?: string;
|
||||
currentAuthority?: string;
|
||||
};
|
||||
|
||||
type PageParams = {
|
||||
current?: number;
|
||||
pageSize?: number;
|
||||
};
|
||||
|
||||
type RuleListItem = {
|
||||
key?: number;
|
||||
disabled?: boolean;
|
||||
href?: string;
|
||||
avatar?: string;
|
||||
name?: string;
|
||||
owner?: string;
|
||||
desc?: string;
|
||||
callNo?: number;
|
||||
status?: number;
|
||||
updatedAt?: string;
|
||||
createdAt?: string;
|
||||
progress?: number;
|
||||
};
|
||||
|
||||
type RuleList = {
|
||||
data?: RuleListItem[];
|
||||
/** 列表的内容总数 */
|
||||
total?: number;
|
||||
success?: boolean;
|
||||
};
|
||||
|
||||
type FakeCaptcha = {
|
||||
code?: number;
|
||||
status?: string;
|
||||
};
|
||||
|
||||
type LoginParams = {
|
||||
username?: string;
|
||||
password?: string;
|
||||
autoLogin?: boolean;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
type ErrorResponse = {
|
||||
/** 业务约定的错误码 */
|
||||
errorCode: string;
|
||||
/** 业务上的错误信息 */
|
||||
errorMessage?: string;
|
||||
/** 业务上的请求是否成功 */
|
||||
success?: boolean;
|
||||
};
|
||||
|
||||
type NoticeIconList = {
|
||||
data?: NoticeIconItem[];
|
||||
/** 列表的内容总数 */
|
||||
total?: number;
|
||||
success?: boolean;
|
||||
};
|
||||
|
||||
type NoticeIconItemType = 'notification' | 'message' | 'event';
|
||||
|
||||
type NoticeIconItem = {
|
||||
id?: string;
|
||||
extra?: string;
|
||||
key?: string;
|
||||
read?: boolean;
|
||||
avatar?: string;
|
||||
title?: string;
|
||||
status?: string;
|
||||
datetime?: string;
|
||||
description?: string;
|
||||
type?: NoticeIconItemType;
|
||||
};
|
||||
}
|
||||
153
src/services/login/index.ts
Normal file
153
src/services/login/index.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
import { request } from "@umijs/max";
|
||||
import * as API from "./types";
|
||||
|
||||
export interface SmsCodeVO {
|
||||
mobile: string;
|
||||
scene: number;
|
||||
}
|
||||
|
||||
export interface SmsLoginVO {
|
||||
mobile: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
// 登录
|
||||
// export const login = (data: UserLoginVO) => {
|
||||
// return request.post({ url: '/system/auth/login', data })
|
||||
// }
|
||||
export async function login(
|
||||
body: API.UserLoginVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.TokenType>("/system/auth/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
// 注册
|
||||
// export const register = (data: RegisterVO) => {
|
||||
// return request.post({ url: "/system/auth/register", data });
|
||||
// };
|
||||
|
||||
// 使用租户名,获得租户编号
|
||||
// export const getTenantIdByName = (name: string) => {
|
||||
// return request.get({ url: "/system/tenant/get-id-by-name?name=" + name });
|
||||
// };
|
||||
|
||||
export async function getTenantIdByName(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: { name: string },
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request("/system/tenant/get-id-by-name", {
|
||||
method: "GET",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
// 使用租户域名,获得租户信息
|
||||
// export const getTenantByWebsite = (website: string) => {
|
||||
// return request.get({
|
||||
// url: "/system/tenant/get-by-website?website=" + website,
|
||||
// });
|
||||
// };
|
||||
export async function getTenantByWebsite(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: { website: string },
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request("/system/tenant/get-by-website", {
|
||||
method: "GET",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
// 登出
|
||||
// export const loginOut = () => {
|
||||
// return request.post({ url: "/system/auth/logout" });
|
||||
// };
|
||||
export async function loginOut(
|
||||
body: API.UserLoginVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request("/system/auth/logout", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
// 获取用户权限信息
|
||||
// export const getInfo = () => {
|
||||
// return request.get({ url: "/system/auth/get-permission-info" });
|
||||
// };
|
||||
export async function getInfo(options?: { [key: string]: any }) {
|
||||
return request<IResponse<{ user: API.UserVO }>>(
|
||||
"/system/auth/get-permission-info",
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
//获取登录验证码
|
||||
// export const sendSmsCode = (data: SmsCodeVO) => {
|
||||
// return request.post({ url: "/system/auth/send-sms-code", data });
|
||||
// };
|
||||
|
||||
// // 短信验证码登录
|
||||
// export const smsLogin = (data: SmsLoginVO) => {
|
||||
// return request.post({ url: "/system/auth/sms-login", data });
|
||||
// };
|
||||
|
||||
// 社交快捷登录,使用 code 授权码
|
||||
// export function socialLogin(type: string, code: string, state: string) {
|
||||
// return request.post({
|
||||
// url: "/system/auth/social-login",
|
||||
// data: {
|
||||
// type,
|
||||
// code,
|
||||
// state,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// 社交授权的跳转
|
||||
// export const socialAuthRedirect = (type: number, redirectUri: string) => {
|
||||
// return request.get({
|
||||
// url:
|
||||
// "/system/auth/social-auth-redirect?type=" +
|
||||
// type +
|
||||
// "&redirectUri=" +
|
||||
// redirectUri,
|
||||
// });
|
||||
// };
|
||||
// 获取验证图片以及 token
|
||||
// export const getCode = (data: any) => {
|
||||
// debugger;
|
||||
// return request.postOriginal({ url: "system/captcha/get", data });
|
||||
// };
|
||||
|
||||
// 滑动或者点选验证
|
||||
// export const reqCheck = (data: any) => {
|
||||
// return request.postOriginal({ url: "system/captcha/check", data });
|
||||
// };
|
||||
|
||||
// 通过短信重置密码
|
||||
// export const smsResetPassword = (data: any) => {
|
||||
// return request.post({ url: "/system/auth/reset-password", data });
|
||||
// };
|
||||
41
src/services/login/oauth2/index.ts
Normal file
41
src/services/login/oauth2/index.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
// 获得授权信息
|
||||
export const getAuthorize = (clientId: string) => {
|
||||
return request.get({ url: '/system/oauth2/authorize?clientId=' + clientId })
|
||||
}
|
||||
|
||||
// 发起授权
|
||||
export const authorize = (
|
||||
responseType: string,
|
||||
clientId: string,
|
||||
redirectUri: string,
|
||||
state: string,
|
||||
autoApprove: boolean,
|
||||
checkedScopes: string[],
|
||||
uncheckedScopes: string[]
|
||||
) => {
|
||||
// 构建 scopes
|
||||
const scopes = {}
|
||||
for (const scope of checkedScopes) {
|
||||
scopes[scope] = true
|
||||
}
|
||||
for (const scope of uncheckedScopes) {
|
||||
scopes[scope] = false
|
||||
}
|
||||
// 发起请求
|
||||
return request.post({
|
||||
url: '/system/oauth2/authorize',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
params: {
|
||||
response_type: responseType,
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
state: state,
|
||||
auto_approve: autoApprove,
|
||||
scope: JSON.stringify(scopes)
|
||||
}
|
||||
})
|
||||
}
|
||||
38
src/services/login/types.ts
Normal file
38
src/services/login/types.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
export type UserLoginVO = {
|
||||
username: string
|
||||
password: string
|
||||
captchaVerification: string
|
||||
socialType?: string
|
||||
socialCode?: string
|
||||
socialState?: string
|
||||
}
|
||||
|
||||
export type TokenType = {
|
||||
id: number // 编号
|
||||
accessToken: string // 访问令牌
|
||||
refreshToken: string // 刷新令牌
|
||||
userId: number // 用户编号
|
||||
userType: number //用户类型
|
||||
clientId: string //客户端编号
|
||||
expiresTime: number //过期时间
|
||||
}
|
||||
|
||||
export type UserVO = {
|
||||
id: number
|
||||
username: string
|
||||
nickname: string
|
||||
deptId: number
|
||||
email: string
|
||||
mobile: string
|
||||
sex: number
|
||||
avatar: string
|
||||
loginIp: string
|
||||
loginDate: string
|
||||
}
|
||||
|
||||
export type RegisterVO = {
|
||||
tenantName: string
|
||||
username: string
|
||||
password: string
|
||||
captchaVerification: string
|
||||
}
|
||||
51
src/services/prodApi/category.ts
Normal file
51
src/services/prodApi/category.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from "@umijs/max";
|
||||
|
||||
/** 获取菜单页面的表 GET /product/category/categoryList */
|
||||
export async function getProductCategoryCategoryList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductCategoryCategoryListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultListCategoryDto>(
|
||||
"/product/category/categoryList",
|
||||
{
|
||||
method: "GET",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 创建产品类目 创建产品类目 POST /product/category/create */
|
||||
export async function postProductCategoryCreate(
|
||||
body: API.CategorySaveReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultLong>("/product/category/create", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 更新产品类目 更新产品类目 PUT /product/category/update */
|
||||
export async function putProductCategoryUpdate(
|
||||
body: API.CategorySaveReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/category/update", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/* eslint-disable */
|
||||
// API 更新时间:
|
||||
// API 唯一标识:
|
||||
import * as api from './api';
|
||||
import * as login from './login';
|
||||
import * as product from "./product";
|
||||
import * as category from "./category";
|
||||
export default {
|
||||
api,
|
||||
login,
|
||||
product,
|
||||
category,
|
||||
};
|
||||
601
src/services/prodApi/product.ts
Normal file
601
src/services/prodApi/product.ts
Normal file
@@ -0,0 +1,601 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from "@umijs/max";
|
||||
|
||||
/** 创建商品 创建商品 POST /prod/create */
|
||||
export async function postProdCreate(
|
||||
body: API.ProdSaveReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultLong>("/prod/create", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 创建商品 创建商品 POST /product/prod/create */
|
||||
export async function postProductProdCreate(
|
||||
body: API.ProdSaveReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultLong>("/product/prod/create", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 创建商品服务配置 创建商品服务配置 POST /product/prod/createProdService */
|
||||
export async function postProductProdCreateProdService(
|
||||
body: API.ProdServiceVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/createProdService", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除商品 删除商品 DELETE /product/prod/delete */
|
||||
export async function deleteProductProdOpenApiDelete(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteProductProd_openAPI_deleteParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/delete", {
|
||||
method: "DELETE",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量删除商品 批量删除商品 DELETE /product/prod/deleteSkuList */
|
||||
export async function deleteProductProdDeleteSkuList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteProductProdDeleteSkuListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/deleteSkuList", {
|
||||
method: "DELETE",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 获得商品回收站分页列表 获得商品回收站分页列表 GET /product/prod/getProdRecycleBinPageList */
|
||||
export async function getProductProdGetProdRecycleBinPageList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductProdGetProdRecycleBinPageListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultPageResultProdRestoreListVO>(
|
||||
"/product/prod/getProdRecycleBinPageList",
|
||||
{
|
||||
method: "GET",
|
||||
params: {
|
||||
// pageNo has a default value: 1
|
||||
pageNo: "1",
|
||||
// pageSize has a default value: 10
|
||||
pageSize: "10",
|
||||
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 获得商品服务信息 获得商品服务信息 GET /product/prod/getProdService */
|
||||
export async function getProductProdGetProdService(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductProdGetProdServiceParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultProdServiceVO>(
|
||||
"/product/prod/getProdService",
|
||||
{
|
||||
method: "GET",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 获得商品分页 获得商品分页 GET /product/prod/page */
|
||||
export async function getProductProdPage(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductProdPageParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultPageResultProdListVO>("/product/prod/page", {
|
||||
method: "GET",
|
||||
params: {
|
||||
// pageNo has a default value: 1
|
||||
pageNo: "1",
|
||||
// pageSize has a default value: 10
|
||||
pageSize: "10",
|
||||
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 恢复商品 恢复商品 POST /product/prod/restoreProdList */
|
||||
export async function postProductProdRestoreProdList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.postProductProdRestoreProdListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/restoreProdList", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 更新商品 更新商品 PUT /product/prod/update */
|
||||
export async function putProductProdUpdate(
|
||||
body: API.ProdSaveReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/update", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量上下架 批量上下架 DELETE /product/prod/updateSkuShelfList */
|
||||
export async function deleteProductProdUpdateSkuShelfList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteProductProdUpdateSkuShelfListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/updateSkuShelfList", {
|
||||
method: "DELETE",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改商品服务配置 修改商品服务配置 POST /product/prod/uptateProdService */
|
||||
export async function postProductProdUptateProdService(
|
||||
body: API.ProdServiceInfoVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/prod/uptateProdService", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 创建sku扩展服务配置 创建sku扩展服务配置 POST /product/sku/createSkuExtend */
|
||||
export async function postProductSkuCreateSkuExtend(
|
||||
body: API.SkuExtendVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/createSkuExtend", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除单品SKU 删除单品SKU DELETE /product/sku/delete */
|
||||
export async function deleteProductSkuOpenApiDelete(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteProductSku_openAPI_deleteParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/delete", {
|
||||
method: "DELETE",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除规格值 删除规格值 PUT /product/sku/deleteProp */
|
||||
export async function putProductSkuDeleteProp(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.putProductSkuDeletePropParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/deleteProp", {
|
||||
method: "PUT",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量删除SKU 批量删除SKU DELETE /product/sku/deleteSkuList */
|
||||
export async function deleteProductSkuDeleteSkuList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteProductSkuDeleteSkuListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/deleteSkuList", {
|
||||
method: "DELETE",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 禁用或者启用规格值 禁用规格值 PUT /product/sku/disableProp */
|
||||
export async function putProductSkuDisableProp(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.putProductSkuDisablePropParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/disableProp", {
|
||||
method: "PUT",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 获得单品SKU 获得单品SKU GET /product/sku/get */
|
||||
export async function getProductSkuGet(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductSkuGetParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultSkuRespVO>("/product/sku/get", {
|
||||
method: "GET",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取规格回收站 获取规格回收站 GET /product/sku/getPropRecycleBinList */
|
||||
export async function getProductSkuGetPropRecycleBinList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductSkuGetPropRecycleBinListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultPageResultProPropRecycleBinVO>(
|
||||
"/product/sku/getPropRecycleBinList",
|
||||
{
|
||||
method: "GET",
|
||||
params: {
|
||||
// pageNo has a default value: 1
|
||||
pageNo: "1",
|
||||
// pageSize has a default value: 10
|
||||
pageSize: "10",
|
||||
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取sku扩展服务配置信息 获取sku扩展服务配置信息 POST /product/sku/getSkuExtend */
|
||||
export async function postProductSkuGetSkuExtend(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.postProductSkuGetSkuExtendParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultSkuExtendVO>("/product/sku/getSkuExtend", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 获得SKU分页列表 获得SKU分页列表 GET /product/sku/getSkuPageList */
|
||||
export async function getProductSkuGetSkuPageList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductSkuGetSkuPageListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultPageResultSkuDO>(
|
||||
"/product/sku/getSkuPageList",
|
||||
{
|
||||
method: "GET",
|
||||
params: {
|
||||
// pageNo has a default value: 1
|
||||
pageNo: "1",
|
||||
// pageSize has a default value: 10
|
||||
pageSize: "10",
|
||||
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取sku规格 获取sku规格 GET /product/sku/getSKuPropList */
|
||||
export async function getProductSkuGetSKuPropList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductSkuGetSKuPropListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultSkuPropInfoVO>("/product/sku/getSKuPropList", {
|
||||
method: "GET",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 获得SKU回收站分页列表 获得SKU回收站分页列表 GET /product/sku/getSkuRecycleBinPageList */
|
||||
export async function getProductSkuGetSkuRecycleBinPageList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getProductSkuGetSkuRecycleBinPageListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultPageResultSkuRecycleBinVO>(
|
||||
"/product/sku/getSkuRecycleBinPageList",
|
||||
{
|
||||
method: "GET",
|
||||
params: {
|
||||
// pageNo has a default value: 1
|
||||
pageNo: "1",
|
||||
// pageSize has a default value: 10
|
||||
pageSize: "10",
|
||||
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 恢复规格 恢复规格 POST /product/sku/restorePropList */
|
||||
export async function postProductSkuRestorePropList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.postProductSkuRestorePropListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/restorePropList", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 恢复SKU 恢复SKU POST /product/sku/restoreSkuList */
|
||||
export async function postProductSkuRestoreSkuList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.postProductSkuRestoreSkuListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/restoreSkuList", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 更新单品SKU 更新单品SKU PUT /product/sku/update */
|
||||
export async function putProductSkuUpdate(
|
||||
body: API.SkuSaveReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/update", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改配送方式 修改配送方式 POST /product/sku/updateDeliver */
|
||||
export async function postProductSkuUpdateDeliver(
|
||||
body: API.SkuServiceDeliverDO[],
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateDeliver", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修物料配置 修物料配置 POST /product/sku/updateMaterial */
|
||||
export async function postProductSkuUpdateMaterial(
|
||||
body: API.SkuServiceMaterialDO[],
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateMaterial", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改属性规格值 修改属性规格值 PUT /product/sku/updateProdProp */
|
||||
export async function putProductSkuUpdateProdProp(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.putProductSkuUpdateProdPropParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateProdProp", {
|
||||
method: "PUT",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 新增统一保存sku规格 更新sku规格 PUT /product/sku/updateProp */
|
||||
export async function putProductSkuUpdateProp(
|
||||
body: API.SkuPropVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateProp", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改属性下面规格值 修改属性下面规格值 PUT /product/sku/updatePropValue */
|
||||
export async function putProductSkuUpdatePropValue(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.putProductSkuUpdatePropValueParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updatePropValue", {
|
||||
method: "PUT",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改扩展服务信息配置(遗体接运扩展服务,遗体清洁配置,追思告别配置,骨灰处理配置......) 修改扩展服务信息配置(遗体接运扩展服务,遗体清洁配置,追思告别配置,骨灰处理配置......) POST /product/sku/updateServiceDetails */
|
||||
export async function postProductSkuUpdateServiceDetails(
|
||||
body: API.SkuServiceDetailsDO[],
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateServiceDetails", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改单品上下架 修改单品上下架 PUT /product/sku/updateSkuShelf */
|
||||
export async function putProductSkuUpdateSkuShelf(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.putProductSkuUpdateSkuShelfParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateSkuShelf", {
|
||||
method: "PUT",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改单品上下架 修改单品上下架 POST /product/sku/updateSkuShelf */
|
||||
export async function postProductSkuUpdateSkuShelf(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.postProductSkuUpdateSkuShelfParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateSkuShelf", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量上下架 批量上下架 PUT /product/sku/updateSkuShelfList */
|
||||
export async function putProductSkuUpdateSkuShelfList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.putProductSkuUpdateSkuShelfListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateSkuShelfList", {
|
||||
method: "PUT",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量上下架 批量上下架 POST /product/sku/updateSkuShelfList */
|
||||
export async function postProductSkuUpdateSkuShelfList(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.postProductSkuUpdateSkuShelfListParams,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>("/product/sku/updateSkuShelfList", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改接运地址配置 修改接运地址配置 POST /product/sku/updateTransportAdress */
|
||||
export async function postProductSkuUpdateTransportAdress(
|
||||
body: API.SkuServiceTransportDO[],
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request<API.CommonResultBoolean>(
|
||||
"/product/sku/updateTransportAdress",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
}
|
||||
);
|
||||
}
|
||||
2086
src/services/prodApi/typings.d.ts
vendored
Normal file
2086
src/services/prodApi/typings.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
// API 更新时间:
|
||||
// API 唯一标识:
|
||||
import * as pet from './pet';
|
||||
import * as store from './store';
|
||||
import * as user from './user';
|
||||
export default {
|
||||
pet,
|
||||
store,
|
||||
user,
|
||||
};
|
||||
@@ -1,153 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** Update an existing pet PUT /pet */
|
||||
export async function updatePet(body: API.Pet, options?: { [key: string]: any }) {
|
||||
return request<any>('/pet', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Add a new pet to the store POST /pet */
|
||||
export async function addPet(body: API.Pet, options?: { [key: string]: any }) {
|
||||
return request<any>('/pet', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Find pet by ID Returns a single pet GET /pet/${param0} */
|
||||
export async function getPetById(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getPetByIdParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { petId: param0, ...queryParams } = params;
|
||||
return request<API.Pet>(`/pet/${param0}`, {
|
||||
method: 'GET',
|
||||
params: { ...queryParams },
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Updates a pet in the store with form data POST /pet/${param0} */
|
||||
export async function updatePetWithForm(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.updatePetWithFormParams,
|
||||
body: { name?: string; status?: string },
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { petId: param0, ...queryParams } = params;
|
||||
const formData = new FormData();
|
||||
|
||||
Object.keys(body).forEach((ele) => {
|
||||
const item = (body as any)[ele];
|
||||
|
||||
if (item !== undefined && item !== null) {
|
||||
formData.append(
|
||||
ele,
|
||||
typeof item === 'object' && !(item instanceof File) ? JSON.stringify(item) : item,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return request<any>(`/pet/${param0}`, {
|
||||
method: 'POST',
|
||||
params: { ...queryParams },
|
||||
data: formData,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Deletes a pet DELETE /pet/${param0} */
|
||||
export async function deletePet(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deletePetParams & {
|
||||
// header
|
||||
api_key?: string;
|
||||
},
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { petId: param0, ...queryParams } = params;
|
||||
return request<any>(`/pet/${param0}`, {
|
||||
method: 'DELETE',
|
||||
headers: {},
|
||||
params: { ...queryParams },
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** uploads an image POST /pet/${param0}/uploadImage */
|
||||
export async function uploadFile(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.uploadFileParams,
|
||||
body: { additionalMetadata?: string; file?: string },
|
||||
file?: File,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { petId: param0, ...queryParams } = params;
|
||||
const formData = new FormData();
|
||||
|
||||
if (file) {
|
||||
formData.append('file', file);
|
||||
}
|
||||
|
||||
Object.keys(body).forEach((ele) => {
|
||||
const item = (body as any)[ele];
|
||||
|
||||
if (item !== undefined && item !== null) {
|
||||
formData.append(
|
||||
ele,
|
||||
typeof item === 'object' && !(item instanceof File) ? JSON.stringify(item) : item,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return request<API.ApiResponse>(`/pet/${param0}/uploadImage`, {
|
||||
method: 'POST',
|
||||
params: { ...queryParams },
|
||||
data: formData,
|
||||
requestType: 'form',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Finds Pets by status Multiple status values can be provided with comma separated strings GET /pet/findByStatus */
|
||||
export async function findPetsByStatus(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.findPetsByStatusParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<API.Pet[]>('/pet/findByStatus', {
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Finds Pets by tags Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. GET /pet/findByTags */
|
||||
export async function findPetsByTags(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.findPetsByTagsParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<API.Pet[]>('/pet/findByTags', {
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** Returns pet inventories by status Returns a map of status codes to quantities GET /store/inventory */
|
||||
export async function getInventory(options?: { [key: string]: any }) {
|
||||
return request<Record<string, any>>('/store/inventory', {
|
||||
method: 'GET',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Place an order for a pet POST /store/order */
|
||||
export async function placeOrder(body: API.Order, options?: { [key: string]: any }) {
|
||||
return request<API.Order>('/store/order', {
|
||||
method: 'POST',
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Find purchase order by ID For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions GET /store/order/${param0} */
|
||||
export async function getOrderById(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getOrderByIdParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { orderId: param0, ...queryParams } = params;
|
||||
return request<API.Order>(`/store/order/${param0}`, {
|
||||
method: 'GET',
|
||||
params: { ...queryParams },
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Delete purchase order by ID For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors DELETE /store/order/${param0} */
|
||||
export async function deleteOrder(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteOrderParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { orderId: param0, ...queryParams } = params;
|
||||
return request<any>(`/store/order/${param0}`, {
|
||||
method: 'DELETE',
|
||||
params: { ...queryParams },
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
112
src/services/swagger/typings.d.ts
vendored
112
src/services/swagger/typings.d.ts
vendored
@@ -1,112 +0,0 @@
|
||||
declare namespace API {
|
||||
type ApiResponse = {
|
||||
code?: number;
|
||||
type?: string;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
type Category = {
|
||||
id?: number;
|
||||
name?: string;
|
||||
};
|
||||
|
||||
type deleteOrderParams = {
|
||||
/** ID of the order that needs to be deleted */
|
||||
orderId: number;
|
||||
};
|
||||
|
||||
type deletePetParams = {
|
||||
api_key?: string;
|
||||
/** Pet id to delete */
|
||||
petId: number;
|
||||
};
|
||||
|
||||
type deleteUserParams = {
|
||||
/** The name that needs to be deleted */
|
||||
username: string;
|
||||
};
|
||||
|
||||
type findPetsByStatusParams = {
|
||||
/** Status values that need to be considered for filter */
|
||||
status: ('available' | 'pending' | 'sold')[];
|
||||
};
|
||||
|
||||
type findPetsByTagsParams = {
|
||||
/** Tags to filter by */
|
||||
tags: string[];
|
||||
};
|
||||
|
||||
type getOrderByIdParams = {
|
||||
/** ID of pet that needs to be fetched */
|
||||
orderId: number;
|
||||
};
|
||||
|
||||
type getPetByIdParams = {
|
||||
/** ID of pet to return */
|
||||
petId: number;
|
||||
};
|
||||
|
||||
type getUserByNameParams = {
|
||||
/** The name that needs to be fetched. Use user1 for testing. */
|
||||
username: string;
|
||||
};
|
||||
|
||||
type loginUserParams = {
|
||||
/** The user name for login */
|
||||
username: string;
|
||||
/** The password for login in clear text */
|
||||
password: string;
|
||||
};
|
||||
|
||||
type Order = {
|
||||
id?: number;
|
||||
petId?: number;
|
||||
quantity?: number;
|
||||
shipDate?: string;
|
||||
/** Order Status */
|
||||
status?: 'placed' | 'approved' | 'delivered';
|
||||
complete?: boolean;
|
||||
};
|
||||
|
||||
type Pet = {
|
||||
id?: number;
|
||||
category?: Category;
|
||||
name: string;
|
||||
photoUrls: string[];
|
||||
tags?: Tag[];
|
||||
/** pet status in the store */
|
||||
status?: 'available' | 'pending' | 'sold';
|
||||
};
|
||||
|
||||
type Tag = {
|
||||
id?: number;
|
||||
name?: string;
|
||||
};
|
||||
|
||||
type updatePetWithFormParams = {
|
||||
/** ID of pet that needs to be updated */
|
||||
petId: number;
|
||||
};
|
||||
|
||||
type updateUserParams = {
|
||||
/** name that need to be updated */
|
||||
username: string;
|
||||
};
|
||||
|
||||
type uploadFileParams = {
|
||||
/** ID of pet to update */
|
||||
petId: number;
|
||||
};
|
||||
|
||||
type User = {
|
||||
id?: number;
|
||||
username?: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
password?: string;
|
||||
phone?: string;
|
||||
/** User Status */
|
||||
userStatus?: number;
|
||||
};
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** Create user This can only be done by the logged in user. POST /user */
|
||||
export async function createUser(body: API.User, options?: { [key: string]: any }) {
|
||||
return request<any>('/user', {
|
||||
method: 'POST',
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Get user by user name GET /user/${param0} */
|
||||
export async function getUserByName(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.getUserByNameParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { username: param0, ...queryParams } = params;
|
||||
return request<API.User>(`/user/${param0}`, {
|
||||
method: 'GET',
|
||||
params: { ...queryParams },
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Updated user This can only be done by the logged in user. PUT /user/${param0} */
|
||||
export async function updateUser(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.updateUserParams,
|
||||
body: API.User,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { username: param0, ...queryParams } = params;
|
||||
return request<any>(`/user/${param0}`, {
|
||||
method: 'PUT',
|
||||
params: { ...queryParams },
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Delete user This can only be done by the logged in user. DELETE /user/${param0} */
|
||||
export async function deleteUser(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.deleteUserParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
const { username: param0, ...queryParams } = params;
|
||||
return request<any>(`/user/${param0}`, {
|
||||
method: 'DELETE',
|
||||
params: { ...queryParams },
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Creates list of users with given input array POST /user/createWithArray */
|
||||
export async function createUsersWithArrayInput(
|
||||
body: API.User[],
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<any>('/user/createWithArray', {
|
||||
method: 'POST',
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Creates list of users with given input array POST /user/createWithList */
|
||||
export async function createUsersWithListInput(body: API.User[], options?: { [key: string]: any }) {
|
||||
return request<any>('/user/createWithList', {
|
||||
method: 'POST',
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Logs user into the system GET /user/login */
|
||||
export async function loginUser(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.loginUserParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<string>('/user/login', {
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Logs out current logged in user session GET /user/logout */
|
||||
export async function logoutUser(options?: { [key: string]: any }) {
|
||||
return request<any>('/user/logout', {
|
||||
method: 'GET',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
0
src/services/system/index.ts
Normal file
0
src/services/system/index.ts
Normal file
119
src/services/system/permission/index.ts
Normal file
119
src/services/system/permission/index.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { request } from "@umijs/max";
|
||||
|
||||
export interface PermissionAssignUserRoleReqVO {
|
||||
userId: number;
|
||||
roleIds: number[];
|
||||
}
|
||||
|
||||
export interface PermissionAssignRoleMenuReqVO {
|
||||
roleId: number;
|
||||
menuIds: number[];
|
||||
}
|
||||
|
||||
export interface PermissionAssignRoleDataScopeReqVO {
|
||||
roleId: number;
|
||||
dataScope: number;
|
||||
dataScopeDeptIds: number[];
|
||||
}
|
||||
|
||||
// export async function postProductProdRestoreProdList(
|
||||
// // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
// params: API.postProductProdRestoreProdListParams,
|
||||
// options?: { [key: string]: any }
|
||||
// ) {
|
||||
// return request<API.CommonResultBoolean>("/product/prod/restoreProdList", {
|
||||
// method: "POST",
|
||||
// params: {
|
||||
// ...params,
|
||||
// },
|
||||
// ...(options || {}),
|
||||
// });
|
||||
// }
|
||||
// export async function getRoleMenuList(
|
||||
// // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
// params: API.getProductCategoryCategoryListParams,
|
||||
// options?: { [key: string]: any }
|
||||
// ) {
|
||||
// return request<API.CommonResultListCategoryDto>(
|
||||
// "/product/category/categoryList",
|
||||
// {
|
||||
// method: "GET",
|
||||
// params: {
|
||||
// ...params,
|
||||
// },
|
||||
// ...(options || {}),
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// 查询角色拥有的菜单权限
|
||||
// export const getRoleMenuList = async (roleId: number) => {
|
||||
// return await request.get({ url: '/system/permission/list-role-menus?roleId=' + roleId })
|
||||
// }
|
||||
export async function getRoleMenuList(roleId: number) {
|
||||
return request("/system/permission/list-role-menus", {
|
||||
method: "GET",
|
||||
params: {
|
||||
roleId,
|
||||
},
|
||||
});
|
||||
}
|
||||
// // 赋予角色菜单权限
|
||||
// export const assignRoleMenu = async (data: PermissionAssignRoleMenuReqVO) => {
|
||||
// return await request.post({ url: '/system/permission/assign-role-menu', data })
|
||||
// }
|
||||
export async function assignRoleMenu(
|
||||
params: PermissionAssignRoleMenuReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request("/system/permission/assign-role-menu", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
// // 赋予角色数据权限
|
||||
// export const assignRoleDataScope = async (data: PermissionAssignRoleDataScopeReqVO) => {
|
||||
// return await request.post({ url: '/system/permission/assign-role-data-scope', data })
|
||||
// }
|
||||
export async function assignRoleDataScope(
|
||||
params: PermissionAssignRoleDataScopeReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request("/system/permission/assign-role-data-scope", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
// // 查询用户拥有的角色数组
|
||||
// export const getUserRoleList = async (userId: number) => {
|
||||
// return await request.get({ url: '/system/permission/list-user-roles?userId=' + userId })
|
||||
// }
|
||||
export async function getUserRoleList(userId: number) {
|
||||
return request("/system/permission/list-user-roles", {
|
||||
method: "GET",
|
||||
params: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
// // 赋予用户角色
|
||||
// export const assignUserRole = async (data: PermissionAssignUserRoleReqVO) => {
|
||||
// return await request.post({ url: '/system/permission/assign-user-role', data })
|
||||
// }
|
||||
export async function assignUserRole(
|
||||
params: PermissionAssignUserRoleReqVO,
|
||||
options?: { [key: string]: any }
|
||||
) {
|
||||
return request("/system/permission/assign-user-role", {
|
||||
method: "POST",
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
0
src/services/system/typings.d.ts
vendored
Normal file
0
src/services/system/typings.d.ts
vendored
Normal file
78
src/types/global.d.ts
vendored
Normal file
78
src/types/global.d.ts
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
export {};
|
||||
declare global {
|
||||
interface Fn<T = any> {
|
||||
(...arg: T[]): T;
|
||||
}
|
||||
|
||||
type Nullable<T> = T | null;
|
||||
|
||||
type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>;
|
||||
|
||||
type Recordable<T = any, K = string> = Record<
|
||||
K extends null | undefined ? string : K,
|
||||
T
|
||||
>;
|
||||
|
||||
type ComponentRef<T> = InstanceType<T>;
|
||||
|
||||
type LocaleType = "zh-CN" | "en";
|
||||
|
||||
declare type TimeoutHandle = ReturnType<typeof setTimeout>;
|
||||
declare type IntervalHandle = ReturnType<typeof setInterval>;
|
||||
|
||||
type AxiosHeaders =
|
||||
| "application/json"
|
||||
| "application/x-www-form-urlencoded"
|
||||
| "multipart/form-data";
|
||||
|
||||
type AxiosMethod =
|
||||
| "get"
|
||||
| "post"
|
||||
| "delete"
|
||||
| "put"
|
||||
| "GET"
|
||||
| "POST"
|
||||
| "DELETE"
|
||||
| "PUT";
|
||||
|
||||
type AxiosResponseType =
|
||||
| "arraybuffer"
|
||||
| "blob"
|
||||
| "document"
|
||||
| "json"
|
||||
| "text"
|
||||
| "stream";
|
||||
|
||||
interface AxiosConfig {
|
||||
params?: any;
|
||||
data?: any;
|
||||
url?: string;
|
||||
method?: AxiosMethod;
|
||||
headersType?: string;
|
||||
responseType?: AxiosResponseType;
|
||||
}
|
||||
|
||||
interface IResponse<T> {
|
||||
code: string;
|
||||
data: T;
|
||||
msg: string;
|
||||
}
|
||||
|
||||
interface PageParam {
|
||||
pageSize?: number;
|
||||
pageNo?: number;
|
||||
total?: number;
|
||||
}
|
||||
|
||||
interface Tree {
|
||||
id: number;
|
||||
name: string;
|
||||
children?: Tree[] | any[];
|
||||
}
|
||||
// 分页数据公共返回
|
||||
interface PageResult<T> {
|
||||
list: T; // 数据
|
||||
total: number; // 总量
|
||||
msg: string;
|
||||
}
|
||||
}
|
||||
72
src/utils/auth.ts
Normal file
72
src/utils/auth.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { useCache, CACHE_KEY } from "@/hooks/web/useCache";
|
||||
import type { TokenType } from "@/services/login/types";
|
||||
import { decrypt, encrypt } from "@/utils/jsencrypt";
|
||||
|
||||
const { wsCache } = useCache();
|
||||
|
||||
const AccessTokenKey = "ACCESS_TOKEN";
|
||||
const RefreshTokenKey = "REFRESH_TOKEN";
|
||||
|
||||
// 获取token
|
||||
export const getAccessToken = () => {
|
||||
// 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错
|
||||
const accessToken = wsCache.get(AccessTokenKey);
|
||||
return accessToken ? accessToken : wsCache.get("ACCESS_TOKEN");
|
||||
};
|
||||
|
||||
// 刷新token
|
||||
export const getRefreshToken = () => {
|
||||
return wsCache.get(RefreshTokenKey);
|
||||
};
|
||||
|
||||
// 设置token
|
||||
export const setToken = (token: TokenType) => {
|
||||
wsCache.set(RefreshTokenKey, token.refreshToken);
|
||||
wsCache.set(AccessTokenKey, token.accessToken);
|
||||
};
|
||||
|
||||
// 删除token
|
||||
export const removeToken = () => {
|
||||
wsCache.delete(AccessTokenKey);
|
||||
wsCache.delete(RefreshTokenKey);
|
||||
};
|
||||
|
||||
/** 格式化token(jwt格式) */
|
||||
export const formatToken = (token: string): string => {
|
||||
return "Bearer " + token;
|
||||
};
|
||||
// ========== 账号相关 ==========
|
||||
|
||||
export type LoginFormType = {
|
||||
tenantName: string;
|
||||
username: string;
|
||||
password: string;
|
||||
rememberMe: boolean;
|
||||
};
|
||||
|
||||
export const getLoginForm = () => {
|
||||
const loginForm: LoginFormType = wsCache.get(CACHE_KEY.LoginForm);
|
||||
if (loginForm) {
|
||||
loginForm.password = decrypt(loginForm.password) as string;
|
||||
}
|
||||
return loginForm;
|
||||
};
|
||||
|
||||
export const setLoginForm = (loginForm: LoginFormType) => {
|
||||
loginForm.password = encrypt(loginForm.password) as string;
|
||||
wsCache.set(CACHE_KEY.LoginForm, loginForm, { exp: 30 * 24 * 60 * 60 });
|
||||
};
|
||||
|
||||
export const removeLoginForm = () => {
|
||||
wsCache.delete(CACHE_KEY.LoginForm);
|
||||
};
|
||||
|
||||
// ========== 租户相关 ==========
|
||||
|
||||
export const getTenantId = () => {
|
||||
return wsCache.get(CACHE_KEY.TenantId);
|
||||
};
|
||||
|
||||
export const setTenantId = (username: string) => {
|
||||
wsCache.set(CACHE_KEY.TenantId, username);
|
||||
};
|
||||
31
src/utils/jsencrypt.ts
Normal file
31
src/utils/jsencrypt.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { JSEncrypt } from 'jsencrypt'
|
||||
|
||||
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
||||
|
||||
const publicKey =
|
||||
'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
|
||||
'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
||||
|
||||
const privateKey =
|
||||
'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
|
||||
'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
|
||||
'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
|
||||
'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
|
||||
'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
|
||||
'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
|
||||
'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
|
||||
'UP8iWi1Qw0Y='
|
||||
|
||||
// 加密
|
||||
export const encrypt = (txt: string) => {
|
||||
const encryptor = new JSEncrypt()
|
||||
encryptor.setPublicKey(publicKey) // 设置公钥
|
||||
return encryptor.encrypt(txt) // 对数据进行加密
|
||||
}
|
||||
|
||||
// 解密
|
||||
export const decrypt = (txt: string) => {
|
||||
const encryptor = new JSEncrypt()
|
||||
encryptor.setPrivateKey(privateKey) // 设置私钥
|
||||
return encryptor.decrypt(txt) // 对数据进行解密
|
||||
}
|
||||
@@ -19,5 +19,5 @@
|
||||
}
|
||||
},
|
||||
"include": ["./**/*.d.ts", "./**/*.ts", "./**/*.tsx"],
|
||||
"exclude": ["config"]
|
||||
"exclude": ["config", "src/services/*/*.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user