314 lines
9.1 KiB
TypeScript
314 lines
9.1 KiB
TypeScript
import { PlusOutlined } from '@ant-design/icons';
|
||
import {
|
||
ActionType,
|
||
ProColumns,
|
||
ProFormInstance,
|
||
ProFormSelect,
|
||
ProFormText,
|
||
ProFormUploadButton,
|
||
ProFormDependency,
|
||
} from '@ant-design/pro-components';
|
||
import { ModalForm, PageContainer, ProTable } from '@ant-design/pro-components';
|
||
import '@umijs/max';
|
||
import { Button, message } from 'antd';
|
||
import { Select } from 'antd';
|
||
import { createStyles } from 'antd-style';
|
||
import dayjs from 'dayjs';
|
||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||
|
||
import { CITY_OPTIONS } from '@/constants/city';
|
||
import { TIME_FORMAT } from '@/constants/global';
|
||
import { uploadFileWx } from '@/services/file';
|
||
import {
|
||
deleteCityOperator,
|
||
getAllStaffList,
|
||
getCityOpratorList,
|
||
getProductList,
|
||
updateCityOperator,
|
||
} from '@/services/list';
|
||
|
||
const useStyles = createStyles(({ token }) => {
|
||
return {
|
||
img: {
|
||
width: 100,
|
||
height: 100,
|
||
},
|
||
delete: {
|
||
color: token.colorError,
|
||
},
|
||
button: {
|
||
marginRight: '8px',
|
||
},
|
||
};
|
||
});
|
||
|
||
const calcPrice = (productSpecId: string, specList: API.ProductSpecListItem[]) => {
|
||
const product = specList.find(o => o.productSpecId === productSpecId);
|
||
return { price: product?.showPrice, originalPrice: product?.originalPrice, sendCount: product?.count };
|
||
};
|
||
const TableList: React.FC = () => {
|
||
const [updateModalOpen, handleUpdateModalOpen] = useState<boolean>(false);
|
||
const [specList, setSpecList] = useState<API.ProductSpecListItem[]>([]);
|
||
const [currentRow, setCurrentRow] = useState<API.CityOperatorListItem>();
|
||
const actionRef = useRef<ActionType>();
|
||
const formRef = useRef<ProFormInstance>();
|
||
const [staffOptions, setStaffOptions] = useState<Array<{ label: string; value: number; isDefault: boolean }>>([]);
|
||
const defaultStaff = useMemo(() => {
|
||
return staffOptions.find(it => it.isDefault) || staffOptions[0];
|
||
}, [staffOptions]);
|
||
const { styles } = useStyles();
|
||
const specOptions = useMemo(
|
||
() =>
|
||
specList.map(it => ({
|
||
value: it.productSpecId,
|
||
label: it.title,
|
||
})),
|
||
[specList],
|
||
);
|
||
|
||
const getAllStaffOptions = async () => {
|
||
try {
|
||
const results = await getAllStaffList();
|
||
setStaffOptions(
|
||
results.map(it => ({
|
||
label: `${it.staffName}${it.isDefault ? ' (默认)' : ''}`,
|
||
isDefault: Boolean(it.isDefault),
|
||
value: it.id,
|
||
})),
|
||
);
|
||
} catch (e) {
|
||
} finally {
|
||
}
|
||
};
|
||
|
||
const getAllSpectList = async () => {
|
||
const list = await getProductList('GROUP_BATCH_PUSH');
|
||
setSpecList(list);
|
||
};
|
||
|
||
const handleDelete = async (id: number) => {
|
||
await deleteCityOperator(id);
|
||
message.success('操作成功');
|
||
actionRef.current?.reload();
|
||
};
|
||
const handleUpload = async (file: File) => {
|
||
const url = await uploadFileWx({ file, id: currentRow?.id });
|
||
return url;
|
||
};
|
||
useEffect(() => {
|
||
getAllStaffOptions();
|
||
getAllSpectList();
|
||
}, []);
|
||
|
||
const columns: ProColumns<API.CityOperatorListItem>[] = [
|
||
{
|
||
title: '城市',
|
||
dataIndex: 'cityCode',
|
||
valueType: 'textarea',
|
||
render: (_text, record) => record.cityName,
|
||
renderFormItem() {
|
||
return (
|
||
<Select
|
||
showSearch
|
||
allowClear
|
||
options={CITY_OPTIONS}
|
||
filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
|
||
/>
|
||
);
|
||
},
|
||
},
|
||
{
|
||
title: '运营',
|
||
dataIndex: 'staffName',
|
||
valueType: 'textarea',
|
||
search: false,
|
||
},
|
||
{
|
||
title: '创建时间',
|
||
dataIndex: 'created',
|
||
valueType: 'dateTime',
|
||
renderText(created: string) {
|
||
return dayjs(created).format(TIME_FORMAT);
|
||
},
|
||
search: false,
|
||
},
|
||
{
|
||
title: '进群链接',
|
||
dataIndex: 'groupLink',
|
||
valueType: 'textarea',
|
||
search: false,
|
||
},
|
||
{
|
||
title: '企微好友二维码',
|
||
dataIndex: 'contactQrCode',
|
||
valueType: 'textarea',
|
||
copyable: true,
|
||
search: false,
|
||
render(_dom, { contactQrCode }) {
|
||
return contactQrCode ? <img className={styles.img} src={contactQrCode} alt="" /> : '-';
|
||
},
|
||
},
|
||
{
|
||
title: '进群二维码',
|
||
dataIndex: 'groupQrCode',
|
||
valueType: 'textarea',
|
||
copyable: true,
|
||
search: false,
|
||
render(_dom, { groupQrCode }) {
|
||
return groupQrCode ? <img className={styles.img} src={groupQrCode} alt="" /> : '-';
|
||
},
|
||
},
|
||
{
|
||
title: '可群发数量',
|
||
dataIndex: 'productSpecId',
|
||
valueType: 'textarea',
|
||
search: false,
|
||
renderText: productSpecId => calcPrice(productSpecId, specList).sendCount || '-',
|
||
},
|
||
{
|
||
title: '群代发价格',
|
||
dataIndex: 'productSpecId',
|
||
valueType: 'textarea',
|
||
search: false,
|
||
renderText: productSpecId => calcPrice(productSpecId, specList).price || '-',
|
||
},
|
||
{
|
||
title: '操作',
|
||
valueType: 'option',
|
||
render: (_, record) => (
|
||
<>
|
||
<a
|
||
key="config"
|
||
className={styles.button}
|
||
onClick={() => {
|
||
handleUpdateModalOpen(true);
|
||
setCurrentRow(record);
|
||
setTimeout(() => {
|
||
formRef.current?.setFieldsValue({
|
||
...record,
|
||
city: {
|
||
label: record.cityName,
|
||
value: record.cityCode,
|
||
},
|
||
qrCode: record.groupQrCode
|
||
? [
|
||
{
|
||
uid: `${record.id}_qrCode`,
|
||
name: `${record.cityName}_qrCode`,
|
||
status: 'done',
|
||
url: record.groupQrCode,
|
||
},
|
||
]
|
||
: undefined,
|
||
});
|
||
});
|
||
}}
|
||
>
|
||
修改
|
||
</a>
|
||
<a key="delete" className={styles.delete} onClick={() => handleDelete(record.id)}>
|
||
删除
|
||
</a>
|
||
</>
|
||
),
|
||
},
|
||
];
|
||
return (
|
||
<PageContainer>
|
||
<ProTable<API.CityOperatorListItem, API.PageParams>
|
||
headerTitle="查询表格"
|
||
actionRef={actionRef}
|
||
rowKey="key"
|
||
search={{ labelWidth: 120, collapsed: false, collapseRender: false }}
|
||
request={getCityOpratorList}
|
||
columns={columns}
|
||
toolBarRender={() => [
|
||
<Button
|
||
type="primary"
|
||
key="add"
|
||
icon={<PlusOutlined />}
|
||
onClick={() => {
|
||
handleUpdateModalOpen(true);
|
||
setCurrentRow(undefined);
|
||
formRef.current?.resetFields();
|
||
}}
|
||
>
|
||
新增
|
||
</Button>,
|
||
]}
|
||
/>
|
||
<ModalForm
|
||
title={`${currentRow ? '修改' : '新增'}城市`}
|
||
width="400px"
|
||
formRef={formRef}
|
||
initialValues={{ staffId: defaultStaff?.value }}
|
||
open={updateModalOpen}
|
||
onOpenChange={handleUpdateModalOpen}
|
||
onFinish={async formData => {
|
||
const params: API.UpdateCityOperator = {
|
||
id: currentRow?.id,
|
||
staffId: formData.staffId,
|
||
cityCode: formData.city.value,
|
||
cityName: formData.city.label,
|
||
groupLink: formData.groupLink,
|
||
productSpecId: formData.productSpecId,
|
||
groupQrCode: formData.qrCode[0].xhr ? formData.qrCode[0].xhr.responseURL : formData.qrCode[0].url,
|
||
};
|
||
console.log('update confirm', formData, params);
|
||
try {
|
||
await updateCityOperator(params);
|
||
actionRef.current?.reload();
|
||
formRef.current?.resetFields();
|
||
} catch (e) {}
|
||
handleUpdateModalOpen(false);
|
||
}}
|
||
>
|
||
<ProFormSelect.SearchSelect
|
||
name="city"
|
||
mode="single"
|
||
label="所属城市"
|
||
options={CITY_OPTIONS}
|
||
rules={[{ required: true, message: '必填项' }]}
|
||
/>
|
||
<ProFormSelect
|
||
mode="single"
|
||
name="staffId"
|
||
showSearch
|
||
label="运营"
|
||
options={staffOptions}
|
||
rules={[{ required: true, message: '必填项' }]}
|
||
/>
|
||
<ProFormText name="groupLink" label="进群链接" rules={[{ message: '请输入链接', type: 'url' }]} />
|
||
<ProFormUploadButton
|
||
name="qrCode"
|
||
label="进群二维码"
|
||
max={1}
|
||
accept="image/*"
|
||
rules={[{ required: true, message: '必填项' }]}
|
||
fieldProps={{
|
||
name: 'file',
|
||
}}
|
||
action={handleUpload}
|
||
/>
|
||
<ProFormSelect
|
||
mode="single"
|
||
name="productSpecId"
|
||
label="可群发数量"
|
||
options={specOptions}
|
||
rules={[{ required: true, message: '必填项' }]}
|
||
/>
|
||
<ProFormDependency name={['productSpecId']}>
|
||
{({ productSpecId }) =>
|
||
productSpecId ? (
|
||
<div>
|
||
价格:{calcPrice(productSpecId, specList).price}(原价:{calcPrice(productSpecId, specList).originalPrice})
|
||
</div>
|
||
) : null
|
||
}
|
||
</ProFormDependency>
|
||
</ModalForm>
|
||
</PageContainer>
|
||
);
|
||
};
|
||
export default TableList;
|