fix(api):update store

This commit is contained in:
wang_yp 2024-09-21 22:45:54 +08:00
parent c08daa777e
commit dc86692261
15 changed files with 1237 additions and 128 deletions

703
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,8 @@
"@types/node": "^16.11.65",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-react": "^1.0.6",
"ali-oss": "^6.18.1",
"antd": "^5.20.6",
"axios": "^1.2.1",

View File

@ -1,74 +1,66 @@
import { Editor } from "@tinymce/tinymce-react";
import { useEffect, useState } from "react";
import baseHttp from "@/service/base";
import { Editor as TinyMCEEditor } from "tinymce";
interface EditorPropsData {
data:string,
updateChange:Function
}
const EditorComponent = (props:EditorPropsData) => {
const [value, setValue] = useState<any>("");
const imagesUploadHandler = async (blobInfo, progress) => {
var data = new FormData();
data.append("attachments", blobInfo.blob(), blobInfo.filename());
let url = "http://81.68.81.205:1234/apis/v1/attachment";
let res = await baseHttp.upload(url, data);
return res.data.url;
};
useEffect(() => {
setValue(props.data);
}, [props.data]);
const handleEditorChange = (content: string, editor: TinyMCEEditor) => {
props.updateChange(content)
};
return (
<Editor
initialValue={value}
apiKey="hq72bjfug6s56a5qxa2oxpbqsxc58nv4v7nfruyd5ndpgu72"
init={{
menubar: false,
statusbar: false, // 隐藏底部状态栏
branding: false, // 隐藏tinymce右下角水印
resize: false, //右下角调整编辑器大小false关闭true开启只改变高度'both' 宽高都能改变
plugins: [
"autolink",
"link",
"image ",
"lists",
"charmap",
"preview",
"anchor",
"pagebreak",
"visualblocks",
"visualchars",
"fullscreen",
"insertdatetime",
"nonbreaking",
"directionality",
"template",
"searchreplace",
"hr",
"advlist",
"textpattern",
"help",
"autosave",
"bdmap",
"autoresize",
"formatpainter",
"paragraph",
],
toolbar: [
" blocks | paragraph |styleselect| blockquote | hr bold underline italic alignleft aligncenter alignright | forecolor backcolor | fontsize lineheight | bullist numlist outdent indent | link image | undo redo | fullscreen | bdmap",
],
font_size_formats: "8px 10px 12px 14px 18px 24px 36px",
line_height_formats: "1 1.2 1.4 1.6 2",
height: 600,
min_height: 600,
images_upload_handler: imagesUploadHandler,
}}
onEditorChange={handleEditorChange}
/>
);
};
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
export default EditorComponent;
import React, { useState, useEffect } from "react";
import { Editor, Toolbar } from "@wangeditor/editor-for-react";
import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
interface EditorProps {
value: string;
onChange: (value: string) => void;
}
function MyEditor(props:EditorProps) {
// editor 实例
const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
// 编辑器内容
const [html, setHtml] = useState("<p>hello</p>");
// 模拟 ajax 请求,异步设置 html
useEffect(() => {
if (props.value){
setHtml(props.value)
}
}, [props]);
// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {}; // TS 语法
// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
// TS 语法
placeholder: "请输入内容...",
};
// 及时销毁 editor ,重要!
useEffect(() => {
return () => {
if (editor == null) return;
editor.destroy();
setEditor(null);
};
}, [editor]);
return (
<>
<div style={{ border: "1px solid #ccc", zIndex: 100 }}>
<Toolbar
editor={editor}
defaultConfig={toolbarConfig}
mode="default"
style={{ borderBottom: "1px solid #ccc" }}
/>
<Editor
defaultConfig={editorConfig}
value={html}
onCreated={setEditor}
onChange={(editor) => {
setHtml(editor.getHtml())
props.onChange(editor.getHtml())
}}
mode="default"
style={{ height: "500px", overflowY: "hidden" }}
/>
</div>
</>
);
}
export default MyEditor;

View File

