ソースを参照

update auth api

dev
powersir 1年前
コミット
88b812d0c4
16個のファイルの変更420行の追加152行の削除
  1. +0
    -0
      .env.development
  2. +0
    -1
      build/utils.ts
  3. +1
    -1
      src/layout/header/index.tsx
  4. +6
    -0
      src/models/index.ts
  5. +4
    -29
      src/models/user.ts
  6. +3
    -3
      src/pages/custom/product/sample/components/attr-editor.tsx
  7. +165
    -0
      src/pages/custom/product/sample/components/mask-picture-editor.tsx
  8. +123
    -62
      src/pages/custom/product/sample/index.tsx
  9. +25
    -16
      src/pages/login/index.tsx
  10. +61
    -14
      src/request/index.ts
  11. +16
    -0
      src/request/service/auth.ts
  12. +0
    -15
      src/request/service/login.ts
  13. +3
    -3
      src/request/service/user.ts
  14. +11
    -5
      src/store/global/index.ts
  15. +1
    -3
      src/utils/env.ts
  16. +1
    -0
      vite.config.ts

.env.develop → .env.development ファイルの表示


+ 0
- 1
build/utils.ts ファイルの表示

@@ -20,7 +20,6 @@ export function isReportMode(): boolean {
// Read all environment variable configuration files to process.env
export function wrapperEnv(envConf: Recordable): ViteEnv {
const ret: any = {};

for (const envName of Object.keys(envConf)) {
let realName = envConf[envName].replace(/\\n/g, '\n');
realName = realName === 'true' ? true : realName === 'false' ? false : realName;


+ 1
- 1
src/layout/header/index.tsx ファイルの表示

@@ -12,7 +12,7 @@ import { i18n, t } from '@/utils/i18n';
import { BellOutlined, MenuOutlined, SettingOutlined } from '@ant-design/icons';
import { useUserStore } from '@/store/global/user';
import { useRequest } from '@/hooks/use-request';
import loginService from '@/request/service/login';
import loginService from '@/request/service/auth';

const Header = () => {



+ 6
- 0
src/models/index.ts ファイルの表示

@@ -1,5 +1,11 @@
export * from './user.ts'

export interface ResponseDTO<T>{
code: number;
msg: string;
data: T
}

export interface PageData<T> {
data: T[];
total: number;


+ 4
- 29
src/models/user.ts ファイルの表示

@@ -1,9 +1,11 @@
export interface LoginDTO {
userName: string;
captchaVerification: string;
username: string;
password: string;
rememberMe: boolean;
tenantName: string;
}


export interface TokenDTO {
userId: number,
accessToken: string;
@@ -55,33 +57,6 @@ export interface UserDTO {
idToString: string;
}

export interface PopMenu {
id: number;
parentid: number;
homeid: number;
menuName: string;
parentMenuName: string;
pageUrl: string;
sort: number;
level: number;
}

export interface LoginRespDTO {
ack: number;
data: UserDTO;
msg: string;
pop: Array<PopMenu>;
}

// "id": 0,
// "parentId": 1024,
// "name": "芋道",
// "path": "post",
// "component": "system/post/index",
// "icon": "/menu/list",
// "visible": false,
// "keepAlive": false

export interface Menu {
id: string;
parentId?: string;


src/pages/custom/product/sample/attr-editor.tsx → src/pages/custom/product/sample/components/attr-editor.tsx ファイルの表示

@@ -43,7 +43,7 @@ const getBase64 = (file: RcFile): Promise<string> =>
});


const CreateSampleAttr: React.FC<CreateSampleAttrProps> = (props) => {
const SampleAttrEditor: React.FC<CreateSampleAttrProps> = (props) => {

const { visible, onCancel, curRecord, onSave, editData } = props;
const [saveLoading, setSaveLoading] = useState(false);
@@ -144,7 +144,7 @@ const CreateSampleAttr: React.FC<CreateSampleAttrProps> = (props) => {
okText="确认"
cancelText="取消"
>
<DeleteOutlined style={{ fontSize: '16px' }}/>
<DeleteOutlined style={{ fontSize: '16px' }} className='hover:(bg-[rgb(94,53,177)]'/>
</Popconfirm>
}
>
@@ -207,4 +207,4 @@ const CreateSampleAttr: React.FC<CreateSampleAttrProps> = (props) => {
)
}

export default CreateSampleAttr;
export default SampleAttrEditor;

+ 165
- 0
src/pages/custom/product/sample/components/mask-picture-editor.tsx ファイルの表示

@@ -0,0 +1,165 @@
import React, { useEffect, useMemo, useState } from 'react'
import { CloseOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import { Drawer, Form, Input, Card, Space, Button, Upload, Popconfirm, Modal, FormListOperation, FormListFieldData } from 'antd'
import type { RcFile, UploadProps } from 'antd/es/upload';
import type { UploadFile } from 'antd/es/upload/interface';

const layout = {
labelCol: { span: 4, },
wrapperCol: { span: 16 },
bordered: false,
};

// {
// "id": 412,
// "prototypeId": 89,
// "": 1991125,
// "maskImgId": 1991130,
// "imgName": "3.jpg",
// "imgType": 2,
// "imgWidth": 600.0,
// "imgHeight": 600.0,
// "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A056.jpg",
// "maskImgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114413A061.png"
// }

export interface MaskPicture {
id: number;
prototypeId: number;
imgId: number;
maskImgId?: number;
imgName: string;
imgType: number;
imgWidth: number;
imgHeight: number;
imgUrl: string;
maskImgUrl?: string;
}

interface MaskPictureProps {
visible: boolean;
onCancel: (flag?: boolean) => void;
onSave: () => void;
dataSource?: MaskPicture[] | null;
}

const getBase64 = (file: RcFile): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});


const MaskPictureEditor: React.FC<MaskPictureProps> = (props) => {

const { visible, onCancel, onSave, dataSource } = props;
const [saveLoading, setSaveLoading] = useState(false);
const [previewOpen, setPreviewOpen] = useState(false);
const [previewImage, setPreviewImage] = useState('');
const [previewTitle, setPreviewTitle] = useState('');
const [form] = Form.useForm();

useEffect(() => {
if (visible) {
setInitValue();
} else {
form.resetFields();
}
}, [visible]);

async function setInitValue() {
}

const save = async (values: any) => {
setSaveLoading(true);

setSaveLoading(false);
}

const handleCancel = () => setPreviewOpen(false);

const handlePreview = async (file: UploadFile) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj as RcFile);
}

setPreviewImage(file.url || (file.preview as string));
setPreviewOpen(true);
setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));
};

const uploadButton = (text: string) => (
<div>
<PlusOutlined />
<div style={{ marginTop: 8 }}>{text}</div>
</div>
);

const handleChange: UploadProps['onChange'] = (info) => {
debugger
}

const MaskPictureItem = (item: MaskPicture) => {
const mainPicture: UploadFile[] = [{
uid: `${item.imgId}`,
name: item.imgUrl.split("/")[-1],
status: 'done',
url: item.imgUrl,
}]
const maskPicture: UploadFile[] = item.maskImgId ? [{
uid: `${item.maskImgId}`,
name: item.maskImgUrl!!.split("/")[-1],
status: 'done',
url: item.maskImgUrl,
}] : []
return (
<div className='flex justify-start'>
<Upload
listType="picture-card"
fileList={mainPicture}
maxCount={1}
onPreview={handlePreview}
onChange={handleChange}>
{mainPicture.length === 0 && uploadButton("上传主图")}
</Upload>
<Upload
listType="picture-card"
fileList={maskPicture}
onPreview={handlePreview}
maxCount={1}>
{maskPicture.length === 0 && uploadButton("上传蒙版图")}
</Upload>
</div>
)
}

return (
<>
<Drawer
open={visible}
title="蒙版图"

onClose={() => { onCancel() }}
extra={
<Space>
<Button type="primary" size='middle' onClick={() => { save }}>
保存
</Button>
</Space>
}
destroyOnClose
>
{dataSource?.map((item) => {
return MaskPictureItem(item)
})}
</Drawer>
<Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel} zIndex={2000}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
</>
)
}

