Commit d4ddcfbe authored by 左玲玲's avatar 左玲玲 😬

用户,租赁客户

parent b2288f17
...@@ -302,4 +302,17 @@ export default [ ...@@ -302,4 +302,17 @@ export default [
}, },
], ],
}, },
{
name: '租赁管理',
path: '/lease',
icon: 'laptop',
routes: [
{
name: '租赁客户',
path: '/lease/custom',
icon: '',
component: './lease/custom',
}
],
},
]; ];
...@@ -33,7 +33,7 @@ import { doFetch } from '@/utils/doFetch'; ...@@ -33,7 +33,7 @@ import { doFetch } from '@/utils/doFetch';
import moment from 'moment'; import moment from 'moment';
import { useAsyncEffect, useRequest } from 'ahooks'; import { useAsyncEffect, useRequest } from 'ahooks';
import * as Antd from 'antd'; import * as Antd from 'antd';
import { PlusOutlined, DownOutlined, CloseOutlined, RedoOutlined } from '@ant-design/icons'; import { PlusOutlined, DownOutlined, CloseOutlined, RedoOutlined, UploadOutlined } from '@ant-design/icons';
import BraftEditor from 'braft-editor'; import BraftEditor from 'braft-editor';
import EditTable from './EditTable'; import EditTable from './EditTable';
import EditorItem from './EditorItem'; import EditorItem from './EditorItem';
...@@ -53,6 +53,7 @@ const { ...@@ -53,6 +53,7 @@ const {
message, message,
AutoComplete, AutoComplete,
Row, Row,
Button
} = Antd; } = Antd;
const AntdCheckBox = Antd.Checkbox; const AntdCheckBox = Antd.Checkbox;
...@@ -1172,96 +1173,72 @@ function Slider({ item, colProps }) { ...@@ -1172,96 +1173,72 @@ function Slider({ item, colProps }) {
); );
} }
//uploadbtn function UploadImg({ value, onChange, fieldProps, valueType }) {
function UploadBtn({ item, colProps }) { let allValue = value?.map(it => {
let token = `Bearer ${localStorage.getItem('TOKENES')}`; if (!it.response) {
return ( return it;
<> } else {
<ProFormUploadButton if (it?.response?.code == "0000") {
fieldProps={{ return { ...it };
...item?.fieldProps, } else {
action: defaultSetting.proxypath + '/base/sysAttachment/uploadFile', return undefined;
headers: { Authorization: token }, }
onPreview: (file) => { }
let url = ''; });
if (file.response) {
url = file.response.data.dataList[0].url;
} else if (file.url) {
url = file.url;
} else {
url = file.thumbUrl;
}
window.open(url);
},
}}
transform={(value) => {
const key = item?.key ?? item?.dataIndex;
const transvalue = value?.map((it) => {
if (it.response) {
return it?.response?.data?.dataList[0];
} else {
return it;
}
});
return {
[key]: transvalue,
};
}}
formItemProps={item.formItemProps}
name={item?.key ?? item?.dataIndex}
colProps={item.colProps ?? colProps}
label={item.title}
title={`上传${item.title}`}
max={item.max}
/>
</>
);
}
function UploadImg({ value, onChange, fieldProps }) {
let token = `Bearer ${localStorage.getItem('TOKENES')}`;
const [image, setImage] = useState({}); const [image, setImage] = useState({});
let token = `Bearer ${localStorage.getItem('TOKENES')}`;
const flag = value?.some(it => it.status == "done" && it?.response?.code != "0000"),
newValue = value?.filter(it => it.status == "done" && it?.response?.code == "0000");
function beforeUpload(file) { function beforeUpload(file) {
const isJpgOrPng = let itemSize = fieldProps.size ?? 10;
file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png'; const isLtM = file.size / 1024 / 1024 < itemSize;
if (!isJpgOrPng) { if (!isLtM) {
message.error('只能上传.jpg/.jpeg/.png图片!'); message.error(`上传文件或图片大小不能超过${itemSize}MB`);
return; }
let isJpgOrPng;
if (valueType == "uploadImage") {
isJpgOrPng =
file.type === "image/jpg" ||
file.type === "image/jpeg" ||
file.type === "image/png";
if (!isJpgOrPng) {
message.error("只能上传.jpg/.jpeg/.png图片!");
return;
}
return (isJpgOrPng && isLtM) || Upload.LIST_IGNORE;
} }
return true; return isLtM || Upload.LIST_IGNORE;
} }
// maxCount 最大数量
const defaultconfig = { const defaultconfig = {
name: 'file', name: "file",
action: defaultSetting.proxypath + '/base/sysAttachment/uploadFile', action: defaultSetting.proxypath + '/base/sysAttachment/uploadFile',
accept: '.jpg,.png,.jpeg', accept: valueType == "uploadImage" ? ".jpg,.png,.jpeg" : '',
listType: 'picture-card', listType: valueType == "uploadImage" ? "picture-card" : "picture",
beforeUpload: beforeUpload, beforeUpload: beforeUpload,
defaultFileList: value, fileList: flag ? newValue : allValue ?? [],
headers: { Authorization: token }, headers: { Authorization: token },
maxCount: fieldProps.limit ? fieldProps.limit : 1000,
onChange(info) { onChange(info) {
let { let {
file: { name, status, response }, file: { status, response },
fileList, fileList,
event,
} = info; } = info;
onChange(fileList);
if (response && response?.code != "0000") {
message.destroy();
message.error(response?.msg);
}
if (status == 'error') { if (status == 'error') {
message.error(`${info.file.name} 上传失败`); message.error(`${info.file.name} 上传失败`);
} else if (status === 'done') {
const transfile = fileList.map((it) => {
return it?.response ? it?.response?.data?.dataList[0] : it;
});
onChange(transfile);
} }
}, },
onRemove(file) { onRemove(file) {
let uid = file?.response?.data?.dataList[0]?.uid ?? file?.uid; let uid = file?.response?.data?.dataList?.[0]?.uid ?? file?.uid;
let newvalue = value?.filter((it) => it.uid != uid); let newvalue = value?.filter((it) => it?.uid != uid);
onChange(newvalue); onChange(newvalue);
}, },
onPreview(file) { onPreview(file) {
let url = ''; let url = "";
if (file.response) { if (file.response) {
url = file.response.data.dataList[0].url; url = file.response.data.dataList[0].url;
} else if (file.url) { } else if (file.url) {
...@@ -1274,15 +1251,18 @@ function UploadImg({ value, onChange, fieldProps }) { ...@@ -1274,15 +1251,18 @@ function UploadImg({ value, onChange, fieldProps }) {
visible: true, visible: true,
}); });
}, },
className: "upload-list-inline"
}; };
const uploadButton = ( const uploadButton = valueType == "uploadImage" ? <div>
<div> <PlusOutlined />
<PlusOutlined /> <div style={{ marginTop: 8 }}>上传图片</div>
<div style={{ marginTop: 8 }}>上传图片</div> </div> :
</div> valueType == "uploadBtn" ?
); <Button icon={<UploadOutlined />}>上传文件</Button>
//console.log(value?.length, fieldProps.limit); :
null;
const limit = fieldProps.limit ? fieldProps.limit : 1000;
return ( return (
<> <>
<Image <Image
...@@ -1291,7 +1271,7 @@ function UploadImg({ value, onChange, fieldProps }) { ...@@ -1291,7 +1271,7 @@ function UploadImg({ value, onChange, fieldProps }) {
height={0} height={0}
preview={{ preview={{
visible: image?.visible, visible: image?.visible,
onVisibleChange: (e) => { onVisibleChange: () => {
if (image?.visible) { if (image?.visible) {
setImage((s) => ({ setImage((s) => ({
...s, ...s,
...@@ -1301,34 +1281,53 @@ function UploadImg({ value, onChange, fieldProps }) { ...@@ -1301,34 +1281,53 @@ function UploadImg({ value, onChange, fieldProps }) {
}, },
}} }}
/> />
{fieldProps?.crop ? ( {
<ImgCrop valueType == "uploadDragger" ?
rotate <Dragger {...defaultconfig}>
grid <p className="ant-upload-drag-icon">
quality={1} <InboxOutlined />
shape={fieldProps?.crop?.shape ?? 'rect'} //裁切区域形状,'rect' 或 'round' </p>
aspect={fieldProps?.crop?.aspect ?? 1 / 1} //裁切区域宽高比,width / height <p className="ant-upload-text">单击或拖动文件到此区域进行上传</p>
> </Dragger>
:
<Upload {...defaultconfig}> <Upload {...defaultconfig}>
{!value ? uploadButton : value?.length < fieldProps.limit ? uploadButton : null} {value && value.length > limit - 1 && !flag
? null
: uploadButton}
</Upload> </Upload>
</ImgCrop> }
) : (
<Upload {...defaultconfig}>
{!value ? uploadButton : value?.length < fieldProps.limit ? uploadButton : null}
</Upload>
)}
</> </>
); );
} }
//uploadbtn
function UploadBtn({ item, colProps }) {
let col = item.colProps ?? colProps;
return (
<Col {...col}>
<Form.Item
name={item.key ?? item.dataIndex}
label={item.title}
{...item.formItemProps}
>
<UploadImg fieldProps={{ ...item?.fieldProps }} valueType={item.valueType} />
</Form.Item>
</Col>
);
}
//upload Image //upload Image
function UploadImage({ item, colProps }) { function UploadImage({ item, colProps }) {
let col = item.colProps ?? colProps; let col = item.colProps ?? colProps;
return ( return (
<Col {...col}> <Col {...col}>
<Form.Item name={item?.key ?? item?.dataIndex} label={item.title} {...item.formItemProps}> <Form.Item
<UploadImg fieldProps={{ ...item?.fieldProps }} /> name={item.key ?? item.dataIndex}
label={item.title}
{...item.formItemProps}
>
<UploadImg fieldProps={{ ...item?.fieldProps }} valueType={item.valueType} />
</Form.Item> </Form.Item>
</Col> </Col>
); );
...@@ -1336,46 +1335,18 @@ function UploadImage({ item, colProps }) { ...@@ -1336,46 +1335,18 @@ function UploadImage({ item, colProps }) {
// uploadDragger // uploadDragger
function UploadDragger({ item, colProps }) { function UploadDragger({ item, colProps }) {
let token = `Bearer ${localStorage.getItem('TOKENES')}`; let col = item.colProps ?? colProps;
return ( return (
<> <Col {...col}>
<ProFormUploadDragger <Form.Item
fieldProps={{ name={item.key ?? item.dataIndex}
...item?.fieldProps,
action: defaultSetting.proxypath + '/base/sysAttachment/uploadFile',
headers: { Authorization: token },
onPreview: (file) => {
let url = '';
if (file.response) {
url = file.response.data.dataList[0].url;
} else if (file.url) {
url = file.url;
} else {
url = file.thumbUrl;
}
window.open(url);
},
}}
transform={(value) => {
const key = item?.key ?? item?.dataIndex;
const transvalue = value?.map((it) => {
if (it.response) {
return it?.response?.data?.dataList[0];
} else {
return it;
}
});
return {
[key]: transvalue,
};
}}
formItemProps={item.formItemProps}
name={item?.key ?? item?.dataIndex}
colProps={item.colProps ?? colProps}
label={item.title} label={item.title}
/> {...item.formItemProps}
</> >
); <UploadImg fieldProps={{ ...item?.fieldProps }} valueType={item.valueType} />
</Form.Item>
</Col>
)
} }
// editor // editor
......
...@@ -109,16 +109,50 @@ function InitForm(props) { ...@@ -109,16 +109,50 @@ function InitForm(props) {
style = {}, style = {},
} = props; } = props;
const { run } = useDebounceFn(onFinish, { wait: 400 }); // const { run } = useDebounceFn(onFinish, { wait: 400 });
let proformRef = useRef(); let proformRef = useRef();
proformRef = formRef ?? proformRef; proformRef = formRef ?? proformRef;
function formartData(item, val) {
let formartValue = val;
if (item.valueType == 'uploadBtn' || item.valueType == "uploadImage" || item.valueType == "uploadDragger") {
let stepval = val?.filter(it => {
if (!it?.response) {
return it;
} else {
if (it?.response?.code == "0000") {
return it;
}
}
}) ?? [];
formartValue = stepval.map((it) => {
if (it.response) {
if (it.response.code != "0000") {
return undefined;
}
return it?.response?.data?.dataList[0] ?? undefined;
} else {
return it ? it : undefined;
}
});
}
return formartValue;
}
return fields?.length == 0 ? ( return fields?.length == 0 ? (
<ColumnsTrans /> <ColumnsTrans />
) : ( ) : (
<ProForm <ProForm
style={{ overflow: 'hidden', ...style }} style={{ overflow: 'hidden', ...style }}
formRef={proformRef} formRef={proformRef}
onFinish={run} onFinish={async (values) => {
let newAllvalues = {};
for (let i in values) {
newAllvalues[i] = formartData(fields?.find(it => it.key == i), values[i]);
}
await onFinish(newAllvalues);
}}
formKey={formKey ?? parseInt(Math.random() * 1000000)} formKey={formKey ?? parseInt(Math.random() * 1000000)}
params={params} params={params}
submitter={submitter ?? true} submitter={submitter ?? true}
......
import { Tooltip } from "antd";
function getcolumns(setdrawer) {
return {
columns: [
{
title: '客户编号',
dataIndex: 'f1',
key: 'f1',
formItemProps: { rules: [{ required: true, message: '此项为必填项' }] },
colProps: { span: 8 },
},
{
title: '客户名称',
dataIndex: 'f2',
key: 'f2',
formItemProps: { rules: [{ required: true, message: '此项为必填项' }] },
colProps: { span: 8 },
render: (_, row) => {
return (
<Tooltip title={row.f2}>
<a
className="table-cell"
onClick={() => {
setdrawer((s) => ({
...s,
visible: true,
item: row,
val: 'detailaddon',
title: '客户信息'
}));
}}
>
{row.f2}
</a>
</Tooltip>
);
},
},
{
title: '负责工厂',
dataIndex: 'f3',
key: 'f3',
valueType: 'select',
options: { path: '/', params: {} },
formItemProps: { rules: [{ required: true, message: '此项为必填项' }] },
colProps: { span: 8 },
},
{ title: '企业法人', dataIndex: 'f4', key: 'f4', colProps: { span: 8 }, hideInSearch: true },
{ title: '联系电话', dataIndex: 'f5', key: 'f5', colProps: { span: 8 }, hideInSearch: true },
{
title: '产值',
dataIndex: 'f6',
key: 'f6',
colProps: { span: 8 },
hideInTable: true,
hideInSearch: true,
},
{
title: '所属行业',
dataIndex: 'f7',
key: 'f7',
colProps: { span: 8 },
hideInTable: true,
hideInSearch: true,
},
{
title: '地址',
dataIndex: 'f8',
key: 'f8',
colProps: { span: 8 },
hideInTable: true,
hideInSearch: true,
},
{
title: '纳税人识别号',
dataIndex: 'f9',
key: 'f9',
colProps: { span: 8 },
hideInSearch: true,
},
{
title: '开户行银行',
dataIndex: 'f10',
key: 'f10',
colProps: { span: 8 },
hideInSearch: true,
},
{
title: '收款账户',
dataIndex: 'f11',
key: 'f11',
colProps: { span: 8 },
hideInSearch: true,
},
{
title: '所属区域',
dataIndex: 'f12',
key: 'f12',
colProps: { span: 8 },
valueType: 'select',
mode: 'multiple',
formItemProps: { rules: [{ required: true, message: '此项为必填项' }] },
options: { path: '/', params: {} },
hideInSearch: true,
},
{
title: '企业简介',
dataIndex: 'f13',
key: 'f13',
hideInSearch: true,
hideInTable: true,
valueType: 'textarea',
colProps: { span: 24 },
},
{
title: '附件上传(最多5个)',
dataIndex: 'f14',
key: 'f14',
hideInSearch: true,
hideInTable: true,
valueType: 'uploadBtn',
colProps: { span: 24 },
fieldProps: {
limit: 5,
},
},
],
pathconfig: {
add: '',
edit: '',
list: '',
delete: '',
},
};
}
export default getcolumns;
import React, { useState, useMemo, useRef, useEffect } from 'react';
import DrawerPro from '@/components/DrawerPro';
import AutoTable from '@/components/AutoTable';
import PremButton from '@/components/PremButton';
import getcolumns from './columns';
import { doFetch } from '@/utils/doFetch';
import { useRequest } from "ahooks";
const Custom = () => {
let actionRef = useRef();
const [drawer, setdrawer] = useState({
visible: false,
});
const { run, loading, runAsync } = useRequest(doFetch, {
manual: true,
onSuccess: (res, params) => {
if (res?.code == "0000") {
actionRef?.current?.reload();
setdrawer((s) => ({
...s,
visible: false,
}));
}
},
});
const edit = (text, row, _, action) => {
return (
<PremButton
key='edit'
btn={{
size: 'small',
onClick: () => {
setdrawer((s) => ({
...s,
visible: true,
item: row,
val: 'edit',
title: '编辑'
}));
},
}}
>
编辑
</PremButton>
);
};
const remove = (text, row, _, action) => {
return (
<PremButton
key='remove'
pop={{
title: '是否删除该客户?',
okText: '确认',
cancelText: '取消',
onConfirm: async () => {
let res = await doFetch({ url: urlParams.remove, params: { id: row.id } });
if (res.code === '0000') {
actionRef.current.reload();
}
},
}}
btn={{
size: 'small',
type: 'danger',
}}
>
删除
</PremButton>
);
};
const columns = useMemo(() => {
let defcolumn = getcolumns(setdrawer)?.columns ?? [];
return defcolumn.concat({
title: '操作',
valueType: 'option',
width: 150,
render: (text, row, _, action) => [edit(text, row, _, action), remove(text, row, _, action)],
});
}, []);
const pathconfig = useMemo(() => {
let pathconf = getcolumns(setdrawer)?.pathconfig ?? {};
return pathconf;
}, []);
return <div>
<AutoTable
pagetitle={<h3 className="page-title">客户管理</h3>}
columns={columns}
path={pathconfig?.list}
// dataSource={[{ 'f1': '111', 'f2': '222', id: 1 }]}
actionRef={actionRef}
pageextra={'add'}
resizeable={false}
addconfig={{
// access: 'sysDepartment_save',
btn: {
type: 'primary',
disabled: false,
onClick: () => {
// let res = await doFetch({url:})
setdrawer((s) => ({
...s,
visible: true,
item: {},
params: {},
title: '新增',
val: 'add'
}));
},
},
}}
/>
<DrawerPro
fields={columns}
// detailpath={drawer.type == 'add' ? '' : drawer?.detailpath}
params={{ id: drawer?.item?.id }}
defaultFormValue={drawer?.item ?? {}}
detailData={drawer?.item ?? {}}
placement="right"
onClose={() => {
setdrawer((s) => ({
...s,
visible: false,
}));
}}
{...drawer}
onFinish={async (vals) => {
if (drawer?.val == "add") {
await runAsync({ url: pathconfig?.add, params: { ...vals } });
} else if (drawer?.val == "edit") {
await runAsync({
url: pathconfig?.edit,
params: { ...vals, id: drawer?.item?.id },
});
}
}}
>
</DrawerPro>
</div>
}
export default Custom;
\ No newline at end of file
...@@ -215,6 +215,61 @@ function getcolumns(setDrawer, ifs, formRef) { ...@@ -215,6 +215,61 @@ function getcolumns(setDrawer, ifs, formRef) {
hideInForm: true, hideInForm: true,
hideInTable: true, hideInTable: true,
}, },
{
title: '用户类型',
dataIndex: 'f1',
key: 'f1',
formItemProps: {
rules: [
{
required: true,
message: '此项为必填项',
},
],
},
colProps: {
span: 12,
},
valueType: 'select',
mode: 'radio',
options: [
{
label: '平台用户',
value: '1',
},
{
label: '租户用户',
value: '2',
},
],
},
{
title: '所属客户',
dataIndex: 'f2',
key: 'f2',
formItemProps: {
rules: [
{
required: true,
message: '此项为必填项',
},
],
},
colProps: {
span: 12,
},
valueType: 'select',
mode: 'radio',
options: {
path: '',
params: {},
},
hideInForm: {
f1: {
reverse: ['2'],
},
},
},
{ {
title: '角色名称', title: '角色名称',
dataIndex: 'roleNames', dataIndex: 'roleNames',
...@@ -236,7 +291,7 @@ function getcolumns(setDrawer, ifs, formRef) { ...@@ -236,7 +291,7 @@ function getcolumns(setDrawer, ifs, formRef) {
searchKey: 'factoryNames', searchKey: 'factoryNames',
searchValueType: 'input', searchValueType: 'input',
options: { path: '/auth/sysFactory/getAllFactorySelection', params: {} }, options: { path: '/auth/sysFactory/getAllFactorySelection', params: {} },
showAll: true showAll: true,
}, },
{ {
title: '负责车间', title: '负责车间',
...@@ -258,6 +313,7 @@ function getcolumns(setDrawer, ifs, formRef) { ...@@ -258,6 +313,7 @@ function getcolumns(setDrawer, ifs, formRef) {
}, },
key: 'shopIdList', key: 'shopIdList',
formItemProps: { rules: [{ required: false, message: '此项为必填项' }] }, formItemProps: { rules: [{ required: false, message: '此项为必填项' }] },
showAll: true,
}, },
{ {
title: '负责工段', title: '负责工段',
...@@ -279,6 +335,7 @@ function getcolumns(setDrawer, ifs, formRef) { ...@@ -279,6 +335,7 @@ function getcolumns(setDrawer, ifs, formRef) {
shopIdList: '', shopIdList: '',
}, },
}, },
showAll: true,
}, },
{ {
title: '负责产线', title: '负责产线',
...@@ -299,6 +356,7 @@ function getcolumns(setDrawer, ifs, formRef) { ...@@ -299,6 +356,7 @@ function getcolumns(setDrawer, ifs, formRef) {
shopIdList: '', shopIdList: '',
}, },
}, },
showAll: true,
}, },
{ {
title: '角色配置', title: '角色配置',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment