Explorar el Código

后厨商品导入导出修改及商品分类修改20240815

kitchenmanage
gwbvipvip hace 2 meses
padre
commit
334b1a6b10
Se han modificado 31 ficheros con 851 adiciones y 439 borrados
  1. +8
    -1
      config/routes.js
  2. +1
    -1
      src/app.jsx
  3. +2
    -2
      src/pages/database/goods/goodsInfo/index.jsx
  4. +2
    -2
      src/pages/database/goods/goodsattribute/components/CreateForm.jsx
  5. +1
    -1
      src/pages/database/goods/goodsattribute/index.jsx
  6. +1
    -1
      src/pages/database/goods/goodsattributeprice/index.jsx
  7. +1
    -1
      src/pages/database/goods/goodsbom/components/CreateBom.jsx
  8. +51
    -0
      src/pages/database/goods/goodsclassify/components/CreateForm.jsx
  9. +329
    -0
      src/pages/database/goods/goodsclassify/index.jsx
  10. +41
    -0
      src/pages/database/goods/goodsclassify/service.js
  11. +1
    -1
      src/pages/database/goods/goodstechnology/components/From.jsx
  12. +2
    -2
      src/pages/database/goods/goodstechnology/components/goodstechnologymaken.jsx
  13. +1
    -1
      src/pages/database/goods/goodstypemanage/components/CreateAttribute.jsx
  14. +1
    -1
      src/pages/database/goods/goodstypemanage/components/CreateForm.jsx
  15. +4
    -4
      src/pages/database/goods/goodstypemanage/service.js
  16. +56
    -0
      src/pages/database/goods/newgoods/components/ChooseForm.jsx
  17. +10
    -12
      src/pages/database/goods/newgoods/components/CreateForm.jsx
  18. +186
    -374
      src/pages/database/goods/newgoods/index.jsx
  19. +15
    -2
      src/pages/database/goods/newgoods/service.js
  20. +11
    -11
      src/pages/device/deviceInfo/index.jsx
  21. +6
    -3
      src/pages/device/deviceVesion/components/CreateForm.jsx
  22. +8
    -2
      src/pages/device/deviceVesion/index.jsx
  23. +1
    -1
      src/pages/device/productmanage/index.jsx
  24. +38
    -0
      src/pages/device/technology/components/CreateRemarkForm.jsx
  25. +59
    -9
      src/pages/device/technology/index.jsx
  26. +6
    -0
      src/pages/device/technology/services.js
  27. +5
    -3
      src/pages/device/warehousepostion/components/CreateForm.jsx
  28. +1
    -1
      src/pages/order/orderflow/service.js
  29. +1
    -1
      src/pages/push/goodspush/components/PushFrom.jsx
  30. +1
    -1
      src/pages/push/technologypush/components/PushFrom.jsx
  31. +1
    -1
      src/pages/scene/foodmenu/components/FoodMenuGoods.jsx

+ 8
- 1
config/routes.js Ver fichero

@@ -131,7 +131,14 @@ export default [
path: '/database',
routes: [
{
name: '商品类型',
name: '商品分类',
icon: 'smile',
path: '/database/goods/goodsclassify',
component: './database/goods/goodsclassify',
access: 'k7',
},
{
name: '工艺分类',
icon: 'smile',
path: '/database/goods/goodstypemanage',
component: './database/goods/goodstypemanage',


+ 1
- 1
src/app.jsx Ver fichero

@@ -230,7 +230,7 @@ export async function getInitialState() {
routes:[
{
code: 'goods-type',
name: '商品类型',
name: '工艺分类',
icon: 'smile',
path: '/database/goods/goodstypemanage',
component: './database/goods/goodstypemanage',


+ 2
- 2
src/pages/database/goods/goodsInfo/index.jsx Ver fichero

@@ -237,7 +237,7 @@ const Advanced = (props) => {
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item name="goodsTypeId" label="商品分类" rules={[{ required: true }]}>
<Form.Item name="goodsTypeId" label="工艺分类" rules={[{ required: true }]}>
<TreeSelect
allowClear
showSearch
@@ -247,7 +247,7 @@ const Advanced = (props) => {
onChange={onChange}
filterTreeNode={filterOption}
value={goodsTypeIdvalue}
placeholder="请选择商品类型"
placeholder="请选择工艺分类"
treeDefaultExpandAll
/>


+ 2
- 2
src/pages/database/goods/goodsattribute/components/CreateForm.jsx Ver fichero

@@ -74,7 +74,7 @@ const headleOk=()=>{
<Input />
</Form.Item>

{/* <Form.Item name="goodsTypeId" label="商品类型" rules={[{ required: true }]}>
{/* <Form.Item name="goodsTypeId" label="工艺分类" rules={[{ required: true }]}>
<TreeSelect
allowClear
showSearch
@@ -84,7 +84,7 @@ const headleOk=()=>{
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={props.treeDatas}
placeholder="请选择商品类型"
placeholder="请选择工艺分类"
treeDefaultExpandAll
/>
</Form.Item> */}


+ 1
- 1
src/pages/database/goods/goodsattribute/index.jsx Ver fichero

@@ -143,7 +143,7 @@ const handleUpdate = async (fields) => {
},

// {
// title: '商品类型',
// title: '工艺分类',
// dataIndex: 'goodsTypeName',
// valueType: 'treeSelect',
// fieldProps: {


+ 1
- 1
src/pages/database/goods/goodsattributeprice/index.jsx Ver fichero

@@ -232,7 +232,7 @@ const onresetsubmit=()=>{
<Card>
<span><span style={{color:'red',marginRight: 3}}>*</span>商品属性</span>
{
goodsAttriburteData==undefined || goodsAttriburteData.length ==0 ? ( <div style={{fontSize: '12px',marginLeft:10}}>当前商品分类还未配置属性点击跳转 <a
goodsAttriburteData==undefined || goodsAttriburteData.length ==0 ? ( <div style={{fontSize: '12px',marginLeft:10}}>当前商品的工艺分类还未配置属性点击跳转 <a
key="primary"
type="primary"
onClick={() => {


+ 1
- 1
src/pages/database/goods/goodsbom/components/CreateBom.jsx Ver fichero

@@ -244,7 +244,7 @@ const GoodsbomFrom = (props) => {
>
<span><span style={{color:'red',marginRight: 3}}>*</span>商品属性</span>
{
props.goodsAttriburteData == undefined || props.goodsAttriburteData.length==0 ? ( <div style={{fontSize: '12px',marginLeft:10}}>当前商品分类还未配置属性点击跳转 <a
props.goodsAttriburteData == undefined || props.goodsAttriburteData.length==0 ? ( <div style={{fontSize: '12px',marginLeft:10}}>当前商品的工艺分类还未配置属性点击跳转 <a
key="primary"
type="primary"
onClick={() => {


+ 51
- 0
src/pages/database/goods/goodsclassify/components/CreateForm.jsx Ver fichero

@@ -0,0 +1,51 @@
import React from 'react';
import { Modal, Form, Input, Button, InputNumber } from 'antd';

const CreateForm = (props) => {

return (
<Modal
title={props.values.id ? '编辑' : '新建'}
width={640}
visible={props.goodsClassifyVisible}
bodyStyle={{ padding: '32px 40px 1px 48px' }}
footer={null}
onCancel={() => {
props.onCancel();
}}
maskClosable={false}
destroyOnClose={true}
>
<Form
labelCol={{ span: 4 }}
layout="horizontal"
preserve={false}
initialValues={props.values}
onFinish={props.onFinish}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item name="name" label="分类名称" rules={[{ required: true, max: 50 }]}>
<Input />
</Form.Item>
<Form.Item name="remark" label="备注" >
<Input />
</Form.Item>
<Form.Item name="sort" label="排序" >
<InputNumber />
</Form.Item>
<Form.Item>
<Button htmlType="button" style={{ float: 'right', left: 10 }} onClick={props.onCancel} >
取消
</Button>
<Button type="primary" htmlType="submit" style={{ float: 'right' }} >
保存
</Button>
</Form.Item>
</Form>
</Modal>
);
};

export default CreateForm;

+ 329
- 0
src/pages/database/goods/goodsclassify/index.jsx Ver fichero

@@ -0,0 +1,329 @@
import { Button, message, Popconfirm, Modal, Transfer } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import CreateForm from './components/CreateForm';
import React, { useState, useRef, useEffect } from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import { getGoodsClassifyPage, updateGoodsClassify, deleteGoodsClassify, getgoodslist, getRelation, setRelation } from './service';

const GoodsClassify = () => {
const [goodsClassifyVisible, setGoodsClassifyVisible] = useState(false);
const actionRef = useRef();
const [currentRow, setCurrentRow] = useState();
const [selectedRowsState, setSelectedRows] = useState([]);
const [targetKeys, setTargetKeys] = useState([]);
const [isModalOpen, setIsModalOpen] = useState(false);
const [mockData, setMockData] = useState([]);
const [classifyId, setClassifyId] = useState([]);
useEffect(() => {
getgoodslist().then((item) => {
var data = item.data;
const tempMockData = [];
data.forEach((item) => {
tempMockData.push({
key: item.id,
title: item.name,
description: item.name,
});
})
setMockData(tempMockData);
});
}, []);
/**
* 添加节点
*
* @param fields
*/
const handleAdd = async (fields) => {
const hide = message.loading('正在添加');
try {
await updateGoodsClassify(JSON.stringify(fields)).then((r) => {
if (r.succeeded) {
message.success('添加成功');
} else {
message.error(r.errors);
}
});
hide();
return true;
} catch (error) {
hide();
message.error('添加失败请重试!');
return false;
}
};

/**
* 更新节点去
*
* @param fields
*/
const handleUpdate = async (fields) => {
const hide = message.loading('正在修改');
try {
await updateGoodsClassify(JSON.stringify(fields)).then((r) => {
if (r.succeeded) {
message.success('修改成功');
} else {
message.error(r.errors);
}
});
hide();
return true;
} catch (error) {
hide();
message.error('修改失败请重试!');
return false;
}
};
const BatchDeletion = () => {
return (
selectedRowsState?.length > 0 &&
(
<Popconfirm
title="确认删除吗?"
onConfirm={onClickdele}
okText="确定"
cancelText="取消"
>
<Button type="primary">批量删除</Button>
</Popconfirm>
))
}
const onClickdele = () => {
handleRemove(selectedRowsState);
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}
/**
* 批量删除
*
* @param selectedRows
*/
const handleRemove = async (selectedRows) => {
if (!selectedRows) return true;
await deleteGoodsClassify(selectedRows.map((row) => row.id)).then((r) => {
if (r.succeeded) {
message.success('删除成功');
actionRef.current.reload();
} else {
message.error(r.errors);
}
});
return true;
};

const editGoodsClassify = async () => {
const tempMockData = [];
targetKeys.forEach(function (item, index, array) {
tempMockData.push({
"goodsId": item
});
})
var data = {
"classifyId": classifyId,
"goodsIdList": tempMockData
}
setRelation(data).then((r) => {
console.log(r);
if (r.succeeded) {
message.success('编辑成功');
} else {
message.error(r.errors)
}
});
setIsModalOpen(false);
actionRef.current.reload();
};

const getGoodsList = async (classifyId) => {
var list = [];
getRelation(classifyId).then((item) => {
item.data.forEach(function (item) {
list.push(item.goodsId);
})
setTargetKeys(list);
});
};

const handleChange = (newTargetKeys) => {
setTargetKeys(newTargetKeys);
};

const columns = [
{
title: '主键',
dataIndex: 'id',
hideInSearch: true,
hideInTable: true,
tip: '规则名称是唯一的 key',
render: (dom, entity) => {
return (
<a
onClick={() => {
setCurrentRow(entity);
}}
>
{dom}
</a>
);
},
},
{
title: '名称',
dataIndex: 'name',
valueType: 'textarea',
ellipsis: true,
},

{
title: '备注',
dataIndex: 'remark',
ellipsis: true,
hideInForm: true,
hideInSearch: true,
},
{
title: '排序',
dataIndex: 'sort',
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="config"
onClick={() => {
setGoodsClassifyVisible(true);
setCurrentRow(record);
}}
>
更新
</a>,
<Popconfirm
type="primary"
key="primary"
title="确认删除吗?"
okText="是"
cancelText="否"
onConfirm={async () => {
await deleteGoodsClassify(record.id).then((r) => {
if (r.succeeded) {
message.success('删除成功');
actionRef.current.reload();
} else {
message.error(r.errors);
}
});
}}
onCancel={() => { }}
>
<a href="#">删除</a>
</Popconfirm>,
<a
key="edit"
onClick={() => {
getGoodsList(record.id);
setClassifyId(record.id);
setIsModalOpen(true);
}}
>
设置设备商品
</a>,
],
},
];

return (
<PageContainer host header={{
title: '',
breadcrumb: {},
}}>
<ProTable
headerTitle=""
actionRef={actionRef}
rowKey="id"
pagination={{ defaultPageSize: 10 }}
search={{
labelWidth: 120,
}}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
setGoodsClassifyVisible(true);
}}
>
<PlusOutlined /> 新建
</Button>,
<BatchDeletion />
]}
request={async (params) => {
var goodsClassifyData = [];
var total = 0;
await getGoodsClassifyPage(params).then((r) => {
goodsClassifyData = r.data.data;
total = r.data.total;
});
return {
data: goodsClassifyData,
success: true,
total: total
};
}}
columns={columns}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
}
}}
/>
<CreateForm
key={Date.now()}
onFinish={async (value) => {
var success = false;
if (value.id) {
success = await handleUpdate(value);
} else {
success = await handleAdd(value);
}
if (success) {
setGoodsClassifyVisible(false);
setCurrentRow(undefined);
actionRef.current.reload();
}
}}
onCancel={() => {
setGoodsClassifyVisible(false);
setCurrentRow(undefined);
}}
goodsClassifyVisible={goodsClassifyVisible}
values={currentRow || {}}
/>
<Modal
width={600}
title="编辑设备商品"
open={isModalOpen}
destroyOnClose
onOk={() => { editGoodsClassify() }}
onCancel={() => { setIsModalOpen(false) }}>
<Transfer
className="tree-transfer"
listStyle={{
width: 250,
height: 300,
}}
dataSource={mockData}
targetKeys={targetKeys}
onChange={handleChange}
onSearch={() => { }}
render={(item) => item.title}
/>
</Modal>
</PageContainer>
);
}
export default GoodsClassify;

+ 41
- 0
src/pages/database/goods/goodsclassify/service.js Ver fichero

@@ -0,0 +1,41 @@
import { request } from 'umi';
import { getDataBaseUrl } from '@/global_data';

export async function getGoodsClassifyPage(data) {
return request(getDataBaseUrl() + `/api/goodsClassify/getGoodsClassifyPage`, {
method: 'POST',
data: data
});
}

export async function updateGoodsClassify(data) {
return request(getDataBaseUrl() + `/api/goodsClassify/updateGoodsClassify`, {
method: 'POST',
data: data
});
}

export async function deleteGoodsClassify(data) {
return request(getDataBaseUrl() + `/api/goodsClassify/deleteGoodsClassify?ids=${data}`, {
method: 'Get'
});
}

export async function getgoodslist() {
return request(getDataBaseUrl() + `/api/goods/getgoodslist`, {
method: 'Get',
});
}

export async function getRelation(classifyId) {
return request(getDataBaseUrl() + `/api/goodsClassify/getRelation?classifyId=${classifyId}`, {
method: 'Get',
});
}

export async function setRelation(data) {
return request(getDataBaseUrl() + `/api/goodsClassify/setRelation`, {
method: 'POST',
data: data
});
}

+ 1
- 1
src/pages/database/goods/goodstechnology/components/From.jsx Ver fichero

@@ -81,7 +81,7 @@ const From = (props) => {
{
props.propsdata.length > 0 ?
props.propsdata.map((x, index) => {
let value=props.optiondata.find(p=>p.id==x.technologyactionId && p.actionName==x.actionName).actionValue;
let value=props.optiondata.find(p=>p.id==x.technologyactionId && p.actionName==x.actionName)?.actionValue;
if (x.actionType == "text") {
return <>
<div style={{width:'100%',height: '40px'}}>


+ 2
- 2
src/pages/database/goods/goodstechnology/components/goodstechnologymaken.jsx Ver fichero

@@ -116,7 +116,7 @@ const goodstechnologymaken = (props) => {
// {key:'1',label:'',children:(<div><img style={{width:100,height:100}} src={res.data.imgUrl}></img></div>)},
{ key: '1', label: '商品名称', children: res.data.name },
{ key: '2', label: '商品价格', children: res.data.price },
{ key: '3', label: '商品类型', children: res.data.goodsTypeName },
{ key: '3', label: '工艺分类', children: res.data.goodsTypeName },
{ key: '4', label: '商品单位', children: res.data.goodsUintName },
]
setItems(it)
@@ -618,7 +618,7 @@ const goodstechnologymaken = (props) => {
<Card bodyStyle={{ padding: 15 }} >
<div style={{ fontSize: 16, marginBottom: 5, color: '#1890ff', fontWeight: 600 }}>商品属性</div>
{
goodsinfo.goodsAttributeList == undefined || goodsinfo.goodsAttributeList == "" ? (<div style={{ fontSize: '12px', marginLeft: 10 }}>当前商品分类还未配置属性点击跳转 <a
goodsinfo.goodsAttributeList == undefined || goodsinfo.goodsAttributeList == "" ? (<div style={{ fontSize: '12px', marginLeft: 10 }}>当前商品的工艺分类还未配置属性点击跳转 <a
key="primary"
type="primary"
onClick={() => {


+ 1
- 1
src/pages/database/goods/goodstypemanage/components/CreateAttribute.jsx Ver fichero

@@ -136,7 +136,7 @@ const handleUpdate = async (fields) => {
},

// {
// title: '商品类型',
// title: '工艺分类',
// dataIndex: 'goodsTypeName',
// valueType: 'treeSelect',
// fieldProps: {


+ 1
- 1
src/pages/database/goods/goodstypemanage/components/CreateForm.jsx Ver fichero

@@ -38,7 +38,7 @@ const CreateForm = (props) => {
treeDefaultExpandAll
/>
</Form.Item>
<Form.Item name="name" label="类名称" rules={[{ required: true,max:50 }]}>
<Form.Item name="name" label="类名称" rules={[{ required: true,max:50 }]}>
<Input />
</Form.Item>


+ 4
- 4
src/pages/database/goods/goodstypemanage/service.js Ver fichero

@@ -3,7 +3,7 @@
/* eslint-disable */
import { request } from 'umi';
import { getDataBaseUrl } from '@/global_data';
/** 获取商品类型 sdsa GET /kitchen/api/rule */
/** 获取工艺分类 sdsa GET /kitchen/api/rule */
export async function goodsType(data) {
return request(getDataBaseUrl()+`/api/goodstype/page`, {
method: 'POST',
@@ -12,7 +12,7 @@ export async function goodsType(data) {
// ...(options || {}),
});
}
/** 新建商品类型 POST /kitchen/api/rule */
/** 新建工艺分类 POST /kitchen/api/rule */
export async function GetDicList(TypeCode) {
return request(getDataBaseUrl()+`/api/dict-data/dic-list/${TypeCode}`, {
method: 'Get',
@@ -29,7 +29,7 @@ export async function addGoodsType(data) {
});
}

/** 更新商品类型 PUT /kitchen/api/rule */
/** 更新工艺分类 PUT /kitchen/api/rule */

export async function updateGoodsType(data) {
return request(getDataBaseUrl()+'/api/goodstype/update', {
@@ -39,7 +39,7 @@ export async function updateGoodsType(data) {
});
}

/** 删除商品类型 DELETE /kitchen/api/rule */
/** 删除工艺分类 DELETE /kitchen/api/rule */

export async function DeleteGoodsType(data) {
return request(getDataBaseUrl()+`/api/goodstype/delete?id=${data}`, {


+ 56
- 0
src/pages/database/goods/newgoods/components/ChooseForm.jsx Ver fichero

@@ -0,0 +1,56 @@
import React, { useRef, useState, useEffect } from 'react';
import { message, Modal, Form, Input, Button, Upload, Select, InputNumber, TreeSelect, Switch, Divider, Space } from 'antd';
import { } from '../service';

const ChooseForm = (props) => {
const inputRef = useRef();

return (
<Modal
title='以下商品重复,请选择覆盖或跳过'
width={500}
visible={props.showChooseForm}
onCancel={props.onCancel}
footer={null}
maskClosable={false}
destroyOnClose
>
<Form
layout="inline"
preserve={false}
form={props.form}
onFinish={props.onFinish}
>
{Array.isArray(props.values) && props.values.map((t, index) => (
<div key={index} style={{ marginBottom: '10px', clear: 'both' }}>
<div style={{ float: 'left', marginRight: '10px' }}>
<Form.Item name={t.goodsName} label="商品名称">
<span>{t.goodsName}</span>
</Form.Item>
</div>
<div style={{ float: 'left' }}>
<Form.Item
name={t.goodsName}
label="覆盖或跳过"
valuePropName="checked"
>
<Switch checkedChildren="覆盖" unCheckedChildren="跳过" defaultChecked={false} />
</Form.Item>
</div>
</div>
))}
<Form.Item style={{ textAlign: 'right', marginTop: '10px', float: 'right', width: '100%' }}>
<Button htmlType="button" style={{ marginRight: '10px' }} onClick={props.onCancel}>
取消
</Button>
<Button type="primary" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
</Modal>
);
};


export default ChooseForm;

+ 10
- 12
src/pages/database/goods/newgoods/components/CreateForm.jsx Ver fichero

@@ -9,17 +9,14 @@ const CreateForm = (props) => {
const [goodsTypeIdvalue, setgoodsTypeIdvalue] = useState();
const inputRef = useRef();
const [unitname, setunitname] = useState('');
const [url, setUrl] = useState(props.values ? props.values.imgUrl : null);
const [url, setUrl] = useState(null);
const [hovered, setHovered] = useState(false);
const [imageError, setImageError] = useState(false);
useEffect(() => {
initGoodsUnit();
initGoodsType();
if (props.values) {
setUrl(props.values.imgUrl);
} else {
setUrl(null);
}
props.form.setFieldsValue(props.values);
setUrl(props.values.imgUrl);
}, [props.values])
function initGoodsUnit() {
unitList().then((r) => {
@@ -29,7 +26,6 @@ const CreateForm = (props) => {
list.push({ text: item.name, value: item.id, label: item.name });
});
}
console.log("list", list)
setGoodsUnit(list);
});
}
@@ -94,8 +90,10 @@ const CreateForm = (props) => {
}
};
const handleDeleteImage = () => {
props.values.imgUrl = null;
setUrl(null);
};
props.form.setFieldsValue({ imgUrl: props.values.imgUrl });
};
const handleImageError = () => {
setImageError(true);
};
@@ -116,12 +114,12 @@ const CreateForm = (props) => {
labelCol={{ span: 4 }}
layout="horizontal"
preserve={false}
initialValues={props.values}
form={props.form}
onFinish={props.onFinish}>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item name="goodsTypeId" label="商品分类" rules={[{ required: true }]}>
<Form.Item name="goodsTypeId" label="工艺分类" rules={[{ required: true }]}>
<TreeSelect
allowClear
showSearch
@@ -131,7 +129,7 @@ const CreateForm = (props) => {
onChange={onChange}
filterTreeNode={filterOption}
value={goodsTypeIdvalue}
placeholder="请选择商品类型"
placeholder="请选择工艺分类"
treeDefaultExpandAll
/>
</Form.Item>
@@ -169,7 +167,7 @@ const CreateForm = (props) => {
)}
/>
</Form.Item>
<Form.Item name="price" label="商品价格" rules={[{ required: true }]}>
<Form.Item name="price" label="商品价格">
<InputNumber style={{ width: '100%' }} placeholder="价格" min={0} />
</Form.Item>
<Form.Item name="isWeigh" label="是否称重" valuePropName="checked" >


+ 186
- 374
src/pages/database/goods/newgoods/index.jsx Ver fichero

@@ -1,14 +1,15 @@
import { PlusOutlined, UploadOutlined, QuestionCircleOutlined, DownloadOutlined } from '@ant-design/icons';
import { Button, message, Input, Drawer, Popconfirm, Upload, Spin, Tooltip, Modal, Select } from 'antd';
import { Button, message, Input, Drawer, Popconfirm, Upload, Spin, Tooltip, Modal, Select, Form } from 'antd';
import React, { useState, useRef, useEffect } from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import ProDescriptions from '@ant-design/pro-descriptions';
import { history } from 'umi';
import CreateForm from './components/CreateForm';
import ChooseForm from './components/ChooseForm';
import { getDataBaseUrl } from '@/global_data';
import { gettree, goods, removeGoods, addGoods, updateGoods, GetDeviceTechnology, TechnologyTemplateExport, GoodsTechnologyExport, GetgoodsWithIds, Getgoodslist, GoodsSimpleExport } from './service';
import { getdevicegoods } from '../../../device/deviceInfo/services'
import { gettree, goods, removeGoods, addGoods, updateGoods, GetDeviceTechnology, GetgoodsWithIds, Getgoodslist, GoodsExport } from './service';
import axios from 'axios';

const aliyunHostUrl = 'https://bpa.oss-cn-chengdu.aliyuncs.com/hkerp/test/goods/';

@@ -17,29 +18,30 @@ const GoodsManage = () => {
/** 新建/更新窗口的弹窗 */
const [createModalVisible, handleModalVisible] = useState(false);
/** 分布更新窗口的弹窗 */
const [form] = Form.useForm();
const [showDetail, setShowDetail] = useState(false);
//表单
const myformRef = useRef();
//列表
const actionRef = useRef();
const [currentRow, setCurrentRow] = useState();
const [selectedRowsState, setSelectedRows] = useState([]);
const [treeData, setTreeData] = useState();
const [treeData, setTreeData] = useState([]);
const [loading, setLoading] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [deviceData, setDeviceData] = useState([]);
const [goodData, setGoodData] = useState([]);
const [deviceGoodData, setDeviceGoodData] = useState([]);
const [deviceId, setDeviceId] = useState('');
const [deviceName, setDeviceName] = useState('');
const [goodsId, setGoodsId] = useState([]);
const [isDataModalOpen, setIsDataModalOpen] = useState(false);
const [ids, setIds] =useState('');
const [importFile, setImportFile] = useState();
const [showChooseForm, setShowChooseForm] = useState(false);
const [chooseFormData, setChooseFormData] = useState([]);
/** 国际化配置 */
useEffect(() => {
gettree().then((r) => {
setTreeData(r.data);
});

initGetDeviceTechnology();
initGetgoodslist();
}, []);

const initGetDeviceTechnology = () =>{
@@ -57,46 +59,6 @@ const GoodsManage = () => {
}
});
}
const initGetgoodslist = () =>{
Getgoodslist().then((r)=>{
var arr = r.data;
if (r.succeeded) {
var list = [];
arr.forEach((item) => {
list.push({
value: item.id,
label: item.name
});
});
setGoodData(list);
}
});
}
const initGetdevicegoodsList = async (deviceId) => {
getdevicegoods(deviceId).then((r) => {
var arr = r.data;
if (r.succeeded) {
var idList = [];
arr.forEach((item) => {
idList.push(item.goodsId);
});
setIds(idList);
GetgoodsWithIds(idList).then((t) => {
var a = t.data;
if (t.succeeded) {
var list = [];
a.forEach((i) => {
list.push({
value: i.id,
label: i.name
})
})
setDeviceGoodData(list);
}
})
}
});
};

/**
* 添加节点
@@ -104,7 +66,7 @@ const GoodsManage = () => {
* @param fields
*/
const handleAdd = async (fields) => {
fields.createBy = 'admin';
fields.price = fields.price ? fields.price : 0;
fields.isAttrubute = true;
fields.ImgUrl = fields.imgUrl1 ? aliyunHostUrl + fields.imgUrl1.file.name : null;
await addGoods(JSON.stringify(fields)).then((r) => {
@@ -130,10 +92,10 @@ const GoodsManage = () => {
goodsTypeId: fields.goodsTypeId,
name: fields.name,
goodsUintId: fields.goodsUintId,
price: fields.price,
price: fields.price ? fields.price : 0,
isWeigh: fields.isWeigh,
descritption: fields.descritption,
imgUrl: fields.imgUrl1 ? aliyunHostUrl + fields.imgUrl1.file.name : null
imgUrl: fields.imgUrl1 ? aliyunHostUrl + fields.imgUrl1.file.name : fields.imgUrl
}).then((r) => {
if (r.succeeded) {
message.success('修改成功');
@@ -208,15 +170,36 @@ const GoodsManage = () => {
renderText: (val) => `${val}¥`,
hideInSearch: true,
},
{
title: '商品类型',
title: '设备',
dataIndex: 'deviceId',
valueType: 'treeSelect',
hideInTable: true,
fieldProps: {
showSearch:true,
allowClear:true,
options: deviceData,
treeNodeFilterProp: 'label',
onChange: (val, row) => {
setDeviceId(val)
setDeviceName(row[0])
myformRef.current.submit()
}
},
},
{
title: '工艺分类',
dataIndex: 'goodsTypeName',
valueType: 'treeSelect',
fieldProps: {
showSearch:true,
allowClear:true,
options: treeData
fieldNames: {
children: 'children',
label: 'title',
},
options: treeData,
treeNodeFilterProp: 'title',
},
},
{
@@ -286,23 +269,32 @@ const GoodsManage = () => {
>
工艺配置
</a>,
<a
key="primary"
type="primary"
onClick={() => {
history.push({
pathname: '/database/goods/goodsattributeprice',
query: {
isAdd: false,
values: record,
},
});
// handleModalVisible(true);
// setCurrentRow(record);
}}
>
价格配置
</a>
// <a
// key="primary"
// type="primary"
// onClick={() => {
// history.push({
// pathname: '/database/goods/goodsattributeprice',
// query: {
// isAdd: false,
// values: record,
// },
// });
// // handleModalVisible(true);
// // setCurrentRow(record);
// }}
// >
// 价格配置
// </a>
<a
key="primary"
type="primary"
onClick={()=>{
handleDownload(record.id)
}}
>
下载商品
</a>
,
<Popconfirm
type="primary"
@@ -328,6 +320,27 @@ const GoodsManage = () => {
},
];

const importMessage = (json) =>{
const formDataAll = new FormData();
formDataAll.append('file', importFile);
formDataAll.append('json', json);
formDataAll.append('deviceId', deviceId);
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
};
axios.post(getDataBaseUrl() + '/api/goods/goodsImport', formDataAll, { headers }).then(r => {
if(r.data.succeeded == true){
message.success("导入成功");
actionRef.current.reload();
}else{
message.error(r.data.errors);
}
}).catch(error => {
message.error(error);
});
}

/**
* 删除节点
*
@@ -345,182 +358,95 @@ const GoodsManage = () => {
});
return true;
};
const props = {
const importProps = {
beforeUpload: (file) => {
setLoading(true);
if (
file.type !== 'application/vnd.ms-excel' &&
file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
) {
message.error(`${file.name} 不是 exelce 文件`);
}
return file.type == 'application/vnd.ms-excel' ||
file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
? true
: Upload.LIST_IGNORE;
},
name: 'file',
action: getDataBaseUrl()+'/api/goods/GoodsImport',
headers: {
// authorization: 'authorization-text',
Authorization: 'Bearer ' + localStorage.getItem('token')
},
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
setImportFile(file);
if (deviceName == '' || deviceId == undefined) {
message.error('请选择一个设备!');
return Upload.LIST_IGNORE;
}
if (info.file.status === 'done') {
setLoading(false);
message.success(`${info.file.name}导入成功`);
actionRef.current.reload();
} else if (info.file.status === 'error') {
setLoading(false);
message.error(`${info.file.name}:${info.file.response} `);
}
}
};
const technologprops = {
beforeUpload: (file) => {
if (
file.type !== 'application/vnd.ms-excel' &&
file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' &&
file.type !== 'application/x-zip-compressed'
) {
message.error(`${file.name} 不是 exelce 文件`);
message.error(`${file.name} 不是excel或zip文件`);
}
return file.type == 'application/vnd.ms-excel' ||
file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
file.type == 'application/x-zip-compressed'
? true
: Upload.LIST_IGNORE;
},
name: 'file',
action: getDataBaseUrl() + '/api/goods/goodsTechnologyImport',
action: getDataBaseUrl() + '/api/goods/getFileToChoose',
headers: {
// authorization: 'authorization-text',
Authorization: 'Bearer ' + localStorage.getItem('token')
},
onChange(info) {
setLoading(true);
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
setLoading(false);
message.success(`${info.file.name}导入成功`);
actionRef.current.reload();
} else if (info.file.status === 'error') {
setLoading(false);
message.error(`${info.file.name}:${info.file.response} `);
if(info.file.response.data.length > 0){
setChooseFormData(info.file.response.data);
setShowChooseForm(true);
}
else{
importMessage([]);
myformRef.current.submit()
}
}
// setLoading(true);
// if (info.file.status !== 'uploading') {
// console.log(info.file, info.fileList);
// }
// if (info.file.status === 'done') {
// setLoading(false);
// message.success(`${info.file.name}导入成功`);
// actionRef.current.reload();
// } else if (info.file.status === 'error') {
// setLoading(false);
// message.error(`${info.file.name}:${info.file.response} `);
// }
}
};
const handleDataDeviceChange = (value, option) => {
setDeviceId(option?.value);
setDeviceName(option?.label);
initGetdevicegoodsList(option?.value);
}
const handleDeviceChange = (value, option) => {
setDeviceId(option?.value);
setDeviceName(option?.label);
}
const handleGoodChange = (value, option) => {
setGoodsId(value);
}
const handleDataDownload = async()=>{
if(deviceName == '')
{
message.error('请选择一个设备!');
return;
}
if(goodsId == '')
{
message.error('请选择至少一个商品!');
return;
}
const base64String = await GoodsSimpleExport({ goodsId: goodsId, deviceId: deviceId, ids: ids });
// 解码 Base64 数据
const binaryString = atob(base64String);
// 转换为 Uint8Array
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 创建 Blob 对象
const blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// 创建一个临时的 URL,指向 Blob 对象
const url = window.URL.createObjectURL(blob);
// 创建 <a> 元素,用于下载文件
const link = document.createElement('a');
const fileName = "商品.xlsx";
link.href = url;
link.setAttribute('download', fileName);
// 将 <a> 元素添加到页面中
document.body.appendChild(link);
// 模拟用户点击下载链接,触发文件下载
link.click();
// 下载完成后,移除 <a> 元素
document.body.removeChild(link);
setDeviceId('');
setDeviceName('');
setGoodsId([]);
setIds('');
setIsDataModalOpen(false);
}
const handleDownload = async () => {
if(deviceName == '')
{
const handleDownload = async (goodId) => {
if (deviceName == '' || deviceId == undefined) {
message.error('请选择一个设备!');
return;
}
try {
// 第一次下载操作
const r = await TechnologyTemplateExport(deviceId);
if (!r) {
message.error('未能获取第一个文件下载链接');
return;
}
const fileName1 = r.substring(r.lastIndexOf('/') + 1);
const link1 = document.createElement('a');
link1.href = r;
link1.setAttribute('download', fileName1);
document.body.appendChild(link1);
link1.click();
document.body.removeChild(link1);
// 第二次下载操作
const base64String = await GoodsTechnologyExport({ goodsId: goodsId, deviceId: deviceId, fileName: fileName1 });
if (!base64String) {
message.error('未能获取第二个文件Base64数据');
return;
}
// 解码 Base64 数据
const binaryString = atob(base64String);
// 转换为 Uint8Array
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 创建 Blob 对象
const blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// 创建一个临时的 URL,指向 Blob 对象
const url = window.URL.createObjectURL(blob);
// 创建第二个 <a> 元素,用于下载第二个文件
const link2 = document.createElement('a');
const fileName2 = "商品.xlsx";
link2.href = url;
link2.setAttribute('download', fileName2);
// 将第二个 <a> 元素添加到页面中
document.body.appendChild(link2);
// 模拟用户点击下载链接,触发第二个文件下载
link2.click();
// 下载完成后,移除第二个 <a> 元素
document.body.removeChild(link2);
setDeviceId('');
setDeviceName('');
setGoodsId([]);
setIsModalOpen(false);
} catch (error) {
message.error('下载过程中发生错误:', error);
}
await GoodsExport({ goodId: goodId, deviceId: deviceId, goodsId: goodsId }).then((r) => {
if (r.succeeded) {
const base64String = r.data;
// 解码 Base64 数据
const binaryString = atob(base64String);
// 转换为 Uint8Array
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 创建 Blob 对象
const blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// 创建一个临时的 URL,指向 Blob 对象
const url = window.URL.createObjectURL(blob);
// 创建 <a> 元素,用于下载文件
const link = document.createElement('a');
const fileName = "商品.zip";
link.href = url;
link.setAttribute('download', fileName);
// 将 <a> 元素添加到页面中
document.body.appendChild(link);
// 模拟用户点击下载链接,触发文件下载
link.click();
// 下载完成后,移除 <a> 元素
document.body.removeChild(link);
message.success("下载成功");
}else{
message.error(r.errors);
}
})
}

return (
<PageContainer host header={{
title: '',
@@ -529,6 +455,7 @@ const GoodsManage = () => {
<Spin spinning={loading} tip="上传中...">
<ProTable
headerTitle=""
formRef={myformRef}
actionRef={actionRef}
rowKey="id"
pagination={{ defaultPageSize: 10 }}
@@ -555,64 +482,40 @@ const GoodsManage = () => {
</Button>,
<Button
key="primary"
onClick={async () => {
const link = document.createElement('a');
link.href = "https://bpa.oss-cn-chengdu.aliyuncs.com/hkerp/test/goods/商品导入模版.xlsx";
link.click();
}}
onClick={() => handleDownload(null)}
>
<DownloadOutlined /> 下载商品导入模板
<DownloadOutlined />下载商品
<Tooltip placement="top" title="下载后请使用wps进行编辑"><QuestionCircleOutlined /></Tooltip>
</Button>,
<Upload {...props} showUploadList={false} >
<Button icon={<UploadOutlined />} >导入商品</Button>
<Upload {...importProps} showUploadList={false}>
<Button icon={<UploadOutlined />}>导入商品</Button>
</Upload>,
<Button
key="primary"
onClick={async () => {
initGetgoodslist();
setIsModalOpen(true);
}}
>
<DownloadOutlined /> 下载工艺模板
<Tooltip placement="top" title="下载后请使用wps进行编辑"><QuestionCircleOutlined /></Tooltip>
</Button>,
<Upload {...technologprops} showUploadList={false}>
<Button icon={<UploadOutlined />}>导入工艺</Button>
</Upload>,
<Button
key="primary"
onClick={async () => {
setIsDataModalOpen(true);
}}
>
<DownloadOutlined /> 下载商品工艺
</Button>,
<BatchDeletion />
]}
request={async (params) => {
var goodsData = [];
var goodsIds = [];
if (params.goodsTypeId != undefined) {
params.goodsTypeId = goodsTypes[params.goodsTypeId].goodsTypeId;
}
var total = 0;
await goods(params).then((r) => {
goodsData = r.data.data;
console.log(goodsData)
goodsData.forEach((x) => {
goodsIds.push(x.id);
if (x.defaultMate != null) {
x.defaultMate = x.defaultMate.split(",");
}

});
console.log(goodsData)
total = r.data.total;
});
setGoodsId(goodsIds);
return {
data: goodsData,
success: true,
total: total,
};

}}
columns={columns}
rowSelection={{
@@ -644,125 +547,34 @@ const GoodsManage = () => {
}}
createModalVisible={createModalVisible}
values={currentRow || {}}
form={form}
/>
<Modal
title="下载设备工艺及商品工艺模版"
open={isModalOpen}
footer={false}
width={450}
maskClosable={false}
destroyOnClose={true}
onCancel={() => {
setDeviceId('')
setDeviceName('')
setIsModalOpen(false)
}}>
<div style={{ marginBottom: 10 }}>
<span style={{ marginRight: 10 }}><span style={{color:'red',marginRight: 3}}>*</span>选择设备:</span>
<Select
showSearch
allowClear
style={{
width: 300,
marginRight: 10
}}
placeholder="请选择设备下载该设备的工艺模版"
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').includes(input)}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={async (value, option) => { handleDeviceChange(value, option) }}
options={deviceData}
required
/>
</div>
<div style={{ marginBottom: 10 }}>
<span style={{ marginLeft: 9, marginRight: 10 }}>选择商品:</span>
<Select
mode='multiple'
showSearch
allowClear
style={{
width: 300,
marginRight: 10
}}
placeholder="选择商品下载模版"
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').includes(input)}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={async (value, option) => { handleGoodChange(value, option) }}
options={goodData}
/>
</div>
<Button
icon={<DownloadOutlined />}
style={{ marginLeft: '22.2%' }}
onClick = {handleDownload}
>下载</Button>
</Modal>
<Modal
title="下载商品工艺"
open={isDataModalOpen}
footer={false}
width={450}
destroyOnClose={true}
<ChooseForm
onFinish={async (data) => {
const transformedData = Object.entries(data).map(([key, value]) => ({
key,
value
}));
var list = [];
transformedData.forEach((item) => {
list.push({
key: item.key,
value: item.value == true ? true : false
});
});
importMessage(JSON.stringify(list));
setShowChooseForm(false);
setChooseFormData(undefined);
myformRef.current.submit()
}}
onCancel={() => {
setDeviceGoodData([])
setDeviceId('')
setDeviceName('')
setGoodsId([])
setIds('')
setIsDataModalOpen(false)
}}>
<div style={{ marginBottom: 10 }}>
<span style={{ marginRight: 10 }}><span style={{color:'red',marginRight: 3}}>*</span>选择设备:</span>
<Select
showSearch
allowClear
style={{
width: 300,
marginRight: 10
}}
placeholder="请选择设备"
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').includes(input)}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={async (value, option) => { handleDataDeviceChange(value, option) }}
options={deviceData}
required
/>
</div>
<div style={{ marginBottom: 10 }}>
<span style={{ marginLeft: 9, marginRight: 10 }}>选择商品:</span>
<Select
mode='multiple'
showSearch
allowClear
style={{
width: 300,
marginRight: 10
}}
placeholder="选择商品下载工艺"
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').includes(input)}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={async (value, option) => { handleGoodChange(value, option) }}
options={deviceGoodData}
/>
</div>
<Button
icon={<DownloadOutlined />}
style={{ marginLeft: '22.2%' }}
onClick = {handleDataDownload}
>下载</Button>
</Modal>
setShowChooseForm(false);
setChooseFormData(undefined);
}}
showChooseForm={showChooseForm}
values={chooseFormData || {}}
form={form}
/>
<Drawer
width={600}
visible={showDetail}


+ 15
- 2
src/pages/database/goods/newgoods/service.js Ver fichero

@@ -68,7 +68,7 @@ export async function removeGoods(data) {
});
}

/** 获取商品类型 sdsa GET /kitchen/api/rule */
/** 获取工艺分类 sdsa GET /kitchen/api/rule */
export async function goodsType(data) {
return request(getDataBaseUrl()+`/api/goods-type/goods-types`, {
method: 'POST',
@@ -170,6 +170,19 @@ export async function GoodsSimpleExport(data) {
return request(getDataBaseUrl()+`/api/goods/goodsSimpleExport`, {
method: 'post',
data: data
// responseType: 'blob'
});
}

export async function GoodsExport(data) {
return request(getDataBaseUrl()+`/api/goods/goodsExport`, {
method: 'post',
data: data
});
}

export async function GoodsImport(data) {
return request(getDataBaseUrl()+`/api/goods/goodsImport`, {
method: 'post',
data: data
});
}

+ 11
- 11
src/pages/device/deviceInfo/index.jsx Ver fichero

@@ -258,7 +258,7 @@ const GoodsTypeManage = () => {
dataIndex: 'option',
valueType: 'option',
fixed: 'right',
width: 400,
width: 300,
render: (_, record) => [
<a
key="update"
@@ -344,16 +344,16 @@ const GoodsTypeManage = () => {
导出工艺模版
</a>,

<a
key="edit"
onClick={() => {
GetdevicegoodsList(record.id);
setCurrentRow(record);
setIsModalOpen(true);
}}
>
设置设备商品
</a>,
// <a
// key="edit"
// onClick={() => {
// GetdevicegoodsList(record.id);
// setCurrentRow(record);
// setIsModalOpen(true);
// }}
// >
// 设置设备商品
// </a>,

],
},


+ 6
- 3
src/pages/device/deviceVesion/components/CreateForm.jsx Ver fichero

@@ -2,11 +2,10 @@ import React, { useRef, useState, useEffect } from 'react';
import { Modal, Form, Input, Button, Select, Upload, InputNumber, message } from 'antd';
import { PlusOutlined, UploadOutlined, DeleteOutlined } from '@ant-design/icons';
import { GetAliyunRequestURL } from '../services';
import $ from 'jquery';
const CreateForm = (props) => {
const [modalVisible, setModalVisible] = useState(false);
const [modalContent, setModalContent] = useState('');
const [url, setUrl] = useState(props.values ? props.values.productUrl : null);
const [url, setUrl] = useState(null);
const [hovered, setHovered] = useState(false);
const [imageError, setImageError] = useState(false);
const uploadProp = {
@@ -53,7 +52,9 @@ const CreateForm = (props) => {
props.onCancel();
};
const handleDeleteImage = () => {
props.values.productUrl = null;
setUrl(null);
props.form.setFieldsValue({ productUrl: props.values.productUrl });
};
const handleImageError = () => {
setImageError(true);
@@ -73,7 +74,6 @@ const CreateForm = (props) => {
layout="vertical"
preserve={false}
form={props.form}
// initialValues={props.values}
onFinish={props.onFinish} >
<Form.Item name="id" hidden={true}>
<Input />
@@ -95,6 +95,9 @@ const CreateForm = (props) => {
<Form.Item label={"仓位数量"} name="productNumber" rules={[{ required: true, }]} >
<InputNumber min={1} />
</Form.Item>
<Form.Item label={"备注"} name="remark">
<Input />
</Form.Item>
<Form.Item name="productUrl" hidden={true}>
<Input />
</Form.Item>


+ 8
- 2
src/pages/device/deviceVesion/index.jsx Ver fichero

@@ -42,7 +42,7 @@ const GoodsTypeManage = () => {
file.type !== 'application/vnd.ms-excel' &&
file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
) {
message.error(`${file.name} 不是 exelce 文件`);
message.error(`${file.name} 不是 excel 文件`);
}
return file.type == 'application/vnd.ms-excel' ||
file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
@@ -96,7 +96,7 @@ const handleAdd = async (fields) => {
//修改
const handleUpdate = async (fields) => {
try {
fields.productUrl = fields.productUrl1 ? aliyunHostUrl + fields.productUrl1.file.name : null;
fields.productUrl = fields.productUrl1 ? aliyunHostUrl + fields.productUrl1.file.name : fields.productUrl;
message.loading('正在修改', key);
message.destroy(key);
await UpdateDeviceVesion(JSON.stringify(fields)).then((r) => {
@@ -165,6 +165,12 @@ const handleRemove = async (selectedRows) => {
valueType: 'textarea',
hideInSearch: true,
},
{
title: '备注',
dataIndex: 'remark',
valueType: 'textarea',
hideInSearch: true,
},
{
title: '图片',
dataIndex: 'productUrl',


+ 1
- 1
src/pages/device/productmanage/index.jsx Ver fichero

@@ -30,7 +30,7 @@ const props = {
file.type !== 'application/vnd.ms-excel' &&
file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
) {
message.error(`${file.name} 不是 exelce 文件`);
message.error(`${file.name} 不是 excel 文件`);
}
return file.type == 'application/vnd.ms-excel' ||
file.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'


+ 38
- 0
src/pages/device/technology/components/CreateRemarkForm.jsx Ver fichero

@@ -0,0 +1,38 @@
import React, {} from 'react';
import { Modal, Form, Input, Button } from 'antd';

const CreateRemarkForm = (props) => {

return (
<Modal
width={400}
title="编辑备注"
open={props.remarkModalOpen}
footer={null}
maskClosable={false}
destroyOnClose
onCancel={props.onCancel}
>
<Form
layout="horizontal"
preserve={false}
initialValues={props.values}
onFinish={props.onFinish}
>
<Form.Item name="id" hidden={true}>
<Input />
</Form.Item>
<Form.Item label={"备注"} name="remark">
<Input />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" style={{ float: 'right' }}>
保存
</Button>
</Form.Item>
</Form>
</Modal>
);
};

export default CreateRemarkForm;

+ 59
- 9
src/pages/device/technology/index.jsx Ver fichero

@@ -1,14 +1,14 @@

import { Modal, Button, message, Form, Upload, Select ,Popconfirm} from 'antd';
import { Modal, Button, message, Form, Upload, Select ,Popconfirm, Input} from 'antd';
import React, { useState, useRef, useEffect } from 'react';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table';
import {GetTechnologyPage,GetProductList,GetDeviceVesionList,DeleteTechnology,GetAliyunRequestURL,GoodsTemplateExport } from "./services"
import {GetTechnologyPage,GetProductList,GetDeviceVesionList,DeleteTechnology,GetAliyunRequestURL,GoodsTemplateExport,UpdateRecodeRemark } from "./services"
import { history } from 'umi';
import { getDataBaseUrl } from '@/global_data';
import Technologylist from './components/technologylist'
import useFetchData from '@ant-design/pro-descriptions/lib/useFetchData';
import CreateRemarkForm from './components/CreateRemarkForm';
const key = 'message';
import $ from 'jquery';
import { set } from 'lodash';
@@ -26,6 +26,8 @@ const GoodsTypeManage = () => {
const [deviceTypeKey, setdeviceTypeKey] = useState('');
const [version, setversion] = useState('');
const [url, setUrl] = useState('');
const [remarkModalOpen, setRemarkModalOpen] = useState(false);
const [remarkData, setRemarkData] = useState();
let aliyunHostUrl = 'https://bpa.oss-cn-chengdu.aliyuncs.com/hkerp/test/technology/';
const props = {
beforeUpload: (file) => {
@@ -35,7 +37,7 @@ const GoodsTypeManage = () => {
file.type !== 'application/vnd.ms-excel' &&
file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
) {
message.error(`${file.name} 不是 exelce 文件`);
message.error(`${file.name} 不是 excel 文件`);
}
if(ProductVesionId.length==0){
message.error(`请选择版本`);
@@ -129,6 +131,12 @@ const GoodsTypeManage = () => {
valueType: 'textarea',
search:false
},
{
title: '备注',
dataIndex: 'remark',
valueType: 'textarea',
search:false
},
// {
// title: '是否存在模板',
// dataIndex: 'templatePath',
@@ -197,7 +205,12 @@ const GoodsTypeManage = () => {
// href={record.templatePath}

// > 下载工艺模板</a>,
<a
key="config"
onClick={() => {
setRemarkModalOpen(true);
setRemarkData(record);
}} > 编辑备注</a>
],
},
];
@@ -250,6 +263,26 @@ const GoodsTypeManage = () => {
setDeviceVesionData([])
handleModalVisible(false);
}
const handleUpdate = async (fields) => {
try {
message.loading('正在修改', key);
message.destroy(key);
await UpdateRecodeRemark(JSON.stringify(fields)).then((r) => {
message.destroy(key);
if (r.data) {
message.success('修改成功',);
actionRef.current?.reloadAndRest?.();
return true;
} else {
message.error(r.errors);
return false;
}
});
} catch (error) {
message.error('修改失败请重试!');
return false;
}
};
return (
<PageContainer host header={{
title: '',
@@ -321,12 +354,12 @@ const GoodsTypeManage = () => {
</Button>
</FooterToolbar>
)}
<Modal title="上传工艺模版" open={isModalOpen} footer={null} maskClosable={false}
<Modal title="上传工艺模版" open={isModalOpen} footer={null} maskClosable={false} width={400}
destroyOnClose onCancel={() => { setDeviceVesionData();setdeviceTypeKey("");
setProductVesionId('');setIsModalOpen(false) }}>
<div style={{marginBottom:10}}>
<span style={{marginRight:10}}>选择产品</span>
<Select style={{width: '60%'}} onChange={handleChange}>
<Select style={{width: '80%'}} onChange={handleChange}>
{DictData?.map((item, index) => {
return (
<Select.Option index={index} value={item.id} key={item.id}>
@@ -338,7 +371,7 @@ const GoodsTypeManage = () => {
</div>
<div style={{marginBottom:10}}>
<span style={{marginRight:10}}>选择版本</span>
<Select style={{width: '60%'}} onChange={handleVisChange}>
<Select style={{width: '80%'}} onChange={handleVisChange}>
{DeviceVesionData?.map((item, index) => {
return (
<Select.Option index={index} value={item.id} key={item.id}>
@@ -349,12 +382,29 @@ const GoodsTypeManage = () => {
</Select>
</div>
<Upload
// {...uploadProp}
{...props}
maxCount={1}>
<Button icon={<UploadOutlined />} style={{marginLeft:'48%'}}>导入工艺模版</Button>
</Upload>
</Modal>
<CreateRemarkForm
onFinish={async (value) => {
var success = handleUpdate(value);
if (success) {
setRemarkModalOpen(false);
setRemarkData(undefined);
}
actionRef.current.reload();
}}
onCancel={() => {
setRemarkModalOpen(false);
setRemarkData(undefined);
}}
remarkModalOpen={remarkModalOpen}
values={remarkData || {}}
>

</CreateRemarkForm>
<Technologylist createModalVisible={createModalVisible} dataSource={currentRow} onCancel={onCancel}/>
</PageContainer>
);


+ 6
- 0
src/pages/device/technology/services.js Ver fichero

@@ -32,4 +32,10 @@ export async function GetTechnologyPage(data) {
method: 'POST',
data: data,
});
}
export async function UpdateRecodeRemark(data) {
return request(getDataBaseUrl() + `/api/technology/UpdateRecodeRemark`, {
method: 'POST',
data: data,
});
}

+ 5
- 3
src/pages/device/warehousepostion/components/CreateForm.jsx Ver fichero

@@ -1,5 +1,5 @@
import React, {useState,useEffect } from 'react';
import { Modal, Form, Input, Button, Select,Image } from 'antd';
import { Modal, Form, Input, Button, Select,Image, InputNumber } from 'antd';
import {
EditableProTable
} from '@ant-design/pro-table';
@@ -15,6 +15,7 @@ const CreateForm = (props) => {
form.setFieldsValue({
id: props.values.id,
templateName:props.values.templateName,
sort:props.values.sort,
deviceId:props.values.deviceId,
});
var data=props.values.warehousePostion.map(x=>{
@@ -138,8 +139,9 @@ const CreateForm = (props) => {
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={handleChange} options={options}/>
</Form.Item>
<Form.Item label={"序号"} name="sort">
<InputNumber style={{width: '100%'}}/>
</Form.Item>
<Form.Item label={"设备仓位图"} name="productUrl" rules={[{ required: false,max:50}]} >
<Image


+ 1
- 1
src/pages/order/orderflow/service.js Ver fichero

@@ -74,7 +74,7 @@ GetFlowExport(data) {
});
},
/**
* 查询商品类型
* 查询工艺分类
*/
goodsTypeList(data) {
return request(`/kitchen/api/goodstype/list`, {


+ 1
- 1
src/pages/push/goodspush/components/PushFrom.jsx Ver fichero

@@ -76,7 +76,7 @@ const PushFrom = (props) => {
valueType: 'textarea',
},
{
title: '商品类型',
title: '工艺分类',
dataIndex: 'goodsTypeName',
valueType: 'treeSelect',
fieldProps: {


+ 1
- 1
src/pages/push/technologypush/components/PushFrom.jsx Ver fichero

@@ -88,7 +88,7 @@ const handleStopChange=(value)=>{
valueType: 'textarea',
},
{
title: '商品类型',
title: '工艺分类',
dataIndex: 'goodsTypeName',
valueType: 'treeSelect',
fieldProps: {


+ 1
- 1
src/pages/scene/foodmenu/components/FoodMenuGoods.jsx Ver fichero

@@ -37,7 +37,7 @@ const FoodMenuGoods = (props) => {
tip: '规则名称是唯一的 key',
},
{
title: '商品类型',
title: '工艺分类',
dataIndex: 'goodsTypeName',
valueType: 'treeSelect',
hideInTable: true,


Cargando…
Cancelar
Guardar