export default MaskPictureEditor;

+ 123
- 62
src/pages/custom/product/sample/index.tsx ファイルの表示

@@ -4,8 +4,10 @@ import { t } from '@/utils/i18n';
import { IconBuguang } from '@/assets/icons/buguang';
import React, { useState } from 'react';
import type { TableRowSelection } from 'antd/es/table/interface';
import CreateSampleAttr from './attr-editor'
import type { SampleAttribute } from './attr-editor'
import SampleAttrEditor from './components/attr-editor'
import MaskPictureEditor from './components/mask-picture-editor';
import type { SampleAttribute } from './components/attr-editor'
import type { MaskPicture } from './components/mask-picture-editor';

interface DataType {
id: number;
@@ -50,7 +52,7 @@ const TablePage: React.FC = () => {
key: 'prototypeName',
},
{
title:'类目',
title: '类目',
key: 'categoryName',
dataIndex: 'categoryName'
},
@@ -60,7 +62,7 @@ const TablePage: React.FC = () => {
key: 'createName',
},
{
title:'创建时间',
title: '创建时间',
key: 'createTime',
dataIndex: 'createTime'
},
@@ -69,11 +71,13 @@ const TablePage: React.FC = () => {
key: 'action',
render: (_, record) => (
<Space size="middle">
<a>蒙版图 </a>
<a onClick={() => {
setMaskEditorVisible(true)
}}>蒙版图 </a>
<a
onClick={() => {
// setEditData(record);
setCreateVisible(true);
setAttrEditorVisible(true);
}}>属性设置</a>
<a>编辑</a>
<a>删除</a>
@@ -96,72 +100,123 @@ const TablePage: React.FC = () => {
dictDetails: []
},
{
id: 76,
createTime: "2023-07-13 17:24:25",
spuCode: "2-47GEE7",
categoryId: 1264,
prototypeName: "kfc-test",
createId: 2,
categoryName: "男士T恤",
createName: "陈相荣✨",
oneImgUrl: "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A056.jpg",
dictDetails: []
id: 76,
createTime: "2023-07-13 17:24:25",
spuCode: "2-47GEE7",
categoryId: 1264,
prototypeName: "kfc-test",
createId: 2,
categoryName: "男士T恤",
createName: "陈相荣✨",
oneImgUrl: "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A056.jpg",
dictDetails: []
}
];

const attrData: SampleAttribute[] = [
{
"id": 105,
"prototypeId": 88,
"attrName": "Color",
"isContainImg": 1,
"attrVals": [
{
"id": 273,
"attrId": 105,
"valName": "Pink",
"imgId": 1990260,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821104322A047.jpg"
},
{
"id": 274,
"attrId": 105,
"valName": "Black",
"imgId": 1990263,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821104322A050.jpg"
}
]
"id": 105,
"prototypeId": 88,
"attrName": "Color",
"isContainImg": 1,
"attrVals": [
{
"id": 273,
"attrId": 105,
"valName": "Pink",
"imgId": 1990260,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821104322A047.jpg"
},
{
"id": 274,
"attrId": 105,
"valName": "Black",
"imgId": 1990263,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821104322A050.jpg"
}
]
},
{
"id": 106,
"prototypeId": 88,
"attrName": "Size",
"isContainImg": 2,
"attrVals": [
{
"id": 275,
"attrId": 106,
"valName": "XL"
},
{
"id": 276,
"attrId": 106,
"valName": "XXL"
}
]
"id": 106,
"prototypeId": 88,
"attrName": "Size",
"isContainImg": 2,
"attrVals": [
{
"id": 275,
"attrId": 106,
"valName": "XL"
},
{
"id": 276,
"attrId": 106,
"valName": "XXL"
}
]
}
]
]

const maskPictures: MaskPicture[] = [
{
"id": 412,
"prototypeId": 89,
"imgId": 1991125,
"maskImgId": 1991130,
"imgName": "3.jpg",
"imgType": 2,
"imgWidth": 600.0,
"imgHeight": 600.0,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A056.jpg",
"maskImgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114413A061.png"
},
{
"id": 413,
"prototypeId": 89,
"imgId": 1991122,
"maskImgId": 1991131,
"imgName": "1.jpg",
"imgType": 2,
"imgWidth": 600.0,
"imgHeight": 600.0,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A053.jpg",
"maskImgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114413A062.png"
},
{
"id": 414,
"prototypeId": 89,
"imgId": 1991127,
"imgName": "f60911abe38e82e9dd2aaa75f3292ed2.jpg",
"imgType": 2,
"imgWidth": 1000.0,
"imgHeight": 1000.0,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A058.jpg"
},
{
"id": 415,
"prototypeId": 89,
"imgId": 1991123,
"imgName": "d247c5ec0ef78f302b803c6bf00658a2.jpg",
"imgType": 2,
"imgWidth": 1000.0,
"imgHeight": 1000.0,
"imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A054.jpg"
}
]

const [createVisible, setCreateVisible] = useState(false);
const [attrEditorVisible, setAttrEditorVisible] = useState(false);
const [maskEditorVisible, setMaskEditorVisible] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);

