fix(api):update store

This commit is contained in:
wang_yp 2024-09-18 17:59:47 +08:00
parent 193d88f09c
commit 53bb00191f
18 changed files with 490 additions and 116 deletions

View File

@ -1,8 +1,31 @@
import { inject, observer } from "mobx-react";
import "antd/dist/antd.css";
import Home from "./pages/home/home";
const App = (props: any) => {
return <Home />
// import Home from "./pages/home/home";
import { Modal } from "antd";
import { Store } from "antd/lib/form/interface";
import { Outlet } from "react-router";
const App = (props: Store) => {
const { usrStore } = props;
return (
<>
<Outlet/>
<Modal
title="登录"
className="owner_model"
width={"50%"}
open={usrStore.isNeedLogin}
afterClose={() => {}}
onOk={() => {
usrStore.closeLoginDilog();
}}
onCancel={() => {
usrStore.closeLoginDilog();
}}
>
<p>cascsa</p>
</Modal>
</>
);
};
export default inject("usrStore")(observer(App));

View File

@ -1,10 +1,7 @@
import ossClie from "@/util/oss";
import Modal from "antd/lib/modal";
import { PlusOutlined } from "@ant-design/icons";
import Upload, { RcFile, UploadFile, UploadProps } from "antd/lib/upload";
import { useEffect, useState } from "react";
import baseHttp from "@/service/base";
import SystemConfig from "@/service/apiConfig/system_config";
interface UploadFileProps {
imgList: Array<UploadFileEx>;
@ -25,11 +22,11 @@ const getBase64 = (file: RcFile): Promise<string> =>
reader.onerror = (error) => reject(error);
});
const AliUpload = (props:UploadFileProps) => {
const AliUpload = (props: UploadFileProps) => {
const [previewOpen, setPreviewOpen] = useState(false);
const [previewImage, setPreviewImage] = useState("");
const [previewTitle, setPreviewTitle] = useState("");
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [files, setFileList] = useState<UploadFile[]>([]);
const handleCancel = () => setPreviewOpen(false);
const handlePreview = async (file: UploadFile) => {
if (!file.url && !file.preview) {
@ -47,30 +44,7 @@ const AliUpload = (props:UploadFileProps) => {
}, [props.imgList]);
const handleChange: UploadProps["onChange"] = ({ fileList: newFileList }) => {
let isChange: Boolean = false;
newFileList.forEach(async (item) => {
if (item.originFileObj) {
isChange = true;
await ossClie(newFileList[newFileList.length - 1].originFileObj).then(
(resUploadFileEx: UploadFileEx) => {
resUploadFileEx.uid = resUploadFileEx.name;
resUploadFileEx.bannerName = resUploadFileEx.name;
baseHttp.post( SystemConfig.AddImages, { url: resUploadFileEx.url }).then((resp)=>{
resUploadFileEx.systemImageId = resp.data.id;
resUploadFileEx.id = resp.data.id;
resUploadFileEx.redictUrl = "";
fileList.push(resUploadFileEx);
props.onChnage(fileList);
setFileList(fileList);
})
}
);
}
});
if (!isChange) {
props.onChnage(newFileList);
setFileList(newFileList);
}
console.log(newFileList);
};
const uploadButton = (
<div>
@ -78,15 +52,17 @@ const AliUpload = (props:UploadFileProps) => {
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<div style={{ margin: 10 }}>
<Upload
listType="picture-card"
fileList={fileList}
fileList={files}
action={"http://127.0.0.1:12214/v1/public/fts/upload"}
onPreview={handlePreview}
onChange={handleChange}
>
{fileList.length >= 4 ? null : uploadButton}
{files.length >= 4 ? null : uploadButton}
</Upload>
<Modal
open={previewOpen}

View File

@ -9,7 +9,7 @@ export const FormSelect = (v: FormDatas) => {
baseHttp
.get(`${v.selectUrl}/?pageSize=100&pageNum=1` ?? "", "")
.then((res) => {
setList(res.data.list ?? []);
setList(res.data.record ?? []);
});
}, [v.selectUrl]);
return (
@ -18,7 +18,7 @@ export const FormSelect = (v: FormDatas) => {
{list?.map((v: any) => {
return (
<Option key={v.id} value={v.id}>
{v.productTypeName}
{v.dep_name}
</Option>
);
})}

View File

@ -31,13 +31,7 @@ const SimpleForm = (props: SimpleFormData) => {
switch (v.type) {
case "input":
return (
<Form.Item
key={v.label}
label={v.label}
name={v.name}
rules={v.rules}
>
<Form.Item key={v.label} label={v.label} name={v.name} rules={v.rules}>
<Input defaultValue={v.value} value={v.value} />
</Form.Item>
);
@ -84,6 +78,7 @@ const SimpleForm = (props: SimpleFormData) => {
<AliUpload
imgList={form.getFieldValue(v.name) ?? []}
onChnage={(res) => {
console.log(res);
form.setFieldValue(v.name, res);
}}
/>
@ -91,17 +86,8 @@ const SimpleForm = (props: SimpleFormData) => {
);
case "textArea":
return (
<Form.Item
key={v.label}
label={v.label}
name={v.name}
rules={v.rules}
>
<TextArea
value={v.name}
placeholder="Controlled autosize"
autoSize={{ minRows: 3, maxRows: 5 }}
/>
<Form.Item key={v.label} label={v.label} name={v.name} rules={v.rules}>
<TextArea value={v.name} placeholder="Controlled autosize" autoSize={{ minRows: 3, maxRows: 5 }}/>
</Form.Item>
);
case "Radio":

View File

@ -3,8 +3,8 @@ let fileName = "test.tsx";
let path = "pages/test"
let storeName = "TestStore"
let className = "Test"
let str =
`
let str =`
import { Tooltip } from "antd";
import { inject, observer } from "mobx-react";
import type { ColumnsType } from 'antd/es/table';

View File

@ -20,5 +20,13 @@ export interface UserDataType {
startTime: any;
endTime: any;
status: any;
}
export interface TagDataType {
key: React.Key;
tag_name: string;
tag_desc: string;
id: number;
status: any;
identity: string;
}

156
src/pages/dep/index.tsx Normal file
View File

@ -0,0 +1,156 @@
import { Button, Space, Modal, FormInstance } from "antd";
import { inject, observer } from "mobx-react";
import type { ColumnsType } from "antd/es/table";
import BTable from "@/components/b_table";
import { useEffect, useState } from "react";
import UserConfig from "@/service/apiConfig/user_config";
import { UserDataType } from "@/model/userModel";
import { Store } from "antd/lib/form/interface";
import SimpleForm from "@/components/form/simple_form";
import React from "react";
const Dep = (props: Store) => {
const { depStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [projectConfig, setProjectConfig] = useState<any>([]);
const formRef = React.useRef<FormInstance>(null);
const [record, setRecord] = useState<any>(null);
const [tagId, setId] = useState<Number | null>(null);
const columns: ColumnsType<UserDataType> = [
{ title: "部门名称", dataIndex: "dep_name" },
{ title: "部门描述", dataIndex: "remark" },
{
title: "操作",
dataIndex: "id",
render: (any, record) => (
<div>
<Space direction="vertical">
<Space wrap>
<Button
type="dashed"
size="small"
onClick={() => {
edit(record);
}}
>
</Button>
<Button
type="dashed"
danger
size="small"
onClick={() => {
depStore.deleteItem(record.id);
}}
>
</Button>
</Space>
</Space>
</div>
),
},
];
const edit = (record) => {
record = {
...record,
imageUrl: [{ url: record.imageUrl }],
};
setProjectConfig(defaultConfig);
setIsModalOpen(true);
formRef.current?.setFieldsValue(record);
setRecord(record);
setId(record.id);
};
const onFinish = (values: any) => {
console.log(values);
if (!tagId) {
depStore.add(values);
} else {
depStore.putItem(tagId, values);
}
setIsModalOpen(false);
};
useEffect(() => {
depStore.getlist(UserConfig.LIST);
}, [depStore]);
const defaultConfig = [
{
type: "select",
label: "上级部门名称",
name: "pdep_id",
value: "",
selectUrl: "dep/list",
rules: [{ required: false, message: "请输入上级部门!" }],
},
{
type: "input",
label: "部门名称",
name: "dep_name",
value: "",
rules: [{ required: true, message: "请输入部门名称!" }],
},
{
type: "input",
label: "部门描述",
name: "remark",
value: "",
rules: [{ required: true, message: "请输入部门描述" }],
},
{
type: "upload",
label: "头像",
name: "head_img",
value: [],
rules: [{ required: false }],
},
];
const onFinishFailed = () => {};
return (
<div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}>
<Space direction="horizontal" size={"middle"}>
<Button
type="default"
onClick={() => {
setProjectConfig(defaultConfig);
setId(null);
setIsModalOpen(true);
}}
>
</Button>
</Space>
<BTable store={depStore} columns={columns} dataSource={depStore.list} />
<Modal
title={!tagId ? "添加部门" : "编辑部门"}
width={800}
open={isModalOpen}
afterClose={() => formRef.current?.resetFields()}
onOk={() => formRef.current?.submit()}
onCancel={() => {
setId(null);
setIsModalOpen(false);
}}
>
<SimpleForm
formRef={formRef}
createCallback={() => {
formRef.current?.setFieldsValue(record);
}}
formName="card_basic"
colProps={4}
subBtnName="提交"
formDatas={projectConfig}
onFinish={onFinish}
initialValues={true}
onFinishFailed={onFinishFailed}
/>
</Modal>
</Space>
</div>
);
};
export default inject("depStore")(observer(Dep));

View File

@ -1,11 +1,16 @@
import { useState } from "react";
import { Modal } from "antd";
import "./left.less";
import { useNavigate } from "react-router";
const HomeLeft = () => {
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const navigate = useNavigate();
const openDispatch = () => {
setIsModalOpen(true);
};
const jumpToUser = () => {
navigate("/user")
};
return (
<div className="left_container">
@ -14,7 +19,7 @@ const HomeLeft = () => {
<p></p>
</div>
</div>
<div onClick={openDispatch} className="org">
<div onClick={jumpToUser} className="org">
<div className="org_head">
<p></p>
</div>
@ -24,12 +29,6 @@ const HomeLeft = () => {
<p>HomeLeft</p>
</div>
</div>
{/* <div onClick={openDispatch}>
</div>
<div onClick={openDispatch}>
HomeLeft
</div> */}
<Modal
title="组织架构"
className="owner_model"

132
src/pages/tag/tag.tsx Normal file
View File

@ -0,0 +1,132 @@
import { Button, Space, Modal, FormInstance } from "antd";
import { inject, observer } from "mobx-react";
import type { ColumnsType } from "antd/es/table";
import BTable from "@/components/b_table";
import { useEffect, useState } from "react";
import UserConfig from "@/service/apiConfig/user_config";
import { UserDataType } from "@/model/userModel";
import { Store } from "antd/lib/form/interface";
import SimpleForm from "@/components/form/simple_form";
import React from "react";
const Tag = (props: Store) => {
const { tagStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [projectConfig, setProjectConfig] = useState<any>([]);
const formRef = React.useRef<FormInstance>(null);
const [record, setRecord] = useState<any>(null);
const [tagId, setId] = useState<Number | null>(null);
const columns: ColumnsType<UserDataType> = [
{ title: "标签昵称", dataIndex: "tag_name" },
{ title: "标签描述", dataIndex: "tag_desc" },
{
title: "操作",
dataIndex: "id",
render: (any, record) => (
<div>
<Space direction="vertical">
<Space wrap>
<Button type="dashed" size="small" onClick={() => {edit(record);}}></Button>
<Button
type="dashed"
danger
size="small"
onClick={() => {
tagStore.deleteItem(record.id);
}}
>
</Button>
</Space>
</Space>
</div>
),
},
];
const edit = (record) => {
record = {
...record,
imageUrl: [{ url: record.imageUrl }],
};
setProjectConfig(defaultConfig);
setIsModalOpen(true);
formRef.current?.setFieldsValue(record);
setRecord(record);
setId(record.id);
};
const onFinish = (values: any) => {
if (!tagId) {
tagStore.add(values);
} else {
tagStore.putItem(tagId,values);
}
setIsModalOpen(false);
};
useEffect(() => {
tagStore.getlist(UserConfig.LIST);
}, [tagStore]);
const defaultConfig = [
{
type: "input",
label: "标签名称",
name: "tag_name",
value: "",
rules: [{ required: true, message: "请输入标签名称!" }],
},
{
type: "input",
label: "标签描述",
name: "tag_desc",
value: "",
rules: [{ required: true, message: "请输入标签描述" }],
},
];
const onFinishFailed = () => {};
return (
<div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}>
<Space direction="horizontal" size={"middle"}>
<Button
type="default"
onClick={() => {
setProjectConfig(defaultConfig);
setId(null);
setIsModalOpen(true);
}}
>
</Button>
</Space>
<BTable store={tagStore} columns={columns} dataSource={tagStore.list} />
<Modal
title={!tagId ? "添加标签" : "编辑标签"}
width={800}
open={isModalOpen}
afterClose={() => formRef.current?.resetFields()}
onOk={() => formRef.current?.submit()}
onCancel={() => {
setId(null);
setIsModalOpen(false);
}}
>
<SimpleForm
formRef={formRef}
createCallback={() => {
formRef.current?.setFieldsValue(record);
}}
formName="card_basic"
colProps={4}
subBtnName="提交"
formDatas={projectConfig}
onFinish={onFinish}
initialValues={true}
onFinishFailed={onFinishFailed}
/>
</Modal>
</Space>
</div>
);
};
export default inject("tagStore")(observer(Tag));

View File

@ -1,4 +1,4 @@
import { Button, Tooltip, Image, Space, Modal, FormInstance } from "antd";
import { Button, Image, Space, Modal, FormInstance } from "antd";
import { inject, observer } from "mobx-react";
import type { ColumnsType } from "antd/es/table";
import BTable from "@/components/b_table";
@ -9,10 +9,12 @@ import { Store } from "antd/lib/form/interface";
import "./user.less";
import SimpleForm from "@/components/form/simple_form";
import React from "react";
import { useNavigate } from "react-router";
const User = (props: Store) => {
const { usrStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const nav = useNavigate()
const [projectConfig, setProjectConfig] = useState<any>([]);
const formRef = React.useRef<FormInstance>(null);
const [record, setRecord] = useState<any>(null);
@ -20,24 +22,12 @@ const User = (props: Store) => {
const columns: ColumnsType<UserDataType> = [
{
title: "用户名",
dataIndex: "acount",
dataIndex: "user_name",
},
{
title: "年龄",
dataIndex: "age",
},
{
title: "居住地",
dataIndex: "address",
ellipsis: {
showTitle: false,
},
render: (address) => (
<Tooltip placement="topLeft" title={address}>
{address}
</Tooltip>
),
},
{
title: "性别",
dataIndex: "sex",
@ -45,17 +35,16 @@ const User = (props: Store) => {
},
{
title: "头像",
dataIndex: "headImg",
dataIndex: "head_img",
render: (headImg) => <Image src={headImg}></Image>,
},
{
title: "角色",
dataIndex: "roleName",
title: "职位",
dataIndex: "position",
},
{
title: "会员",
dataIndex: "level",
render: (level) => <span>{level === "0" ? "包年" : "超级会员"}</span>,
title: "备注",
dataIndex: "remark",
},
{
title: "操作",
@ -77,9 +66,14 @@ const User = (props: Store) => {
</Button>
<Button type="dashed" danger size="small" onClick={() => {
usrStore.deleteItem(record.id)
}}>
<Button
type="dashed"
danger
size="small"
onClick={() => {
usrStore.deleteItem(record.id);
}}
>
</Button>
</Space>
@ -106,12 +100,11 @@ const User = (props: Store) => {
values = {
...values,
headImg:"cascas" //images.join(","),
headImg: "cascas", //images.join(","),
};
if (!userId) {
usrStore.add(values);
} else {
}
setIsModalOpen(false);
};
@ -165,16 +158,38 @@ const User = (props: Store) => {
return (
<div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}>
<Button
type="default"
onClick={() => {
setProjectConfig(defaultConfig);
setId(null);
setIsModalOpen(true);
}}
>
</Button>
<Space direction="horizontal" size={"middle"}>
<Button
type="default"
onClick={() => {
setProjectConfig(defaultConfig);
setId(null);
setIsModalOpen(true);
}}
>
</Button>
<Button type="default" onClick={() => {nav("/tag")}}>
</Button>
<Button type="default" onClick={() => { nav("/dep")}}>
</Button>
<Button type="default" onClick={() => {}}>
</Button>
<Button type="default" onClick={() => {}}>
</Button>
<Button type="default" onClick={() => {
nav("/warehouse")
}}>
</Button>
</Space>
<BTable store={usrStore} columns={columns} dataSource={usrStore.list} />
<Modal
title={!userId ? "添加用户" : "编辑用户"}

View File

@ -1,4 +1,7 @@
import Dep from "@/pages/dep";
import Home from "@/pages/home/home";
import Tag from "@/pages/tag/tag";
import User from "@/pages/user/user";
export const homeRouter = [
{
path: "/",
@ -11,4 +14,19 @@ export const homeRouter = [
index: false,
element: <Home />
},
{
path: "/user",
index: true,
element: <User />
},
{
path: "/tag",
index: true,
element: <Tag />
},
{
path: "/dep",
index: true,
element: <Dep />
},
];

View File

@ -1,6 +1,6 @@
class UserConfig {
static LOGINURI: string = "login"
static LIST: string = "user/list"
static LIST: string = "userMgmt/user/list"
static ADD: string = "user"
static DELETE: string = "user"
static EDIT: string = "user"

View File

@ -1,13 +1,14 @@
import store from "@/store";
import axios, { AxiosResponse } from "axios";
// 添加请求拦截器
axios.defaults.headers.common["CommonType"] = "shouka";
// axios.defaults.headers.common["CommonType"] = "shouka";
axios.defaults.headers.common["Content-Type"] = "application/json; charset=utf8";
// axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
axios.interceptors.request.use((config) => {
config.baseURL = "http://quwanya.cn:8899/v1/api/";
config.baseURL = "http://127.0.0.1:12214/v1/";
config.timeout = 5000;
let token = window.localStorage.getItem("token")
config.headers.Authorization = 'Bearer ' + token
config.headers.Authorization = token
return config;
}, (error) => {
// 对请求错误做些什么
@ -17,10 +18,15 @@ axios.interceptors.request.use((config) => {
// 添加响应拦截器
axios.interceptors.response.use((res: AxiosResponse) => {
if (res.data.status === 401) {
store.usrStore.openLoginDilog()
store.usrStore.logOut()
}
return res;
}, (err) => {
if (err.status === 401) {
store.usrStore.openLoginDilog()
store.usrStore.logOut()
}
return Promise.reject(err);
});
class BaseHttp {
@ -75,4 +81,5 @@ class BaseHttp {
};
}
// eslint-disable-next-line import/no-anonymous-default-export
export default new BaseHttp()

View File

@ -58,34 +58,31 @@ class BaseStore<B> implements BaseStoreInterface<B> {
async getlist() {
this.listStatus = true;
let res = await baseHttp.get(this.urlConfig.LIST, {
size: this.page?.Size | 1,
offset: this.page?.Offset | 20,
isSelf:0
size: this.page?.Size | 20,
offset: this.page?.Offset | 1,
});
this.page = {
Offset: res.data?.pageNum,
Size: res.data?.pageSize
}
let data: Array<B> = []
if (!res.data.list) {
if (!res.data.record) {
runInAction(() => {
this.list = data;
})
this.listStatus = false;
return;
}
for (let i = 0; i < res.data.list.length; i++) {
console.log(res.data.record);
for (let i = 0; i < res.data.record.length; i++) {
data.push({
key: res.data.list[i].id,
...res.data.list[i]
key: res.data.record[i].id,
...res.data.record[i]
})
}
console.log(data);
runInAction(() => {
this.list = data;
this.total = res.data.total | res.data.totals
this.total = res.data.count
})
console.log(this.list);
this.listStatus = false;
}
list!: Array<B>;

21
src/store/dep.ts Normal file
View File

@ -0,0 +1,21 @@
import { makeObservable } from "mobx";
// 用户信息
import BaseStore from "./baseStore";
import { TagDataType } from "@/model/userModel";
class DepConfig {
static LIST: string = "dep/list"
static ADD: string = "dep"
static DELETE: string = "dep"
static EDIT: string = "dep"
}
class DepStore extends BaseStore<TagDataType> {
constructor() {
super(DepConfig)
makeObservable(this, {})
}
}
// eslint-disable-next-line import/no-anonymous-default-export
export default new DepStore();

View File

@ -1,7 +1,11 @@
import usrStore from '@/store/user'
import tagStore from '@/store/tag'
import depStore from '@/store/dep'
const store = {
usrStore,
tagStore,
depStore
};
export default store;

21
src/store/tag.ts Normal file
View File

@ -0,0 +1,21 @@
import { makeObservable } from "mobx";
// 用户信息
import BaseStore from "./baseStore";
import { TagDataType } from "@/model/userModel";
class TagConfig {
static LIST: string = "tag/list"
static ADD: string = "tag"
static DELETE: string = "tag"
static EDIT: string = "tag"
}
class TagStore extends BaseStore<TagDataType> {
constructor() {
super(TagConfig)
makeObservable(this, {})
}
}
// eslint-disable-next-line import/no-anonymous-default-export
export default new TagStore();

View File

@ -7,12 +7,16 @@ import { UserDataType, UserInfos } from "@/model/userModel";
class UserStore extends BaseStore<UserDataType> {
_userinfo: UserInfos = {}; // 用户信息
isNeedLogin: boolean = false; // 是否需要登录
constructor() {
super(UserConfig)
makeObservable(this, {
logOut: action,
login: action,
_userinfo: observable,
isNeedLogin: observable,
openLoginDilog: action,
userInfo: computed,
})
}
@ -43,6 +47,13 @@ class UserStore extends BaseStore<UserDataType> {
};
window.localStorage.setItem("token", data.data.token ?? "");
}
openLoginDilog(){
this.isNeedLogin = true;
}
closeLoginDilog(){
this.isNeedLogin = false;
}
}
// eslint-disable-next-line import/no-anonymous-default-export
export default new UserStore();