完善功能
This commit is contained in:
parent
9160a37bbe
commit
c83637d1bc
@ -1,18 +1,20 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
root: true,
|
||||
env: {browser: true, es2020: true},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
},
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{allowConstantExport: true},
|
||||
],
|
||||
// 去除any报错
|
||||
'@typescript-eslint/no-explicit-any': ['off']
|
||||
},
|
||||
}
|
||||
|
@ -2,10 +2,13 @@ import './card-proj-type.css';
|
||||
import {ICardProj, ICardProjChargeLine} from "../../interfaces/proj/ICardProj.ts";
|
||||
import {Checkbox} from 'antd';
|
||||
import {useState} from "react";
|
||||
import {ProjAdditionalType} from "../../interfaces/proj/IProj.ts";
|
||||
|
||||
export default function CardProjType(props: ICardProj) {
|
||||
|
||||
const [chargeAmount, setChargeAmount] = useState(0);
|
||||
const [pkg, setPkg] = useState(false);
|
||||
const [videoDemo, setVideoDemo] = useState(false);
|
||||
|
||||
const renderContents = (lineIndex: number, contents: string[]) => {
|
||||
return contents.map((item, index) => <li key={`content_${lineIndex}_${index}`}>
|
||||
@ -29,8 +32,18 @@ export default function CardProjType(props: ICardProj) {
|
||||
|
||||
const onChargeChange = (checked: boolean, line: ICardProjChargeLine) => {
|
||||
if (checked) {
|
||||
if (line.id == ProjAdditionalType.PKG) {
|
||||
setPkg(true);
|
||||
} else if (line.id == ProjAdditionalType.VIDEO_DEMO) {
|
||||
setVideoDemo(true);
|
||||
}
|
||||
setChargeAmount(chargeAmount + line.price);
|
||||
} else {
|
||||
if (line.id == ProjAdditionalType.PKG) {
|
||||
setPkg(false);
|
||||
} else if (line.id == ProjAdditionalType.VIDEO_DEMO) {
|
||||
setVideoDemo(false);
|
||||
}
|
||||
setChargeAmount(chargeAmount - line.price);
|
||||
}
|
||||
}
|
||||
@ -60,13 +73,15 @@ export default function CardProjType(props: ICardProj) {
|
||||
return props.buyArray.map((buy, index) => {
|
||||
return (
|
||||
<div className="buy-btn" key={`buy_${index}`}>
|
||||
<div className="price">{buy.label}{buy.price + chargeAmount} 元</div>
|
||||
<div className="price">{buy.label}{(buy.price + chargeAmount) / 100} 元</div>
|
||||
<hr/>
|
||||
<div className="buy">
|
||||
<button onClick={() => {
|
||||
buy.handleClick(props.head, buy.price + chargeAmount);
|
||||
}}>购买
|
||||
</button>
|
||||
buy.handleClick(props.head, {
|
||||
pkg: pkg,
|
||||
videoDemo: videoDemo
|
||||
});
|
||||
}}>购买</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,9 +1,9 @@
|
||||
import './list-proj.css'
|
||||
import CardProj from "../card/CardProj.tsx";
|
||||
import {useRef, MutableRefObject, useState, useEffect} from "react";
|
||||
import {Input, Pagination} from 'antd';
|
||||
import {Input, Pagination, message} from 'antd';
|
||||
import type {SearchProps} from 'antd/es/input/Search';
|
||||
import {Axios} from "../../util/AjaxUtils.ts";
|
||||
import {get} from "../../util/AjaxUtils.ts";
|
||||
|
||||
|
||||
const {Search} = Input;
|
||||
@ -17,25 +17,28 @@ export default function ListProj() {
|
||||
const listProjRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
const listRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
|
||||
const [page, _setPage] = useState(1);
|
||||
const [total, _setTotal] = useState(0);
|
||||
const [projs, _setProjs] = useState([]);
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [projs, setProjs] = useState([]);
|
||||
|
||||
const domHeight = window.innerHeight - 280;
|
||||
|
||||
const renderData = () => {
|
||||
Axios.get('/api/proj/listpage/self', {
|
||||
params: {
|
||||
page: page,
|
||||
rows: 20
|
||||
const reqData = (currentPage: number) => {
|
||||
get({
|
||||
messageApi: messageApi,
|
||||
url: '/api/proj/listpage/self',
|
||||
config: {
|
||||
params: {
|
||||
page: currentPage,
|
||||
rows: 20
|
||||
}
|
||||
},
|
||||
onSuccess({data}) {
|
||||
setProjs(data.page);
|
||||
setTotal(data.total);
|
||||
setProjs(data.rows);
|
||||
}
|
||||
}).then(res => {
|
||||
const data = res.data;
|
||||
_setProjs(data.page);
|
||||
_setTotal(data.total);
|
||||
_setProjs(data.rows);
|
||||
}).catch(res => {
|
||||
console.log(res);
|
||||
})
|
||||
}
|
||||
|
||||
@ -44,22 +47,28 @@ export default function ListProj() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
renderData();
|
||||
reqData(page);
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="list-proj" ref={listProjRef}>
|
||||
<div className="top">
|
||||
<Search placeholder="按项目名搜索" onSearch={onSearch} style={{width: 200}}/>
|
||||
</div>
|
||||
<div className="body">
|
||||
<div className="list" ref={listRef} style={{height: `${domHeight}px`}}>
|
||||
{renderList()}
|
||||
<>
|
||||
{contextHolder}
|
||||
<div className="list-proj" ref={listProjRef}>
|
||||
<div className="top">
|
||||
<Search placeholder="按项目名搜索" onSearch={onSearch} style={{width: 200}}/>
|
||||
</div>
|
||||
<div className="page">
|
||||
<Pagination defaultCurrent={page} total={total}/>
|
||||
<div className="body">
|
||||
<div className="list" ref={listRef} style={{height: `${domHeight}px`}}>
|
||||
{renderList()}
|
||||
</div>
|
||||
<div className="page">
|
||||
<Pagination defaultCurrent={page} total={total} onChange={(page) => {
|
||||
setPage(page);
|
||||
reqData(page);
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,18 +1,24 @@
|
||||
|
||||
export interface ICardProjBodyLine {
|
||||
title: string;
|
||||
contents: string[];
|
||||
}
|
||||
|
||||
export interface ICardProjChargeLine {
|
||||
id: string;
|
||||
title: string;
|
||||
price: number;
|
||||
}
|
||||
|
||||
export interface ICardProjBuy {
|
||||
id: string;
|
||||
label?: string,
|
||||
price: number;
|
||||
|
||||
handleClick(title: string, price: number): void;
|
||||
handleClick(title: string, additional: {
|
||||
pkg: boolean,
|
||||
videoDemo: boolean
|
||||
}): void;
|
||||
}
|
||||
|
||||
export interface ICardProj {
|
||||
|
@ -20,6 +20,34 @@ export enum GenerateStatus {
|
||||
ERROR = 'ERROR'
|
||||
}
|
||||
|
||||
export enum ProjChargeType {
|
||||
ALL = 'ALL',
|
||||
MATERIAL_AGENT = 'MATERIAL_AGENT',
|
||||
MATERIAL_AGENT_URGENT = 'MATERIAL_AGENT_URGENT',
|
||||
MATERIAL = 'MATERIAL',
|
||||
FREE = 'FREE',
|
||||
}
|
||||
|
||||
export enum ProjAdditionalType {
|
||||
PKG = 'PKG',
|
||||
VIDEO_DEMO = 'VIDEO_DEMO'
|
||||
}
|
||||
|
||||
export interface IProjCharge {
|
||||
proj: {
|
||||
all: number;
|
||||
materialAgent: number;
|
||||
materialAgentUrgent: number;
|
||||
material: number;
|
||||
free: number;
|
||||
},
|
||||
additional: {
|
||||
pkg: number;
|
||||
videoDemo: number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export interface IProj {
|
||||
|
||||
projId: string,
|
||||
@ -33,5 +61,4 @@ export interface IProj {
|
||||
gmtCreate: string,
|
||||
generateStatus: GenerateStatus
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,11 @@ const router = createBrowserRouter([
|
||||
element: <ProjCreate />
|
||||
},
|
||||
{
|
||||
path: '/proj-new/:type/:price',
|
||||
path: '/proj-new/:projChargeType',
|
||||
element: <ProjNew />
|
||||
},
|
||||
{
|
||||
path: '/proj-edit',
|
||||
path: '/proj-edit/:projId',
|
||||
element: <ProjEdit />
|
||||
},
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './App.tsx'
|
||||
import './index.css'
|
||||
|
@ -1,13 +1,42 @@
|
||||
import './proj-create.css'
|
||||
import {Link, useNavigate} from "react-router-dom";
|
||||
import {Breadcrumb} from "antd";
|
||||
import {Breadcrumb, message} from "antd";
|
||||
import CardProjType from "../../components/card/CardProjType.tsx";
|
||||
import {IProjCharge, ProjAdditionalType, ProjChargeType} from "../../interfaces/proj/IProj.ts";
|
||||
import {useEffect, useState} from "react";
|
||||
import {get} from "../../util/AjaxUtils.ts";
|
||||
|
||||
export default function ProjCreate() {
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [charge, setCharge] = useState<IProjCharge>({
|
||||
proj: {
|
||||
all: 0,
|
||||
materialAgent: 0,
|
||||
materialAgentUrgent: 0,
|
||||
material: 0,
|
||||
free: 0,
|
||||
},
|
||||
additional: {
|
||||
pkg: 0,
|
||||
videoDemo: 0
|
||||
}
|
||||
});
|
||||
const nav = useNavigate();
|
||||
const height = window.innerHeight - 150;
|
||||
|
||||
useEffect(() => {
|
||||
get({
|
||||
messageApi: messageApi,
|
||||
url: '/api/proj/charge/get',
|
||||
onSuccess({data}) {
|
||||
setCharge(data);
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{title: <Link to={'/'}>首页</Link>},
|
||||
@ -15,7 +44,7 @@ export default function ProjCreate() {
|
||||
]}
|
||||
/>
|
||||
<div style={{height: `${height}px`, overflow: 'auto'}}>
|
||||
<div className="proj-create" >
|
||||
<div className="proj-create">
|
||||
<CardProjType
|
||||
head={'全托管'}
|
||||
bodyLineArray={[
|
||||
@ -42,9 +71,10 @@ export default function ProjCreate() {
|
||||
]}
|
||||
buyArray={[
|
||||
{
|
||||
price: 500,
|
||||
handleClick: (_title, price) => {
|
||||
nav(`/proj-new/q/${price}`)
|
||||
id: ProjChargeType.ALL,
|
||||
price: charge.proj.all,
|
||||
handleClick: () => {
|
||||
nav(`/proj-new/${ProjChargeType.ALL}`)
|
||||
}
|
||||
}
|
||||
]}
|
||||
@ -72,27 +102,31 @@ export default function ProjCreate() {
|
||||
]}
|
||||
chargeLineArray={[
|
||||
{
|
||||
price: 100,
|
||||
title: '安装包100元'
|
||||
id: ProjAdditionalType.PKG,
|
||||
price: charge.additional.pkg,
|
||||
title: `安装包 ${charge.additional.pkg / 100} 元`
|
||||
},
|
||||
{
|
||||
price: 50,
|
||||
title: '系统演示视频文件50元'
|
||||
id: ProjAdditionalType.VIDEO_DEMO,
|
||||
price: charge.additional.videoDemo,
|
||||
title: `系统演示视频文件 ${charge.additional.videoDemo / 100} 元`
|
||||
}
|
||||
]}
|
||||
buyArray={[
|
||||
{
|
||||
id: ProjChargeType.MATERIAL_AGENT,
|
||||
label: '普件:',
|
||||
price: 200,
|
||||
handleClick: (_title, price) => {
|
||||
nav(`/proj-new/xdp/${price}`)
|
||||
price: charge.proj.materialAgent,
|
||||
handleClick: (_title, additional) => {
|
||||
nav(`/proj-new/${ProjChargeType.MATERIAL_AGENT}?pkg=${additional.pkg}&videoDemo=${additional.videoDemo}`)
|
||||
}
|
||||
},
|
||||
{
|
||||
id: ProjChargeType.MATERIAL_AGENT_URGENT,
|
||||
label: '加急:',
|
||||
price: 300,
|
||||
handleClick: (_title, price) => {
|
||||
nav(`/proj-new/xdj/${price}`)
|
||||
price: charge.proj.materialAgentUrgent,
|
||||
handleClick: (_title, additional) => {
|
||||
nav(`/proj-new/${ProjChargeType.MATERIAL_AGENT_URGENT}?pkg=${additional.pkg}&videoDemo=${additional.videoDemo}`)
|
||||
}
|
||||
}
|
||||
]}
|
||||
@ -123,19 +157,22 @@ export default function ProjCreate() {
|
||||
]}
|
||||
chargeLineArray={[
|
||||
{
|
||||
price: 100,
|
||||
title: '安装包100元'
|
||||
id: ProjAdditionalType.PKG,
|
||||
price: charge.additional.pkg,
|
||||
title: `安装包 ${charge.additional.pkg / 100} 元`
|
||||
},
|
||||
{
|
||||
price: 50,
|
||||
title: '系统演示视频文件50元'
|
||||
id: ProjAdditionalType.VIDEO_DEMO,
|
||||
price: charge.additional.videoDemo,
|
||||
title: `系统演示视频文件 ${charge.additional.videoDemo / 100} 元`
|
||||
}
|
||||
]}
|
||||
buyArray={[
|
||||
{
|
||||
price: 200,
|
||||
handleClick: (_title, price) => {
|
||||
nav(`/proj-new/x/${price}`)
|
||||
id: ProjChargeType.MATERIAL,
|
||||
price: charge.proj.material,
|
||||
handleClick: () => {
|
||||
nav(`/proj-new/${ProjChargeType.MATERIAL}`)
|
||||
}
|
||||
}
|
||||
]}
|
||||
@ -159,9 +196,10 @@ export default function ProjCreate() {
|
||||
]}
|
||||
buyArray={[
|
||||
{
|
||||
price: 0,
|
||||
handleClick: (_title, price) => {
|
||||
nav(`/proj-new/m/${price}`)
|
||||
id: ProjChargeType.FREE,
|
||||
price: charge.proj.free,
|
||||
handleClick: () => {
|
||||
nav(`/proj-new/${ProjChargeType.FREE}`)
|
||||
}
|
||||
}
|
||||
]}
|
||||
|
@ -1,38 +1,76 @@
|
||||
import './proj-new.css';
|
||||
import {Link, useNavigate, useParams} from "react-router-dom";
|
||||
import {Breadcrumb, Button, Flex, Form, type FormProps, Input, Modal} from "antd";
|
||||
import {useState} from "react";
|
||||
import {Link, useNavigate, useParams, useSearchParams} from "react-router-dom";
|
||||
import {Breadcrumb, Button, Flex, Form, Input, message, Modal, Spin} from "antd";
|
||||
import {useEffect, useState} from "react";
|
||||
import {get, post} from "../../util/AjaxUtils.ts";
|
||||
import {IProjCharge, ProjAdditionalType, ProjChargeType} from "../../interfaces/proj/IProj.ts";
|
||||
|
||||
const {TextArea} = Input;
|
||||
|
||||
type FieldType = {
|
||||
projTitle: string;
|
||||
projDesc: string;
|
||||
type ProjInfo = {
|
||||
projName: string;
|
||||
projIntroduction: string;
|
||||
};
|
||||
|
||||
export default function ProjNew() {
|
||||
const height = window.innerHeight - 150;
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const nav = useNavigate();
|
||||
const params = useParams();
|
||||
const pathParams = useParams();
|
||||
const [queryParams] = useSearchParams();
|
||||
|
||||
const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
|
||||
console.log('Success:', values);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const height = window.innerHeight - 150;
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
|
||||
const [chargePrice, setChargePrice] = useState(0);
|
||||
const [projInfo, setProjInfo] = useState<ProjInfo>({
|
||||
projName: '',
|
||||
projIntroduction: '',
|
||||
});
|
||||
const listProjChargeAdditional: string[] = [];
|
||||
let createProjId = '';
|
||||
|
||||
const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
const handleConfirmOk = () => {
|
||||
// 扣款
|
||||
nav('/proj-edit');
|
||||
}
|
||||
|
||||
const handleConfirmCancel = () => {
|
||||
setIsModalOpen(false);
|
||||
}
|
||||
useEffect(() => {
|
||||
get({
|
||||
messageApi: messageApi,
|
||||
url: '/api/proj/charge/get',
|
||||
onSuccess({data}) {
|
||||
const charge = data as IProjCharge;
|
||||
let price = 0;
|
||||
switch (pathParams.projChargeType) {
|
||||
case ProjChargeType.ALL:
|
||||
price = charge.proj.all;
|
||||
break;
|
||||
case ProjChargeType.MATERIAL_AGENT:
|
||||
price = charge.proj.materialAgent;
|
||||
break;
|
||||
case ProjChargeType.MATERIAL_AGENT_URGENT:
|
||||
price = charge.proj.materialAgentUrgent;
|
||||
break;
|
||||
case ProjChargeType.MATERIAL:
|
||||
price = charge.proj.material;
|
||||
break;
|
||||
case ProjChargeType.FREE:
|
||||
price = charge.proj.free;
|
||||
break;
|
||||
default:
|
||||
messageApi.error({
|
||||
type: 'error',
|
||||
content: '价格类型错误',
|
||||
})
|
||||
}
|
||||
if (queryParams.get('pkg')) {
|
||||
price += charge.additional.pkg;
|
||||
listProjChargeAdditional.push(ProjAdditionalType.PKG);
|
||||
}
|
||||
if (queryParams.get('videoDemo')) {
|
||||
price += charge.additional.videoDemo;
|
||||
listProjChargeAdditional.push(ProjAdditionalType.VIDEO_DEMO);
|
||||
}
|
||||
setChargePrice(price);
|
||||
}
|
||||
})
|
||||
}, []);
|
||||
|
||||
const onBack = () => {
|
||||
nav(-1);
|
||||
@ -40,6 +78,7 @@ export default function ProjNew() {
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{title: <Link to={'/'}>首页</Link>},
|
||||
@ -58,21 +97,26 @@ export default function ProjNew() {
|
||||
wrapperCol={{span: 24}}
|
||||
style={{width: 500}}
|
||||
initialValues={{remember: true}}
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
onFinish={(formData) => {
|
||||
setIsCreateModalOpen(true);
|
||||
setProjInfo({
|
||||
projName: formData.projName,
|
||||
projIntroduction: formData.projIntroduction
|
||||
})
|
||||
}}
|
||||
autoComplete="off"
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
<Form.Item<ProjInfo>
|
||||
label="系统标题"
|
||||
name="projTitle"
|
||||
name="projName"
|
||||
rules={[{required: true, message: '请输入系统标题'}]}
|
||||
>
|
||||
<Input placeholder="请输入系统标题"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<FieldType>
|
||||
<Form.Item<ProjInfo>
|
||||
label="简单描述"
|
||||
name="projDesc"
|
||||
name="projIntroduction"
|
||||
rules={[{required: true, message: '请输入简单描述'}]}
|
||||
>
|
||||
<TextArea rows={6} placeholder="请用一段话简单描述系统"/>
|
||||
@ -80,7 +124,8 @@ export default function ProjNew() {
|
||||
|
||||
<Form.Item>
|
||||
<Flex align="center" justify="center" gap="large">
|
||||
<Button type="primary" htmlType="submit" style={{backgroundColor: 'var(--color-primary)'}}>
|
||||
<Button type="primary" htmlType="submit"
|
||||
style={{backgroundColor: 'var(--color-primary)'}}>
|
||||
提交并付款
|
||||
</Button>
|
||||
<Button type="default" htmlType="button" onClick={onBack}>
|
||||
@ -92,10 +137,51 @@ export default function ProjNew() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal title="提示" okText="确定" cancelText="取消" open={isModalOpen} onOk={handleConfirmOk}
|
||||
onCancel={handleConfirmCancel}>
|
||||
<div>该操作会扣除{params.price}元,确定操作码?</div>
|
||||
<Modal title="提示"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
open={isCreateModalOpen}
|
||||
onOk={() => {
|
||||
setIsCreateModalOpen(false);
|
||||
post({
|
||||
messageApi,
|
||||
url: '/api/proj/create',
|
||||
body: {
|
||||
projName: projInfo.projName,
|
||||
projIntroduction: projInfo.projIntroduction,
|
||||
projChargeType: pathParams.projChargeType,
|
||||
listProjChargeAdditional: listProjChargeAdditional
|
||||
},
|
||||
onBefore() {
|
||||
setLoading(true);
|
||||
},
|
||||
onSuccess({data}) {
|
||||
setIsEditModalOpen(true);
|
||||
createProjId = data.data;
|
||||
},
|
||||
onFinally() {
|
||||
setLoading(false);
|
||||
}
|
||||
})
|
||||
}}
|
||||
onCancel={() => {
|
||||
setIsCreateModalOpen(false);
|
||||
}}>
|
||||
<div>该操作会扣除 {chargePrice / 100} 元,确定操作码?</div>
|
||||
</Modal>
|
||||
<Modal title="提示"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
open={isEditModalOpen}
|
||||
onOk={() => {
|
||||
nav(`/proj-edit/${createProjId}`);
|
||||
}}
|
||||
onCancel={() => {
|
||||
setIsEditModalOpen(false);
|
||||
}}>
|
||||
<div>项目创建成功,开始编辑项目?</div>
|
||||
</Modal>
|
||||
<Spin tip="正在提交..." spinning={loading} fullscreen/>
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,6 +1,100 @@
|
||||
import axios from "axios";
|
||||
import axios, {AxiosRequestConfig, AxiosResponse} from "axios";
|
||||
import type {MessageInstance} from "antd/es/message/interface";
|
||||
|
||||
type Req = {
|
||||
messageApi: MessageInstance;
|
||||
url: string;
|
||||
body?: any;
|
||||
config?: AxiosRequestConfig;
|
||||
onBefore?(): void;
|
||||
onSuccess(data: AxiosResponse): void;
|
||||
onFinally?(): void;
|
||||
}
|
||||
|
||||
axios.defaults.baseURL = 'http://127.0.0.1:7025/copyright';
|
||||
axios.defaults.headers['X-USER-ID'] = '80d3365e-0597-4988-979e-18ef1c3ec671';
|
||||
axios.interceptors.request.use(config => {
|
||||
if (config.method === 'get') {
|
||||
config.data = {unused: 0} // 这个是关键点,解决get 请求添加不上content_type
|
||||
}
|
||||
config.headers['X-USER-ID'] = '80d3365e-0597-4988-979e-18ef1c3ec671';
|
||||
return config
|
||||
}
|
||||
);
|
||||
|
||||
export const Axios = axios;
|
||||
export const Axios = axios;
|
||||
|
||||
export function get(req: Req) {
|
||||
req.onBefore?.();
|
||||
Axios.get(req.url, req.config).then(res => {
|
||||
req.onSuccess(res);
|
||||
}).catch(error => {
|
||||
if (error.response) {
|
||||
const data = error.response.data;
|
||||
req.messageApi.open({
|
||||
type: 'error',
|
||||
content: data.msg ? data.msg : `${data.path}(${data.status})`,
|
||||
});
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
}).finally(() => {
|
||||
req.onFinally?.();
|
||||
})
|
||||
}
|
||||
|
||||
export function post(req: Req) {
|
||||
req.onBefore?.();
|
||||
Axios.post(req.url, req.body, req.config).then(res => {
|
||||
req.onSuccess(res);
|
||||
}).catch(error => {
|
||||
if (error.response) {
|
||||
const data = error.response.data;
|
||||
req.messageApi.open({
|
||||
type: 'error',
|
||||
content: data.msg ? data.msg : `${data.path}(${data.status})`,
|
||||
});
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
}).finally(() => {
|
||||
req.onFinally?.();
|
||||
})
|
||||
}
|
||||
|
||||
export function put(req: Req) {
|
||||
req.onBefore?.();
|
||||
Axios.put(req.url, req.config).then(res => {
|
||||
req.onSuccess(res);
|
||||
}).catch(error => {
|
||||
if (error.response) {
|
||||
const data = error.response.data;
|
||||
req.messageApi.open({
|
||||
type: 'error',
|
||||
content: data.msg ? data.msg : `${data.path}(${data.status})`,
|
||||
});
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
}).finally(() => {
|
||||
req.onFinally?.();
|
||||
})
|
||||
}
|
||||
|
||||
export function del(req: Req) {
|
||||
req.onBefore?.();
|
||||
Axios.delete(req.url, req.config).then(res => {
|
||||
req.onSuccess(res);
|
||||
}).catch(error => {
|
||||
if (error.response) {
|
||||
const data = error.response.data;
|
||||
req.messageApi.open({
|
||||
type: 'error',
|
||||
content: data.msg ? data.msg : `${data.path}(${data.status})`,
|
||||
});
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
}).finally(() => {
|
||||
req.onFinally?.();
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user