提交 89bb7a79 作者: 龚洪江

联调:行业方案,品牌,产品管理联调

上级 185fd540
......@@ -7,7 +7,7 @@ VITE_REQUEST_BASE_URL='/api'
#VITE_REQUEST_BASE_URL='https://test.iuav.mmcuav.cn'
#本地测试
#VITE_REQUEST_BASE_URL='http://192.168.3.22:10001'
#VITE_REQUEST_BASE_URL='http://192.168.3.22:8099'
#VITE_REQUEST_BASE_URL='http://192.168.3.17:8099'
#VITE_REQUEST_BASE_URL='http://192.168.3.23:35150'
#版本
NODE_ENV='development'
......
// 分页通用接口
export interface PaginationProps {
pageSize?: number;
pageNo?: number;
pageSize: number;
pageNo: number;
}
// 通用返回接口(分页)
......
// 分类详情
import { InterFunction, InterItemFunction } from '~/api/interface';
export interface GoodsInfo {
goodsId: number;
goodsImg: string;
......@@ -26,3 +28,27 @@ export interface categoryDec {
id: number;
sortName: string;
}
//分类列表类型
type categoryReposeType = {
id: number;
classifyName: string;
icon: string;
createTime: string;
children: categoryReposeType[];
directoryId: number;
remark: string;
};
export type categoryListType = InterItemFunction<
{ directoryId?: number; type?: number },
categoryReposeType[]
>;
//目录列表类型-不分页
export type directoryListType = InterFunction<
{ type: number },
{
id: number;
directoryName: string;
type: number;
}[]
>;
// 行业方案-列表
import { InterFunction, InterItemFunction } from '~/api/interface';
//行业方案-列表
export type listIndustryType = InterItemFunction<
{ categoryId?: number; solutionName?: string },
{
categoryId: number;
categoryName: string;
createTime: string;
description: string;
id: number;
solutionName: string;
}[]
>;
//行业方案-新增
export type industryAddType = InterFunction<
{ categoryId: number; description: string; solutionName: string },
null
>;
//行业方案-编辑
export type industryEditType = InterFunction<
{ categoryId: number; description: string; solutionName: string; id?: number },
null
>;
//行业方案-删除
export type industryDeleteType = InterFunction<{ id: number }, null>;
//行业方案-详情
export type industryDetailType = InterFunction<
{ id: number },
{
categoryId: number;
description: string;
solutionName: string;
categoryName: string;
id: number;
}
>;
//行业方案-方案规格列表
export type industrySpecList = InterItemFunction<{ productSkuId: number }, any>;
//行业方案-方案规格-新增
export type industrySpecAdd = InterFunction<
{
industrySkuId: number;
specImage: string;
specName: string;
productInventoryList: {
productSku: {
id: number;
productName: string;
productBrandId: number;
productBrand: string;
model: string;
goodsTypeId: number;
directoryId: number;
directoryName: string;
};
productSpecList: {
id: number;
partNo: string;
specImage: string;
specName: string;
versionDesc: string;
productSkuId: number;
}[];
select: number;
}[];
},
null
>;
//行业方案-方案规格-删除
export type removeIndustrySpecType = InterFunction<{ id: number }, any>;
//行业方案-方案规格-详情
export type industrySpecDetailType = InterFunction<
{ industrySpecId: number },
{
id: number;
industrySkuId: number;
specImage: string;
specName: string;
productInventoryList: {
productSku: {
id: number;
productName: string;
productBrandId: number;
productBrand: string;
model: string;
goodsTypeId: number;
directoryId: number;
categoryName: string;
};
productSkuId: number;
productSpecList: {
id: number;
partNo: string;
specImage: string;
specName: string;
versionDesc: string;
productSkuId: number;
}[];
select: number;
}[];
}
>;
//行业-方案规格-编辑
export type editIndustrySpecType = InterFunction<
{
id: number;
industrySkuId: number;
specImage: string;
specName: string;
productInventoryList: {
productSku: {
id: number;
productName: string;
productBrandId: number;
productBrand: string;
model: string;
goodsTypeId: number;
directoryId: number;
directoryName: string;
};
productSpecList: {
id: number;
partNo: string;
specImage: string;
specName: string;
versionDesc: string;
productSkuId: number;
}[];
select: number;
}[];
},
null
>;
......@@ -8,3 +8,38 @@ export type MakeListType = InterItemFunction<
id: number;
}[]
>;
//产品-列表
export type productListType = InterItemFunction<
{ categoryId?: number; directoryId?: number; productName?: string },
{
id: number;
productName: string;
productBrandId: number;
productBrand: string;
model: string;
categoriesId: number;
categoryName: string;
directoryId: number;
directoryName: string;
productSpecList: {
id: number;
partNo: string;
specImage: string;
specName: string;
versionDesc: string;
productSkuId: number;
}[];
}[]
>;
//产品-规格-列表
export type ProductSpecListType = InterItemFunction<
{ productSkuId: number },
{
id: number;
partNo: string;
specImage: string;
specName: string;
versionDesc: string;
productSkuId: number;
}[]
>;
import axios from '../request';
import { PaginationEntity } from '~/common/interface/PaginationEntity';
import { categoryListType, directoryListType } from '~/api/interface/categoryManage';
export class CategoryManageAPI {
// 分类管理
// 分类目录
static directoryList = () => {
return axios.get('uavgoods/directory/directoryList');
static getDirectoryList: directoryListType = (params) => {
return axios.get('/pms/classify/getDirectoryList', { params });
};
// 新增或编辑目录
......@@ -24,8 +24,8 @@ export class CategoryManageAPI {
};
// 分类列表
static getListGoodsTypeList = (type: number): any => {
return axios.get(`uavgoods/mgoods/getGoodsTypeInfoList/${type}`);
static getCategoryList: categoryListType = (data) => {
return axios.post('/pms/classify/getClassificationList', data);
};
// PC端-根据分类信息新增自定义规格-下拉选项 (只查产品类型)
......
import axios from '../request';
import {
industryAddType,
industryDeleteType,
industryDetailType,
industryEditType,
industrySpecAdd,
industrySpecDetailType,
industrySpecList,
listIndustryType,
removeIndustrySpecType,
editIndustrySpecType,
} from '~/api/interface/industryManageType';
export class IndustryManageAPI {
// 行业列表
static getFirstIndustryTypeInfo = (params: unknown) => {
return axios.get('uavgoods/appgoods/getFirstGoodsTypeInfo/2', { params });
static getIndustryList: listIndustryType = (data) => {
return axios.post('/pms/industry/spec/listPageIndustrySku', data);
};
// 行业sku管理-方案规格管理-分页列表
static listPageIndustrySpec = (params: unknown) => {
return axios.get('uavgoods/industry/spec/listPageIndustrySpec', {
params,
});
};
// 行业sku管理---分页列表
static listPageIndustrySku = (data: unknown) => {
return axios.post('uavgoods/industry/spec/listPageIndustrySku', data);
// 行业-新增
static addIndustryRequest: industryAddType = (data) => {
return axios.post('/pms/industry/spec/addIndustrySku', data);
};
// 行业sku管理---新增行业sku
static addIndustrySku = (data: unknown) => {
return axios.post('uavgoods/industry/spec/addIndustrySku', data);
// 行业---编辑
static editIndustryRequest: industryEditType = (data) => {
return axios.post('/pms/industry/spec/editIndustrySku', data);
};
// 行业sku管理---编辑行业sku
static editIndustrySku = (data: unknown) => {
return axios.post('uavgoods/industry/spec/editIndustrySku', data);
// 行业--删除
static removeIndustryRequest: industryDeleteType = (params) => {
return axios.get('/pms/industry/spec/removeIndustrySku', { params });
};
// 行业sku管理---删除行业sku
static removeIndustrySku = (params: unknown) => {
return axios.get('uavgoods/industry/spec/removeIndustrySku', { params });
// 行业-详情
static getIndustryDetail: industryDetailType = (params) => {
return axios.get('/pms/industry/spec/getIndustrySkuDetail', {
params,
});
};
// 行业sku管理-详情-基本信息
static getIndustrySkuDetail = (params: unknown) => {
return axios.get('uavgoods/industry/spec/getIndustrySkuDetail', {
// 行业-方案规格-列表
static getIndustrySpecList: industrySpecList = (params) => {
return axios.get('/pms/industry/spec/listPageIndustrySpec', {
params,
});
};
// 行业sku管理---方案规格管理---新增方案规格
static addIndustrySpec = (data: unknown) => {
return axios.post('uavgoods/industry/spec/addIndustrySpec', data);
// 行业---方案规格管理---新增方案规格
static addIndustrySpec: industrySpecAdd = (data) => {
return axios.post('/pms/industry/spec/addIndustrySpec', data);
};
// 行业sku管理---方案规格管理---编辑行业规格
static editIndustrySpec = (data: unknown) => {
return axios.post('uavgoods/industry/spec/editIndustrySpec', data);
static editIndustrySpec: editIndustrySpecType = (data) => {
return axios.post('/pms/industry/spec/editIndustrySpec', data);
};
// 行业sku管理---方案规格管理---删除行业规格
static removeIndustrySpec = (params: unknown) => {
return axios.get('uavgoods/industry/spec/removeIndustrySpec', { params });
// 行业---方案规格管理---删除行业规格
static removeIndustrySpec: removeIndustrySpecType = (params) => {
return axios.get('/pms/industry/spec/removeIndustrySpec', { params });
};
// 行业sku管理---方案规格管理---获取价格配置信息 (获取价格配置)
......@@ -69,8 +74,8 @@ export class IndustryManageAPI {
};
// 行业sku管理---方案规格管理---单个方案规格回显 (查看产品清单)
static getIndustrySpecDetail = (params: unknown) => {
return axios.get('uavgoods/industry/spec/getIndustrySpecDetail', {
static getIndustrySpecDetail: industrySpecDetailType = (params) => {
return axios.get('/pms/industry/spec/getIndustrySpecDetail', {
params,
});
};
......
import axios from '../request';
import { MakeListType } from '~/api/interface/produceManageType';
import {
MakeListType,
productListType,
ProductSpecListType,
} from '~/api/interface/produceManageType';
export class ProduceManageAPI {
// 产品sku管理-分页列表
static listPageProductSku = (data: unknown) => {
return axios.post('uavgoods/product/spec/listPageProductSku', data);
// 产品管理-分页列表
static listPageProductSku: productListType = (data) => {
return axios.post('/pms/product/spec/listPageProductSku', data);
};
// 产品sku管理-删除产品sku
static removeProductSku = (params: unknown) => {
......@@ -41,7 +45,7 @@ export class ProduceManageAPI {
};
// 产品sku管理-产品规格管理-分页列表
static listPageProductSpec = (params: unknown) => {
return axios.get('uavgoods/product/spec/listPageProductSpec', { params });
static listPageProductSpec: ProductSpecListType = (params) => {
return axios.get('/pms/product/spec/listPageProductSpec', { params });
};
}
/*
* @Author: 龚洪江
* @Date: 2022-07-26 11:43:44
* @LastEditors: 龚洪江
* @LastEditTime: 2022-07-26 11:45:29
* @FilePath: \code\mmc-store\src\common\PaginationEntity\index.ts
* @Description:
*
* Copyright (c) 2022 by 龚洪江 2238959530@qq.com, All Rights Reserved.
*/
export interface PaginationEntity {
pageNo: number;
pageSize: number;
......
......@@ -112,7 +112,7 @@ export const Uploader: React.FC<PropsType> = (props) => {
if (defaultFileList?.length) {
setFileList(defaultFileList);
}
}, []);
}, [defaultFileList]);
return (
<div className='uploader-view'>
{listType === 'text' ? (
......
import React, { FC, useEffect, useState } from 'react';
import { Form, Input, Modal, message, Table, Button, ModalProps } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { InterDataType, PaginationProps } from '~/api/interface';
import { Uploader } from '~/components/uploader';
import { UploadOutlined } from '@ant-design/icons';
import { productListType } from '~/api/interface/produceManageType';
import { IndustryManageAPI } from '~/api';
import { filterObjAttr } from '~/utils';
import { industrySpecDetailType } from '~/api/interface/industryManageType';
//自定义产品返回类型
type selfProduceItemType = InterDataType<productListType>['list'][0] & {
radio?: number;
};
//方案规格详情返回类型
type specDetailType = InterDataType<industrySpecDetailType>;
interface PropsType {
produceSpecList: selfProduceItemType[];
close: () => void;
connectSpecModalShow: () => void;
industrySkuId: number;
handleSuccess: () => void;
specDetail: specDetailType;
}
const AddOrEditSpecModal: FC<ModalProps & PropsType> = ({
open,
produceSpecList,
close,
connectSpecModalShow,
industrySkuId,
specDetail,
handleSuccess,
}) => {
// 表格事件
const [form] = Form.useForm<{ specName: string; specImage: string; list: any }>();
//图片
const [fileList, setFileList] = useState<
{
id: number;
name: string;
uid: number;
url: string;
}[]
>([]);
// 表格结构
const columns: ColumnsType<selfProduceItemType> = [
{
title: '序号',
align: 'center',
render: (text: string, record: selfProduceItemType, index: number) => {
return (pagination.pageNo - 1) * pagination.pageSize + index + 1;
},
},
{ title: '产品名称', dataIndex: 'productName', align: 'center' },
{ title: '产品类型', dataIndex: 'categoryName', align: 'center' },
{ title: '型号', dataIndex: 'model', align: 'center' },
{ title: '产品品牌', dataIndex: 'productBrand', align: 'center' },
{
title: '产品规格',
// align: "left",
width: 300,
ellipsis: true,
render: (record: selfProduceItemType) => {
if (record.radio === 0) {
return '不指定';
}
return record.productSpecList.map((i: any, index: number) => (
<div key={index}>
{i.specName}({i.partNo})
</div>
));
},
onHeaderCell: () => {
return {
style: {
textAlign: 'center',
},
};
},
},
];
// 分页
const [pagination, setPagination] = useState<PaginationProps>({
pageNo: 1,
pageSize: 10,
});
// 关闭弹窗
const handleClosed = async () => {
setFileList([]);
form.resetFields();
close();
};
// 打开关联产品弹窗
const handleConnectSpecModalShow = () => {
connectSpecModalShow();
};
//图片上传成功
const uploadFileSuccess = (
fileList: {
id: number;
name: string;
uid: number;
url: string;
}[],
) => {
form.setFieldsValue({
specImage: fileList[0].url,
});
};
// 触发表单验证
const handleSubmit = () => {
form
.validateFields()
.then((values) => {
const productInventoryList: any = produceSpecList.map((v) => ({
productSku: {
id: v.id,
directoryId: v.directoryId,
goodsTypeId: v.categoriesId,
model: v.model,
productBrand: v.productBrand,
productBrandId: v.productBrandId,
productName: v.productName,
},
select: v.radio,
productSpecList: v.productSpecList,
}));
IndustryManageAPI[specDetail.id ? 'editIndustrySpec' : 'addIndustrySpec']({
...filterObjAttr(values, ['list']),
productInventoryList,
industrySkuId,
id: specDetail.id ? specDetail.id : undefined,
}).then(({ code }) => {
if (code === '200') {
message.success(specDetail.id ? '编辑成功' : '新增成功');
form.resetFields();
handleSuccess();
}
});
})
.catch((err) => {
message.warning(err.errorFields[0].errors[0]).then();
});
};
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
setPagination({ ...pagination });
};
// componentsDidMounted
useEffect(() => {
form.setFieldsValue({
list: produceSpecList.length !== 0 ? produceSpecList : undefined,
});
}, [produceSpecList]);
useEffect(() => {
form.setFieldsValue({
specName: specDetail.specName || undefined,
specImage: specDetail.specImage || undefined,
});
if (specDetail.specImage) {
setFileList([
{
id: Math.random(),
name: 'img',
uid: Math.random(),
url: specDetail.specImage,
},
]);
} else {
setFileList([]);
}
}, [specDetail]);
return (
<>
<Modal
open={open}
title='新增'
onCancel={handleClosed}
onOk={handleSubmit}
destroyOnClose
width={800}
>
<Form name='form' form={form} layout='horizontal'>
<Form.Item
name='specName'
label='规格名称'
rules={[{ required: true, message: '请输入方案产品名称' }]}
>
<Input
placeholder='请输入规格名称'
allowClear
style={{ width: '400px' }}
maxLength={30}
/>
</Form.Item>
<Form.Item
name='specImage'
label='规格图片'
rules={[{ required: true, message: '请上传规格图片' }]}
>
<Uploader
listType='picture-card'
fileUpload
onChange={uploadFileSuccess}
defaultFileList={fileList}
>
<UploadOutlined />
</Uploader>
</Form.Item>
<Form.Item
label='产品清单'
name='list'
rules={[{ required: true, message: '请选择产品清单' }]}
>
<Button type='primary' onClick={handleConnectSpecModalShow}>
添加关联
</Button>
</Form.Item>
<Form.Item>
<Table
size='small'
dataSource={produceSpecList}
columns={columns}
rowKey='id'
style={{ width: '100%' }}
pagination={{
pageSize: pagination.pageSize,
current: pagination.pageNo,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
}}
bordered
/>
</Form.Item>
</Form>
</Modal>
</>
);
};
export default AddOrEditSpecModal;
import React, { FC, useEffect, useState } from 'react';
import { Button, Form, Input, message, Modal, ModalProps, Radio, Select, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { CategoryManageAPI, ProduceManageAPI } from '~/api';
import { InterDataType, PaginationProps } from '~/api/interface';
import { productListType } from '~/api/interface/produceManageType';
import { categoryListType } from '~/api/interface/categoryManage';
//自定义产品返回类型
type selfProduceItemType = InterDataType<productListType>['list'][0] & {
radio?: number;
};
//分类通用类型
type categoryResponseType = InterDataType<categoryListType>['list'];
const { Option } = Select;
interface PropsType {
close: () => void;
data: selfProduceItemType[]; //已被关联产品
connectProduceSubmit: (data: selfProduceItemType[]) => void;
toDesignateSpec: (id: number) => void;
}
// 表单提交
interface FormType {
keyword?: string;
userType?: number;
roleId?: number;
accountStatus?: number;
}
// 当前选择的参数
const ConnectProduceModal: FC<ModalProps & PropsType> = ({
open,
close,
connectProduceSubmit,
data,
toDesignateSpec,
}) => {
// 表格数据
const [tableData, setTableData] = useState<selfProduceItemType[]>([]);
// 所有表格数据
const [allTableData, setAllTableData] = useState<selfProduceItemType[]>([]);
// 产品类型列表
const [productTypeList, setProductTypeList] = useState<categoryResponseType>([]);
// 表格结构
const columns: ColumnsType<selfProduceItemType> = [
{ title: '产品名称', dataIndex: 'productName', align: 'center' },
{
title: '产品类型',
dataIndex: 'categoryName',
align: 'center',
width: '100px',
},
{ title: '型号', dataIndex: 'model', align: 'center' },
{ title: '产品品牌', dataIndex: 'productBrand', align: 'center' },
{
title: '产品规格',
align: 'center',
width: '250px',
render: (record) => {
return (
<div>
<Radio.Group
onChange={(e) => {
const { value } = e.target;
// 通过index生成新tableData
const list = tableData.map((i) => {
if (i.id === record.id) {
return {
...i,
radio: value,
};
}
return i;
});
setTableData(list);
const allList = allTableData.map((i) => {
if (i.id === record.id) {
return {
...i,
radio: value,
};
}
return i;
});
setAllTableData(allList);
}}
value={record.radio}
disabled={getTableDisable(record.id)}
>
<Radio value={0}>不指定</Radio>
<Radio value={1}>指定</Radio>
</Radio.Group>
<Button
disabled={getTableDisable(record.id) || record.radio === 0}
onClick={() => toDesignateSpecClick(record.id)}
type='link'
>
去指定
</Button>
</div>
);
},
},
];
// 表格分页配置
const [pagination, setPagination] = useState<
PaginationProps & { totalCount: number; totalPage: number }
>({
totalCount: 0,
pageSize: 10,
pageNo: 1,
totalPage: 0,
});
// 表格多选
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
// 表格多选事件
const onSelectChange = (newSelectedRowKeys: React.Key[], selectedRows: selfProduceItemType[]) => {
// 新增
const isAdd: boolean = newSelectedRowKeys.some((v: React.Key) => !selectedRowKeys.includes(v));
// 删除
const isDelete: boolean = selectedRowKeys.some(
(v: React.Key) => !newSelectedRowKeys.includes(v),
);
let rowKeys: React.Key[] = [];
if (isAdd) {
const filterList: selfProduceItemType[] = selectedRows.filter(
(v: selfProduceItemType) => !selectedRowKeys.includes(v.id),
);
const obj: selfProduceItemType | undefined = filterList.find(
(v: selfProduceItemType) => !v.productSpecList,
);
const currentKeys: React.Key[] = filterList
.filter((v: selfProduceItemType) => v.productSpecList)
.map((v: selfProduceItemType) => v.id);
rowKeys = [...selectedRowKeys, ...currentKeys];
if (obj) {
message.warning(`请先为产品${obj?.productName}添加规格`);
}
} else if (isDelete) {
rowKeys = selectedRowKeys.filter((v: React.Key) => {
const bol: boolean = tableData.every((i: selfProduceItemType) => i.id !== v);
return bol || newSelectedRowKeys.includes(v);
});
}
setSelectedRowKeys(rowKeys);
};
// 根据id判断是否有操作的权限
const getTableDisable = (id: number) => {
return !selectedRowKeys.includes(id);
};
//获取产品列表
const getListPageProductSku = (value?: any, tip?: string) => {
ProduceManageAPI.listPageProductSku({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
...value,
}).then(({ result: { list, totalPage, totalCount } }) => {
pagination.totalCount = totalCount;
pagination.totalPage = totalPage;
setPagination(pagination);
// 设置产品规格默认项
if (!list) {
return setTableData([]);
}
const arr = list.map((i) => {
return {
...i,
radio: 0,
};
});
const brr = arr.map((i) => {
const item = data.find((j) => j.id === i.id);
if (item?.id === i.id) {
return {
...i,
radio: item.radio,
};
}
return i;
});
setTableData(brr);
if (tip === 'all') {
setAllTableData(brr);
}
});
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getListPageProductSku();
};
// 表单提交
const onFinish = (val: FormType) => {
// 在这里对提交的数据做处理,如range转为开始和结束时间
const data = Object.fromEntries(
// 过滤为空项
Object.entries({
...val,
}).filter((i) => i[1] !== '' && i[1] !== undefined && i[1] !== null),
);
getListPageProductSku(data);
};
// 获取产品类型
const getProduceTypeList = () => {
CategoryManageAPI.getCategoryList({ directoryId: 1, type: 4, pageNo: 1, pageSize: 99999 }).then(
({ result }) => {
setProductTypeList(result.list || []);
},
);
};
// 关联产品的数据提交
const handleSubmit = () => {
if (selectedRowKeys.length === 0) {
return message.warning('请选择关联产品');
}
const connectProduceList = allTableData.filter((i) => selectedRowKeys.includes(i.id));
connectProduceSubmit(connectProduceList);
};
// componentsDidMounted
useEffect(() => {
getListPageProductSku();
getListPageProductSku({ pageNo: 1, pageSize: 99999 }, 'all');
getProduceTypeList();
if (data.length !== 0) {
setSelectedRowKeys(data.map((v) => v.id));
}
}, [data]);
//去指定
const toDesignateSpecClick = (id: number) => {
toDesignateSpec(id);
};
return (
<>
<Modal
open={open}
title='关联产品'
onCancel={() => close()}
onOk={handleSubmit}
destroyOnClose
width={860}
>
<Form name='basic' layout='inline' onFinish={onFinish} style={{ marginBottom: '20px' }}>
<Form.Item name='productName' label='产品名称'>
<Input placeholder='请输入产品名称' allowClear />
</Form.Item>
<Form.Item name='goodsTypeId' label='产品类型'>
<Select placeholder='请选择产品类型' allowClear>
{productTypeList.map((i, j) => (
<Option value={i.id} key={j}>
{i.classifyName}
</Option>
))}
</Select>
</Form.Item>
<Form.Item>
<Button type='primary' htmlType='submit'>
搜索
</Button>
</Form.Item>
</Form>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
scroll={{ x: '100%' }}
bordered
rowSelection={{
selectedRowKeys,
onChange: onSelectChange,
}}
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} 条数据`,
}}
/>
</Modal>
</>
);
};
export default ConnectProduceModal;
import React, { FC, useEffect, useState } from 'react';
import { Image, message, Modal, ModalProps, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { ProduceManageAPI } from '~/api';
import { InterDataType, PaginationProps } from '~/api/interface';
import { ProductSpecListType } from '~/api/interface/produceManageType';
//产品sku返回类型
type produceSpecType = InterDataType<ProductSpecListType>['list'];
interface PropsType {
data: produceSpecType;
produceSpecSelectEvent: (data: produceSpecType) => void;
productId: number;
onCancel: () => void;
}
const DesignateSpecModal: FC<ModalProps & PropsType> = ({
open,
onCancel,
data,
produceSpecSelectEvent,
productId,
}) => {
// 表格多选
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
// 表格多选事件
const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
setSelectedRowKeys(newSelectedRowKeys);
};
// 产品sku列表
const [productSpecList, setProductSpecList] = useState<produceSpecType>([]);
// 表格结构
const columns: ColumnsType<{ id: number }> = [
{ title: '规格名称', dataIndex: 'specName', align: 'center' },
{
title: '规格图片',
dataIndex: 'specImage',
align: 'center',
render: (record) => {
return <Image width={50} height={50} src={record.specImage} alt='图片' />;
},
},
{ title: '版本描述', dataIndex: 'versionDesc', align: 'center' },
{ title: '料号', dataIndex: 'partNo', align: 'center' },
];
// 表格分页配置
const [pagination, setPagination] = useState<
PaginationProps & { totalCount: number; totalPage: number }
>({
totalCount: 0,
pageSize: 5,
pageNo: 1,
totalPage: 0,
});
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getProduceSpecList(productId);
};
// 提交数据到父组件
const handleSubmit = () => {
if (selectedRowKeys.length === 0) {
return message.warning('请选择产品规格');
}
const selectProductSpecList = productSpecList.filter((i) => selectedRowKeys.includes(i.id));
if (selectProductSpecList.length === 0) {
return message.warning('请选择产品规格');
}
produceSpecSelectEvent(selectProductSpecList);
};
//取消
const handleCancel = () => {
setSelectedRowKeys([]);
onCancel();
};
//获取产品-sku
const getProduceSpecList = (productSkuId: number) => {
ProduceManageAPI.listPageProductSpec({
productSkuId,
pageSize: pagination.pageSize,
pageNo: pagination.pageNo,
}).then(({ result }) => {
setProductSpecList(result.list || []);
pagination.totalPage = result.totalPage;
pagination.totalCount = result.totalCount;
setPagination(pagination);
setSelectedRowKeys(data.map((v) => v.id));
});
};
useEffect(() => {
if (productId) {
getProduceSpecList(productId);
}
}, [productId]);
return (
<div>
<Modal
title='指定产品规格'
open={open}
onCancel={handleCancel}
width={768}
zIndex={1010}
onOk={handleSubmit}
>
<Table
dataSource={productSpecList}
columns={columns}
rowKey='id'
style={{ width: '100%' }}
size='small'
bordered
rowSelection={{
selectedRowKeys,
onChange: onSelectChange,
}}
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} 条数据`,
}}
/>
</Modal>
</div>
);
};
export default DesignateSpecModal;
import React, { FC } from 'react';
import { Modal, ModalProps, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { InterDataType } from '~/api/interface';
import { industrySpecDetailType } from '~/api/interface/industryManageType';
//方案规格详情返回类型
type productInventoryListType = InterDataType<industrySpecDetailType>['productInventoryList'];
interface PropsType {
data: productInventoryListType;
onCancel: () => void;
}
const ProductListModal: FC<ModalProps & PropsType> = ({ open, onCancel, data }) => {
// 表格结构
const columns: ColumnsType<productInventoryListType[0]> = [
{
title: '序号',
align: 'center',
width: '50px',
render: (text: string, record: productInventoryListType[0], index: number) => {
return index + 1;
},
},
{
title: '产品名称',
dataIndex: 'productName',
align: 'center',
width: '100px',
render: (text: string, record: productInventoryListType[0]) => {
return record.productSku.productName;
},
},
{
title: '产品类型',
dataIndex: 'typeName',
align: 'center',
width: '100px',
render: (text: string, record: productInventoryListType[0]) => {
return record.productSku.goodsTypeId;
},
},
{
title: '型号',
dataIndex: 'model',
align: 'center',
width: '100px',
render: (text: string, record: productInventoryListType[0]) => {
return record.productSku.model;
},
},
{
title: '产品品牌',
dataIndex: 'productBrand',
align: 'center',
width: '100px',
render: (text: string, record: productInventoryListType[0]) => {
return record.productSku.productName;
},
},
{
title: '产品规格',
// align: "left",
width: '200px',
render: (text: string, record) => {
if (record.select === 0) {
return '不指定';
}
return record.productSpecList.map((i: any, index: number) => (
<div key={index}>
{i.specName}({i.partNo})
</div>
));
},
onHeaderCell: () => {
return {
style: {
textAlign: 'center',
},
};
},
},
];
// 关闭
const onClose = () => {
onCancel();
};
return (
<Modal open={open} title='产品清单' onCancel={onClose} destroyOnClose footer={null} width={800}>
<Table
size='small'
dataSource={data}
columns={columns}
rowKey='id'
style={{ width: '100%' }}
bordered
pagination={false}
/>
</Modal>
);
};
export default ProductListModal;
import React, { useEffect, useState } from 'react';
import qs from 'query-string';
import { Button, Descriptions, message, Table } from 'antd';
import { Button, Descriptions, Image, message, Table } from 'antd';
import { useNavigate } from 'react-router-dom';
import { ColumnsType } from 'antd/es/table';
// import { ListModal } from '@/pages/goodsManage/industryManage/comp/listModal';
// import { PriceModal } from '@/pages/goodsManage/industryManage/comp/priceModal';
// import { AddEditDetailModal } from '@/pages/goodsManage/industryManage/comp/addEditDetailModal';
import useOption from '~/common/hook/optionHook';
import { IndustryManageAPI } from '~/api';
import { IndustrySkuType, IndustrySpecType, inventoryType } from '../industryList/propsType';
// import DeleteModal from '@/components/DeleteModal';
import { useSearchParams } from 'react-router-dom';
import { inventoryType } from '../industryList/propsType';
import { InterDataType, PaginationProps } from '~/api/interface';
import {
industryDetailType,
industrySpecDetailType,
industrySpecList,
} from '~/api/interface/industryManageType';
import AddOrEditSpecModal from './components/addOrEditSpecModal';
import ConnectProduceModal from './components/connectProduceModal';
import DesignateSpecModal from './components/designateSpecModal';
import ProductListModal from './components/productListModal';
import { productListType, ProductSpecListType } from '~/api/interface/produceManageType';
import { filterObjAttr } from '~/utils';
// eslint-disable-next-line react/no-unused-prop-types
function IndustryDetail(props: any) {
// const productSkuId = Number(qs.parse(props.location.search).id);
//行业详情返回类型
type detailType = InterDataType<industryDetailType>;
//方案规格返回类型
type industrySpecType = InterDataType<industrySpecList>['list'];
//产品sku返回类型
type produceSpecType = InterDataType<ProductSpecListType>['list'];
//自定义产品返回类型
type selfProduceItemType = InterDataType<productListType>['list'][0] & {
radio?: number;
};
//方案规格详情返回类型
type specDetailType = InterDataType<industrySpecDetailType>;
function IndustryDetail() {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
// 行业列表对象
const [industryTypeObj, setIndustryTypeObj] = useState<{}>({});
// 产品类型对象
const [productTypeObj, setProductTypeObj] = useState<{}>({});
//行业ID
const [industryId, setIndustryId] = useState<number>(0);
// 基本信息
const [detailData, setDetailData] = useState<IndustrySkuType>();
// 表格数据
const [tableData, setTableData] = useState<IndustrySpecType[]>([]);
// 图片是否放大
const [visibleImg, setVisibleImg] = useState<boolean>(false);
// 当前放大图片
const [currentImgList, setCurrentImgList] = useState<{ src: string }[]>([]);
const [detailData, setDetailData] = useState<detailType>({
id: 0,
description: '',
categoryId: 0,
solutionName: '',
categoryName: '',
});
// 方案规格
const [industrySpecData, setIndustrySpecData] = useState<industrySpecType>([]);
// 产品清单弹窗显示
const [visibleList, setVisibleList] = useState<boolean>(false);
// 产品规格清单
......@@ -37,148 +56,33 @@ function IndustryDetail(props: any) {
// 当前配置价格数据
const [priceData, setPriceData] = useState([]);
// 新增编辑规格弹窗是否显示
const [visibleAddEdit, setVisibleAddEdit] = useState<boolean>(false);
// 删除行业规格弹窗是否显示
const [visibleDeleteSpec, setVisibleDeleteSpec] = useState<boolean>(false);
// 当前行业规格id
const [industrySpecId, setIndustrySpecId] = useState<number>();
// 新增编辑规格弹窗数据
const [addEditData, setAddEditData] = useState<IndustrySpecType>({
createTime: '',
id: 0,
industrySkuId: 0,
list: [],
specImage: '',
specName: '',
productSkuId: 0,
});
// 按钮权限
const btnAdd = useOption(22205);
const btnSetPrice = useOption(22206);
const btnEdit = useOption(22207);
const btnDelete = useOption(22208);
// 预览图片
const previewImage = (url: string) => {
setVisibleImg(true);
setCurrentImgList([{ src: url }]);
};
// 关闭图片放大
const setVisibleEvent = () => {
setVisibleImg(false);
};
// 查看产品清单
const handleList = async (id: number) => {
const obj = await getIndustrySpecDetail(id);
setListData(obj?.list || []);
setVisibleList(true);
};
// 关闭产品清单
const handleListClosed = () => {
setListData([]);
setVisibleList(false);
};
// 打开配置价格弹窗
const handlePrice = (arr: any) => {
setPriceData(arr);
setVisiblePrice(true);
};
// 关闭配置价格弹窗
const handlePriceClosed = () => {
setPriceData([]);
setVisiblePrice(false);
};
// 打开新增弹窗
const handleAdd = () => {
setAddEditData({
createTime: undefined,
const [addOrEditSpecModalShow, setAddOrEditSpecModalShow] = useState<boolean>(false);
//关联产品弹窗
const [connectProduceModalShow, setConnectProduceModalShow] = useState<boolean>(false);
const [connectProduceList, setConnectProduceList] = useState<selfProduceItemType[]>([]);
const [designateProduceId, setDesignateProduceId] = useState<number>(0);
//指定sku弹窗
const [designateSpecModalShow, setDesignateSpecModalShow] = useState<boolean>(false);
const [selectProduceSpecList, setSelectProduceSpecList] = useState<produceSpecType>([]);
//产品清单弹窗
const [productListModalShow, setProductListModalShow] = useState<boolean>(false);
//方案规格详情
const [specDetails, setSpecDetails] = useState<specDetailType>({
productInventoryList: [],
id: 0,
productSkuId,
industrySkuId: 0,
list: [],
specImage: '',
specName: '',
});
setVisibleAddEdit(true);
};
// 打开编辑弹窗
const handleEdit = async (id: number) => {
const obj: any = await getIndustrySpecDetail(id);
setAddEditData({ ...obj, productSkuId });
setVisibleAddEdit(true);
};
// 关闭新增编辑弹窗
const handleAddEditClosed = async (isRefresh: boolean) => {
// setAddEditData({ id: 0, img: "", list: [], name: "" });
setVisibleAddEdit(false);
if (isRefresh) {
await getDetailData();
await getTableList();
}
};
// 打开删除行业规格弹窗
const openDeleteDialog = (id: number) => {
setVisibleDeleteSpec(true);
setIndustrySpecId(id);
};
// 关闭删除行业规格弹窗
const handleDeleteSpecClosed = () => {
setVisibleDeleteSpec(false);
};
// 删除行业规格
const handleDeleteSpec = async () => {
const res: any = await IndustryManageAPI.removeIndustrySpec({ id: industrySpecId });
if (res.code === '200') {
if (res.result) {
message.info({
content: (
<div style={{ textAlign: 'left' }}>
{res.result.goodsName && (
<div>
<div style={{ color: 'red' }}>删除失败,已被商品关联</div>
<div style={{ display: 'flex' }}>
<div>关联的商品为:</div>
<div>{res.result.goodsName.join('、')}</div>
</div>
</div>
)}
</div>
),
// className: "custom-class",
duration: 3,
});
} else {
message.success('操作成功');
getTableList().then();
}
handleDeleteSpecClosed();
} else {
message.error(res.message);
handleDeleteSpecClosed();
}
};
// 表格结构
const columns: ColumnsType<IndustrySpecType> = [
const columns: ColumnsType<industrySpecType[0]> = [
{ title: '规格名称', dataIndex: 'specName', align: 'center' },
{
title: '规格图片',
dataIndex: 'specImage',
align: 'center',
render: (text: string) => {
return (
<img
style={{ width: '50px', height: '50px' }}
src={text}
alt='图片'
onClick={() => {
previewImage(text);
}}
/>
);
render: (text: string, record) => {
return <Image width={50} height={50} src={record.specImage} alt='图片' />;
},
},
{
......@@ -187,7 +91,7 @@ function IndustryDetail(props: any) {
align: 'center',
render: (id: number) => {
return (
<Button type='link' onClick={() => handleList(id)}>
<Button type='link' onClick={() => lookProductList(id)}>
查看产品清单
</Button>
);
......@@ -197,10 +101,9 @@ function IndustryDetail(props: any) {
title: '操作',
align: 'center',
width: '250px',
render: (text: string, record: IndustrySpecType) => {
render: (text: string, record: any) => {
return (
<div>
{btnSetPrice ? (
<Button
type='link'
onClick={() => {
......@@ -209,169 +112,209 @@ function IndustryDetail(props: any) {
>
配置价格
</Button>
) : (
''
)}
{btnEdit ? (
<Button
type='link'
onClick={() => {
handleEdit(record.id);
editIndustrySpec(record.id);
}}
>
编辑
</Button>
) : (
''
)}
{btnDelete ? (
<Button
type='link'
onClick={() => {
openDeleteDialog(record.id);
}}
>
<Button type='link' onClick={deleteIndustrySpec}>
删除
</Button>
) : (
''
)}
</div>
);
},
},
];
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
const [pagination, setPagination] = useState<
PaginationProps & { totalCount: number; totalPage: number }
>({
totalCount: 0,
pageSize: 10,
current: 1,
pageNo: 1,
totalPage: 0,
});
// 获取所属行业下拉列表
const getFirstIndustryTypeInfo = async () => {
const res: any = await IndustryManageAPI.getFirstIndustryTypeInfo({});
if (res && res.code === '200') {
const obj = res.result.reduce((prev: any, curt: any) => {
prev[curt.goodsMasterTypeId] = curt.goodsMasterType;
return prev;
}, {});
setIndustryTypeObj(obj);
}
};
// 获取产品类型
const getFirstProductTypeInfo = async () => {
const res: any = await IndustryManageAPI.getFirstProductTypeInfo({});
if (res && res.code === '200') {
const obj = res.result.reduce((prev: any, curt: any) => {
prev[curt.goodsMasterTypeId] = curt.goodsMasterType;
return prev;
}, {});
setProductTypeObj(obj);
}
// 关闭产品清单
const handleListClosed = () => {
setListData([]);
setVisibleList(false);
};
// 获取产品清单详情
const getIndustrySpecDetail = async (id: number) => {
const res: any = await IndustryManageAPI.getIndustrySpecDetail({
industrySpecId: id,
// 打开配置价格弹窗
const handlePrice = (arr: any) => {
setPriceData(arr);
setVisiblePrice(true);
};
// 关闭配置价格弹窗
const handlePriceClosed = () => {
setPriceData([]);
setVisiblePrice(false);
};
// 打开新增弹窗
const handleAdd = () => {
setAddOrEditSpecModalShow(true);
};
// 编辑方案规格
const editIndustrySpec = (industrySpecId: number) => {
IndustryManageAPI.getIndustrySpecDetail({
industrySpecId,
}).then(({ result }) => {
setSpecDetails(result);
const connectProduct: selfProduceItemType[] = result.productInventoryList.map((v) => ({
categoriesId: v.productSku.goodsTypeId,
...filterObjAttr(v.productSku, ['goodsTypeId']),
categoryName: v.productSku.categoryName,
productSpecList: v.productSpecList,
radio: v.select,
id: v.productSkuId,
}));
const designateList = result.productInventoryList.reduce((pre: any, cur) => {
if (cur.productSpecList) {
pre.push(...cur.productSpecList);
}
return pre;
}, []);
setSelectProduceSpecList(designateList);
setConnectProduceList(connectProduct);
});
if (res && res.code === '200') {
const { specImage, specName, productInventoryList, createTime, id, industrySkuId } =
res.result;
const list =
productInventoryList &&
productInventoryList.map((item: inventoryType) => {
return {
...item.productSku,
sku: item.productSpecList,
radio: item.select,
typeName: productTypeObj[item.productSku.goodsTypeId as keyof typeof productTypeObj],
id: item.productSkuId,
setAddOrEditSpecModalShow(true);
};
// 删除方案规格
const deleteIndustrySpec = () => {
IndustryManageAPI.removeIndustrySpec({ id: industryId }).then(({ code, result }) => {
if (code === '200') {
if (result) {
message.info({
content: (
<div style={{ textAlign: 'left' }}>
{result.goodsName && (
<div>
<div style={{ color: 'red' }}>删除失败,已被商品关联</div>
<div style={{ display: 'flex' }}>
<div>关联的商品为:</div>
<div>{result.goodsName.join('、')}</div>
</div>
</div>
)}
</div>
),
duration: 3,
});
// console.log("当前数据--->", list);
const obj = { list, specImage, specName, createTime, id, industrySkuId };
return obj;
} else {
message.success('操作成功');
}
}
});
};
useEffect(() => {
// const sku: SkuType[] = [1, 2, 3].map((i, j) => {
// return {
// id: [469, 466, 458][j],
// name: `入云龙【红黑】${i}`,
// img:
// i % 2 === 1
// ? "https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/file/test111.gif"
// : "https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/file/111.gif",
// desc: "上盖丝印",
// no: "3.1.29.0068-G",
// };
// });
// const list: ArrType[] = [1, 2, 3, 4].map((i, j) => {
// return {
// id: i,
// skuId: [
// "772189430646845440",
// "771012649717870592",
// "771037713385402368",
// "771016084857040896",
// ][j],
// name: `入云龙${i}`,
// type: "无人机",
// num: "SN_000001",
// brand: "科比特",
// radio: j % 2 === 1 ? 1 : 2,
// sku: j % 2 === 1 ? [] : sku,
// };
// });
// const arr: ListType[] = [1, 2, 3, 4, 5].map((i) => {
// return {
// id: i,
// name: `升级方案${i}`,
// img:
// i % 2 === 1
// ? "https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/file/test111.gif"
// : "https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/file/111.gif",
// list,
// };
// });
// console.log("数据源 --->", arr);
// setTableData(arr);
(async () => {
// await getFirstIndustryTypeInfo();
// await getFirstProductTypeInfo();
// await getDetailData();
// await getTableList();
})();
}, []);
// 获取方案规格详情
const getIndustrySpecDetail = (industrySpecId: number) => {
IndustryManageAPI.getIndustrySpecDetail({
industrySpecId,
}).then(({ result }) => {
setSpecDetails(result);
});
};
// 返回上一页
const handleBack = () => {
navigate(-1);
};
// 获取方案规格数据
const getTableList = async (value = {}) => {
const res: any = await IndustryManageAPI.listPageIndustrySpec({
pageNo: pagination.current,
const getIndustrySpecList = (productSkuId: number) => {
IndustryManageAPI.getIndustrySpecList({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
productSkuId,
}).then(({ result }) => {
setIndustrySpecData(result.list || []);
pagination.totalCount = result.totalCount;
pagination.totalPage = result.totalPage;
setPagination(pagination);
});
};
// 获取行业信息
const getIndustryDetail = (id: number) => {
IndustryManageAPI.getIndustryDetail({ id }).then(({ result }) => {
setDetailData(result);
});
if (res && res.code === '200') {
setTableData(res.result.list || []);
}
};
// 获取基本信息
const getDetailData = async () => {
const { id } = qs.parse(props.location.search);
const res: any = await IndustryManageAPI.getIndustrySkuDetail({ id });
if (res && res.code === '200') {
setDetailData(res.result);
//新增、编辑规格弹窗
const addOrEditSpecModalClose = () => {
setAddOrEditSpecModalShow(false);
setConnectProduceList([]);
};
const addOrEditSpecSuccess = () => {
getIndustrySpecList(industryId);
addOrEditSpecModalClose();
};
//关联指定产品弹窗
const connectSpecModalShow = () => {
setConnectProduceModalShow(true);
};
const connectProduceModalClose = () => {
setConnectProduceModalShow(false);
};
const connectProduceSubmit = (data: selfProduceItemType[]) => {
const cloneSelectProduce: selfProduceItemType[] = JSON.parse(JSON.stringify(data));
//判断是否存在未指定规格
const produceObj = cloneSelectProduce.find(
(v) =>
v.radio &&
!selectProduceSpecList.some((item) => v.productSpecList.some((j) => item.id === j.id)),
);
if (produceObj) {
return message.warning(`请选择 ${produceObj.productName} 指定的规格`);
}
//产品,规格组合好
const filterConnectProduceList = cloneSelectProduce.reduce((pre: any, cur) => {
const specList = selectProduceSpecList.filter((v) =>
cur.productSpecList.some((i) => i.id === v.id && cur.radio == 1),
);
cur.productSpecList = specList;
return [...pre, cur];
}, []);
setConnectProduceList(filterConnectProduceList);
setConnectProduceModalShow(false);
};
//指定sku弹窗
const toDesignateSpec = (id: number) => {
setDesignateProduceId(id);
setDesignateSpecModalShow(true);
};
const produceSpecSelectEvent = (data: produceSpecType) => {
setSelectProduceSpecList([...selectProduceSpecList, ...data]);
setDesignateSpecModalShow(false);
};
const designateSpecModalCancel = () => {
setDesignateProduceId(0);
setDesignateSpecModalShow(false);
};
//产品清单弹窗
const lookProductList = (id: number) => {
getIndustrySpecDetail(id);
setProductListModalShow(true);
};
const productListModalCancel = () => {
setSpecDetails({
productInventoryList: [],
id: 0,
industrySkuId: 0,
specImage: '',
specName: '',
});
setProductListModalShow(false);
};
useEffect(() => {
setIndustryId(Number(searchParams.get('id')));
getIndustryDetail(Number(searchParams.get('id')));
getIndustrySpecList(Number(searchParams.get('id')));
}, []);
return (
<div className='detail-wrap'>
<Descriptions
......@@ -387,12 +330,9 @@ function IndustryDetail(props: any) {
</Button>
}
>
<Descriptions.Item label='方案名称'>{detailData?.solutionName}</Descriptions.Item>
<Descriptions.Item label='所属行业'>
{' '}
{industryTypeObj[detailData?.goodsTypeId as keyof typeof industryTypeObj] || ''}
</Descriptions.Item>
<Descriptions.Item label='描述'>{detailData?.description}</Descriptions.Item>
<Descriptions.Item label='方案名称'>{detailData.solutionName}</Descriptions.Item>
<Descriptions.Item label='所属行业'>{detailData.categoryName}</Descriptions.Item>
<Descriptions.Item label='描述'>{detailData.description}</Descriptions.Item>
</Descriptions>
<Descriptions
title='二、方案规格'
......@@ -401,27 +341,23 @@ function IndustryDetail(props: any) {
labelStyle={{ width: '200px' }}
style={{ marginTop: '20px' }}
>
{btnAdd ? (
<Descriptions.Item>
<Button type='primary' onClick={handleAdd}>
新增规格
</Button>
</Descriptions.Item>
) : (
''
)}
<Descriptions.Item>
<Table
size='small'
dataSource={tableData}
dataSource={industrySpecData}
columns={columns}
rowKey='id'
style={{ width: '100%' }}
bordered
pagination={{
total: pagination.total,
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.current,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
// onChange: (page: number, pageSize: number) =>
......@@ -432,18 +368,38 @@ function IndustryDetail(props: any) {
/>
</Descriptions.Item>
</Descriptions>
{/*<ListModal visible={visibleList} closed={handleListClosed} data={listData} />*/}
{/*<PriceModal visible={visiblePrice} closed={handlePriceClosed} data={priceData} />*/}
{/*<AddEditDetailModal*/}
{/* visible={visibleAddEdit}*/}
{/* closed={handleAddEditClosed}*/}
{/* data={addEditData}*/}
{/*/>*/}
{/*<DeleteModal*/}
{/* visible={visibleDeleteSpec}*/}
{/* onCancel={handleDeleteSpecClosed}*/}
{/* onOK={handleDeleteSpec}*/}
{/*/>*/}
{/*新增、编辑方案规格*/}
<AddOrEditSpecModal
open={addOrEditSpecModalShow}
connectSpecModalShow={connectSpecModalShow}
close={addOrEditSpecModalClose}
produceSpecList={connectProduceList}
industrySkuId={industryId}
handleSuccess={addOrEditSpecSuccess}
specDetail={specDetails}
/>
{/*指定产品*/}
<ConnectProduceModal
open={connectProduceModalShow}
close={connectProduceModalClose}
data={connectProduceList}
toDesignateSpec={toDesignateSpec}
connectProduceSubmit={connectProduceSubmit}
/>
{/*指定sku*/}
<DesignateSpecModal
open={designateSpecModalShow}
productId={designateProduceId}
onCancel={designateSpecModalCancel}
produceSpecSelectEvent={produceSpecSelectEvent}
data={selectProduceSpecList}
/>
{/*产品清单*/}
<ProductListModal
open={productListModalShow}
onCancel={productListModalCancel}
data={specDetails.productInventoryList}
/>
</div>
);
}
......
import React, { useEffect, useState } from 'react';
import { Form, Input, Modal, message, Select } from 'antd';
import React, { FC, useEffect } from 'react';
import { Form, Input, Modal, message, Select, ModalProps } from 'antd';
import { IndustryManageAPI } from '~/api';
import { IndustrySkuType } from '../../propsType';
import './index.scss';
import { InterDataType, InterReqType } from '~/api/interface';
import { categoryListType } from '~/api/interface/categoryManage';
import { industryAddType, listIndustryType } from '~/api/interface/industryManageType';
type categoryResponseType = InterDataType<categoryListType>['list'];
type industryListType = InterDataType<listIndustryType>['list'];
type industryFormType = InterReqType<industryAddType>;
interface PropsType {
visible: boolean;
closed: any;
data: IndustrySkuType;
categoryIndustryList: categoryResponseType;
industryItem: Partial<industryListType[0]> | undefined;
close: () => void;
addOrEditSuccess: () => void;
}
const { Option } = Select;
function AddOrEditIndustryModal(props: PropsType) {
// 父组件传参
const { visible, closed, data } = props;
const AddOrEditIndustryModal: FC<ModalProps & PropsType> = ({
open,
categoryIndustryList,
industryItem,
close,
addOrEditSuccess,
}) => {
// 表格事件
const [form] = Form.useForm();
// 所属行业列表
const [industryType, setIndustryType] = useState<{ label: string; val: number }[]>([]);
const [form] = Form.useForm<industryFormType>();
// 关闭弹窗
const handleClosed = async () => {
form.setFieldsValue({
goodsTypeId: undefined,
description: undefined,
solutionName: undefined,
id: undefined,
});
closed();
};
// 获取所属行业列表
const getFirstIndustryTypeInfo = async () => {
const res: any = await IndustryManageAPI.getFirstIndustryTypeInfo({});
if (res && res.code === '200') {
const arr = res.result.map((i: { goodsMasterType: string; goodsMasterTypeId: number }) => {
return {
label: i.goodsMasterType,
val: i.goodsMasterTypeId,
};
});
setIndustryType(arr);
}
const handleClosed = () => {
form.resetFields();
close();
};
// 触发表单验证
const handleSubmit = () => {
form
.validateFields()
.then(async (values) => {
const obj = { ...data, ...values };
const res: any = await IndustryManageAPI[!obj.id ? 'addIndustrySku' : 'editIndustrySku'](
obj,
);
const res: any = await IndustryManageAPI[
industryItem ? 'editIndustryRequest' : 'addIndustryRequest'
]({ ...values, id: industryItem ? industryItem.id : undefined });
if (res && res.code === '200') {
message.success('操作成功');
await handleClosed();
handleClosed();
addOrEditSuccess();
} else {
message.warning(res.message);
}
......@@ -62,19 +52,19 @@ function AddOrEditIndustryModal(props: PropsType) {
message.warning(err.errorFields[0].errors[0]).then();
});
};
// componentsDidMounted
useEffect(() => {
if (!data) return;
// console.log("新增编辑弹窗 -->", data);
if (industryItem) {
form.setFieldsValue({
...data,
solutionName: industryItem.solutionName,
categoryId: industryItem.categoryId,
description: industryItem.description,
});
getFirstIndustryTypeInfo().then();
}, [data]);
}
}, [industryItem]);
return (
<Modal
open={visible}
title={data.id ? '修改' : '新增'}
open={open}
title={industryItem ? '修改' : '新增'}
onCancel={handleClosed}
onOk={handleSubmit}
destroyOnClose
......@@ -96,15 +86,15 @@ function AddOrEditIndustryModal(props: PropsType) {
<Input placeholder='请输入方案名称' allowClear maxLength={30} />
</Form.Item>
<Form.Item
name='goodsTypeId'
name='categoryId'
label='所属行业'
rules={[{ required: true, message: '请选择所属行业' }]}
>
<Select placeholder='请选择所属行业' allowClear>
{industryType.map((i, j) => (
<Option value={i.val} key={j}>
{i.label}
</Option>
{categoryIndustryList.map((i, j) => (
<Select.Option value={i.id} key={j}>
{i.classifyName}
</Select.Option>
))}
</Select>
</Form.Item>
......@@ -124,5 +114,5 @@ function AddOrEditIndustryModal(props: PropsType) {
</Form>
</Modal>
);
}
};
export default AddOrEditIndustryModal;
import React, { useEffect, useState } from 'react';
import './index.scss';
import { Button, Form, Input, message, Select, Table } from 'antd';
import { Button, message, Modal, Table } from 'antd';
import { useNavigate } from 'react-router-dom';
import { ColumnsType } from 'antd/es/table';
import { IndustryManageAPI } from '~/api';
import { IndustrySkuType } from './propsType';
import { CategoryManageAPI, IndustryManageAPI } from '~/api';
import AddOrEditIndustryModal from './components/addOrEditIndustryModal';
// import DeleteModal from '@/components/DeleteModal';
import useOption from '~/common/hook/optionHook';
import { InterDataType, InterReqType, PaginationProps } from '~/api/interface';
import { categoryListType } from '~/api/interface/categoryManage';
import SearchBox, { searchColumns } from '~/components/search-box';
import { PlusOutlined } from '@ant-design/icons';
import { listIndustryType } from '~/api/interface/industryManageType';
const { Option } = Select;
// 搜索表单的数据
let query: any = {};
// 表单提交
interface FormType {
goodsTypeId?: number;
solutionName?: string;
}
//行业列表返回类型
type industryListType = InterDataType<listIndustryType>['list'];
//行业列表筛选类型
type industrySearchParameter = InterReqType<listIndustryType>;
//分类通用类型
type categoryResponseType = InterDataType<categoryListType>['list'];
function IndustryList() {
// 路由操作
const navigate = useNavigate();
const [searchColumns, setSearchColumns] = useState<searchColumns[]>([
{
label: '方案名称',
type: 'input',
placeholder: '请输入方案名称',
name: 'solutionName',
},
{
label: '所属行业',
type: 'select',
placeholder: '请选择所属行业',
name: 'categoryId',
options: [],
},
]);
// 表格数据
const [tableData, setTableData] = useState<any>([{ id: 1 }]);
const [tableData, setTableData] = useState<industryListType>([]);
// 加载中
const [loading, setLoading] = useState<boolean>(false);
// 行业列表
const [industryType, setIndustryType] = useState<{ label: string; val: number }[]>([]);
// 行业列表对象
const [industryTypeObj, setIndustryTypeObj] = useState<any>({});
// 跳转详情
const handleDetail = (record: { id: number }) => {
navigate({
pathname: '/mallManage/industryDetail',
search: `id=${record.id}`,
});
// console.log(record);
};
// 删除弹窗是否显示
const [visibleDeleteModal, setVisibleDeleteModal] = useState<boolean>(false);
// 当前操作方案
const [curtRow, setCurtRow] = useState<IndustrySkuType>({
goodsTypeId: undefined,
description: '',
solutionName: '',
createTime: '',
id: 0,
//行业-筛选
const [query, setQuery] = useState<Omit<industrySearchParameter, 'pageSize' | 'pageNo'>>({
categoryId: undefined,
solutionName: undefined,
});
//行业分类列表
const [industryCategoryList, setIndustryCategoryList] = useState<categoryResponseType>([]);
// 表格结构
const columns: ColumnsType<IndustrySkuType> = [
const columns: ColumnsType<industryListType[0]> = [
{ title: '方案名称', dataIndex: 'solutionName', align: 'center' },
{
title: '所属行业',
align: 'center',
render: (text: string, record) => {
return (
<div>{industryTypeObj[record.goodsTypeId as keyof typeof industryTypeObj] || ''}</div>
);
},
dataIndex: 'categoryName',
},
{ title: '描述', dataIndex: 'description', align: 'center' },
{
......@@ -66,7 +61,7 @@ function IndustryList() {
align: 'center',
width: '15%',
fixed: 'right',
render: (text: string, record) => {
render: (record) => {
return (
<div>
<Button type='link' onClick={() => handleDetail(record)}>
......@@ -75,7 +70,7 @@ function IndustryList() {
<Button type='link' onClick={() => handleEdit(record)}>
编辑
</Button>
<Button type='link' onClick={() => openDeleteModal(record)}>
<Button type='link' onClick={() => handleDelete(record)}>
删除
</Button>
</div>
......@@ -84,184 +79,118 @@ function IndustryList() {
},
];
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
const [pagination, setPagination] = useState<
PaginationProps & { totalCount: number; totalPage: number }
>({
totalCount: 0,
pageSize: 10,
current: 1,
pageNo: 1,
totalPage: 0,
});
// 按钮权限
const btnAdd = useOption(22201);
const btnDelete = useOption(22202);
const btnEdit = useOption(22203);
const btnDetail = useOption(22204);
// 新增弹窗是否显示
const [visibleAddEdit, setVisibleAddEdit] = useState(false);
// 新增弹窗内容
const [currentIndustryItem, setCurrentIndustryItem] = useState<Partial<industryListType[0]>>();
// 新版通用部分(ES6+ for React) ZhangLK 2022/08/30 Start
// 加载列表
const getTableList = async (value = {}) => {
//行业列表
const getIndustryList = (search: Omit<industrySearchParameter, 'pageSize' | 'pageNo'>) => {
setLoading(true);
// 只需要修改这个地方的接口即可
const res: any = await IndustryManageAPI.listPageIndustrySku({
pageNo: pagination.current,
IndustryManageAPI.getIndustryList({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
...value,
...query,
});
...search,
}).then(({ result }) => {
setLoading(false);
if (res && res.code === '200') {
// console.log("res -->", res);
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
pageSize,
current: pageNo,
totalPage,
setTableData(result.list || []);
pagination.totalCount = result.totalCount;
pagination.totalPage = result.totalPage;
setPagination(pagination);
});
setTableData(list);
} else {
message.warning(res.message);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getIndustryList(query);
};
// 表单提交
const onFinish = (val: FormType) => {
// 在这里对提交的数据做处理,如range转为开始和结束时间
const data = Object.fromEntries(
// 过滤为空项
Object.entries({
...val,
}).filter((i) => i[1] !== '' && i[1] !== undefined && i[1] !== null),
);
query = data;
getTableList(data).then();
};
// 获取所属行业下拉列表
const getFirstIndustryTypeInfo = async () => {
const res: any = await IndustryManageAPI.getFirstIndustryTypeInfo({});
if (res && res.code === '200') {
const arr = res.result.map((i: { goodsMasterType: string; goodsMasterTypeId: number }) => {
return {
label: i.goodsMasterType,
val: i.goodsMasterTypeId,
// 行业-筛选
const searchIndustryEvent = (val: any) => {
setQuery(val);
getIndustryList(val);
};
});
const obj = res.result.reduce((prev: any, curt: any) => {
prev[curt.goodsMasterTypeId] = curt.goodsMasterType;
return prev;
}, {});
setIndustryType(arr);
setIndustryTypeObj(obj);
//获取行业目录下的分类
const getIndustryCategory = () => {
CategoryManageAPI.getCategoryList({ pageNo: 1, pageSize: 99999, type: 0, directoryId: 2 }).then(
({ result }) => {
if (result.list) {
setIndustryCategoryList(result.list);
const industryOptions = result.list.map((v) => ({ id: v.id, name: v.classifyName }));
searchColumns[1].options = industryOptions;
setSearchColumns(searchColumns);
}
},
);
};
// 新增弹窗是否显示
const [visibleAddEdit, setVisibleAddEdit] = useState(false);
// 新增弹窗内容
const [addEditData, setAddEditData] = useState<IndustrySkuType>({
goodsTypeId: undefined,
description: '',
solutionName: '',
createTime: '',
id: 0,
});
// 新增弹窗
const handleAdd = () => {
setVisibleAddEdit(true);
setAddEditData({
createTime: '',
goodsTypeId: undefined,
description: '',
solutionName: '',
id: 0,
});
setCurrentIndustryItem(undefined);
};
// 编辑弹窗
const handleEdit = (record: IndustrySkuType) => {
const handleEdit = (record: industryListType[0]) => {
setVisibleAddEdit(true);
setAddEditData(record);
setCurrentIndustryItem(record);
};
// 关闭弹窗
const handleAddEditClosed = () => {
const addOrEditIndustryModalClose = () => {
setVisibleAddEdit(false);
setAddEditData({
createTime: '',
goodsTypeId: undefined,
description: '',
solutionName: '',
id: 0,
});
paginationChange(pagination.current, pagination.pageSize);
setCurrentIndustryItem(undefined);
};
// 删除弹窗是否显示
// 打开删除弹窗
const openDeleteModal = (record: IndustrySkuType) => {
setVisibleDeleteModal(true);
setCurtRow(record);
};
// 关闭删除弹窗
const handleDeleteSkuClosed = () => {
setVisibleDeleteModal(false);
//新增或编辑成功
const addOrEditSuccess = () => {
getIndustryList(query);
};
// 删除行业方案
const handleDeleteSku = async () => {
const res: any = await IndustryManageAPI.removeIndustrySku({ id: curtRow.id });
if (res.code === '200') {
message.success('操作成功');
handleDeleteSkuClosed();
getTableList().then();
} else {
message.error(res.message);
handleDeleteSkuClosed();
//行业删除
const handleDelete = (record: industryListType[0]) => {
Modal.confirm({
content: '确认删除该行业?',
onOk: () => {
IndustryManageAPI.removeIndustryRequest({ id: record.id }).then(({ code }) => {
if (code === '200') {
message.success('删除成功');
if (tableData.length === 1 && pagination.pageNo !== 1) {
pagination.pageNo -= 1;
}
getIndustryList(query);
}
});
},
});
};
// 跳转详情
const handleDetail = (record: industryListType[0]) => {
navigate({
pathname: '/mallManage/industryDetail',
search: `id=${record.id}`,
});
};
// componentDidMount
useEffect(() => {
// query = {};
// (async () => {
// await getFirstIndustryTypeInfo();
// await getTableList();
// })();
getIndustryCategory();
getIndustryList(query);
}, []);
return (
<div className='from-table-wrap'>
<div className='header-view'>
<Form name='basic' layout='inline' onFinish={onFinish}>
{btnAdd || true ? (
<Form.Item>
<Button type='primary' onClick={handleAdd}>
<div className='industry-list'>
<SearchBox
search={searchColumns}
child={
<Button type='primary' icon={<PlusOutlined />} onClick={handleAdd}>
新增
</Button>
</Form.Item>
) : (
''
)}
<Form.Item name='solutionName' label='方案名称'>
<Input placeholder='请输入方案名称' allowClear />
</Form.Item>
<Form.Item name='goodsTypeId' label='所属行业'>
<Select placeholder='请选择所属行业' allowClear>
{industryType.map((i, j) => (
<Option value={i.val} key={j}>
{i.label}
</Option>
))}
</Select>
</Form.Item>
<Form.Item>
<Button type='primary' htmlType='submit'>
搜索
</Button>
</Form.Item>
</Form>
</div>
}
searchData={searchIndustryEvent}
/>
<Table
size='small'
dataSource={tableData}
......@@ -271,9 +200,9 @@ function IndustryList() {
bordered
loading={loading}
pagination={{
total: pagination.total,
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.current,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
......@@ -282,16 +211,12 @@ function IndustryList() {
/>
<AddOrEditIndustryModal
visible={visibleAddEdit}
closed={handleAddEditClosed}
data={addEditData}
open={visibleAddEdit}
industryItem={currentIndustryItem}
categoryIndustryList={industryCategoryList}
close={addOrEditIndustryModalClose}
addOrEditSuccess={addOrEditSuccess}
/>
{/*<DeleteModal*/}
{/* visible={visibleDeleteModal}*/}
{/* onCancel={handleDeleteSkuClosed}*/}
{/* onOK={handleDeleteSku}*/}
{/*/>*/}
</div>
);
}
......
// 行业sku管理-分页列表
export interface IndustrySkuType {
goodsTypeId: number | undefined;
description: string;
solutionName: string;
id: number;
createTime: string;
}
// 行业sku管理-行业规格管理-分页列表
export interface IndustrySpecType {
createTime?: string;
productSkuId?: number;
id: number;
industrySkuId?: number;
list: inventoryType[];
specImage: string;
specName: string;
}
// 行业sku管理-行业规格管理-清单列表
export interface inventoryType {
productSku: productSkuType;
......
import { FC, useEffect } from 'react';
import { Form, Input, Modal, message, ModalProps } from 'antd';
import { MakeManageAPI } from '~/api';
interface selfProps {
makeItem: any;
onOk: () => void;
handleCancel: () => void;
}
const AddOrEditModal: FC<ModalProps & selfProps> = ({
open,
handleCancel,
onOk,
title,
makeItem,
}) => {
const [form] = Form.useForm<{ brandName: string }>();
const submit = () => {
form.validateFields().then((value) => {
MakeManageAPI[makeItem ? 'editBrandInfo' : 'addBrandInfo']({
...value,
id: makeItem?.id,
}).then(({ code, message: msg }) => {
if (code === '200') {
message.success(makeItem ? '编辑成功' : '新增成功');
onOk();
form.resetFields();
} else {
message.error(msg);
}
});
});
};
const onCancel = () => {
form.resetFields();
handleCancel();
};
useEffect(() => {
if (makeItem) {
form.setFieldsValue({
brandName: makeItem.brandName,
});
}
}, [makeItem]);
return (
<Modal open={open} onOk={submit} onCancel={onCancel} title={title}>
<Form form={form}>
<Form.Item
label='品牌名称'
name='brandName'
rules={[{ required: true, message: '请输入品牌名称!' }]}
>
<Input placeholder='请输入品牌名称' maxLength={10} />
</Form.Item>
</Form>
</Modal>
);
};
export default AddOrEditModal;
import { Button, Table } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnsType } from 'antd/es/table';
// import AddOrEditMakeModal from './components/addOrEditMakeModal';
const MakeList = () => {
const columns: ColumnsType<any> = [
{
title: '品牌名称',
align: 'center',
dataIndex: 'brandName',
},
{
title: '创建时间',
align: 'center',
dataIndex: 'createTime',
},
{
title: '操作',
align: 'center',
render: () => (
<>
<Button type='link'>编辑</Button>
<Button type='link' danger>
删除
</Button>
</>
),
},
];
return (
<div className='make-list'>
<div className='make-list-operate'>
<Button type='primary' icon={<PlusOutlined />}>
新增
</Button>
</div>
<div className='make-list-content' style={{ marginTop: '10px' }}>
<Table bordered columns={columns} />
</div>
{/*<AddOrEditMakeModal />*/}
</div>
);
};
export default MakeList;
......@@ -2,7 +2,71 @@ import React from 'react';
import { Table, Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import './index.scss';
import { ColumnsType } from 'antd/es/table';
const columns: ColumnsType<any> = [
{
title: '序号',
align: 'center',
render: () => <div>--</div>,
},
{
title: `产品类型`,
align: 'center',
// dataIndex: "goodsTypeId",
render: () => <div>--</div>,
},
{
title: '规格名称',
align: 'center',
dataIndex: 'goodsSpecName',
},
{
title: `方案`,
align: 'center',
dataIndex: 'skuName',
},
{
title: '选项来源',
align: 'center',
dataIndex: 'specIds',
render: () => <div>--</div>,
},
{
title: '选择方式',
align: 'center',
dataIndex: 'chooseType',
render: () => <div>--</div>,
},
{
title: '是否必选',
align: 'center',
dataIndex: 'must',
render: () => <div>--</div>,
},
{
title: '规格单位',
align: 'center',
dataIndex: 'skuUnitId',
render: () => {
return <div>--</div>;
},
},
{
title: '操作',
align: 'center',
width: '20%',
render: () => {
return (
<div>
<Button type='link' style={{ marginRight: '10px' }}>
编辑
</Button>
<Button type='link'>删除</Button>
</div>
);
},
},
];
const StockSku: React.FC<any> = () => {
return (
<div className='stock-sku'>
......@@ -13,7 +77,7 @@ const StockSku: React.FC<any> = () => {
添加规格
</Button>
</div>
<Table size='small' bordered rowKey='id' pagination={false} />
<Table size='small' bordered rowKey='id' pagination={false} columns={columns} />
</div>
</div>
);
......
import React, { useEffect, useState } from 'react';
import { Form, Input, Modal, message, Select } from 'antd';
import { ProduceManageAPI } from '~/api';
import { CategoryManageAPI, ProduceManageAPI } from '~/api';
import { ProductSkuType, MakeItemEntity } from '../../propsType';
// import { categoryDec } from '@/api/modules/goods';
import { InterDataType } from '~/api/interface';
import { categoryListType, directoryListType } from '~/api/interface/categoryManage';
//目录返回类型
type directoryType = InterDataType<directoryListType>;
//分类返回类型
type categoryType = InterDataType<categoryListType>['list'];
interface PropsType {
visible: boolean;
closed: any;
data: ProductSkuType | undefined;
makeList: MakeItemEntity[];
decList: any;
decList: directoryType;
}
const { Option } = Select;
......@@ -18,9 +24,7 @@ function AddOrEditProduceModal(props: PropsType) {
// 父组件传参
const { visible, closed, data, makeList, decList } = props;
// 产品类型下拉列表
const [productTypeSelectList, setProductTypeSelectList] = useState<
{ label: string; val: number }[]
>([]);
const [productTypeSelectList, setProductTypeSelectList] = useState<categoryType>([]);
// 表格事件
const [form] = Form.useForm();
// 关闭弹窗
......@@ -46,28 +50,23 @@ function AddOrEditProduceModal(props: PropsType) {
message.warning(err.errorFields[0].errors[0]).then();
});
};
// 获取产品类型列表
const getListGoodsTypeList = async (type: number) => {
const res: any = await ProduceManageAPI.getListGoodsTypeList(type);
if (res && res.code === '200') {
const arr = res.result.map((i: { goodsMasterType: string; goodsMasterTypeId: number }) => {
return {
label: i.goodsMasterType,
val: i.goodsMasterTypeId,
};
});
setProductTypeSelectList(arr);
}
//根据目录获取分类
const getCategoryListByDirectory = (directoryId: number) => {
CategoryManageAPI.getCategoryList({ pageNo: 1, pageSize: 99999, directoryId, type: 4 }).then(
({ result }) => {
setProductTypeSelectList(result.list || []);
},
);
};
// 目录修改
const decSelectChange = (value: number) => {
form.setFieldValue('goodsTypeId', undefined);
getListGoodsTypeList(value);
getCategoryListByDirectory(value);
};
// componentsDidMounted
useEffect(() => {
if (!data) return;
getListGoodsTypeList(data.directoryId);
getCategoryListByDirectory(data.directoryId);
form.setFieldsValue({
...data,
});
......@@ -103,7 +102,7 @@ function AddOrEditProduceModal(props: PropsType) {
<Select placeholder='请选择产品目录' onChange={decSelectChange}>
{decList.map((v: any, index: number) => (
<Select.Option value={v.id} key={index}>
{v.sortName}
{v.directoryName}
</Select.Option>
))}
</Select>
......@@ -122,8 +121,8 @@ function AddOrEditProduceModal(props: PropsType) {
}
>
{productTypeSelectList.map((i, j) => (
<Option value={i.val} key={j}>
{i.label}
<Option value={i.id} key={j}>
{i.classifyName}
</Option>
))}
</Select>
......
......@@ -3,11 +3,19 @@ import './index.scss';
import { Button, Form, Input, message, Modal, Select, Table } from 'antd';
import { useNavigate } from 'react-router-dom';
import { ColumnsType } from 'antd/es/table';
import { ProduceManageAPI } from '~/api';
import { CategoryManageAPI, ProduceManageAPI } from '~/api';
import AddOrEditProduce from './components/addOrEditProduceModal';
import { ProductSkuType, MakeItemEntity } from './propsType';
import useOption from '~/common/hook/optionHook';
// import { categoryDec } from '@/api/modules/goods';
import { MakeItemEntity } from './propsType';
import { InterDataType, PaginationProps } from '~/api/interface';
import { productListType } from '~/api/interface/produceManageType';
import { categoryListType, directoryListType } from '~/api/interface/categoryManage';
//产品列表返回类型
type produceListType = InterDataType<productListType>['list'];
//分类返回类型
type categoryType = InterDataType<categoryListType>['list'];
//目录返回类型
type directoryType = InterDataType<directoryListType>;
const { Option } = Select;
const { confirm } = Modal;
......@@ -24,62 +32,21 @@ function ProduceManage() {
// 路由操作
const navigate = useNavigate();
// 表格数据
const [tableData, setTableData] = useState<any>([{ id: 1 }]);
const [tableData, setTableData] = useState<produceListType>([]);
// 加载中
const [loading, setLoading] = useState<boolean>(false);
// 产品类型下拉列表
const [productTypeSelectList, setProductTypeSelectList] = useState<
{ label: string; val: number }[]
>([]);
const [productTypeSelectList, setProductTypeSelectList] = useState<categoryType>([]);
// 新增弹窗是否显示
const [visibleAddEdit, setVisibleAddEdit] = useState(false);
// 新增弹窗内容
const [addEditData, setAddEditData] = useState<ProductSkuType>();
const [addEditData, setAddEditData] = useState<produceListType[0]>();
// 品牌列表
const [makeList, setMakeList] = useState<MakeItemEntity[]>([]);
// 目录列表
const [decList, setDecList] = useState<any>([]);
// 跳转详情
const handleDetail = (record: ProductSkuType) => {
navigate({
pathname: '/mallManage/produceDetail',
search: `id=${record.id}`,
});
};
// 新增弹窗
const handleAdd = () => {
setVisibleAddEdit(true);
setAddEditData(undefined);
};
// 编辑弹窗
const handleEdit = (record: ProductSkuType) => {
setVisibleAddEdit(true);
setAddEditData(record);
};
// 关闭弹窗
const handleAddEditClosed = () => {
setVisibleAddEdit(false);
setAddEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
};
// 删除产品
const handleDelete = (record: ProductSkuType) => {
confirm({
title: '提示',
content: '删除后此数据将会丢失,确定删除吗?',
async onOk() {
const res: any = await ProduceManageAPI.removeProductSku({ id: record.id });
if (res && res.code === '200') {
await message.success('操作成功');
await paginationChange(pagination.current, pagination.pageSize);
} else {
message.error(res.message);
}
},
});
};
const [decList, setDecList] = useState<directoryType>([]);
// 表格结构
const columns: ColumnsType<ProductSkuType> = [
const columns: ColumnsType<produceListType[0]> = [
{
title: '产品名称',
dataIndex: 'productName',
......@@ -88,12 +55,10 @@ function ProduceManage() {
},
{
title: '产品目录',
dataIndex: 'directoryId',
dataIndex: 'directoryName',
align: 'center',
render: (text: string, record: ProductSkuType) =>
decList.find((v) => v.id === record.directoryId)?.sortName || '',
},
{ title: '产品类型', dataIndex: 'typeName', align: 'center' },
{ title: '产品类型', dataIndex: 'categoryName', align: 'center' },
{ title: '型号', dataIndex: 'model', align: 'center' },
{ title: '产品品牌', dataIndex: 'productBrand', align: 'center' },
{
......@@ -119,46 +84,66 @@ function ProduceManage() {
},
];
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
const [pagination, setPagination] = useState<PaginationProps & { totalCount: number }>({
pageSize: 10,
current: 1,
totalPage: 0,
pageNo: 1,
totalCount: 0,
});
// 按钮权限
const btnAdd = useOption(22151);
const btnEdit = useOption(22152);
const btnDelete = useOption(22153);
const btnDetail = useOption(22154);
// 新版通用部分(ES6+ for React) ZhangLK 2022/08/30 Start
// 加载列表
const getTableList = async (value = {}) => {
setLoading(true);
// 只需要修改这个地方的接口即可
const res: any = await ProduceManageAPI.listPageProductSku({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
...query,
// 跳转详情
const handleDetail = (record: produceListType[0]) => {
navigate({
pathname: '/mallManage/produceDetail',
search: `id=${record.id}`,
});
setLoading(false);
};
// 新增弹窗
const handleAdd = () => {
setVisibleAddEdit(true);
setAddEditData(undefined);
};
// 编辑弹窗
const handleEdit = (record: produceListType[0]) => {
setVisibleAddEdit(true);
setAddEditData(record);
};
// 关闭弹窗
const handleAddEditClosed = () => {
setVisibleAddEdit(false);
setAddEditData(undefined);
paginationChange(pagination.pageNo, pagination.pageSize);
};
// 删除产品
const handleDelete = (record: produceListType[0]) => {
confirm({
title: '提示',
content: '删除后此数据将会丢失,确定删除吗?',
async onOk() {
const res: any = await ProduceManageAPI.removeProductSku({ id: record.id });
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
pageSize,
current: pageNo,
totalPage,
});
setTableData(list);
await message.success('操作成功');
await paginationChange(pagination.pageNo, pagination.pageSize);
} else {
message.warning(res.message);
message.error(res.message);
}
},
});
};
//产品列表
const getProduceList = () => {
ProduceManageAPI.listPageProductSku({
pageNo: pagination.pageNo,
pageSize: pagination.pageSize,
}).then(({ result }) => {
setTableData(result.list || []);
setPagination(pagination);
});
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getProduceList();
};
// 表单提交
const onFinish = (val: FormType) => {
......@@ -170,21 +155,7 @@ function ProduceManage() {
}).filter((i) => i[1] !== '' && i[1] !== undefined && i[1] !== null),
);
query = data;
getTableList(data).then();
};
// 获取产品类型列表
const getListGoodsTypeList = async (type: number) => {
const res: any = await ProduceManageAPI.getListGoodsTypeList(type);
if (res && res.code === '200') {
const arr = res.result.map((i: { goodsMasterType: string; goodsMasterTypeId: number }) => {
return {
label: i.goodsMasterType,
val: i.goodsMasterTypeId,
};
});
setProductTypeSelectList(arr);
}
// getTableList(data).then();
};
// 获取品牌列表
const getMakeList = () => {
......@@ -193,43 +164,40 @@ function ProduceManage() {
});
};
// 目录列表
const getDescList = () => {
ProduceManageAPI.directoryList().then((res: any) => {
if (res.result) {
setDecList(res.result.filter((v: any) => v.id !== 2));
}
const getDirectoryList = () => {
CategoryManageAPI.getDirectoryList({ type: 4 }).then(({ result }) => {
setDecList(result || []);
});
};
//根据目录获取分类
const getCategoryListByDirectory = (directoryId: number) => {
CategoryManageAPI.getCategoryList({ pageNo: 1, pageSize: 99999, directoryId, type: 4 }).then(
({ result }) => {
setProductTypeSelectList(result.list || []);
},
);
};
// 目录修改
const decSelectChange = (value: number) => {
if (value) {
getListGoodsTypeList(value);
getCategoryListByDirectory(value);
}
};
// componentDidMount
useEffect(() => {
// query = {};
// getMakeList();
// getDescList();
// (async () => {
// await getTableList();
// })();
getProduceList();
getDirectoryList();
}, []);
return (
<div className='from-table-wrap'>
<div className='header-view'>
<Form name='basic' layout='inline' onFinish={onFinish}>
{btnAdd || true ? (
<Form.Item>
<Button type='primary' onClick={handleAdd}>
新增
</Button>
</Form.Item>
) : (
''
)}
<Form.Item name='productName' label='产品名称'>
<Input placeholder='请输入产品名称' allowClear />
</Form.Item>
......@@ -237,7 +205,7 @@ function ProduceManage() {
<Select placeholder='请选择产品目录' onChange={decSelectChange} allowClear>
{decList.map((v, index: number) => (
<Select.Option value={v.id} key={index}>
{v.sortName}
{v.directoryName}
</Select.Option>
))}
</Select>
......@@ -245,8 +213,8 @@ function ProduceManage() {
<Form.Item name='goodsTypeId' label='产品类型'>
<Select placeholder='请选择产品类型' allowClear>
{productTypeSelectList.map((i, j) => (
<Option value={i.val} key={j}>
{i.label}
<Option value={i.id} key={j}>
{i.classifyName}
</Option>
))}
</Select>
......@@ -267,9 +235,9 @@ function ProduceManage() {
scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.current,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
......
......@@ -2,8 +2,73 @@ import React from 'react';
import { Table, Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import './index.scss';
import { ColumnsType } from 'antd/es/table';
const StockSku: React.FC<any> = () => {
const columns: ColumnsType<any> = [
{
title: '序号',
align: 'center',
render: () => <div>--</div>,
},
{
title: `产品类型`,
align: 'center',
// dataIndex: "goodsTypeId",
render: () => <div>--</div>,
},
{
title: '规格名称',
align: 'center',
dataIndex: 'goodsSpecName',
},
{
title: `方案`,
align: 'center',
dataIndex: 'skuName',
},
{
title: '选项来源',
align: 'center',
dataIndex: 'specIds',
render: () => <div>--</div>,
},
{
title: '选择方式',
align: 'center',
dataIndex: 'chooseType',
render: () => <div>--</div>,
},
{
title: '是否必选',
align: 'center',
dataIndex: 'must',
render: () => <div>--</div>,
},
{
title: '规格单位',
align: 'center',
dataIndex: 'skuUnitId',
render: () => {
return <div>--</div>;
},
},
{
title: '操作',
align: 'center',
width: '20%',
render: () => {
return (
<div>
<Button type='link' style={{ marginRight: '10px' }}>
编辑
</Button>
<Button type='link'>删除</Button>
</div>
);
},
},
];
return (
<div className='stock-sku'>
<div className='stock-sku-title'>库存规格</div>
......@@ -13,7 +78,7 @@ const StockSku: React.FC<any> = () => {
添加规格
</Button>
</div>
<Table size='small' bordered rowKey='id' pagination={false} />
<Table size='small' bordered rowKey='id' pagination={false} columns={columns} />
</div>
</div>
);
......
......@@ -62,6 +62,7 @@ const ProduceListView = React.lazy(() => import('~/pages/mallManage/produceManag
const ProduceDetailView = React.lazy(
() => import('~/pages/mallManage/produceManage/produceDetail'),
); //产品详情
const MakeListView = React.lazy(() => import('~/pages/mallManage/makeManage/makeList'));
const IndustryListView = React.lazy(() => import('~/pages/mallManage/industryManage/industryList')); //行业列表
const IndustryDetailView = React.lazy(
() => import('~/pages/mallManage/industryManage/industryDetail'),
......@@ -304,10 +305,19 @@ export const routerList: Array<RouteObjectType> = [
},
},
{
path: '/mallManage/makeList',
element: withLoadingComponent(<MakeListView />),
meta: {
id: 10170,
icon: <SmileOutlined />,
title: '品牌管理',
},
},
{
path: '/mallManage/industryList',
element: withLoadingComponent(<IndustryListView />),
meta: {
id: 10170,
id: 10180,
icon: <SmileOutlined />,
title: '行业方案',
},
......@@ -316,7 +326,7 @@ export const routerList: Array<RouteObjectType> = [
path: '/mallManage/industryDetail',
element: withLoadingComponent(<IndustryDetailView />),
meta: {
id: 10180,
id: 10190,
icon: <SmileOutlined />,
title: '行业详情',
hidden: true,
......
......@@ -33,3 +33,12 @@ export const urlToBase64 = (url: string) => {
};
});
};
// 过滤对象属性
export const filterObjAttr = (obj: any, key: string[]) => {
return Object.keys(obj).reduce((pre: any, cur: string) => {
if (!key.includes(cur)) {
pre[cur] = obj[cur];
}
return pre;
}, {});
};
......@@ -12,7 +12,7 @@ export default defineConfig({
proxy: {
'/api': {
// target: 'http://192.168.3.111:8077',后端女
target: 'https://test.iuav.shop',
target: 'http://192.168.3.17:8099',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论