提交 cbe2f726 作者: 翁进城

Merge remote-tracking branch 'origin/master' into 分类管理

......@@ -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;
......@@ -31,3 +33,27 @@ export interface categoryDec {
"type": number,
directoryType: 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
>;
......@@ -339,3 +339,59 @@ export type listExpressInfoType = InterFunction<
exCode: string;
}[]
>;
// web/小程序 确认收货-订单
export type renterTakeOrderType = InterFunction<
{
authPwd: string;
imgs: Array<string>;
orderInfoId: number;
orderRefundId: number;
remark: string;
renAddress: string;
renName: string;
renPhone: string;
sendAddress: string;
sendExCode: string;
sendExNo: string;
vcuSatus: number;
videoUrl: string;
},
NonNullable<unknown>
>;
// 后台管理——平台确认归还
export type pfConfirmOrderWareType = InterFunction<
{
authPwd: string;
imgs: Array<string>;
orderInfoId: number;
orderRefundId: number;
remark: string;
renAddress: string;
renName: string;
renPhone: string;
sendAddress: string;
sendExCode: string;
sendExNo: string;
vcuSatus: number;
videoUrl: string;
},
NonNullable<unknown>
>;
// web-小程序——订单详情相关图片信息
export type orderImageDetailType = InterFunction<
{ orderInfoId: number },
{
id: number;
orderInfoId: number;
vcuType: number;
vcuSatus: number;
remark: string;
imgs: Array<string>;
videoUrl: string;
}[]
>;
// 后台管理关闭订单
export type platFormCloseOrderType = InterFunction<
{ orderInfoId: number; shutReason: string },
NonNullable<unknown>
>;
......@@ -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 = (params) => {
return axios.get("pms/classify/directoryList", {
params
});
};
}
//目录列表不含分页
static getDirectoryList = (params) => {
......@@ -36,6 +36,10 @@ export class CategoryManageAPI {
// 分类列表
static getClassificationList = (data: object): any => {
return axios.post(`/pms/classify/getClassificationList`, data);
}
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,
});
};
......
......@@ -5,6 +5,10 @@ import {
listPcWechatOrderType,
listTranStatusType,
orderDetailType,
orderImageDetailType,
pfConfirmOrderWareType,
platFormCloseOrderType,
renterTakeOrderType,
sendOrderWareType,
} from '~/api/interface/orderManageType';
......@@ -29,7 +33,23 @@ export class OrderManageAPI {
static sendOrderWare: sendOrderWareType = (params) =>
axios.post('/oms/RentalOrders/sendOrderWare', params);
// web/小程序 确认收货-订单
static renterTakeOrder: renterTakeOrderType = (params) =>
axios.post('/oms/RentalOrders/renterTakeOrder', params);
// web/小程序 确认收货-订单
static pfConfirmOrderWare: pfConfirmOrderWareType = (params) =>
axios.post('/oms/RentalOrders/pfConfirmOrderWare', params);
// v1.0.1 物流公司列表-字典
static listExpressInfo: listExpressInfoType = (params) =>
axios.get('/oms/express/listExpressInfo', { params });
// web-小程序——订单详情相关图片信息
static orderImageDetail: orderImageDetailType = (params) =>
axios.get('/oms/RentalOrders/orderImageDetail', { params });
// 后台管理关闭订单
static platFormCloseOrder: platFormCloseOrderType = (params) =>
axios.get('/oms/RentalOrders/platFormCloseOrder', { 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 { 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);
form.setFieldsValue({
...data,
});
getFirstIndustryTypeInfo().then();
}, [data]);
if (industryItem) {
form.setFieldsValue({
solutionName: industryItem.solutionName,
categoryId: industryItem.categoryId,
description: industryItem.description,
});
}
}, [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;
// 行业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>
......
......@@ -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>
);
......
import { OrderManageAPI } from '~/api';
import React, { useEffect, useState } from 'react';
import { Timeline } from 'antd';
import { orderDetailType } from '~/api/interface/orderManageType';
import { InterDataType } from '~/api/interface';
// 接口返回的类型
type DataType = InterDataType<orderDetailType>;
// 参数类型
type PropsType = {
detail: DataType;
};
const DetailTimeLine: React.FC<PropsType> = (props) => {
const { detail } = props;
// 流程列表
const [timeLineList, setTimeLineList] = useState<{ label: string; color: string }[]>([]);
// 获取订单流程
const getOrderStatus = async () => {
const res = await OrderManageAPI.listTranStatus({});
if (res && res.code === '200') {
// 转换列表数据(区分完成和未完)
const list = res.result.map((i) => {
if (Number(i.status) < Number(detail?.tranStatus)) {
return {
label: i.doing,
color: '#1890ff',
};
} else {
return {
label: i.waiting,
color: '#ccc',
};
}
});
// 将当前项目变绿
const current = list.findIndex((i) => i.color === '#ccc');
list[current].color = '#52c41a';
setTimeLineList(list);
}
};
// componentDidMount
useEffect(() => {
if (!detail) return;
getOrderStatus().then();
}, [detail]);
return (
<div className={'detail-timeline'} style={{ width: '200px' }}>
<div className={'detail-title'}>订单流程</div>
<Timeline items={timeLineList} mode={'right'} />
</div>
);
};
export default DetailTimeLine;
import { InterListType, InterReqType } from '~/api/interface';
import { listPcWechatOrderType, platFormCloseOrderType } from '~/api/interface/orderManageType';
import React from 'react';
import { Form, message, Modal, Select } from 'antd';
import { OrderManageAPI } from '~/api';
// 表格数据类型
type TableType = InterListType<listPcWechatOrderType>;
// 请求数据的类型
type ReqType = InterReqType<platFormCloseOrderType>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const OrderClosed: React.FC<propType> = (props) => {
OrderClosed.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
// 表单钩子
const [form] = Form.useForm<ReqType>();
// 关闭弹窗
const handleCancel = () => {
form.resetFields();
closed();
};
// 确认事件
const handleOk = () => {
form
.validateFields()
.then(async (values) => {
// console.log('确认事件 --->', values);
await handleSubmit(values);
})
.catch((err) => {
message
.warning({
content: err.errorFields[0].errors[0],
})
.then();
});
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await OrderManageAPI.platFormCloseOrder({
...values,
orderInfoId: Number(data?.id),
});
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
return (
<Modal
open={open}
title={title}
onCancel={handleCancel}
onOk={handleOk}
destroyOnClose
width={400}
>
<Form
name='addForm'
form={form}
labelAlign='right'
labelCol={{ span: 6 }}
wrapperCol={{ span: 12 }}
>
<Form.Item
label='关闭理由'
name='shutReason'
rules={[{ required: true, message: '请选择关闭理由' }]}
>
<Select
placeholder={'请选择关闭理由'}
options={[
{ label: '未及时付款' },
{ label: '买家不想买' },
{ label: '买家信息填写错误,重新下单' },
{ label: '恶意买家,同行捣乱' },
{ label: '缺货' },
{ label: '买家拍错了' },
{ label: '其他原因' },
].map((i) => ({ label: i.label, value: i.label }))}
allowClear
/>
</Form.Item>
</Form>
</Modal>
);
};
export default OrderClosed;
import { InterListType, InterReqType } from '~/api/interface';
import { listPcWechatOrderType, pfConfirmOrderWareType } from '~/api/interface/orderManageType';
import React, { useEffect } from 'react';
import { Col, Form, Input, message, Modal, Radio, Row } from 'antd';
import { Uploader } from '~/components/uploader';
import { PlusOutlined } from '@ant-design/icons';
import { OrderManageAPI } from '~/api';
// 表格数据类型
type TableType = InterListType<listPcWechatOrderType>;
// 请求数据的类型
type ReqType = InterReqType<pfConfirmOrderWareType>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const OrderConfirm: React.FC<propType> = (props) => {
OrderConfirm.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
// 物流列表
const [expressList, setExpressList] = React.useState<{ label: string; value: string }[]>([]);
// 表单钩子
const [form] = Form.useForm<ReqType>();
// 关闭弹窗
const handleCancel = () => {
form.resetFields();
closed();
};
// 确认事件
const handleOk = () => {
form
.validateFields()
.then(async (values) => {
// console.log('确认事件 --->', values);
await handleSubmit(values);
})
.catch((err) => {
message
.warning({
content: err.errorFields[0].errors[0],
})
.then();
});
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await OrderManageAPI.pfConfirmOrderWare({
...values,
orderInfoId: Number(data?.id),
});
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// 获取物流信息
const getListExpressInfo = async () => {
const res = await OrderManageAPI.listExpressInfo({});
if (res && res.code === '200') {
setExpressList(res.result.map((item) => ({ label: item.exName, value: item.exCode })));
// console.log(res);
}
};
// 转换物流信息
const getExpressInfo = (code: string | undefined | null) => {
return expressList.find((item) => item.value === code)?.label || code;
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
getListExpressInfo().then();
console.log('data --->', data);
}, [open]);
return (
<Modal
open={open}
title={title}
onCancel={handleCancel}
onOk={handleOk}
destroyOnClose
width={600}
>
<Form
name='addForm'
form={form}
labelAlign='right'
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
>
<Form.Item label='收货方式' labelCol={{ span: 4 }}>
物流归还
</Form.Item>
<Form.Item label='物流单号' labelCol={{ span: 4 }}>
{data?.receipt?.sendExNo}
</Form.Item>
<Form.Item label='物流公司' labelCol={{ span: 4 }}>
{getExpressInfo(data?.receipt?.sendExCode)}
</Form.Item>
<Row gutter={{ xs: 8, sm: 16, md: 24 }}>
<Col span={11}>
<Form.Item
label='质检照片'
name='imgs'
rules={[{ required: true, message: '请上传质检照片' }]}
>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={3}
onChange={(e) => {
form.setFieldValue(
'imgs',
e.map((item) => item.url),
);
}}
>
<PlusOutlined />
</Uploader>
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
label='质检视频'
name='videoUrl'
rules={[{ required: true, message: '请上传质检视频' }]}
>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileType={['video/mp4', 'video/avi', 'video/wmv', 'video/rmvb']}
fileSize={10}
onChange={(e) => {
form.setFieldValue('videoUrl', e[0].url);
}}
>
<PlusOutlined />
</Uploader>
</Form.Item>
</Col>
</Row>
<Row gutter={{ xs: 8, sm: 16, md: 24 }}>
<Col span={11}>
<Form.Item
label='设备状态'
name='vcuSatus'
rules={[{ required: true, message: '请选择设备状态' }]}
initialValue={0}
>
<Radio.Group
options={[
{ label: '正常', value: 0 },
{ label: '故障', value: 1 },
]}
onChange={(e) => {
form.setFieldValue('vcuSatus', e.target.value);
}}
/>
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
label='操作密码'
name='authPwd'
rules={[{ required: true, message: '请输入操作密码' }]}
>
<Input.Password
placeholder={'请输入操作密码'}
maxLength={20}
allowClear
autoComplete='new-password'
/>
</Form.Item>
</Col>
</Row>
</Form>
</Modal>
);
};
export default OrderConfirm;
......@@ -19,8 +19,8 @@ interface propType {
data?: TableType[0];
}
const DetailDeliver: React.FC<propType> = (props) => {
DetailDeliver.defaultProps = {
const OrderDeliver: React.FC<propType> = (props) => {
OrderDeliver.defaultProps = {
data: undefined,
};
// 参数
......@@ -247,4 +247,4 @@ const DetailDeliver: React.FC<propType> = (props) => {
);
};
export default DetailDeliver;
export default OrderDeliver;
......@@ -41,6 +41,18 @@
flex: 1;
}
.detail-timeline {
overflow: hidden;
.ant-timeline {
transform: translateX(-90px) translateY(10px);
}
.ant-timeline .ant-timeline-item {
padding-bottom: 36px;
}
}
.detail-title {
font-size: 13px;
font-weight: 600;
......@@ -61,12 +73,24 @@
}
}
.detail-price {
text-align: right;
padding-right: 30px;
width: 100%;
font-size: 16px;
.num {
color: orangered;
}
}
.detail-image {
display: flex;
justify-content: flex-start;
margin-left: 56px;
margin-top: -20px;
margin-bottom: 10px;
flex-wrap: wrap;
.image {
width: 68px;
......@@ -76,6 +100,7 @@
.ant-image {
margin-right: 10px;
margin-bottom: 10px;
}
}
}
......
......@@ -8,6 +8,7 @@ import DetailInformation from '~/pages/orderManage/productOrder/comp/detailInfor
import { OrderManageAPI } from '~/api';
import { InterDataType } from '~/api/interface';
import { orderDetailType } from '~/api/interface/orderManageType';
import DetailTimeLine from '~/pages/orderManage/equipmentOrder/comp/detailTimeLine';
// import DetailMessageBox from '~/pages/orderManage/equipmentOrder/comp/detailMessageBox';
// 接口返回的类型
......@@ -59,9 +60,10 @@ function EquipmentOrderDetail() {
</div>
<div className={'detail-wrap'}>
<DetailPurchaser detail={orderDetail} />
<DetailDelivery />
<DetailDelivery detail={orderDetail} />
<DetailTimeLine detail={orderDetail} />
{/*<DetailMessageBox />*/}
<DetailInformation />
<DetailInformation detail={orderDetail} />
</div>
</div>
);
......
......@@ -7,7 +7,9 @@ import qs from 'query-string';
import { InterListType, InterReqType } from '~/api/interface';
import { listPcWechatOrderType } from '~/api/interface/orderManageType';
import { OrderManageAPI } from '~/api';
import DetailDeliver from '~/pages/orderManage/equipmentOrder/comp/detailDeliver';
import OrderDeliver from 'src/pages/orderManage/equipmentOrder/comp/orderDeliver';
import OrderConfirm from '~/pages/orderManage/equipmentOrder/comp/orderConfirm';
import OrderClosed from '~/pages/orderManage/equipmentOrder/comp/orderClosed';
// 表格数据类型
type TableType = InterListType<listPcWechatOrderType>;
......@@ -33,6 +35,10 @@ function EquipmentOrderView() {
const navigate = useNavigate();
// 发货弹窗是否显示
const [deliverVisible, setDeliverVisible] = useState<boolean>(false);
// 收货弹窗是否显示
const [confirmVisible, setConfirmVisible] = useState<boolean>(false);
// 关闭弹窗是否显示
const [closedVisible, setClosedVisible] = useState<boolean>(false);
// 当前选择的是第几个按钮
const [statusCodeButtonIndex, setStatusCodeButtonIndex] = useState<number>(0);
// 订单状态搜索列表
......@@ -120,14 +126,23 @@ function EquipmentOrderView() {
const handleAction = (data: TableType[0]) => {
const { tranStatus } = data;
setEditData(data);
if (tranStatus === '100') {
setClosedVisible(true);
}
if (tranStatus === '200') {
setDeliverVisible(true);
}
if (tranStatus === '500') {
setConfirmVisible(true);
}
};
// 关闭弹窗
const handleClosed = () => {
setEditData(undefined);
setDeliverVisible(false);
setConfirmVisible(false);
setClosedVisible(false);
paginationChange(pagination.current, pagination.pageSize);
};
// componentDidMount
useEffect(() => {
......@@ -310,7 +325,21 @@ function EquipmentOrderView() {
// rowSelection={{ selectedRowKeys, onChange: onSelectChange }}
/>
{/*发货弹窗*/}
<DetailDeliver open={deliverVisible} title={'发货'} data={editData} closed={handleClosed} />
<OrderDeliver
open={deliverVisible}
title={'卖家发货'}
data={editData}
closed={handleClosed}
/>
{/*收货弹窗*/}
<OrderConfirm
open={confirmVisible}
title={'确认收货'}
data={editData}
closed={handleClosed}
/>
{/*关闭订单*/}
<OrderClosed open={closedVisible} title={'关闭订单'} data={editData} closed={handleClosed} />
</>
);
}
......
import React from 'react';
import React, { useEffect, useState } from 'react';
import { Image } from 'antd';
import { orderDetailType, orderImageDetailType } from '~/api/interface/orderManageType';
import { InterDataType } from '~/api/interface';
import { OrderManageAPI } from '~/api';
function DetailDelivery() {
// 接口返回的类型
type DataType = InterDataType<orderDetailType>;
// 参数类型
type PropsType = {
detail: DataType;
};
// 列表的类型
type ListType = InterDataType<orderImageDetailType>;
// 设备状态列表
const vcuSatusList = [
{ label: '正常', value: 0 },
{ label: '故障', value: 1 },
];
// 0:发货 1:收货 2:归还 3:平台收货
const vcuTypeList = [
{ label: '发货验收', value: 0 },
{ label: '收货验收', value: 1 },
{ label: '归还验收', value: 2 },
{ label: '平台收货', value: 3 },
];
const DetailDelivery: React.FC<PropsType> = (props) => {
const { detail } = props;
// 验收信息列表
const [orderImageList, setOrderImageList] = useState<ListType>([]);
// 获取订单验收信息
const getOrderImageDetail = async () => {
const res = await OrderManageAPI.orderImageDetail({ orderInfoId: detail?.id });
if (res && res.code === '200') {
setOrderImageList(res.result);
console.log('获取订单验收信息 --->', res.result);
}
};
// 转换设备状态
const getVcuSatus = (code: number) => {
return vcuSatusList.find((item) => item.value === code)?.label || code;
};
// 转换标题
const getVcuType = (code: number) => {
return vcuTypeList.find((item) => item.value === code)?.label || code;
};
// componentDidMount
useEffect(() => {
if (!detail) return;
getOrderImageDetail().then();
}, [detail]);
return (
<div className={'detail-delivery detail-half'}>
<div className={'detail-title'}>收货信息</div>
<div className={'detail-text'}>收货人:测试</div>
<div className={'detail-text'}>手机号:15889328503</div>
<div className={'detail-text'}>
收货地址:广东省深圳市南山区仙鼓路(南山区万科云城(仙鼓路西50米))
</div>
<div className={'detail-title'}>物流信息</div>
<div className={'detail-text'}>物流单号:YT6732436785799</div>
<div className={'detail-text'}>物流进度:--</div>
<div className={'detail-title'}>验收信息</div>
<div className={'detail-text'}>验收状态:已验收</div>
<div className={'detail-text'}>验收凭证:</div>
<div className={'detail-image'}>
{[
'https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/file/infrastructure-05-05.png',
'https://pad-video-x.oss-cn-shenzhen.aliyuncs.com/file/infrastructure-05-05.png',
].map((i, j) => (
<Image key={j} className={'image'} src={i} alt='付款凭证' />
))}
</div>
{orderImageList.map((i, j) => (
<div key={j}>
<div className={'detail-title'}>{getVcuType(i.vcuType)}</div>
<div className={'detail-text'}>验收状态:{getVcuSatus(i.vcuSatus)}</div>
<div className={'detail-text'}>验收描述:{i.remark || '无'}</div>
<div className={'detail-text'}>验收凭证:</div>
<div className={'detail-image'}>
{i.imgs?.map((i, j) => (
<Image key={j} className={'image'} src={i} alt='付款凭证' />
))}
{!i.imgs && <div style={{ height: '30px' }}></div>}
</div>
</div>
))}
</div>
);
}
};
export default DetailDelivery;
import { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { InterDataType } from '~/api/interface';
import { orderDetailType } from '~/api/interface/orderManageType';
import dayjs from 'dayjs';
// 表格数据类型
type TableType = any;
// 接口返回的类型
type DataType = InterDataType<orderDetailType>;
// 参数类型
type PropsType = {
detail: DataType;
};
function DetailInformation() {
const DetailInformation: React.FC<PropsType> = (props) => {
const { detail } = props;
// 表格数据
const [tableData] = useState<TableType>([{ id: 1 }]);
const [tableData, setTableData] = useState<TableType>([]);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '商品',
dataIndex: 'userName',
dataIndex: 'wareTitle',
align: 'center',
render: (_text, _record) => `--`,
},
{
title: '单价(元)',
dataIndex: 'userName',
dataIndex: 'unitPrice',
align: 'center',
render: (_text, _record) => `--`,
render: (text) => `¥${text.toLocaleString()}`,
},
{
title: '数量',
dataIndex: 'userName',
dataIndex: 'wareNum',
align: 'center',
render: (_text, _record) => `--`,
},
{
title: '订单状态',
dataIndex: 'userName',
dataIndex: 'waiting',
align: 'center',
render: (_text, _record) => `--`,
},
{
title: '收款',
dataIndex: 'userName',
title: '收款',
dataIndex: 'shouldPay',
align: 'center',
render: (_text, _record) => `--`,
render: (text) => `¥${text.toLocaleString()}`,
},
];
useEffect(() => {
if (!detail) return;
setTableData([
{
id: 1,
wareTitle: detail?.wareTitle,
unitPrice: detail?.unitPrice,
wareNum: detail?.wareNum,
waiting: detail?.waiting,
shouldPay: detail?.shouldPay,
},
]);
}, [detail]);
return (
<div className={'detail-information'}>
<div className={'detail-title'}>订单明细</div>
<div className={'detail-text'}>
<span className={'item'}>订单编号:UD202302181041156087</span>
<span className={'item'}>创建时间:2023-02-18 10:41:16</span>
<span className={'item'}>订单编号:{detail?.orderNo}</span>
<span className={'item'} style={{ display: 'none' }}>
合同编号:UAV202334741131
</span>
<span className={'item'}>
订单租期:
{dayjs(detail?.startDate).format('YYYY-MM-DD')}
{' ~ '}
{dayjs(detail?.endDate).format('YYYY-MM-DD')}
</span>
<span className={'item'}>创建时间:{detail?.createTime}</span>
</div>
<Table
style={{ margin: '20px auto', width: '90%' }}
......@@ -61,8 +87,11 @@ function DetailInformation() {
pagination={false}
// rowSelection={{ selectedRowKeys, onChange: onSelectChange }}
/>
<div className='detail-price'>
实收款<span className={'num'}>{detail?.actualPay}</span>
</div>
</div>
);
}
};
export default DetailInformation;
import React from 'react';
import React, { useEffect } from 'react';
import { Button, Image } from 'antd';
import { orderDetailType } from '~/api/interface/orderManageType';
import { InterDataType } from '~/api/interface';
import { OrderManageAPI } from '~/api';
// 接口返回的类型
type DataType = InterDataType<orderDetailType>;
......@@ -12,11 +13,31 @@ type PropsType = {
const DetailPurchaser: React.FC<PropsType> = (props) => {
const { detail } = props;
// 物流列表
const [expressList, setExpressList] = React.useState<{ label: string; value: string }[]>([]);
// 获取物流信息
const getListExpressInfo = async () => {
const res = await OrderManageAPI.listExpressInfo({});
if (res && res.code === '200') {
setExpressList(res.result.map((item) => ({ label: item.exName, value: item.exCode })));
// console.log(res);
}
};
// 转换物流信息
const getExpressInfo = (code: string | undefined | null) => {
return expressList.find((item) => item.value === code)?.label || code;
};
// componentDidMount
useEffect(() => {
getListExpressInfo().then();
}, []);
return (
<div className={'detail-purchaser detail-half'}>
<div className={'detail-title'}>买家信息</div>
<div className={'detail-text'}>UID: {detail?.uid}</div>
<div className={'detail-text'}>企业: 浙江科比特创新科技有限公司</div>
<div className={'detail-text'}>UID:{detail?.uid}</div>
<div className={'detail-text'}>姓名: {detail?.buyerName}</div>
<div className={'detail-text'}>手机号: {detail?.buyerPhone}</div>
{/*<div className={'detail-text'}>企业: 浙江科比特创新科技有限公司</div>*/}
<div className={'detail-text'}>备注: {detail?.remark}</div>
<div style={{ display: 'none' }}>
......@@ -61,6 +82,26 @@ const DetailPurchaser: React.FC<PropsType> = (props) => {
))}
</div>
</div>
<div className={'detail-title'}>发货信息</div>
<div className={'detail-text'}>收货人:{detail?.receipt?.takeName}</div>
<div className={'detail-text'}>手机号:{detail?.receipt?.takePhone}</div>
<div className={'detail-text'}>收货地址:{detail?.receipt?.detailAddress}</div>
<div className={'detail-text'}>物流单号:{detail?.receipt?.sendExNo}</div>
<div className={'detail-text'}>物流公司:{getExpressInfo(detail?.receipt?.sendExCode)}</div>
<div className={'detail-text'}>
物流进度:-- <Button type={'link'}>查看详情</Button>
</div>
<div className={'detail-title'}>归还信息</div>
<div className={'detail-text'}>收货人:{detail?.receipt?.renName}</div>
<div className={'detail-text'}>手机号:{detail?.receipt?.renPhone}</div>
<div className={'detail-text'}>收货地址:{detail?.receipt?.renAddress}</div>
<div className={'detail-text'}>物流单号:{detail?.receipt?.renExNo}</div>
<div className={'detail-text'}>物流公司:{getExpressInfo(detail?.receipt?.renExCode)}</div>
<div className={'detail-text'}>
物流进度:-- <Button type={'link'}>查看详情</Button>
</div>
</div>
);
};
......
......@@ -68,6 +68,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'),
......@@ -312,10 +313,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: '行业方案',
},
......@@ -324,7 +334,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;
}, {});
};
......@@ -11,7 +11,7 @@ export default defineConfig({
host: '0.0.0.0',
proxy: {
'/api': {
// target: 'http://192.168.3.111:8077',后端女
// target: 'http://192.168.3.111:8077', // 后端女oms
target: 'https://test.iuav.shop',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论