This commit is contained in:
ylj20011123 2025-12-17 18:09:08 +08:00
parent 24088d3955
commit 35a6c6832d
17 changed files with 1018 additions and 51 deletions

View File

@ -614,6 +614,11 @@ export default [
name: 'users', name: 'users',
component: './Setting/Users/index', component: './Setting/Users/index',
}, },
{
path: '/setting/department/userstype',
name: 'userstype',
component: './Setting/UserType/index',
},
] ]
}, },
{ {

BIN
dist.zip

Binary file not shown.

View File

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

27
src/pages/Setting/UserType/data.d.ts vendored Normal file
View File

@ -0,0 +1,27 @@
/*
* @Author: cclu
* @Date: 2021-12-13 11:01:23
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-03-28 18:05:34
* @FilePath: \cloud-platform\src\pages\Setting\UserType\data.d.ts
* @Description:
*
* Copyright (c) 2022 by cclu/驿, All Rights Reserved.
*/
// 模块数据类型
export type UserTypeModel = {
USERTYPE_ID: number; // 用户类型内码
USERTYPE_NAME: string; // 用户类型名称
USERTYPE_PID: number; // 用户类型父级内码
USERTYPE_INDEX: number; // 用户类型索引
USERTYPE_LEVEL: number; // 用户类型级别
USERTYPE_GUID: string; // 用户类型唯一标识
USERTYPE_ICO: string; // 用户类型图标
USERTYPE_PROVINCE: number; // 所属省份
USERTYPE_STATUS: number; // 有效状态
STAFF_ID: number; // 操作人内码
STAFF_NAME: string; // 操作人员
OPERATE_DATE: string; // 操作时间
USERTYPE_DESC: string; // 备注说明
}

View File

@ -0,0 +1,451 @@
/*
* @Author: cclu lkrnchocolateaaron@gmail.com
* @Date: 2022-02-17 13:53:19
* @LastEditors: cclu lkrnchocolateaaron@gmail.com
* @LastEditTime: 2022-05-07 11:24:37
* @FilePath: \cloud-platform\src\pages\Setting\UserType\index.tsx
* @Description:
*/
import React, { useState, useRef } from "react";
import useRequest from "@ahooksjs/use-request";
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 type { FormInstance } from 'antd';
import type { UserTypeModel } from "./data";
import type { ProColumns, ActionType } from '@ant-design/pro-table';
import type { ProDescriptionsItemProps } from "@ant-design/pro-descriptions"
import type { ConnectState } from "@/models/connect";
import type { CurrentUser } from '@/models/user';
import { getMerchantTree, getOnwer } from "@/services/options";
import { getUserTypeList, delUserType, updataUserType, getUserTypeCount } from './service'
import { connect } from "umi";
/**
* @en-US add or update node
* @zh-CN
* @param fields
*/
const handleAddUpdate = async (fields: UserTypeModel) => {
const hide = message.loading('正在提交...')
const result = await updataUserType(fields)
hide()
if (result.Result_Code !== 100) {
message.error(`${result.Result_Desc}` || `${result.Result_Code}:提交失败`)
return false
}
message.success(fields.USERTYPE_ID ? "更新成功!" : "新建成功!")
return true
}
/**
* @description:
* @param {nodeId} id
* @return {boolean}
*/
const handleDelete = async (nodeId: number) => {
const hide = message.loading('正在删除...');
try {
const result = await delUserType(nodeId)
hide();
if (result.Result_Code !== 100) {
message.error(`${result.Result_Code }:${result.Result_Desc}`)
return false
}
message.success("删除成功!")
return true
} catch (error) {
hide();
message.error("删除失败")
return false
}
}
// 数字角标生成
const renderBadge = (count: number, active = false) => {
return (
<Badge
count={count}
style={{
marginTop: -2,
marginLeft: 4,
color: active ? '#1890FF' : '#999',
backgroundColor: active ? '#E6F7FF' : '#eee',
}}
/>
);
};
const UserTypeList: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => {
const { currentUser } = props
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const [showDetail, setShowDetail] = useState<boolean>(false); // 是否显示详情
const [currentRow, setCurrentRow] = useState<UserTypeModel>(); // 当前选中行
const [createModalVisible, handleModalVisible] = useState<boolean>(false); // 发布分类更新窗口的弹窗
const [userTypeTree, setUserTypeTree] = useState<[]>(); // 树结构数据分类 用于弹出编辑时选择上级
const [activeKey, setActiveKey] = useState<React.Key>(`${currentUser?.UserPattern===9000?'1000':currentUser?.UserPattern}`); // 树结构数据分类 用于弹出编辑时选择上级
// 查询可选商家
const { data: merchantTree } = useRequest(async () => {
return await getMerchantTree({MerchantPid:currentUser?.BusinessManID||''})
})
// 查询可选商家
const {loading: typeCountLoading,data: typeCount } = useRequest(getUserTypeCount)
// 表格数据配置 <UserTypeModel|SystemMenuModel>
const columns: ProColumns<UserTypeModel>[] = [
{
title: '分类名称',
dataIndex: 'USERTYPE_NAME',
hideInDescriptions: true,
render: (_, record) => {
return <a key="fname" onClick={() => {
setCurrentRow(record)
setShowDetail(true)
}}>{record?.USERTYPE_NAME}</a>
}
},
{
title: '状态',
dataIndex: 'USERTYPE_STATUS',
hideInSearch: true,
filters: true,
valueType: 'select',
initialValue: 1,
valueEnum: {
all: { text: '全部', status: 'Default' },
0: { text: '无效', status: 'Default' },
1: { text: '有效', status: 'Processing' },
},
},
{
title: '所属业主',
dataIndex: 'USERTYPE_PROVINCE',
hideInSearch: true,
hideInTable: activeKey==='2000',
valueType: "select",
request: async () => {
const options = await getOnwer()
return options;
},
},
{
title: '所属商户',
dataIndex: 'USERTYPE_PROVINCE',
hideInSearch: true,
hideInTable: activeKey==='1000',
valueType: "treeSelect",
fieldProps: {
options: merchantTree
},
},
{
title: '索引',
dataIndex: 'USERTYPE_INDEX',
hideInSearch: true
},
{
title: '说明',
dataIndex: 'USERTYPE_DESC',
hideInSearch: true
},
{
title: '操作',
valueType: 'option',
dataIndex: 'option',
hideInDescriptions: true,
render: (text, record) => [
<a
key="editable"
onClick={() => {
handleModalVisible(true);
if (showDetail) {
setShowDetail(false);
}
setCurrentRow({ ...record });
}}
>
</a>,
// <Popconfirm // 删除按钮功能
// title="确认删除该项菜单吗?"
// onConfirm={async () => {
// if (record) {
// const { USERTYPE_ID } = record
// const success = (USERTYPE_ID ? await handleDelete(USERTYPE_ID) : false)
// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
// }
// }
// }
// }}
// >
// <a>无效</a>
// </Popconfirm>
]
}
]
return (<PageContainer header={{
title: '',
breadcrumb: {},
}}>
<ProTable<UserTypeModel>
rowKey="USERTYPE_ID"
actionRef={actionRef}
request={async (params) => {
console.log('params',params)
const data = await getUserTypeList({ ...params })
setUserTypeTree(data)
return { data, success: true }
}}
search={false}
params={{ UserTypePattern: activeKey }}
columns={columns}
toolbar={{
actions: [
<Button
key="new"
icon={<PlusOutlined />}
type="primary"
onClick={() => {
handleModalVisible(true)
}}
></Button>,
],
menu: {
type: 'tab',
activeKey,
items: currentUser?.UserPattern===9000 ? [
{
key: '1000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.OwnerUnitCount: '', activeKey === '1000')}</span>,
},
{
key: '4000',
label: <span>{renderBadge(!typeCountLoading ?typeCount?.SupplierCount:'', activeKey === '4000')}</span>,
},
{
key: '2000',
label: <span>{renderBadge(!typeCountLoading ?typeCount?.MerchantCount:'', activeKey === '2000')}</span>,
}
]:currentUser?.UserPattern===1000 ?[
{
key: '1000',
label: <span>{renderBadge(!typeCountLoading ? typeCount?.OwnerUnitCount: '', activeKey === '1000')}</span>,
},
{
key: '4000',
label: <span>{renderBadge(!typeCountLoading ?typeCount?.SupplierCount:'', activeKey === '4000')}</span>,
},
]:[],
onChange: (key) => {
setActiveKey(key as string);
},
},
}}
pagination={{ defaultPageSize: 10 }}
/>
{/* 编辑新增分类弹出框 */}
<ModalForm
layout={'horizontal'}
wrapperCol={{ span: 16 }}
labelCol={{ span: 6 }}
title={currentRow ? '分类编辑' : '分类新增'}
width={600}
visible={createModalVisible}
formRef={formRef}
onVisibleChange={(value) => {
handleModalVisible(value)
if (value) {
formRef.current?.setFieldsValue(
currentRow ? {
...currentRow, USERTYPE_STATUS: !!currentRow.USERTYPE_STATUS,
USERTYPE_PID: currentRow.USERTYPE_PID !== -1 ? currentRow.USERTYPE_PID : ''
} : { USERTYPE_STATUS: 1,USERTYPE_PATTERN:activeKey },
);
} else {
formRef.current?.resetFields();
setCurrentRow(undefined);
}
}}
onFinish={async (value) => {
let newValue: any = { ...value , USERTYPE_PATTERN:activeKey}
if (currentRow) { // 编辑数据
newValue = { ...currentRow, ...newValue }
}
newValue.USERTYPE_STATUS = value.USERTYPE_STATUS ? 1 : 0
newValue.USERTYPE_PID = value.USERTYPE_PID ? value.USERTYPE_PID : -1
const success = await handleAddUpdate(newValue as UserTypeModel)
if (success) {
if (actionRef.current) {
actionRef.current.reload();
}
// handleModalVisible(false)
return true
}
return false
}}
>
<ProFormText
name="USERTYPE_NAME"
label="分类名称"
placeholder="请输入分类名称"
rules={[
{
required: true,
message: '请输入分类名称',
},
]}
/>
<Form.Item
name="USERTYPE_PID"
label="上级分类"
>
<TreeSelect
placeholder="请选择上级分类"
dropdownStyle={{ maxHeight: 300, overflow: 'auto' }}
// treeDefaultExpandAll
treeData={userTypeTree}
fieldNames={{
label: 'USERTYPE_NAME',
value: "USERTYPE_ID",
children: "children"
}}
>
</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 === '2000' &&
<Form.Item
name="USERTYPE_PROVINCE"
label="所属商家"
// rules={[
// {
// required: true,
// message: '请选择所属商家',
// }
// ]}
>
<TreeSelect
treeData={merchantTree}
treeDefaultExpandAll
showSearch
treeNodeFilterProp="label"
allowClear
/>
</Form.Item>}
{/* <ProFormSwitch // 使form.item
name="USERTYPE_STATUS"
label="是否有效"
checkedChildren="有"
unCheckedChildren="无"
/> */}
<Form.Item
name="USERTYPE_STATUS"
label="是否有效"
>
<Switch
checkedChildren="有"
unCheckedChildren="无"
defaultChecked={currentRow ? !!currentRow.USERTYPE_STATUS : true}
/>
</Form.Item>
<ProFormDigit
name="USERTYPE_INDEX"
label="索引"
placeholder="请输入索引"
min={0}
max={9999}
fieldProps={{ precision: 0 }}
/>
<ProFormTextArea
name="USERTYPE_DESC"
label="备注说明"
placeholder="请输入说明"
/>
</ModalForm>
{/* 分类详情 */}
<Drawer
width={600}
visible={showDetail}
onClose={() => {
setCurrentRow(undefined);
setShowDetail(false);
}}
closable={false}
>
{currentRow?.USERTYPE_NAME && (
<ProDescriptions<UserTypeModel>
column={1}
title={currentRow?.USERTYPE_NAME}
request={async () => ({
data: currentRow || {},
})}
params={{
id: currentRow?.USERTYPE_ID,
}}
columns={columns as ProDescriptionsItemProps<UserTypeModel>[]}
/>
)}
</Drawer>
</PageContainer>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser,
}))(UserTypeList);