@ -1,5 +1,15 @@
import { FormInstance } from "antd"
export enum FormType {
input = "input",
select = "select",
editor = "editor",
date = "date",
textarea = "textarea",
radio = "radio",
upload = "upload",
cehckbox = "checkbox",
password = "password",
}
export interface FormDatas {
type: string,
label: string,

View File

@ -1,8 +1,9 @@
import { Checkbox, DatePicker, Form, Input, Radio } from "antd";
import { useEffect } from "react";
import { SimpleFormData } from "./interface";
import { FormType, SimpleFormData } from "./interface";
import { FormSelect } from "./select";
import AliUpload from "../ali_upload";
import MyEditor from "../edittor";
const { TextArea } = Input;
const SimpleForm = (props: SimpleFormData) => {
const [form] = Form.useForm();
@ -20,7 +21,7 @@ const SimpleForm = (props: SimpleFormData) => {
name={props.formName}
ref={props.formRef}
form={form}
labelCol={{ span: props.span??4 }}
labelCol={{ span: props.span ?? 4 }}
wrapperCol={{ span: props.colProps }}
layout="horizontal"
initialValues={{ menubar: true }}
@ -29,9 +30,14 @@ const SimpleForm = (props: SimpleFormData) => {
>
{props.formDatas.map((v) => {
switch (v.type) {
case "input":
case FormType.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>
);
@ -46,7 +52,7 @@ const SimpleForm = (props: SimpleFormData) => {
<Input.Password value={v.name} />
</Form.Item>
);
case "checkbox":
case FormType.cehckbox:
return (
<Form.Item
key={v.label}
@ -57,9 +63,9 @@ const SimpleForm = (props: SimpleFormData) => {
<Checkbox>Remember me</Checkbox>
</Form.Item>
);
case "select":
case FormType.select:
return FormSelect(v);
case "upload":
case FormType.upload:
return (
<Form.Item
key={v.label}
@ -84,13 +90,38 @@ const SimpleForm = (props: SimpleFormData) => {
/>
</Form.Item>
);
case "textArea":
case FormType.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":
case FormType.editor:
return (
<Form.Item
key={v.label}
label={v.label}
name={v.name}
rules={v.rules}
>
<MyEditor
value={v.value}
onChange={function (value: string): void {
form.setFieldValue(v.name, value);
}}
/>
</Form.Item>
);
case FormType.radio:
return (
<Form.Item
key={v.label}
@ -99,12 +130,12 @@ const SimpleForm = (props: SimpleFormData) => {
rules={v.rules}
>
<Radio.Group>
<Radio value={0}></Radio>
<Radio value={1}></Radio>
<Radio value={1}></Radio>
<Radio value={2}></Radio>
</Radio.Group>
</Form.Item>
);
case "Date":
case FormType.date:
return (
<Form.Item
key={v.label}

View File

@ -10,7 +10,6 @@ import { useEffect } from "react";
const LayOut = (props: Store) => {
const { usrStore } = props;
const nav = useNavigate();
console.log(usrStore.isNeedLogin);
useEffect(() => {
if (usrStore.isNeedLogin) {
nav("/login");

View File

@ -1,10 +1,128 @@
const PoliticalStudy = () => {
import { Button, Space, Modal, FormInstance } from "antd";
import { inject, observer } from "mobx-react";
import BTable from "@/components/b_table";
import { useEffect, useState } from "react";
import { Store } from "antd/lib/form/interface";
import SimpleForm from "@/components/form/simple_form";
import React from "react";
import { columns, defaultConfig } from "./political_column";
const PoliticalStudy = (props: Store) => {
const { politicalStudyStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [projectConfig, setProjectConfig] = useState<any>([]);
const formRef = React.useRef<FormInstance>(null);
const [record, setRecord] = useState<any>(null);
useEffect(() => {
politicalStudyStore.getlist();
setProjectConfig(defaultConfig);
}, [politicalStudyStore]);
const column_widget = (any, record) => {
return (
<>
<p>PoliticalStudy</p>
</>
<Space wrap>
<Button
type="dashed"
size="small"
onClick={() => {
edit(record);
}}
>
</Button>
<Button
type="dashed"
danger
size="small"
onClick={() => {
politicalStudyStore.deleteItem(record.id);
}}
>
</Button>
</Space>
);
};
export default PoliticalStudy;
const edit = (record) => {
setIsModalOpen(true);
setRecord(record);
};
const onFinish = (values: any) => {
let data = {
...values,
score:Number(values.score)
}
data.file_url = "";
if (!record?.id) {
politicalStudyStore.add(data);
} else {
politicalStudyStore.putItem(record.id,data);
}
setIsModalOpen(false);
};
const onFinishFailed = () => {};
return (
<div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}>
<Space direction="horizontal" size={"middle"}>
<Button
type="default"
onClick={() => {
setRecord(null);
setProjectConfig(defaultConfig);
setIsModalOpen(true);
}}
>
</Button>
</Space>
<BTable
store={politicalStudyStore}
columns={[
...columns,
{
title: "操作",
dataIndex: "id",
ellipsis: {
showTitle: false,
},
render: (any, record) => column_widget(any, record),
},
]}
dataSource={politicalStudyStore.list}
/>
<Modal
title={!record?.id ? "添加文章" : "编辑文章"}
width={1200}
open={isModalOpen}
afterClose={() => formRef.current?.resetFields()}
onOk={() => formRef.current?.submit()}
onCancel={() => {
setIsModalOpen(false);
}}
>
<SimpleForm
formRef={formRef}
createCallback={() => {
if (record?.id) {
formRef.current?.setFieldsValue(record);
} else {
formRef.current?.setFieldsValue(null);
}
}}
formName="card_basic"
colProps={25}
subBtnName="提交"
formDatas={projectConfig}
onFinish={onFinish}
initialValues={true}
onFinishFailed={onFinishFailed}
/>
</Modal>
</Space>
</div>
);
};
export default inject("politicalStudyStore")(observer(PoliticalStudy));

View File

@ -0,0 +1,59 @@
import { UserDataType } from "@/model/userModel";
import { ColumnsType } from "antd/lib/table";
export const columns: ColumnsType<UserDataType> = [
{
title: "标题",
dataIndex: "title",
},
{
title: "副标题",
dataIndex: "sub_title",
},
{
title: "内容",
dataIndex: "content",
width: 300,
ellipsis: true,
},
{
title: "积分",
dataIndex: "score",
},
];
export const defaultConfig = [
{
type: "input",
label: "标题",
name: "title",
value: "",
rules: [{ required: true, message: "请输入标题!" }],
},
{
type: "input",
label: "副标题",
name: "sub_title",
value: "",
rules: [{ required: true, message: "请输入副标题!" }],
},
{
type: "input",
label: "积分",
name: "score",
value: "",
rules: [{ required: true, message: "请输入学习积分" }],
},
{
type: "upload",
label: "附件图片",
name: "file_url",
value: [],
},
{
type: "editor",
label: "内容",
name: "content",
value: "",
rules: [{ required: true, message: "请填写内容" }],
},
];

View File

@ -1,10 +1,125 @@
const WhseMgmt = () => {
import { Button, Space, Modal, FormInstance } from "antd";
import { inject, observer } from "mobx-react";
import BTable from "@/components/b_table";
import { useEffect, useState } from "react";
import { Store } from "antd/lib/form/interface";
import SimpleForm from "@/components/form/simple_form";
import React from "react";
import { columns, defaultConfig } from "./whseMgmt_column";
const WhseMgmt = (props: Store) => {
const { stashStore } = props;
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [projectConfig, setProjectConfig] = useState<any>([]);
const formRef = React.useRef<FormInstance>(null);
const [record, setRecord] = useState<any>(null);
useEffect(() => {
stashStore.getlist();
setProjectConfig(defaultConfig);
}, [stashStore]);
const column_widget = (any, record) => {
return (
<>
<p>WhseMgmt</p>
</>
<Space wrap>
<Button type="dashed" size="small" onClick={() => {}}>
</Button>
<Button type="dashed" size="small" onClick={()=>{edit(record)}}>
</Button>
<Button
type="dashed"
danger
size="small"
onClick={() => {
stashStore.deleteItem(record.id);
}}
>
</Button>
</Space>
);
};
export default WhseMgmt;
const edit = (record) => {
setIsModalOpen(true);
setRecord(record);
};
const onFinish = (values: any) => {
let data = {
...values,
score: Number(values.score),
};
data.file_url = "";
if (!record?.id) {
stashStore.add(data);
} else {
stashStore.putItem(record.id, data);
}
setIsModalOpen(false);
};
const onFinishFailed = () => {};
return (
<div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}>
<Space direction="horizontal" size={"middle"}>
<Button
type="default"
onClick={() => {
setRecord(null);
setProjectConfig(defaultConfig);
setIsModalOpen(true);
}}
>
</Button>
</Space>
<BTable
store={stashStore}
columns={[
...columns,
{
title: "操作",
dataIndex: "id",
ellipsis: {
showTitle: false,
},
render: (any, record) => column_widget(any, record),
},
]}
dataSource={stashStore.list}
/>
<Modal
title={!record?.id ? "添加文章" : "编辑文章"}
width={1200}
open={isModalOpen}
afterClose={() => formRef.current?.resetFields()}
onOk={() => formRef.current?.submit()}
onCancel={() => {
setIsModalOpen(false);
}}
>
<SimpleForm
formRef={formRef}
createCallback={() => {
if (record?.id) {
formRef.current?.setFieldsValue(record);
} else {
formRef.current?.setFieldsValue(null);
}
}}
formName="card_basic"
colProps={25}
subBtnName="提交"
formDatas={projectConfig}
onFinish={onFinish}
initialValues={true}
onFinishFailed={onFinishFailed}
/>
</Modal>
</Space>
</div>
);
};
export default inject("stashStore")(observer(WhseMgmt));

View File

@ -0,0 +1,82 @@
import { FormType } from "@/components/form/interface";
import { UserDataType } from "@/model/userModel";
import { ColumnsType } from "antd/lib/table";
export const columns: ColumnsType<UserDataType> = [
{
title: "仓库名称",
dataIndex: "stash_name",
},
{
title: "仓库位置信息",
dataIndex: "stash_position",
},
{
title: "仓库描述",
dataIndex: "stash_desc",
ellipsis: true,
},
{
title: "监控链接",
dataIndex: "monitoring_url",
},
{
title: "是否为第三方仓库",
dataIndex: "is_other",
},
{
title: "三方仓库仓库所有者",
dataIndex: "stash_holder",
},
{
title: "三方仓库联系方式",
dataIndex: "holder_contact_info",
},
];
export const defaultConfig = [
{
type: FormType.input,
label: "仓库名称",
name: "stash_name",
value: "",
rules: [{ required: true, message: "请输入仓库名称!" }],
},
{
type: FormType.input,
label: "仓库位置信息",
name: "stash_position",
value: "",
rules: [{ required: true, message: "请输入仓库位置信息!" }],
},
{
type: FormType.input,
label: "仓库描述",
name: "stash_desc",
value: "",
rules: [{ required: true, message: "请输入仓库描述" }],
},
{
type: FormType.input,
label: "监控链接",
name: "monitoring_url",
value: "",
},
{
type: FormType.radio,
label: "是否为第三方仓库",
name: "is_other",
value: "",
},
{
type: FormType.input,
label: "三方仓库仓库所有者",
name: "stash_holder",
value: "",
},
{
type: FormType.input,
label: "三方仓库联系方式",
name: "holder_contact_info",
value: "",
},
];

View File

@ -17,7 +17,7 @@ axios.interceptors.request.use((config) => {
// 添加响应拦截器
axios.interceptors.response.use((res: AxiosResponse) => {
if (res.data.status === 401) {
if (res.data?.status === 401) {
console.log("res.data.status",res.data.status);
store.usrStore.openLoginDilog()
store.usrStore.logOut()

View File

@ -75,7 +75,7 @@ class BaseStore<B> implements BaseStoreInterface<B> {
offset: this.page?.Offset | 1,
});
let data: Array<B> = []
if (!res.data.record) {
if (!res?.data?.record) {
runInAction(() => {
this.list = data;
})

View File

@ -4,6 +4,8 @@ import { depStore } from '@/store/dep'
import { archivesStore } from '@/store/archives'
import folderStore from '@/store/folder';
import { acStore } from '@/store/archives_category';
import { politicalStudyStore } from "./political_study";
import { stashStore } from "@/store/stash"
const store = {
usrStore,
@ -11,7 +13,9 @@ const store = {
depStore,
archivesStore,
folderStore,
acStore
acStore,
politicalStudyStore,
stashStore
};
export default store;

View File

@ -0,0 +1,19 @@
import { makeObservable } from "mobx";
// 用户信息
import BaseStore from "./baseStore";
import { TagDataType } from "@/model/userModel";
class PoliticalStudyConfig {
static LIST: string = "learning/list"
static ADD: string = "learning/add"
static DELETE: string = "learning"
static EDIT: string = "learning"
}
class PoliticalStudy extends BaseStore<TagDataType> {
constructor() {
super(PoliticalStudyConfig)
makeObservable(this, {})
}
}
export const politicalStudyStore = new PoliticalStudy()

19
src/store/stash.ts Normal file
View File

@ -0,0 +1,19 @@
import { makeObservable } from "mobx";
// 用户信息
import BaseStore from "./baseStore";
import { TagDataType } from "@/model/userModel";
class StashConfig {
static LIST: string = "stash/list"
static ADD: string = "stash"
static DELETE: string = "stash"
static EDIT: string = "stash"
}
class Stash extends BaseStore<TagDataType> {
constructor() {
super(StashConfig)
makeObservable(this, {})
}
}
export const stashStore = new Stash()