const cancelHandle = () => {
setCreateVisible(false);
setAttrEditorVisible(false);
};

const saveHandle = () => {
setCreateVisible(false);
const saveAttributeHandle = () => {
setAttrEditorVisible(false);
}

const saveMaskPictureHandle = () => {
setMaskEditorVisible(false);
}

const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
@@ -211,16 +266,22 @@ const TablePage: React.FC = () => {
return (
<div>
<div className="dark:bg-[rgb(33,41,70)] rounded-md">
<Table rowKey="id" rowSelection={rowSelection} scroll={{ x: true }} columns={columns} dataSource={data} className='bg-transparent'
<Table rowKey="id" rowSelection={rowSelection} scroll={{ x: true }} columns={columns} dataSource={data} className='bg-transparent'
pagination={{ position: ['bottomRight'] }}
/>
</div>
<CreateSampleAttr
onSave={saveHandle}
<SampleAttrEditor
onSave={saveAttributeHandle}
onCancel={cancelHandle}
visible={createVisible}
visible={attrEditorVisible}
curRecord={attrData}
editData={attrData}></CreateSampleAttr>
editData={attrData} />

<MaskPictureEditor
onSave={saveMaskPictureHandle}
onCancel={()=>{ setMaskEditorVisible(false) }}
visible={maskEditorVisible}
dataSource={maskPictures} />
</div>
);
};


+ 25
- 16
src/pages/login/index.tsx ファイルの表示

@@ -6,32 +6,31 @@ import { useNavigate } from 'react-router-dom';
import { useRequest } from '@/hooks/use-request';
import { useUserStore } from '@/store/global/user';
import { useGlobalStore } from '@/store/global';
import loginService from '@/request/service/login';
import loginService from '@/request/service/auth';
import userService from '@/request/service/user';
import homeService from '@/request/service/home';
import { LoginDTO } from '@/models';
import './index.css'

const Login = () => {
const navigate = useNavigate();
const { runAsync: getUserInfo } = useRequest(userService.getUserInfo, { manual: true });
const { runAsync: getAnnouncement } = useRequest(homeService.getAnnouncement, { manual: true });
const { runAsync: listMenus } = useRequest(userService.listMenus, { manual: true });
const { runAsync: login, loading } = useRequest(loginService.login, { manual: true });
const { runAsync: rerefshToken } = useRequest(loginService.rerefshToken, { manual: true });
const { setCurrentUser } = useUserStore();
const { setCookie } = useGlobalStore();
const { setToken, setRefreshToken } = useGlobalStore();
const onFinish = async (values: LoginDTO) => {
const [loginError, data] = await login(values);
values.captchaVerification = "jKXK3cg440w2wbLQWBHOjDURNqT5sfMsQmkwMAEvzapLhQZh7YiMlEah/WhVXqygFmNO4SXEC4MzkjoRqgYK7A=="
values.rememberMe = true
const [loginError, {data}] = await login(values);
if (loginError) {
return;
}
data.data.avatarUrl = 'https://test.vogocm.com:9010/eshop/eshop_img/2023/5/24/43853633d16749bfb291f81bebb73451_20230524150631A001.jpg';
setCookie(data.msg);
setCurrentUser(data.data);
const [e, userInfo] = await getUserInfo();
const [ _, announcementData ] = await getAnnouncement();
console.log(announcementData)
console.log(userInfo)
// data.data.avatarUrl = 'https://test.vogocm.com:9010/eshop/eshop_img/2023/5/24/43853633d16749bfb291f81bebb73451_20230524150631A001.jpg';
setRefreshToken(data.refreshToken);
setToken(data.accessToken);
const [ _, { data: menus } ] = await listMenus()
// const [ error, {data: tokenData}] = await rerefshToken(data.refreshToken)
debugger
navigate('/');
};

@@ -51,12 +50,22 @@ const Login = () => {
<Form
name="super-admin"
className="login-form"
initialValues={{ userName: 'admin', password: '1' }}
initialValues={{ username: 'admin', password: 'admin123', tenantName: '芋道源码' }}
onFinish={onFinish}
size="large"
>
<Form.Item
name="userName"
name="tenantName"
rules={[{ required: true, message: '请输入用户名' }]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder={t("RNISycbR" /* 账号 */)}
size="large"
/>
</Form.Item>
<Form.Item
name="username"
rules={[{ required: true, message: t("wVzXBuYs" /* 请输入账号 */) }]}
>
<Input


+ 61
- 14
src/request/index.ts ファイルの表示

@@ -5,13 +5,16 @@ import axios, {
CreateAxiosDefaults,
InternalAxiosRequestConfig,
} from 'axios';
import {antdUtils} from '@/utils/antd';

import {useGlobalStore} from '@/store/global';
import { useGlobSetting } from '@/hooks/use-global-settings';
import loginService from '@/request/service/auth';
import {antdUtils} from '@/utils/antd';
import { ResponseDTO } from '@/models';

const { apiUrl = '' } = useGlobSetting();

// axios.defaults.withCredentials = true;

const refreshTokenUrl = '/api/auth/refresh/token';

export type Response<T> = Promise<[boolean, T, AxiosResponse<T>]>;

@@ -32,6 +35,7 @@ class Request {

private axiosInstance: AxiosInstance;

private refreshTokenFlag = false;
private requestQueue: {
resolve: any;
config: any;
@@ -48,7 +52,11 @@ class Request {
private async requestInterceptor(
axiosConfig: InternalAxiosRequestConfig
): Promise<any> {
if (this.requestingCount >= this.limit) {
if ([refreshTokenUrl].includes(axiosConfig.url || '')) {
return Promise.resolve(axiosConfig);
}

if (this.refreshTokenFlag || this.requestingCount >= this.limit) {
return new Promise((resolve) => {
this.requestQueue.push({
resolve,
@@ -59,6 +67,12 @@ class Request {
}

this.requestingCount += 1;

const {token} = useGlobalStore.getState();

if (token) {
axiosConfig.headers.Authorization = `Bearer ${token}`;
}
return Promise.resolve(axiosConfig);
}

@@ -83,20 +97,47 @@ class Request {
resolve(await this.request(config));
} else if (type === 'reuqest') {
this.requestingCount += 1;
//TODO: cookie
const {token} = useGlobalStore.getState();
config.headers.Authorization = `Bearer ${token}`;
resolve(config);
}
}
);
}

private async refreshToken() {
const {refreshToken} = useGlobalStore.getState();

if (!refreshToken) {
this.toLoginPage();
}

const [error, {data}] = await loginService.rerefshToken(refreshToken);

if (error) {
this.toLoginPage();
}

useGlobalStore.setState({
refreshToken: data.refreshToken,
token: data.accessToken,
});

this.refreshTokenFlag = false;

this.requestByQueue();
}

private async responseSuccessInterceptor(
response: AxiosResponse<any, any>
): Promise<any> {
this.requestingCount -= 1;
if (this.requestQueue.length) {
this.requestByQueue();
if (response.config.url !== refreshTokenUrl) {
this.requestingCount -= 1;
if (this.requestQueue.length) {
this.requestByQueue();
}
}

return Promise.resolve([false, response.data, response]);
}

@@ -107,6 +148,10 @@ class Request {
if (status === 401) {
return new Promise((resolve) => {
this.requestQueue.unshift({resolve, config, type: 'response'});
if (this.refreshTokenFlag) return;

this.refreshTokenFlag = true;
this.refreshToken();
});
} else {
antdUtils.notification?.error({
@@ -119,18 +164,20 @@ class Request {

private reset() {
this.requestQueue = [];
this.refreshTokenFlag = false;
this.requestingCount = 0;
}

private toLoginPage() {
this.reset();
// router.navigate('/user/login');
}

request<T, D = any>(config: AxiosRequestConfig<D>): Response<T> {
request<T, D = any>(config: AxiosRequestConfig<D>): Response<ResponseDTO<T>> {
return this.axiosInstance(config);
}

get<T, D = any>(url: string, config?: AxiosRequestConfig<D>): Response<T> {
get<T, D = any>(url: string, config?: AxiosRequestConfig<D>): Response<ResponseDTO<T>> {
return this.axiosInstance.get(url, config);
}

@@ -138,7 +185,7 @@ class Request {
url: string,
data?: D,
config?: AxiosRequestConfig<D>
): Response<T> {
): Response<ResponseDTO<T>> {
return this.axiosInstance.post(url, data, config);
}

@@ -146,15 +193,15 @@ class Request {
url: string,
data?: D,
config?: AxiosRequestConfig<D>
): Response<T> {
): Response<ResponseDTO<T>> {
return this.axiosInstance.put(url, data, config);
}

delete<T, D = any>(url: string, config?: AxiosRequestConfig<D>): Response<T> {
delete<T, D = any>(url: string, config?: AxiosRequestConfig<D>): Response<ResponseDTO<T>> {
return this.axiosInstance.delete(url, config);
}
}

const request = new Request({timeout: 60 * 1000 * 5, baseURL: apiUrl});
const request = new Request({timeout: 60 * 1000 * 5, baseURL: apiUrl});

export default request;

+ 16
- 0
src/request/service/auth.ts ファイルの表示

@@ -0,0 +1,16 @@
import request from '@/request';
import { LoginDTO, TokenDTO } from '@/models'

export default {
// 登录
login: (loginDTO: LoginDTO) => {
return request.post<TokenDTO>('/admin-api/system/auth/login', loginDTO);
},

logout: () => {
return request.post<any>('/app-api/member/auth/logout');
},
rerefshToken: (refreshToken: string) => {
return request.post<TokenDTO>('/app-api/member/auth/refresh-token', { refreshToken });
}
};

+ 0
- 15
src/request/service/login.ts ファイルの表示

@@ -1,15 +0,0 @@
import request from '@/request';
import { LoginDTO, LoginRespDTO } from '@/models'

const loginService = {
// 登录
login: (loginDTO: LoginDTO) => {
return request.post<LoginRespDTO>('/api/login', loginDTO, { withCredentials: false });
},

logout: () => {
return request.get<any>('/api/logout');
}
};

export default loginService;

+ 3
- 3
src/request/service/user.ts ファイルの表示

@@ -1,8 +1,8 @@
import request from '@/request';
import { LoginRespDTO } from '@/models';
import { Menu } from '@/models';

export default {
getUserInfo: () => {
return request.get<LoginRespDTO>('/api/userinfo/getUserInfo');
listMenus: () => {
return request.get<Menu>('/admin-api/system/auth/list-menus');
}
};

+ 11
- 5
src/store/global/index.ts ファイルの表示

@@ -5,14 +5,16 @@ interface State {
darkMode: boolean;
collapsed: boolean;
lang: string;
cookie: string;
token: string;
refreshToken: string;
}

interface Action {
setDarkMode: (darkMode: State['darkMode']) => void;
setCollapsed: (collapsed: State['collapsed']) => void;
setLang: (lang: State['lang']) => void;
setCookie: (cookie: State['cookie']) => void;
setToken: (token: State['token']) => void;
setRefreshToken: (refreshToken: State['refreshToken']) => void;
}

export const useGlobalStore = create<State & Action>()(
@@ -22,7 +24,8 @@ export const useGlobalStore = create<State & Action>()(
darkMode: false,
collapsed: false,
lang: 'zh',
cookie: '',
token: '',
refreshToken: '',
setDarkMode: (darkMode: State['darkMode']) => set({
darkMode,
}),
@@ -32,8 +35,11 @@ export const useGlobalStore = create<State & Action>()(
setLang: (lang: State['lang']) => set({
lang,
}),
setCookie: (cookie: State['cookie']) => set({
cookie,
setToken: (token: State['token']) => set({
token,
}),
setRefreshToken: (refreshToken: State['refreshToken']) => set({
refreshToken,
}),
};
},


+ 1
- 3
src/utils/env.ts ファイルの表示

@@ -16,12 +16,11 @@ export function getStorageShortName() {

export function getAppEnvConfig() {
const ENV_NAME = getConfigFileName(import.meta.env);
console.log(import.meta.env)
const ENV = (import.meta.env.DEV
? // Get the global configuration (the configuration will be extracted independently when packaging)
(import.meta.env as unknown as GlobEnvConfig)
: window[ENV_NAME as any]) as unknown as GlobEnvConfig;

const {
VITE_GLOB_APP_TITLE,
VITE_GLOB_API_URL,
@@ -29,7 +28,6 @@ export function getAppEnvConfig() {
VITE_GLOB_API_URL_PREFIX,
VITE_GLOB_UPLOAD_URL,
} = ENV;

if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) {
warn(
`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`,


+ 1
- 0
vite.config.ts ファイルの表示

@@ -9,6 +9,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {

const root = process.cwd();
const env = loadEnv(mode, root);
console.log(env)
const viteEnv = wrapperEnv(env);
const { VITE_PORT } = viteEnv;



読み込み中…
キャンセル
保存