提交 fc0118ea 作者: 龚洪江

功能:商品sku新增编辑

上级 43f628eb
...@@ -14,6 +14,7 @@ import { ResourceManageAPI } from './modules/resourceManageAPI'; ...@@ -14,6 +14,7 @@ import { ResourceManageAPI } from './modules/resourceManageAPI';
import { ForumManageAPI } from './modules/forumManageAPI'; import { ForumManageAPI } from './modules/forumManageAPI';
import { PilotTrainAPI } from './modules/pilotTrainAPI'; import { PilotTrainAPI } from './modules/pilotTrainAPI';
import { FlyerCenterAPI } from './modules/flyerCenterAPI'; import { FlyerCenterAPI } from './modules/flyerCenterAPI';
import { RentManageAPI } from './modules/rentManageAPI';
export { export {
CommonAPI, CommonAPI,
...@@ -32,4 +33,5 @@ export { ...@@ -32,4 +33,5 @@ export {
ForumManageAPI, ForumManageAPI,
PilotTrainAPI, PilotTrainAPI,
FlyerCenterAPI, FlyerCenterAPI,
RentManageAPI,
}; };
...@@ -86,7 +86,7 @@ export type editGoodsType = InterFunction< ...@@ -86,7 +86,7 @@ export type editGoodsType = InterFunction<
export type detailGoodsType = InterFunction< export type detailGoodsType = InterFunction<
{ goodsInfoId: number; type: number; leaseTerm?: number }, { goodsInfoId: number; type: number; leaseTerm?: number },
BaseInfoType & { BaseInfoType & {
goodsSpec?: specEntity[]; goodsSpec: specEntity[];
goodsDetail: { goodsDesc: string; productDesc: string; content: string }; goodsDetail: { goodsDesc: string; productDesc: string; content: string };
otherService: { id: number; saleServiceName: string; saleServiceId: number }[]; otherService: { id: number; saleServiceName: string; saleServiceId: number }[];
goodsVideoId: number; goodsVideoId: number;
...@@ -109,14 +109,14 @@ export type removeMallGoodsType = InterFunction<{ id: number }, any>; ...@@ -109,14 +109,14 @@ export type removeMallGoodsType = InterFunction<{ id: number }, any>;
export type exchangeGoodsInfoType = InterFunction<{ firstId: number; secondId: number }, any>; export type exchangeGoodsInfoType = InterFunction<{ firstId: number; secondId: number }, any>;
//商品-新增(新) //商品-新增(新)
export type addMallGoodsType = InterFunction< //商品item类型
{ type goodsItemType = {
categoryPrimaryId: number; categoryPrimaryId: number;
categorySubId: number; categorySubId: number;
description: string; description: string;
goodsDetails: string; goodsDetails: string;
goodsLabel: string; goodsLabel: string;
goodsSpecList: { goodsSpecList?: {
chooseType: number; chooseType: number;
goodsSpecValuesList: { goodsSpecValuesList: {
channelPrice?: number; channelPrice?: number;
...@@ -152,127 +152,19 @@ export type addMallGoodsType = InterFunction< ...@@ -152,127 +152,19 @@ export type addMallGoodsType = InterFunction<
skuNo: string; skuNo: string;
stock: number; stock: number;
}[]; }[];
}, specAttrList: {
any
>;
//商品-编辑(新)
export type editMallGoodsType = InterFunction<
{
categoryPrimaryId: number;
categorySubId: number;
description: string;
goodsDetails: string;
goodsLabel: string;
goodsSpecList: {
chooseType: number;
goodsSpecValuesList: {
channelPrice?: number;
id: any;
partNo: string;
salePrice: number;
showPrice: number;
specValueImage: string;
specValueName: string;
stock?: number;
goodsSpecId: number;
}[];
id: any;
mallGoodsId: number;
must: number;
skuUnitId: number;
specName: string; specName: string;
}[];
id: number; id: number;
labelShow: number; specValuesList: { specName: string; id: number }[];
resourcesList: {
id: number;
type: number;
url: string;
}[]; }[];
shelfStatus: number; };
tradeName: string; export type addMallGoodsType = InterFunction<goodsItemType, any>;
}, //商品-编辑(新)
any export type editMallGoodsType = InterFunction<goodsItemType & { id: number }, any>;
>;
//商品-列表(新) //商品-列表(新)
export type listPageGoodsInfoType = InterItemFunction< export type listPageGoodsInfoType = InterItemFunction<
{ categoryPrimaryId?: number; tradeName?: string; shelfStatus?: number }, { categoryPrimaryId?: number; tradeName?: string; shelfStatus?: number },
{ goodsItemType & { id: number }[]
categoryPrimaryId: number;
categorySubId: number;
createTime: string;
description: string;
goodsDetails: string;
goodsLabel: string;
goodsSpecList: {
chooseType: number;
goodsSpecValuesList: {
channelPrice: number;
goodsSpecId: number;
id: number;
partNo: string;
salePrice: number;
showPrice: number;
specValueImage: string;
specValueName: string;
stock: number;
}[];
id: number;
mallGoodsId: number;
must: number;
skuUnitId: number;
specName: string;
}[];
id: number;
labelShow: number;
resourcesList: {
id: number;
type: number;
url: string;
}[];
shelfStatus: number;
tradeName: string;
userAccountId: number;
}[]
>; >;
//商城-详情(新) //商城-详情(新)
export type mallGoodsDetailsType = InterFunction< export type mallGoodsDetailsType = InterFunction<{ id: number }, goodsItemType & { id: number }>;
{ id: number },
{
categoryPrimaryId: number;
categorySubId: number;
createTime: string;
description: string;
goodsDetails: string;
goodsLabel: string;
goodsSpecList: {
chooseType: number;
goodsSpecValuesList: {
channelPrice: number;
goodsSpecId: number;
id: number;
partNo: string;
salePrice: number;
showPrice: number;
specValueImage: string;
specValueName: string;
stock: number;
}[];
id: number;
mallGoodsId: number;
must: number;
skuUnitId: number;
specName: string;
}[];
id: number;
labelShow: number;
resourcesList: {
id: number;
type: number;
url: string;
}[];
shelfStatus: number;
tradeName: string;
userAccountId: number;
}
>;
import { InterFunction, InterItemFunction } from '~/api/interface';
//租赁-新增
export type addType = InterFunction<{ name: string; url: string }, any>;
//租赁-列表
export type getTypeListType = InterItemFunction<any, { id: number; name: string; url: string }[]>;
//租赁-编辑
export type rentTypeEditType = InterFunction<{ name: string; url: string; id: number }, any>;
//租赁-删除
export type rentTypeRemoveType = InterFunction<{ id: number }, any>;
import {
addType,
getTypeListType,
rentTypeEditType,
rentTypeRemoveType,
} from '~/api/interface/rentManageType';
import axios from '../request';
export class RentManageAPI {
//租赁-新增类型
static addTypeReq: addType = (data) => axios.post('/pms/attribute/addType', data);
//租赁-类型列表
static getTypeList: getTypeListType = (params) =>
axios.get('/pms/attribute/typeList', { params });
// 租赁-编辑类型
static editTypeReq: rentTypeEditType = (data) => axios.post('/pms/attribute/editType', data);
// 租赁-删除
static rentTypeRemove: rentTypeRemoveType = (params) =>
axios.get('/pms/attribute/removeType', { params });
}
import { useSearchParams, useNavigate } from 'react-router-dom'; import { useSearchParams, useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import GoodsAPI from '~/api/modules/goodsAPI'; import GoodsAPI from '~/api/modules/goodsAPI';
import { InterDataType } from '~/api/interface'; import { InterDataType, InterReqType } from '~/api/interface';
import { mallGoodsDetailsType, skuUnitType } from '~/api/interface/goodsType'; import { addMallGoodsType, mallGoodsDetailsType } from '~/api/interface/goodsType';
import { Badge, Button, Descriptions, Image, Table, Tag } from 'antd'; import { Badge, Button, Descriptions, Image, Table } from 'antd';
import { CategoryManageAPI } from '~/api'; import { CategoryManageAPI } from '~/api';
import { categoryListRespType } from '~/api/interface/categoryManage'; import { categoryListRespType } from '~/api/interface/categoryManage';
import './index.scss'; import './index.scss';
import { ColumnsType } from 'antd/es/table';
//详情返回类型 //详情返回类型
type detailType = InterDataType<mallGoodsDetailsType>; type detailType = InterDataType<mallGoodsDetailsType>;
//分类返回类型 //分类返回类型
type categoryType = InterDataType<categoryListRespType>['list']; type categoryType = InterDataType<categoryListRespType>['list'];
//单位返回类型 //规格表格类型
type unitType = InterDataType<skuUnitType>; type skuTableType = Exclude<InterReqType<addMallGoodsType>, undefined>['priceStock'][0] & {
fileList: {
id: number;
name: string;
uid: number;
url: string;
}[];
};
//规格表单数据类型
type specificationFormListType = {
optionList: { label: string; value: string }[];
id: number;
name: string;
addSpecificationValueShow: boolean;
specificationValueList: { name: string; id: number; specificationName: string }[];
};
const GoodsDetails = () => { const GoodsDetails = () => {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const navigate = useNavigate(); const navigate = useNavigate();
//分类列表 //分类列表
const [categoryList, setCategoryList] = useState<categoryType>([]); const [categoryList, setCategoryList] = useState<categoryType>([]);
//单位列表
const [skuUnitList, setSkuUnitList] = useState<unitType>([]); //表格数据
const [tableData, setTableData] = useState<(skuTableType & { [key: string]: string })[]>([]);
const [goodsInfoDetails, setGoodsInfoDetails] = useState<detailType>(); const [goodsInfoDetails, setGoodsInfoDetails] = useState<detailType>();
const tableColumns: ColumnsType<detailType['goodsSpecList'][0]> = [ const [tableColumns, setTableColumns] = useState<any>([
{ {
title: '序号', title: '商品规格',
align: 'center', align: 'center',
render: (_text: string, _record, index: number) => index + 1, dataIndex: 'specName',
children: [],
}, },
{ {
title: '规格名称', title: '图片',
align: 'center', align: 'center',
dataIndex: 'specName', dataIndex: 'skuImage',
render: (text: string) => <Image src={text} width={50} height={50} alt='暂无图片' />,
}, },
{ {
title: '选择方式', title: 'sku编号',
align: 'center', align: 'center',
dataIndex: 'chooseType', dataIndex: 'skuNo',
render: (text: number) => (text ? '多选' : '单选'),
}, },
{ {
title: '是否必选', title: '销售价',
align: 'center', align: 'center',
dataIndex: 'must', dataIndex: 'salePrice',
render: (text: number) => (text ? '必选' : '非必选'),
}, },
{ {
title: '规格单位', title: '渠道价',
align: 'center', align: 'center',
dataIndex: 'skuUnitId', dataIndex: 'channelPrice',
render: (text: number) => skuUnitList.find((v) => v.id === text)?.unitName || '',
}, },
{ {
title: '规格值', title: '库存',
align: 'center', align: 'center',
dataIndex: 'goodsSpecValuesList', dataIndex: 'stock',
render: (text: detailType['goodsSpecList'][0]['goodsSpecValuesList']) =>
text.map((v) => (
<Tag key={v.id}>
{v.specValueName}
{v.partNo ? `(${v.partNo})` : ''}
</Tag>
)),
}, },
]; ]);
const getGoodsDetails = (id: number) => { const getGoodsDetails = (id: number) => {
GoodsAPI.getMallGoodsDetails({ id }).then(({ result }) => { GoodsAPI.getMallGoodsDetails({ id }).then(({ result }) => {
setGoodsInfoDetails(result); setGoodsInfoDetails(result);
//转化数据
const covertSpecAttrList = result.specAttrList.map((v, index) => ({
id: v.id,
name: 'specName' + index,
optionList: [{ label: v.specName, value: v.specName }],
specificationValueList: v.specValuesList.map((i) => ({
id: i.id,
name: i.specName,
specificationName: v.specName,
})),
addSpecificationValueShow: false,
}));
mergeTableRow(covertSpecAttrList);
const tableDataList: (skuTableType & { [key: string]: string })[] = result.priceStock.map(
(v) => ({
id: v.id,
salePrice: v.salePrice,
skuImage: v.skuImage,
skuNo: v.skuNo,
stock: v.stock,
channelPrice: v.channelPrice,
fileList: v.skuImage
? [{ id: Math.random(), uid: Math.random(), url: v.skuImage, name: '规格图片' }]
: [],
...Object.getOwnPropertyNames(JSON.parse(v.productSpec)).reduce(
(pre: any, cur, currentIndex) => {
pre['name' + (currentIndex + 1)] = JSON.parse(v.productSpec)[cur];
pre['specificationName' + (currentIndex + 1)] = cur;
return pre;
},
{},
),
}),
);
setTableData(tableDataList);
}); });
}; };
//表头拆分及合并列
const mergeTableRow = (filterSpecificationFormList: specificationFormListType[]) => {
const columns = filterSpecificationFormList.map((v, index) => ({
title: v.optionList[0].value,
dataIndex: 'name' + (index + 1),
align: 'center',
onCell: (_: any, i: number) => {
//合并列
if (index < filterSpecificationFormList.length - 1) {
const count: number = filterSpecificationFormList
.slice(index + 1, filterSpecificationFormList.length)
.reduce((pre: number, cur) => {
return pre * cur.specificationValueList.length;
}, 1);
return {
rowSpan: count !== 1 ? ((i + 1) % count === 1 ? count : 0) : 1,
};
} else {
return {
rowSpan: 1,
};
}
},
}));
tableColumns[0].children = columns;
setTableColumns([...tableColumns]);
};
//分类列表 //分类列表
const getCategoryList = () => { const getCategoryList = () => {
CategoryManageAPI.getCategoryRespList({ pageNo: 1, pageSize: 99999 }).then(({ result }) => { CategoryManageAPI.getCategoryRespList({ pageNo: 1, pageSize: 99999 }).then(({ result }) => {
setCategoryList(result.list || []); setCategoryList(result.list || []);
}); });
}; };
//单位列表
const getSkuUnit = () => {
GoodsAPI.getSkuUnit().then(({ result }) => {
setSkuUnitList(result || []);
});
};
//返回 //返回
const backRoute = () => { const backRoute = () => {
navigate(-1); navigate(-1);
...@@ -91,7 +154,6 @@ const GoodsDetails = () => { ...@@ -91,7 +154,6 @@ const GoodsDetails = () => {
useEffect(() => { useEffect(() => {
getGoodsDetails(Number(searchParams.get('id'))); getGoodsDetails(Number(searchParams.get('id')));
getCategoryList(); getCategoryList();
getSkuUnit();
}, []); }, []);
return ( return (
<div className='goods-detail'> <div className='goods-detail'>
...@@ -157,7 +219,7 @@ const GoodsDetails = () => { ...@@ -157,7 +219,7 @@ const GoodsDetails = () => {
<Table <Table
bordered bordered
columns={tableColumns} columns={tableColumns}
dataSource={goodsInfoDetails?.goodsSpecList} dataSource={tableData}
rowKey='id' rowKey='id'
pagination={false} pagination={false}
></Table> ></Table>
......
...@@ -71,7 +71,6 @@ const GoodsAddOrEditOrDetail = () => { ...@@ -71,7 +71,6 @@ const GoodsAddOrEditOrDetail = () => {
//删除规格 //删除规格
const deleteSkuEvent = (record: specEntity) => { const deleteSkuEvent = (record: specEntity) => {
const index = specData.findIndex((v) => v.id === record.id); const index = specData.findIndex((v) => v.id === record.id);
console.log('删除index-->', index);
specData.splice(index, 1); specData.splice(index, 1);
setSpecData([...specData]); setSpecData([...specData]);
}; };
......
import { FC, useEffect, useState } from 'react';
import { Form, Input, message, Modal, ModalProps } from 'antd';
import { Uploader } from '~/components/uploader';
import { UploadOutlined } from '@ant-design/icons';
import { RentManageAPI } from '~/api';
import { InterDataType, InterReqType } from '~/api/interface';
import { addType, getTypeListType } from '~/api/interface/rentManageType';
//类型类别返回类型
type rentTypeListType = InterDataType<getTypeListType>['list'];
//新增租赁类型参数类型
type addRentTypeParameters = InterReqType<addType>;
interface selfProps {
onCancel: () => void;
onOk: () => void;
currentRentTypeItem: rentTypeListType[0] | undefined;
}
const AddOrEditTypeModal: FC<ModalProps & selfProps> = ({
open,
onCancel,
onOk,
currentRentTypeItem,
}) => {
const [form] = Form.useForm<addRentTypeParameters>();
const [fileList, setFileList] = useState<any>([]);
const handleCancel = () => {
form.resetFields();
setFileList([]);
onCancel();
};
const handelOk = () => {
form.validateFields().then((values: any) => {
RentManageAPI[currentRentTypeItem ? 'editTypeReq' : 'addTypeReq']({
...values,
id: currentRentTypeItem ? currentRentTypeItem.id : undefined,
}).then(({ code }) => {
if (code === '200') {
message.success(currentRentTypeItem ? '编辑成功' : '新增成功');
form.resetFields();
setFileList([]);
onOk();
}
});
});
};
//上传成功
const uploadSuccess = (fileList: any) => {
form.setFieldValue('url', fileList[0].url);
setFileList(fileList);
};
useEffect(() => {
if (currentRentTypeItem) {
form.setFieldsValue({
name: currentRentTypeItem.name,
url: currentRentTypeItem.url,
});
setFileList([
{ id: Math.random(), uid: Math.random(), url: currentRentTypeItem.url, name: '类型图片' },
]);
}
}, [currentRentTypeItem]);
return (
<Modal open={open} title='新增类型' onCancel={handleCancel} onOk={handelOk}>
<Form form={form} labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
<Form.Item label='类型名称' name='name'>
<Input placeholder='请输入类型名称' maxLength={30} />
</Form.Item>
<Form.Item label='图片' name='url' rules={[{ required: true, message: '请上传图片' }]}>
<Uploader
fileUpload
listType='picture-card'
onChange={uploadSuccess}
defaultFileList={fileList}
>
<UploadOutlined />
</Uploader>
</Form.Item>
</Form>
</Modal>
);
};
export default AddOrEditTypeModal;
import { Button, Image, message, Modal, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import AddOrEditTypeModal from './components/addOrEditTypeModal';
import { useEffect, useState } from 'react';
import { InterDataType, PaginationProps } from '~/api/interface';
import { RentManageAPI } from '~/api';
import { getTypeListType } from '~/api/interface/rentManageType';
//类型类别返回类型
type rentTypeListType = InterDataType<getTypeListType>['list'];
const RentType = () => {
const [addOrEditTypeModalShow, setAddOrEditTypeModalShow] = useState<boolean>(false);
const [pagination, setPagination] = useState<PaginationProps & { totalCount: number }>({
pageNo: 1,
pageSize: 10,
totalCount: 0,
});
const tableColumns: ColumnsType<rentTypeListType[0]> = [
{
title: '类型名称',
align: 'center',
dataIndex: 'name',
},
{
title: '图片',
align: 'center',
dataIndex: 'url',
render: (text: string) => <Image src={text} width={50} height={50} />,
},
{
title: '操作',
align: 'center',
render: (_text: string, record) => (
<>
<Button type='link' onClick={() => addOrEditTypeModalClick(record)}>
编辑
</Button>
<Button type='link' onClick={() => deleteRentType(record)}>
删除
</Button>
</>
),
},
];
const [tableData, setTableData] = useState<rentTypeListType>([]);
const [currentRentTypeItem, setCurrentRentTypeItem] = useState<rentTypeListType[0]>();
//类型列表
const getTypeList = () => {
RentManageAPI.getTypeList({ pageNo: pagination.pageNo, pageSize: pagination.pageSize }).then(
({ result }) => {
pagination.totalCount = result.totalCount;
setPagination({ ...pagination });
setTableData(result.list || []);
},
);
};
//新增,编辑类型
const addOrEditTypeModalClick = (record?: rentTypeListType[0]) => {
setCurrentRentTypeItem(record ? { ...record } : undefined);
setAddOrEditTypeModalShow(true);
};
const addOrEditTypeModalCancel = () => {
setAddOrEditTypeModalShow(false);
};
const addOrEditTypeModalOk = () => {
setAddOrEditTypeModalShow(false);
getTypeList();
};
//删除类型
const deleteRentType = (record: rentTypeListType[0]) => {
Modal.confirm({
title: '提示',
content: '确认删除该类型',
onOk: () => {
RentManageAPI.rentTypeRemove({ id: record.id }).then(({ code }) => {
if (code === '200') {
if (tableData.length === 1 && pagination.pageNo !== 1) {
pagination.pageNo -= 1;
}
message.success('删除成功');
getTypeList();
}
});
},
});
};
//分页
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getTypeList();
};
useEffect(() => {
getTypeList();
}, []);
return (
<div className='rent-type'>
<div className='rent-type-operate' style={{ marginBottom: '10px' }}>
<Button type='primary' onClick={() => addOrEditTypeModalClick()}>
新增类型
</Button>
</div>
<Table
bordered
columns={tableColumns}
dataSource={tableData}
pagination={{
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
<AddOrEditTypeModal
open={addOrEditTypeModalShow}
onCancel={addOrEditTypeModalCancel}
onOk={addOrEditTypeModalOk}
currentRentTypeItem={currentRentTypeItem}
/>
</div>
);
};
export default RentType;
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论