上架商品压缩图片功能添加

This commit is contained in:
ylj20011123 2025-12-19 16:40:40 +08:00
parent ee6fa92adc
commit 1f17ff805d
11 changed files with 461 additions and 208 deletions

View File

@ -1,6 +1,6 @@
{
"name": "ant-design-pro",
"version": "4.5.91",
"version": "4.5.92",
"private": true,
"description": "An out-of-box UI solution for enterprise applications",
"scripts": {

View File

@ -12,8 +12,8 @@ import { PlusOutlined } from "@ant-design/icons";
import { PageContainer } from "@ant-design/pro-layout";
import ProTable from "@ant-design/pro-table";
import ProDescriptions from "@ant-design/pro-descriptions";
import { Badge, Button, Drawer, Form, message, Switch, TreeSelect } from 'antd';
import { ModalForm, ProFormDigit, ProFormSelect, ProFormText, ProFormTextArea } from "@ant-design/pro-form";
import { Badge, Button, Drawer, Form, message, Switch, TreeSelect } from 'antd';
import { ModalForm, ProFormDigit, ProFormSelect, ProFormText, ProFormTextArea } from "@ant-design/pro-form";
import type { FormInstance } from 'antd';
import type { UserTypeModel } from "./data";
@ -57,7 +57,7 @@ const handleDelete = async (nodeId: number) => {
hide();
if (result.Result_Code !== 100) {
message.error(`${result.Result_Code }:${result.Result_Desc}`)
message.error(`${result.Result_Code}:${result.Result_Desc}`)
return false
}
message.success("删除成功!")
@ -93,14 +93,14 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
const [createModalVisible, handleModalVisible] = useState<boolean>(false); // 发布分类更新窗口的弹窗
const [userTypeTree, setUserTypeTree] = useState<[]>(); // 树结构数据分类 用于弹出编辑时选择上级
const [activeKey, setActiveKey] = useState<React.Key>(`${currentUser?.UserPattern===9000?'1000':currentUser?.UserPattern}`); // 树结构数据分类 用于弹出编辑时选择上级
const [activeKey, setActiveKey] = useState<React.Key>(`${currentUser?.UserPattern === 9000 ? '1000' : currentUser?.UserPattern}`); // 树结构数据分类 用于弹出编辑时选择上级
// 查询可选商家
const { data: merchantTree } = useRequest(async () => {
return await getMerchantTree({MerchantPid:currentUser?.BusinessManID||''})
return await getMerchantTree({ MerchantPid: currentUser?.BusinessManID || '' })
})
// 查询可选商家
const {loading: typeCountLoading,data: typeCount } = useRequest(getUserTypeCount)
const { loading: typeCountLoading, data: typeCount } = useRequest(getUserTypeCount)
// 表格数据配置 <UserTypeModel|SystemMenuModel>
const columns: ProColumns<UserTypeModel>[] = [
@ -134,7 +134,7 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
title: '所属业主',
dataIndex: 'USERTYPE_PROVINCE',
hideInSearch: true,
hideInTable: activeKey==='2000',
hideInTable: activeKey === '2000',
valueType: "select",
request: async () => {
const options = await getOnwer()
@ -145,7 +145,7 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
title: '所属商户',
dataIndex: 'USERTYPE_PROVINCE',
hideInSearch: true,
hideInTable: activeKey==='1000',
hideInTable: activeKey === '1000',
valueType: "treeSelect",
fieldProps: {
options: merchantTree
@ -210,17 +210,16 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
}}>
<ProTable<UserTypeModel>
rowKey="USERTYPE_ID"
actionRef={actionRef}
request={async (params) => {
console.log('params',params)
console.log('params', params)
const data = await getUserTypeList({ ...params })
setUserTypeTree(data)
return { data, success: true }
}}
search={false}
params={{ UserTypePattern: activeKey }}
params={{ UserTypePattern: activeKey, ShowStatus: true }}
columns={columns}
toolbar={{
actions: [
@ -236,29 +235,29 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
menu: {
type: 'tab',
activeKey,
items: currentUser?.UserPattern===9000 ? [
items: currentUser?.UserPattern === 9000 ? [
{
key: '1000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.OwnerUnitCount: '', activeKey === '1000')}</span>,
label: <span>{renderBadge(!typeCountLoading ? typeCount?.OwnerUnitCount : '', activeKey === '1000')}</span>,
},
{
key: '4000',
label: <span>{renderBadge(!typeCountLoading ?typeCount?.SupplierCount:'', activeKey === '4000')}</span>,
key: '4000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.SupplierCount : '', activeKey === '4000')}</span>,
},
{
key: '2000',
label: <span>{renderBadge(!typeCountLoading ?typeCount?.MerchantCount:'', activeKey === '2000')}</span>,
label: <span>{renderBadge(!typeCountLoading ? typeCount?.MerchantCount : '', activeKey === '2000')}</span>,
}
]:currentUser?.UserPattern===1000 ?[
] : currentUser?.UserPattern === 1000 ? [
{
key: '1000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.OwnerUnitCount: '', activeKey === '1000')}</span>,
key: '1000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.OwnerUnitCount : '', activeKey === '1000')}</span>,
},
{
key: '4000',
label: <span>{renderBadge(!typeCountLoading ?typeCount?.SupplierCount:'', activeKey === '4000')}</span>,
key: '4000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.SupplierCount : '', activeKey === '4000')}</span>,
},
]:[],
] : [],
onChange: (key) => {
setActiveKey(key as string);
},
@ -283,7 +282,7 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
currentRow ? {
...currentRow, USERTYPE_STATUS: !!currentRow.USERTYPE_STATUS,
USERTYPE_PID: currentRow.USERTYPE_PID !== -1 ? currentRow.USERTYPE_PID : ''
} : { USERTYPE_STATUS: 1,USERTYPE_PATTERN:activeKey },
} : { USERTYPE_STATUS: 1, USERTYPE_PATTERN: activeKey },
);
} else {
formRef.current?.resetFields();
@ -291,7 +290,7 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
}
}}
onFinish={async (value) => {
let newValue: any = { ...value , USERTYPE_PATTERN:activeKey}
let newValue: any = { ...value, USERTYPE_PATTERN: activeKey }
if (currentRow) { // 编辑数据
newValue = { ...currentRow, ...newValue }
}
@ -339,39 +338,39 @@ const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
>
</TreeSelect >
</Form.Item>
{activeKey === '1000' ||activeKey === '4000'
?<ProFormSelect
name="USERTYPE_PROVINCE"
label="业主单位"
placeholder="请选择业主单位"
rules={[
{
required: true,
message: '请选择业主单位',
},
]}
request={async () => {
const options = await getOnwer()
return options;
}}
fieldProps={{
fieldNames: {
title: 'label',
// key: "value"
},
{activeKey === '1000' || activeKey === '4000'
? <ProFormSelect
name="USERTYPE_PROVINCE"
label="业主单位"
placeholder="请选择业主单位"
rules={[
{
required: true,
message: '请选择业主单位',
},
]}
request={async () => {
const options = await getOnwer()
return options;
}}
fieldProps={{
fieldNames: {
title: 'label',
// key: "value"
},
}}
/>:''}
}}
/> : ''}
{activeKey === '2000' &&
<Form.Item
name="USERTYPE_PROVINCE"
label="所属商家"
// rules={[
// {
// required: true,
// message: '请选择所属商家',
// }
// ]}
// rules={[
// {
// required: true,
// message: '请选择所属商家',
// }
// ]}
>
<TreeSelect
treeData={merchantTree}

View File

@ -508,7 +508,8 @@ const HomepageAds: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
OWNERUNIT_ID: currentUser?.OwnerUnitId,
PROVINCE_CODE: "",
GOODSTYPE: 4000,
USERDEFINEDTYPE_STATE: 1
USERDEFINEDTYPE_STATE: 1,
SCANCODE_ORDER: 1
}
const data = await handlGetUSERDEFINEDTYPEList(req);
return data

View File

@ -474,7 +474,8 @@ const OrderCategoryManage: React.FC<{ currentUser: CurrentUser | undefined }> =
preserve={false}
initialValues={currentRow ? {
...currentRow,
PRESALE_TIME: currentRow?.PRESALE_TYPE ? [currentRow?.PRESALE_STARTTIME, currentRow?.PRESALE_ENDTIME] : ""
PRESALE_TIME: currentRow?.PRESALE_TYPE ? [currentRow?.PRESALE_STARTTIME, currentRow?.PRESALE_ENDTIME] : "",
USERDEFINEDTYPE_DATE: moment(currentRow?.USERDEFINEDTYPE_DATE).format('YYYY-MM-DD HH:mm:ss'),
} : {
USERDEFINEDTYPE_STATE: 1,
USERDEFINEDTYPE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),

View File

@ -50,10 +50,11 @@ const LeftSelectMallType = ({ setSelectedId, reload, actionRef, currentUser, wid
return USERDEFINEDTYPEList
} else {
const req = {
OWNERUNIT_ID: currentUser?.OwnerUnitId,
OWNERUNIT_ID: '911',
PROVINCE_CODE: "",
GOODSTYPE: 4000,
USERDEFINEDTYPE_STATE: 1
USERDEFINEDTYPE_STATE: 1,
SCANCODE_ORDER: 1
}
const data = await handlGetUSERDEFINEDTYPEList(req);
setTreeView(data)

View File

@ -5,18 +5,7 @@ import ProTable from '@ant-design/pro-table';
import { Button, Input, InputNumber, TreeSelect } from 'antd';
import type { ProColumns } from '@ant-design/pro-table';
// 定义表格数据类型
type TableDataType = {
id: string | number;
name?: string;
barcode?: string;
category?: string;
unit?: string;
specification?: string;
price?: number;
taxRate?: number;
taxCode?: string;
};
// 定义树形数据类型
type TreeDataType = {
@ -28,42 +17,31 @@ type TreeDataType = {
type DetailProps = {
leftTreeData?: TreeDataType[]
onRef?: any
comboCommodityDetail?: any // 查询到的套餐数据
};
const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
const SelectSetMealItems = ({ leftTreeData, onRef, comboCommodityDetail }: DetailProps) => {
// 判断用户是否点击了 添加套餐商品的按钮
const [isClickAdd, setIsClickAdd] = useState<boolean>(false);
const [isClickAdd, setIsClickAdd] = useState<boolean>(comboCommodityDetail && comboCommodityDetail.length > 0 ? true : false);
// 表格数据
const [tableData, setTableData] = useState<TableDataType[]>([
{
id: Date.now(),
name: '',
barcode: '',
category: '',
unit: '',
specification: '',
price: undefined,
taxRate: undefined,
taxCode: '',
}
]);
const [tableData, setTableData] = useState<any>(comboCommodityDetail && comboCommodityDetail.length > 0 ? comboCommodityDetail : []);
// 表格列定义
const columns: ProColumns<TableDataType>[] = [
const columns: any = [
{
title: '商品名称',
width: 250,
align: 'center',
dataIndex: 'name',
render: (_, record: TableDataType) => (
dataIndex: 'COMMODITY_NAME',
render: (_, record: any) => (
<Input
style={{ width: '100%' }}
value={record.name}
value={record.COMMODITY_NAME}
placeholder="请输入商品名称"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, name: e.target.value };
return { ...item, COMMODITY_NAME: e.target.value };
}
return item;
});
@ -76,16 +54,16 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
title: '条码',
width: 150,
align: 'center',
dataIndex: 'barcode',
render: (_, record: TableDataType) => (
dataIndex: 'COMMODITY_BARCODE',
render: (_, record: any) => (
<Input
style={{ width: '100%' }}
value={record.barcode}
value={record.COMMODITY_BARCODE}
placeholder="请输入商品条码"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, barcode: e.target.value };
return { ...item, COMMODITY_BARCODE: e.target.value };
}
return item;
});
@ -94,54 +72,54 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
/>
),
},
{
title: <div style={{ textAlign: 'center' }}></div>,
width: 250,
align: 'left',
dataIndex: 'category',
render: (_, record: TableDataType) => (
<TreeSelect
treeData={leftTreeData}
style={{ width: '100%' }}
placeholder="请选择商品分类"
value={record.category && record.category.length > 0 ? record.category : []}
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, category: e };
}
return item;
});
setTableData(newData);
}}
fieldNames={{
label: "USERDEFINEDTYPE_NAME",
value: "USERDEFINEDTYPE_ID",
children: "children"
}}
treeDefaultExpandAll
showSearch
allowClear
multiple
treeNodeFilterProp="USERDEFINEDTYPE_NAME"
placeholder="请输入商品分类"
/>
),
},
// {
// title: <div style={{ textAlign: 'center' }}>分类</div>,
// width: 250,
// align: 'left',
// dataIndex: 'USERDEFINEDTYPE_ID',
// render: (_, record: any) => (
// <TreeSelect
// treeData={leftTreeData}
// style={{ width: '100%' }}
// placeholder="请选择商品分类"
// value={record.USERDEFINEDTYPE_ID && record.USERDEFINEDTYPE_ID.length > 0 ? record.USERDEFINEDTYPE_ID : []}
// onChange={(e) => {
// const newData = tableData.map((item: any) => {
// if (item.id === record.id) {
// return { ...item, USERDEFINEDTYPE_ID: e };
// }
// return item;
// });
// setTableData(newData);
// }}
// fieldNames={{
// label: "USERDEFINEDTYPE_NAME",
// value: "USERDEFINEDTYPE_ID",
// children: "children"
// }}
// treeDefaultExpandAll
// showSearch
// allowClear
// multiple
// treeNodeFilterProp="USERDEFINEDTYPE_NAME"
// placeholder="请输入商品分类"
// />
// ),
// },
{
title: '单位',
width: 120,
align: 'center',
dataIndex: 'unit',
render: (_, record: TableDataType) => (
dataIndex: 'COMMODITY_UNIT',
render: (_, record: any) => (
<Input
style={{ width: '100%' }}
value={record.unit}
value={record.COMMODITY_UNIT}
placeholder="请输入商品单位"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, unit: e.target.value };
return { ...item, COMMODITY_UNIT: e.target.value };
}
return item;
});
@ -154,16 +132,16 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
title: '规格',
width: 120,
align: 'center',
dataIndex: 'specification',
render: (_, record: TableDataType) => (
dataIndex: 'COMMODITY_RULE',
render: (_, record: any) => (
<Input
style={{ width: '100%' }}
value={record.specification}
value={record.COMMODITY_RULE}
placeholder="请输入商品规格"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, specification: e.target.value };
return { ...item, COMMODITY_RULE: e.target.value };
}
return item;
});
@ -173,19 +151,19 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
),
},
{
title: '',
title: '市场价',
width: 120,
align: 'center',
dataIndex: 'price',
render: (_, record: TableDataType) => (
dataIndex: 'COMMODITY_RETAILPRICE',
render: (_, record: any) => (
<InputNumber
style={{ width: '100%' }}
value={record.price}
placeholder="请输入商品价格"
value={record.COMMODITY_RETAILPRICE}
placeholder="请输入市场价"
onChange={(value) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, price: value as number };
return { ...item, COMMODITY_RETAILPRICE: value as number };
}
return item;
});
@ -194,20 +172,65 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
/>
),
},
{
title: '零售价格',
width: 120,
align: 'center',
dataIndex: 'COMMODITY_MEMBERPRICE',
render: (_, record: any) => (
<InputNumber
style={{ width: '100%' }}
value={record.COMMODITY_MEMBERPRICE}
placeholder="请输入零售价格"
onChange={(value) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, COMMODITY_MEMBERPRICE: value as number };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '商品成本',
width: 120,
align: 'center',
dataIndex: 'COMMODITY_PURCHASEPRICE',
render: (_, record: any) => (
<InputNumber
style={{ width: '100%' }}
value={record.COMMODITY_PURCHASEPRICE}
placeholder="请输入商品成本"
onChange={(value) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, COMMODITY_PURCHASEPRICE: value as number };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '税率',
width: 120,
align: 'center',
dataIndex: 'taxRate',
render: (_, record: TableDataType) => (
dataIndex: 'DUTY_PARAGRAPH',
render: (_, record: any) => (
<InputNumber
style={{ width: '100%' }}
value={record.taxRate}
value={record.DUTY_PARAGRAPH}
placeholder="请输入商品税率"
onChange={(value) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, taxRate: value as number };
return { ...item, DUTY_PARAGRAPH: value as number };
}
return item;
});
@ -220,16 +243,16 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
title: '税务代码',
width: 120,
align: 'center',
dataIndex: 'taxCode',
render: (_, record: TableDataType) => (
dataIndex: 'TAX_CODE',
render: (_, record: any) => (
<Input
style={{ width: '100%' }}
value={record.taxCode}
value={record.TAX_CODE}
placeholder="请输入商品税务代码"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
const newData = tableData.map((item: any) => {
if (item.id === record.id) {
return { ...item, taxCode: e.target.value };
return { ...item, TAX_CODE: e.target.value };
}
return item;
});
@ -243,11 +266,11 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
align: 'center',
valueType: 'option',
width: 60,
render: (_, record: TableDataType) => [
render: (_, record: any) => [
<a
key="delete"
onClick={() => {
const newData = tableData.filter((item: TableDataType) => item.id !== record.id);
const newData = tableData.filter((item: any) => item.id !== record.id);
setTableData(newData);
}}
>
@ -282,14 +305,6 @@ const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
onClick={() => {
const newData = {
id: Date.now(),
name: '',
barcode: '',
category: '',
unit: '',
specification: '',
price: undefined,
taxRate: undefined,
taxCode: '',
};
setTableData([...tableData, newData]);
}}

View File

@ -24,9 +24,10 @@ import { getFieldEnumTree, getFieldEnumName } from "@/services/options"; // 枚
import { getList, delcommodity, updatecommodity } from './service'; // 接口相关对象的引用
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectMallType from './component/LeftSelectMallType';
import { handeDeleteCOMMODITY, handeDeleteRTCOMMODITY_MULTI, handeGetCOMMODITY_MULTIList, handeGetCOMMODITYDetail, handeGetCOMMODITYList, handeGetMERCHANTSList, handeGetRTCOMMODITY_MULTIList, handeSetCommodityState, handeSetGoodsDutyParagraph, handeSynchroCOMMODITY, handeSynchroRTCOMMODITYMULTIList, handleGetBRANDList, handlGetUSERDEFINEDTYPEList } from '../service';
import { handeDeleteCOMMODITY, handeDeleteRTCOMMODITY_MULTI, handeGetComboCommodityDetail, handeGetCOMMODITY_MULTIList, handeGetCOMMODITYDetail, handeGetCOMMODITYList, handeGetMERCHANTSList, handeGetRTCOMMODITY_MULTIList, handeSetCommodityState, handeSetGoodsDutyParagraph, handeSyncComboCommodity, handeSynchroCOMMODITY, handeSynchroRTCOMMODITYMULTIList, handleGetBRANDList, handlGetUSERDEFINEDTYPEList } from '../service';
import session from '@/utils/session';
import { deleteAHYDPicture, deletePicture, uploadAHYDPicture, uploadPicture } from '@/services/picture';
import { resizeImageHalf } from '@/utils/resizeImageHalf';
import { exportXlsxFromProColumnsExcelJS, formatTreeData, handleSetlogSave } from '@/utils/format';
import { highlightText } from '@/utils/highlightText';
import { handlecsyncWeChatGetMallGoodsInfo, handlecsyncWeChatGetMallGoodsInfoAll } from '@/pages/operatingMerchants/service';
@ -117,6 +118,8 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
const [rateLoading, setRateLoading] = useState<boolean>(false)
// 点开的商品详情信息
const [currentRowDetail, setCurrentRowDetail] = useState<any>()
// 套餐商品数据
const [comboCommodityDetail, setComboCommodityDetail] = useState<any>()
// 关联卡券的 悬浮框 显示
const [associatedCouponsModal, setAssociatedCouponsModal] = useState<boolean>(false)
// 关联卡券的选择列表
@ -738,6 +741,21 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
};
const handleAddUpdate = async (res: any, type?: string) => {
console.log('setSelectSetMealItemsRef', setSelectSetMealItemsRef.current)
console.log('resresresresresresresres', res)
let itemList = setSelectSetMealItemsRef.current.tableData
if (itemList && itemList.length > 0) {
itemList.forEach((item: any) => {
// item.USERDEFINEDTYPE_ID = item.USERDEFINEDTYPE_ID && item.USERDEFINEDTYPE_ID.length > 0 ? item.USERDEFINEDTYPE_ID.toString() : item.USERDEFINEDTYPE_ID
item.COMMODITY_TYPE = 4000
item.UPPER_STATE = 1
item.PROVINCE_CODE = currentUser?.ProvinceCode
item.COMMODITY_STATE = 1
item.OWNERUNIT_ID = currentUser?.OwnerUnitId
item.OWNERUNIT_NAME = currentUser?.OwnerUnitName
})
}
let req: any = {}
if (currentRow?.USERDEFINEDTYPE_ID && type !== 'saveAs') {
req = {
@ -788,11 +806,18 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
}
}
const data = await handeSynchroCOMMODITY(req)
handleConfirmLoading(false)
// 同步商品数据 因为添加了套餐数据 最方便的方法 就是在当前基础上 换接口 所以换入参
const newReq: any = {
commodityModel: req,
singleCommodityList: itemList && itemList.length > 0 ? itemList : ''
}
console.log('newReqnewReq', newReq);
// const data = await handeSynchroCOMMODITY(req)
const data = await handeSyncComboCommodity(newReq)
if (data.Result_Code === 100) {
await handleUploadShopImg(res, data.Result_Data)
await handleUploadShopImg(res, data.Result_Data?.commodityModel)
handleSetlogSave(`${currentRow?.USERDEFINEDTYPE_ID ? '更新' : '新增'}商品【${data.Result_Data?.COMMODITY_NAME}`)
@ -828,29 +853,45 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
session.set("USERDEFINEDTYPEList", data)
list = data
}
let resPid: any = ''
let resPid: any = []
if (list && list.length > 0) {
let obj: any = {}
list.forEach((item: any) => {
let childrenTypeList: any = []
if (item.children && item.children.length > 0) [
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
childrenTypeList.push(subItem.USERDEFINEDTYPE_ID)
})
]
}
obj[item.USERDEFINEDTYPE_ID] = childrenTypeList
})
// 可能存在多个大类的情况
let UserDefinedTypeIdsList = data.Result_Data?.commodityModel?.UserDefinedTypeIds.split(',')
for (let key in obj) {
if (obj[key].indexOf(Number(data.Result_Data?.USERDEFINEDTYPE_ID)) !== -1) {
resPid = key
if (UserDefinedTypeIdsList && UserDefinedTypeIdsList.length > 0) {
UserDefinedTypeIdsList.forEach((item: any) => {
if (obj[key].indexOf(Number(item)) !== -1) {
// resPid = key
resPid.push(key)
}
})
}
// if (obj[key].indexOf(Number(data.Result_Data?.commodityModel?.USERDEFINEDTYPE_ID)) !== -1) {
// resPid = key
// }
}
}
handlecsyncWeChatGetMallGoodsInfo({ appId: 'wxee018fb96955552a', userdefinedTypeId: resPid })
if (resPid && resPid.length > 0) {
for (let i = 0; i < resPid.length; i++) {
handlecsyncWeChatGetMallGoodsInfo({ appId: 'wxee018fb96955552a', userdefinedTypeId: resPid[i] })
}
}
handleConfirmLoading(false)
} else {
message.error(data.Result_Desc)
handleConfirmLoading(false)
}
};
@ -860,10 +901,28 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
// 主图
if (formRes.mainImgList && formRes.mainImgList.length > 0) {
const formData = new FormData();
formRes.mainImgList.forEach((file: any) => {
formData.append('files[]', file.originFileObj);
formData.append('ImageName', typeof file !== 'string' ? file?.name : '');
});
// 遍历文件列表,压缩后再上传
for (const file of formRes.mainImgList) {
// 跳过已经上传的文件(有 ImageId 的)
if (file.ImageId) {
continue;
}
// 获取原始文件
const originalFile = file.originFileObj || file;
try {
// 压缩图片
const compressedFile = await resizeImageHalf(originalFile);
// 使用压缩后的文件
formData.append('files[]', compressedFile);
formData.append('ImageName', compressedFile.name);
} catch (err) {
// 如果压缩失败,使用原图
formData.append('files[]', originalFile);
formData.append('ImageName', originalFile.name);
}
}
formData.append('TableId', shopData.COMMODITY_ID);
formData.append('imageType', "1000");
formData.append('TableType', "1207");
@ -874,10 +933,25 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
// 头部轮播图
if (formRes.headerImgList && formRes.headerImgList.length > 0) {
const formData = new FormData();
formRes.headerImgList.forEach((file: any) => {
formData.append('files[]', file.originFileObj);
formData.append('ImageName', typeof file !== 'string' ? file?.name : '');
});
// formRes.headerImgList.forEach((file: any) => {
// formData.append('files[]', file.originFileObj);
// formData.append('ImageName', typeof file !== 'string' ? file?.name : '');
// });
for (const file of formRes.headerImgList) {
// 跳过已经上传的文件(有 ImageId 的)
if (file.ImageId) {
continue;
}
// 获取原始文件
const originalFile = file.originFileObj || file;
// 压缩图片
const compressedFile = await resizeImageHalf(originalFile);
// 使用压缩后的文件
formData.append('files[]', compressedFile);
formData.append('ImageName', compressedFile.name);
}
formData.append('TableId', shopData.COMMODITY_ID);
formData.append('imageType', "2000");
formData.append('TableType', "1207");
@ -888,10 +962,24 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
// 头部轮播图
if (formRes.detailImgList && formRes.detailImgList.length > 0) {
const formData = new FormData();
formRes.detailImgList.forEach((file: any) => {
formData.append('files[]', file.originFileObj);
formData.append('ImageName', typeof file !== 'string' ? file?.name : '');
});
for (const file of formRes.detailImgList) {
// 跳过已经上传的文件(有 ImageId 的)
if (file.ImageId) {
continue;
}
// 获取原始文件
const originalFile = file.originFileObj || file;
// 压缩图片
const compressedFile = await resizeImageHalf(originalFile);
// 使用压缩后的文件
formData.append('files[]', compressedFile);
formData.append('ImageName', compressedFile.name);
}
// formRes.detailImgList.forEach((file: any) => {
// formData.append('files[]', file.originFileObj);
// formData.append('ImageName', typeof file !== 'string' ? file?.name : '');
// });
formData.append('TableId', shopData.COMMODITY_ID);
formData.append('imageType', "5000");
formData.append('TableType', "1207");
@ -1127,7 +1215,10 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
}}>excel</Button>
],
}}
pagination={{ defaultPageSize: 10 }}
pagination={{
defaultPageSize: 50,
pageSizeOptions: ['50', '100', '200', '500', '1000'],
}}
rowSelection={{
type: 'checkbox',
selectedRowKeys: selectShopRowKey,
@ -1233,6 +1324,7 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
</div>
<div>
<Button loading={confirmLoading} onClick={() => {
handleConfirmLoading(true)
let oldFormRes: any = {
COMMODITY_NAME: currentRow?.COMMODITY_NAME,
BRAND_ID: `${currentRow?.BRAND_NAME}-${currentRow?.BRAND_ID}`,
@ -1277,10 +1369,10 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
let newFormRes: any = formRef.current?.getFieldsValue(names)
if (isEqual(normalize(oldFormRes), normalize(newFormRes))) {
handleConfirmLoading(false)
message.error('与原商品一致,无法另存为!')
} else {
formRef?.current?.validateFields().then(async (newValue) => {
handleConfirmLoading(true)
await handleAddUpdate(newValue, 'saveAs');
})
// 如果有开关,要把开关的代码写进去
@ -1302,6 +1394,7 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
setHeaderImgList([])
setDetailImgList([])
setCurrentRowDetail(undefined)
setComboCommodityDetail([])
setRelevanceCouponList([])
setSelectRelevanceId([])
}}> </Button>
@ -1339,9 +1432,17 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
labelCol={{ style: { width: 80 } }}
preserve={false}
request={async () => {
console.log('currentRowcurrentRowcurrentRow', currentRow);
if (currentRow?.COMMODITY_ID) {
const data = await handeGetCOMMODITYDetail({ COMMODITYId: currentRow?.COMMODITY_ID })
// const data = await handeGetCOMMODITYDetail({ COMMODITYId: currentRow?.COMMODITY_ID })
const res: any = await handeGetComboCommodityDetail({ COMMODITYId: currentRow?.COMMODITY_ID })
console.log('商品详情', res);
let data: any = res.commodityModel
setCurrentRowDetail(data)
setComboCommodityDetail(res.singleCommodityList || [])
let mainImgList: any = []
let headerImgList: any = []
@ -1385,13 +1486,16 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
setHeaderImgList(headerImgList)
setDetailImgList(detailImgList)
console.log('dsadjmaskda', data.CouponIds ? data.CouponIds.split(',').map(Number) : []);
return {
...data,
USERDEFINEDTYPE_ID: data.UserDefinedTypeIds ? data.UserDefinedTypeIds.split(',').map(Number) : [],
BRAND_ID: `${data?.BRAND_NAME}-${data?.BRAND_ID}`,
MERCHANTS_ID: `${data?.MERCHANTS_NAME}-${data?.MERCHANTS_ID}`,
UPPER_DATE: data.UPPER_DATE && data.OFF_DATE ? [data.UPPER_DATE, data.OFF_DATE] : [],
relevanceCoupon: data.CouponIds.split(',').map(Number)
relevanceCoupon: data.CouponIds ? data.CouponIds.split(',').map(Number) : []
// mainImgList: mainImgList,
// headerImgList: headerImgList,
// detailImgList: detailImgList,
@ -1648,7 +1752,7 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
<Col span={24}>
<ProFormTextArea
name="COMMODITY_DESC"
label="商品简"
label="商品简"
/>
</Col>
@ -1889,14 +1993,6 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
handlePreview(1)
},
fileList: mainImgList, // 绑定 fileList
customRequest: ({ file, onSuccess }) => {
// 自定义上传,不实际发送请求
setTimeout(() => {
if (onSuccess) {
onSuccess({});
}
}, 0);
},
onChange: async (info: any) => {
if (info.file.status === 'removed') {
const index = mainImgList.findIndex(n => n.uid === info.file.uid);
@ -1906,7 +2002,6 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
async onOk() {
if (info.file.ImageId) {
const deleteLoading = message.loading('正在删除...')
// const success = await deletePicture(info.file?.ImagePath, info.file?.uid, '', '6000')
const success = await deleteAHYDPicture(info.file?.ImagePath, info.file?.uid, '', '6000')
deleteLoading()
@ -2059,7 +2154,7 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
{/* 若是一个套餐商品 那么这里就要有一个录入套餐商品的地方 */}
<Col span={24}>
<SelectSetMealItems onRef={setSelectSetMealItemsRef} leftTreeData={leftTreeData} />
<SelectSetMealItems onRef={setSelectSetMealItemsRef} leftTreeData={leftTreeData} comboCommodityDetail={comboCommodityDetail} />
</Col>
</Row>
</ProForm>

View File

@ -440,7 +440,10 @@ const SupplierClassification: React.FC<{ currentUser: CurrentUser | undefined }>
submitter={false}
labelCol={{ style: { width: 80 } }}
preserve={false}
initialValues={currentRow ? currentRow : {
initialValues={currentRow ? {
...currentRow,
OPERATE_DATE: moment(currentRow?.OPERATE_DATE).format('YYYY-MM-DD HH:mm:ss'),
} : {
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
OWNERUNIT_NAME: currentUser?.OwnerUnitName,
AUTOTYPE_VALID: 1

View File

@ -300,6 +300,33 @@ export async function handeSynchroCOMMODITY(params: any) {
return data
}
// 同步套餐商品数据
export async function handeSyncComboCommodity(params: any) {
// const data = await requestEncryption(`/MallBasic/SyncComboCommodity`, {
const data = await requestEncryption(`/MallBasic/SyncComboCommodity`, {
method: 'POST',
data: { ...params, requestEncryption: true }
})
if (data.Result_Code !== 100) {
return []
}
return data
}
// 同步套餐商品详情
export async function handeGetComboCommodityDetail(params: any) {
// const data = await requestEncryption(`/MallBasic/SyncComboCommodity`, {
const data = await requestEncryption(`/MallBasic/GetComboCommodityDetail`, {
method: 'POST',
data: { ...params, requestEncryption: true }
})
if (data.Result_Code !== 100) {
return []
}
return data.Result_Data
}
// 获取商品详情
export async function handeGetCOMMODITYDetail(params: any) {
const data = await requestEncryption(`/MallBasic/GetCOMMODITYDetail`, {

View File

@ -0,0 +1,111 @@
/**
*
*
*/
export interface ResizeHalfOptions {
quality?: number;
}
/**
*
* @param file
* @param options (0-10.8)
* @returns
*/
export const resizeImageHalf = (
file: File,
options: ResizeHalfOptions = {}
): Promise<File> => {
const {
quality = 0.8
} = options;
return new Promise((resolve, reject) => {
if (!file || !file.type.includes('image')) {
reject(new Error('无效的图片文件'));
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
resizeToHalfDimensions(img, file, quality, resolve, reject);
};
img.onerror = () => reject(new Error('图片加载失败'));
img.src = e.target?.result as string;
};
reader.onerror = () => reject(new Error('文件读取失败'));
reader.readAsDataURL(file);
});
};
/**
* -
*/
function resizeToHalfDimensions(
img: HTMLImageElement,
originalFile: File,
quality: number,
resolve: (file: File) => void,
reject: (error: Error) => void
) {
// 判断是否需要压缩:只有当长或宽任意一边大于500px时才压缩
if (img.width <= 500 && img.height <= 500) {
console.log(`图片尺寸 ${img.width}x${img.height} 不大于500px,无需压缩,返回原图`);
resolve(originalFile);
return;
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
reject(new Error('浏览器不支持Canvas'));
return;
}
// 计算减半后的尺寸
const halfWidth = Math.floor(img.width / 2);
const halfHeight = Math.floor(img.height / 2);
console.log(`原图尺寸: ${img.width}x${img.height}`);
console.log(`减半后尺寸: ${halfWidth}x${halfHeight}`);
// 设置canvas尺寸为原图的一半
canvas.width = halfWidth;
canvas.height = halfHeight;
// 在canvas上绘制缩小后的图片
// 使用平滑缩放算法以获得更好的图像质量
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(img, 0, 0, halfWidth, halfHeight);
// 将canvas转换为Blob并创建新的File对象
canvas.toBlob(
(blob) => {
if (!blob) {
reject(new Error('图片处理失败'));
return;
}
// 保持原始文件名不变,避免服务器端根据文件名做特殊处理
const newFileName = originalFile.name;
// 创建压缩后的文件对象
const resizedFile = new File([blob], newFileName, {
type: originalFile.type,
lastModified: Date.now()
});
console.log(`✅ 图片尺寸减半完成: ${img.width}x${img.height}${halfWidth}x${halfHeight}`);
console.log(`文件大小: ${(originalFile.size / 1024).toFixed(1)}KB → ${(resizedFile.size / 1024).toFixed(1)}KB`);
resolve(resizedFile);
},
originalFile.type,
quality
);
}

View File

@ -1,4 +1,4 @@
// 由 scripts/writeVersion.js 自动生成
export const VERSION = "4.5.91";
export const GIT_HASH = "24088d3";
export const BUILD_TIME = "2025-12-16T11:26:58.433Z";
export const VERSION = "4.5.92";
export const GIT_HASH = "ee6fa92";
export const BUILD_TIME = "2025-12-19T01:04:57.460Z";