View File

@ -0,0 +1,57 @@
import request from '@/utils/request';
import { wrapTreeNode } from '@/utils/format';
import type { UserTypeModel } from './data';
// 获取模块列表数据
export async function getUserTypeList(params?: any) {
const data = await request('/FrameWork/GetUserTypeList', {
method: 'GET',
params: {...params,pageindex: params.current,pagesize:params.pageSize},
})
if (data.Result_Code !== 100) {
return []
}
const treeTable = wrapTreeNode(data.Result_Data.List);
return treeTable;
}
// 获取模块列表数据
export async function getUserTypeCount(params?: any) {
const data = await request('/FrameWork/GetUserTypeCount', {
method: 'GET',
params,
})
if (data.Result_Code !== 100) {
return {}
}
return data.Result_Data;
}
// 更新模块
export async function updataUserType(params?: UserTypeModel) {
return request('/platform/synchroUserType', {
method: 'POST',
data: {
...params,
},
requestType: 'form'
});
}
// 删除模块
export async function delUserType(UserType: number) {
return request(`/Platform/DeleteUserType`, {
method: 'GET',
params: {
UserType
}
});
}
/* 模块列表end */

View File

@ -50,7 +50,7 @@ const handelResetPassWord = async (item: { UserId: number, Password: string }) =
/** /**
* @description: * @description:
* @param {function} reloadTable * @param {function} reloadTable
* @param {UserModel} detail * @param {UserModel} detail
* @param {CurrentUser} user * @param {CurrentUser} user
* @return {ReactDOM} * @return {ReactDOM}
*/ */
@ -729,7 +729,7 @@ const Edit = ({ tableTab, openType, detail, reloadTable, currentUser, selectTab,
console.log('params', params); console.log('params', params);
if (pageType === 'merchantManagement') { if (pageType === 'merchantManagement') {
const req: any = { const req: any = {
ProvinceCode: '530000', // ProvinceCode: '530000',
UserTypePattern: 2000 UserTypePattern: 2000
} }
const data = await getUserTypeTree(req) const data = await getUserTypeTree(req)
@ -742,7 +742,7 @@ const Edit = ({ tableTab, openType, detail, reloadTable, currentUser, selectTab,
return data return data
} if (params.USER_PROVINCE || params.USER_PATTERN) { } if (params.USER_PROVINCE || params.USER_PATTERN) {
const req: any = { const req: any = {
ProvinceCode: '530000', // ProvinceCode: '530000',
UserTypePattern: tableTab === 9000 ? 1000 : tableTab UserTypePattern: tableTab === 9000 ? 1000 : tableTab
} }
const data = await getUserTypeTree(req) const data = await getUserTypeTree(req)

View File

@ -262,7 +262,9 @@ const UserList: React.FC<{ currentUser: CurrentUser | undefined }> = (props) =>
checkable checkable
style={{ padding: '20px' }} style={{ padding: '20px' }}
// eslint-disable-next-line no-nested-ternary // eslint-disable-next-line no-nested-ternary
treeData={!typeLoading ? (currentUser?.UserPattern === 9000 ? userTypeTree : userTypeTree[0]?.children) : []} // 虽然不知道前面为啥要[0].children 但是 领导说 按照下面那行的走 那就遵命
// treeData={!typeLoading ? (currentUser?.UserPattern === 9000 ? userTypeTree : userTypeTree[0]?.children) : []}
treeData={!typeLoading ? (currentUser?.UserPattern === 9000 ? userTypeTree : userTypeTree) : []}
fieldNames={{ fieldNames={{
title: "label", title: "label",
// key: "USERTYPE_ID" // key: "USERTYPE_ID"

View File

@ -121,19 +121,19 @@ const Login: React.FC<LoginProps> = (props) => {
useEffect(async () => { useEffect(async () => {
// 先拿到ip // 先拿到ip
let IpInfo: any = await getUserIP() // let IpInfo: any = await getUserIP()
console.log('IpInfoIpInfoIpInfoIpInfo', IpInfo); // console.log('IpInfoIpInfoIpInfoIpInfo', IpInfo);
// 用ip 去获取信息 // 用ip 去获取信息
// let ipDetail: any = await getLocationByIP(IpInfo, 'XrQQuNQRGxap9YH2xmvx3dzuJVkXhTzT') // let ipDetail: any = await getLocationByIP(IpInfo, 'XrQQuNQRGxap9YH2xmvx3dzuJVkXhTzT')
let ipDetail: any = await handleGetIPDetail({ ip: IpInfo }) let ipDetail: any = await handleGetIPDetail({})
console.log('ipDetailipDetailipDetail', ipDetail); console.log('ipDetailipDetailipDetail', ipDetail);
const ipRes: any = { const ipRes: any = {
country: ipDetail.country, country: ipDetail?.country,
prov: ipDetail.province, prov: ipDetail?.province,
city: ipDetail.city, city: ipDetail?.city,
district: ipDetail.district, district: ipDetail?.district,
ip: IpInfo, // ip: IpInfo,
} }
session.set('basicInfo', ipRes); session.set('basicInfo', ipRes);
setBaseInfo(ipRes) setBaseInfo(ipRes)

View File

@ -12,5 +12,22 @@ export async function handleGetIPDetail(params: any) {
return [] return []
} }
return data.content.address_detail if (data.content) {
return data.content.address_detail
}
return null
}
// 同步点餐商品的接口
export async function handleNewJavasyncCommodityList(params: any) {
const data = await request(`/third-party/syncCommodityList`, {
method: 'GET',
params
})
if (data.Result_Code === 500) {
return []
}
return data
} }

View File

@ -132,25 +132,25 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
ellipsis: true, ellipsis: true,
hideInSearch: true, hideInSearch: true,
}, },
{ // {
dataIndex: 'FIELDENUM_STATUS', // dataIndex: 'FIELDENUM_STATUS',
title: '有效状态', // title: '有效状态',
align: 'center', // align: 'center',
width: 120, // width: 120,
ellipsis: true, // ellipsis: true,
valueType: "select", // valueType: "select",
fieldProps: { // fieldProps: {
options: [ // options: [
{ label: '有效', value: "1" }, // { label: '有效', value: "1" },
{ label: '无效', value: "0" } // { label: '无效', value: "0" }
] // ]
}, // },
// valueEnum: { // // valueEnum: {
// "1": "有效", // // "1": "有效",
// "0": "无效" // // "0": "无效"
// }, // // },
initialValue: "1" // initialValue: "1"
}, // },
{ {
dataIndex: 'FIELDENUM_DESC', dataIndex: 'FIELDENUM_DESC',
title: '备注说明', title: '备注说明',
@ -226,12 +226,12 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
req = { req = {
...currentRow, ...currentRow,
...res, ...res,
FIELDENUM_STATUS: 1,
} }
} else { } else {
req = { req = {
...res, ...res,
FIELDEXPLAIN_ID: FIELDEXPLAIN_ID, FIELDENUM_STATUS: 1,
FIELDENUM_PID: -1,
} }
} }
const data = await handeSynchroFIELDENUM(req) const data = await handeSynchroFIELDENUM(req)
@ -250,6 +250,22 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
} }
} }
const markDisabled = (nodes: any, disabledIds: any) => {
return nodes.map((node: any) => {
const copy = { ...node };
if (disabledIds.includes(copy.FIELDENUM_ID)) {
copy.disabled = true;
}
if (copy.children && Array.isArray(copy.children)) {
copy.children = markDisabled(copy.children, disabledIds);
}
return copy;
});
};
return ( return (
<PageContainer header={{ <PageContainer header={{
title: '', title: '',
@ -272,7 +288,7 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
FIELDEXPLAIN_FIELD: 'AFTERSALE_TYPE', FIELDEXPLAIN_FIELD: 'AFTERSALE_TYPE',
FIELDEXPLAIN_ID: "", FIELDEXPLAIN_ID: "",
FIELDENUM_PID: "", FIELDENUM_PID: "",
FIELDENUM_STATUS: params?.FIELDENUM_STATUS, FIELDENUM_STATUS: 1,
SearchKey: "" SearchKey: ""
} }
const data = await handeGetNestingFIELDENUMList(req); const data = await handeGetNestingFIELDENUMList(req);
@ -353,8 +369,10 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
setCurrentRow(undefined); setCurrentRow(undefined);
}} }}
footer={<ModalFooter footer={<ModalFooter
confirmLoading={confirmLoading}
hideDelete={!currentRow?.FIELDENUM_ID} hideDelete={!currentRow?.FIELDENUM_ID}
handleDelete={async () => { handleDelete={async () => {
handleConfirmLoading(true)
await handelDelete(currentRow?.FIELDENUM_ID) await handelDelete(currentRow?.FIELDENUM_ID)
}} }}
handleCancel={() => { handleCancel={() => {
@ -421,14 +439,15 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
}} }}
> >
<Row gutter={8}> <Row gutter={8}>
{/* <Col span={12}> <Col span={12}>
<ProFormTreeSelect <ProFormTreeSelect
name="FIELDENUM_PID" name="FIELDENUM_PID"
label="上级类别" label="上级类别"
request={async () => { request={async () => {
if (typeTreeData && typeTreeData.length > 0) { if (typeTreeData && typeTreeData.length > 0) {
let list: any = [{ FIELDENUM_NAME: "默认类别", FIELDENUM_ID: -1 }, ...typeTreeData] let list: any = [{ FIELDENUM_NAME: "默认类别", FIELDENUM_ID: -1 }, ...typeTreeData]
return list let res = markDisabled(list, currentRow?.FIELDENUM_ID ? [currentRow.FIELDENUM_ID] : [])
return res
} else { } else {
const req = { const req = {
FIELDEXPLAIN_FIELD: 'AFTERSALE_TYPE', FIELDEXPLAIN_FIELD: 'AFTERSALE_TYPE',
@ -440,8 +459,9 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
const data = await handeGetNestingFIELDENUMList(req); const data = await handeGetNestingFIELDENUMList(req);
if (data && data.length > 0) { if (data && data.length > 0) {
data.unshirft({ FIELDENUM_NAME: "默认类别", FIELDENUM_ID: -1 }) data.unshirft({ FIELDENUM_NAME: "默认类别", FIELDENUM_ID: -1 })
let res = markDisabled(data, currentRow?.FIELDENUM_ID ? [currentRow.FIELDENUM_ID] : [])
setTypeTreeData(data) setTypeTreeData(data)
return data return res
} else { } else {
return [{ FIELDENUM_NAME: "默认类别", FIELDENUM_ID: -1 }] return [{ FIELDENUM_NAME: "默认类别", FIELDENUM_ID: -1 }]
} }
@ -464,7 +484,7 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
} }
]} ]}
/> />
</Col> */} </Col>
<Col span={12}> <Col span={12}>
<ProFormText <ProFormText
name="FIELDENUM_NAME" name="FIELDENUM_NAME"
@ -501,7 +521,7 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
]} ]}
/> />
</Col> </Col>
<Col span={12}> {/* <Col span={12}>
<ProFormSelect <ProFormSelect
name="FIELDENUM_STATUS" name="FIELDENUM_STATUS"
label="有效状态" label="有效状态"
@ -513,7 +533,7 @@ const AfterSalesManage: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
} }
]} ]}
/> />
</Col> </Col> */}
<Col span={24}> <Col span={24}>
<ProFormTextArea <ProFormTextArea
name="FIELDENUM_DESC" name="FIELDENUM_DESC"

View File

@ -9,7 +9,7 @@ import Draggable from 'react-draggable';
import SubMenu from "antd/lib/menu/SubMenu"; import SubMenu from "antd/lib/menu/SubMenu";
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
import ProDescriptions from '@ant-design/pro-descriptions'; import ProDescriptions from '@ant-design/pro-descriptions';
import ProForm, { ProFormDatePicker, ProFormDateTimePicker, ProFormDateTimeRangePicker, ProFormMoney, ProFormSelect, ProFormText, ProFormTextArea, ProFormUploadButton } from '@ant-design/pro-form'; import ProForm, { ProFormDatePicker, ProFormDateTimePicker, ProFormDateTimeRangePicker, ProFormMoney, ProFormSelect, ProFormText, ProFormTextArea, ProFormTreeSelect, ProFormUploadButton } from '@ant-design/pro-form';
import { MenuFoldOutlined, PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; import { MenuFoldOutlined, PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-layout'; import { PageContainer } from '@ant-design/pro-layout';
import { Button, Col, Drawer, message, Row, Popconfirm, Space, Image, Modal, Form, Switch, Upload, Tooltip, Descriptions, TreeSelect, Tabs } from 'antd'; import { Button, Col, Drawer, message, Row, Popconfirm, Space, Image, Modal, Form, Switch, Upload, Tooltip, Descriptions, TreeSelect, Tabs } from 'antd';
@ -20,7 +20,7 @@ import type { ActionType, ProColumns } from '@ant-design/pro-table';
import type { ProDescriptionsItemProps } from '@ant-design/pro-descriptions'; import type { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import type { FormInstance } from 'antd'; import type { FormInstance } from 'antd';
import PageTitleBox from '@/components/PageTitleBox'; import PageTitleBox from '@/components/PageTitleBox';
import { handeGetUSERDEFINEDTYPEList, handlDeleteUSERDEFINEDTYPE, handlSynchroUSERDEFINEDTYPE } from '../service'; import { handeGetUSERDEFINEDTYPEList, handlDeleteUSERDEFINEDTYPE, handlGetUSERDEFINEDTYPEList, handlSynchroUSERDEFINEDTYPE } from '../service';
import { render } from 'react-dom'; import { render } from 'react-dom';
import { uploadAHYDPicture, uploadPicture } from '@/services/picture'; import { uploadAHYDPicture, uploadPicture } from '@/services/picture';
import { handleSetlogSave } from '@/utils/format'; import { handleSetlogSave } from '@/utils/format';
@ -242,6 +242,19 @@ const HomepageAds: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
} }
}; };
const processTreeData = (data: any) => {
return data.map((item: any) => {
if (item.children && item.children.length > 0) {
return {
...item,
disabled: true, // 有子节点的节点禁用
children: processTreeData(item.children)
};
}
return item;
});
};
return ( return (
<div style={{ backgroundColor: "#fff" }}> <div style={{ backgroundColor: "#fff" }}>
<div style={{ width: '100%', boxSizing: 'border-box', padding: '24px' }}> <div style={{ width: '100%', boxSizing: 'border-box', padding: '24px' }}>
@ -253,7 +266,7 @@ const HomepageAds: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
{ {
selectTab === "1" ? selectTab === "1" ?
<ProTable <ProTable
scroll={{ x: "100%" }} scroll={{ x: "100%", y: 'calc(100vh - 440px)' }}
formRef={formRef} formRef={formRef}
actionRef={actionRef} actionRef={actionRef}
search={false} search={false}
@ -294,7 +307,7 @@ const HomepageAds: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
{ {
selectTab === "2" ? selectTab === "2" ?
<ProTable <ProTable
scroll={{ x: "100%" }} scroll={{ x: "100%", y: 'calc(100vh - 440px)' }}
formRef={formRef} formRef={formRef}
actionRef={actionRef} actionRef={actionRef}
search={false} search={false}
@ -404,8 +417,10 @@ const HomepageAds: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
</Draggable> </Draggable>
}} }}
footer={<ModalFooter footer={<ModalFooter
confirmLoading={confirmLoading}
hideDelete={!currentRow?.USERDEFINEDTYPE_ID} hideDelete={!currentRow?.USERDEFINEDTYPE_ID}
handleDelete={async () => { handleDelete={async () => {
handleConfirmLoading(true)
await handelDelete(currentRow?.USERDEFINEDTYPE_ID) await handelDelete(currentRow?.USERDEFINEDTYPE_ID)
}} }}
handleCancel={() => { handleCancel={() => {
@ -483,7 +498,32 @@ const HomepageAds: React.FC<{ currentUser: CurrentUser | undefined }> = (props)
initialValue={1000} initialValue={1000}
/> />
</Col> </Col>
{/* 这个字段暂时用来 判断跳转小程序分类页面的 哪个分类 */}
<Col span={12}> <Col span={12}>
<ProFormTreeSelect
label={'跳转路径'}
name={'SERVERPARTSHOP_ID'}
request={async () => {
const req = {
OWNERUNIT_ID: currentUser?.OwnerUnitId,
PROVINCE_CODE: "",
GOODSTYPE: 4000,
USERDEFINEDTYPE_STATE: 1
}
const data = await handlGetUSERDEFINEDTYPEList(req);
return data
}}
fieldProps={{
fieldNames: {
label: "USERDEFINEDTYPE_NAME",
value: "USERDEFINEDTYPE_ID"
},
showSearch: true,
treeDefaultExpandAll: true,
}}
/>
</Col>
<Col span={24}>
<ProFormUploadButton <ProFormUploadButton
name="USERDEFINEDTYPE_ICO" name="USERDEFINEDTYPE_ICO"
label="上传附件" label="上传附件"

View File

@ -32,6 +32,7 @@ import OrderCategoryTreeMultiple from './components/OrderCategoryTreeMultiple';
import Item from 'antd/lib/list/Item'; import Item from 'antd/lib/list/Item';
import { handleSetlogSave } from '@/utils/format'; import { handleSetlogSave } from '@/utils/format';
import { highlightText } from '@/utils/highlightText'; import { highlightText } from '@/utils/highlightText';
import { handleNewJavasyncCommodityList } from '@/pages/User/login/service';
const beforeUpload = (file: any) => { const beforeUpload = (file: any) => {
@ -371,7 +372,10 @@ const OrderProductManage: React.FC<{ currentUser: CurrentUser | undefined }> = (
const data = await handeSyncSellerCommodityInfo({ list: [req] }) const data = await handeSyncSellerCommodityInfo({ list: [req] })
handleConfirmLoading(false) handleConfirmLoading(false)
if (data.Result_Code === 100) { if (data.Result_Code === 100) {
console.log('currentRowcurrentRowcurrentRow', currentRow);
handleSetlogSave(`${currentRow?.COMMODITY_ID ? '更新' : '新增'}${data.Result_Data?.COMMODITY_NAME}】成功`) handleSetlogSave(`${currentRow?.COMMODITY_ID ? '更新' : '新增'}${data.Result_Data?.COMMODITY_NAME}】成功`)
handleUpdateCommodityList(JSON.parse(JSON.stringify(currentRow)))
message.success("同步成功!") message.success("同步成功!")
setCurrentRow(undefined) setCurrentRow(undefined)
formRef?.current?.resetFields() formRef?.current?.resetFields()
@ -384,6 +388,17 @@ const OrderProductManage: React.FC<{ currentUser: CurrentUser | undefined }> = (
} }
}; };
// 调用java的更新商户商品的方法
const handleUpdateCommodityList = async (obj: any) => {
const req: any = {
serverpartshopId: obj.SERVERPARTSHOP_IDS,
provinceCode: "530000"
}
const data = await handleNewJavasyncCommodityList(req)
console.log('datadata', data);
}
// 上传商品图片 // 上传商品图片
const handleUploadShopImg = async (formRes: any) => { const handleUploadShopImg = async (formRes: any) => {
@ -841,6 +856,12 @@ const OrderProductManage: React.FC<{ currentUser: CurrentUser | undefined }> = (
label="商品图片" label="商品图片"
listType="picture-card" listType="picture-card"
accept="image/*" accept="image/*"
rules={[
{
required: true,
message: "请上传商品图片!"
}
]}
fieldProps={{ fieldProps={{
beforeUpload, beforeUpload,
maxCount: 1, maxCount: 1,

View File

@ -0,0 +1,319 @@
import { connect } from "umi";
import type { ConnectState } from "@/models/connect";
import { useImperativeHandle, useState } from "react";
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 = {
USERDEFINEDTYPE_ID: string | number;
USERDEFINEDTYPE_NAME: string;
children?: TreeDataType[];
};
type DetailProps = {
leftTreeData?: TreeDataType[]
onRef?: any
};
const SelectSetMealItems = ({ leftTreeData, onRef }: DetailProps) => {
// 判断用户是否点击了 添加套餐商品的按钮
const [isClickAdd, setIsClickAdd] = useState<boolean>(false);
// 表格数据
const [tableData, setTableData] = useState<TableDataType[]>([
{
id: Date.now(),
name: '',
barcode: '',
category: '',
unit: '',
specification: '',
price: undefined,
taxRate: undefined,
taxCode: '',
}
]);
// 表格列定义
const columns: ProColumns<TableDataType>[] = [
{
title: '商品名称',
width: 250,
align: 'center',
dataIndex: 'name',
render: (_, record: TableDataType) => (
<Input
style={{ width: '100%' }}
value={record.name}
placeholder="请输入商品名称"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, name: e.target.value };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '条码',
width: 150,
align: 'center',
dataIndex: 'barcode',
render: (_, record: TableDataType) => (
<Input
style={{ width: '100%' }}
value={record.barcode}
placeholder="请输入商品条码"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, barcode: e.target.value };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
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: '单位',
width: 120,
align: 'center',
dataIndex: 'unit',
render: (_, record: TableDataType) => (
<Input
style={{ width: '100%' }}
value={record.unit}
placeholder="请输入商品单位"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, unit: e.target.value };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '规格',
width: 120,
align: 'center',
dataIndex: 'specification',
render: (_, record: TableDataType) => (
<Input
style={{ width: '100%' }}
value={record.specification}
placeholder="请输入商品规格"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, specification: e.target.value };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '价格',
width: 120,
align: 'center',
dataIndex: 'price',
render: (_, record: TableDataType) => (
<InputNumber
style={{ width: '100%' }}
value={record.price}
placeholder="请输入商品价格"
onChange={(value) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, price: value as number };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '税率',
width: 120,
align: 'center',
dataIndex: 'taxRate',
render: (_, record: TableDataType) => (
<InputNumber
style={{ width: '100%' }}
value={record.taxRate}
placeholder="请输入商品税率"
onChange={(value) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, taxRate: value as number };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '税务代码',
width: 120,
align: 'center',
dataIndex: 'taxCode',
render: (_, record: TableDataType) => (
<Input
style={{ width: '100%' }}
value={record.taxCode}
placeholder="请输入商品税务代码"
onChange={(e) => {
const newData = tableData.map((item: TableDataType) => {
if (item.id === record.id) {
return { ...item, taxCode: e.target.value };
}
return item;
});
setTableData(newData);
}}
/>
),
},
{
title: '操作',
align: 'center',
valueType: 'option',
width: 60,
render: (_, record: TableDataType) => [
<a
key="delete"
onClick={() => {
const newData = tableData.filter((item: TableDataType) => item.id !== record.id);
setTableData(newData);
}}
>
</a>,
],
},
];
// 暴露表格数据
useImperativeHandle(onRef, () => ({
tableData
}));
return (
<div>
{
isClickAdd ?
<div>
<ProTable
rowKey="id"
headerTitle="套餐商品"
columns={columns}
dataSource={tableData}
pagination={false}
search={false}
options={false}
bordered
toolBarRender={() => [
<Button
key="add"
type={'primary'}
onClick={() => {
const newData = {
id: Date.now(),
name: '',
barcode: '',
category: '',
unit: '',
specification: '',
price: undefined,
taxRate: undefined,
taxCode: '',
};
setTableData([...tableData, newData]);
}}
>
</Button>,
<Button onClick={() => {
setIsClickAdd(false)
}}>
</Button>
]}
/>
</div> :
<div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
<Button type={'primary'} onClick={() => {
setIsClickAdd(true)
}}></Button>
</div>
}
</div>
)
}
export default connect(({ user, }: ConnectState) => ({
currentUser: user.currentUser,
}))(SelectSetMealItems);

View File

@ -33,6 +33,7 @@ import { handlecsyncWeChatGetMallGoodsInfo, handlecsyncWeChatGetMallGoodsInfoAll
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import RelevanceCoupon from './component/RelevanceCoupon'; import RelevanceCoupon from './component/RelevanceCoupon';
import { handleGetCOUPONList } from '@/pages/CardInformation/service'; import { handleGetCOUPONList } from '@/pages/CardInformation/service';
import SelectSetMealItems from './component/SelectSetMealItems';
const beforeUpload = (file: any) => { const beforeUpload = (file: any) => {
@ -51,6 +52,7 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
const { currentUser } = props const { currentUser } = props
const { confirm } = Modal; const { confirm } = Modal;
const associatedCouponsModalRef = useRef<any>() const associatedCouponsModalRef = useRef<any>()
const setSelectSetMealItemsRef = useRef<any>()
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
const ruleActionRef = useRef<ActionType>(); const ruleActionRef = useRef<ActionType>();
// 税率的表单 // 税率的表单
@ -1504,7 +1506,6 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
name="USERDEFINEDTYPE_ID" name="USERDEFINEDTYPE_ID"
label="商品分类" label="商品分类"
request={async () => { request={async () => {
return leftTreeData return leftTreeData
}} }}
fieldProps={{ fieldProps={{
@ -1650,6 +1651,8 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
label="商品简称" label="商品简称"
/> />
</Col> </Col>
<Divider orientation="left"></Divider> <Divider orientation="left"></Divider>
<Col span={6}> <Col span={6}>
<ProFormSelect <ProFormSelect
@ -2053,6 +2056,11 @@ const COMMODITYTable: React.FC<{ currentUser: CurrentUser | undefined }> = (prop
}} }}
/> />
</Col> </Col>
{/* 若是一个套餐商品 那么这里就要有一个录入套餐商品的地方 */}
<Col span={24}>
<SelectSetMealItems onRef={setSelectSetMealItemsRef} leftTreeData={leftTreeData} />
</Col>
</Row> </Row>
</ProForm> </ProForm>
</Modal> </Modal>

View File

@ -59,7 +59,7 @@ const request = extend({
errorHandler, // default error handling errorHandler, // default error handling
// prefix: '/EShangApiMain',// 开发 // prefix: '/EShangApiMain',// 开发
prefix: 'https://java.es.eshangtech.com:443', // 正式 prefix: 'https://java.es.eshangtech.com:443', // 正式
// prefix: 'http://111.229.213.193:18071', // 正式 // prefix: 'http://111.229.213.193:18071', // 测试
headers: { headers: {
token: '', token: '',
ProvinceCode: '', ProvinceCode: '',

View File

@ -1,4 +1,4 @@
// 由 scripts/writeVersion.js 自动生成 // 由 scripts/writeVersion.js 自动生成
export const VERSION = "4.5.90"; export const VERSION = "4.5.91";
export const GIT_HASH = "e555058"; export const GIT_HASH = "24088d3";
export const BUILD_TIME = "2025-12-12T09:26:16.901Z"; export const BUILD_TIME = "2025-12-16T11:26:58.433Z";