ylj20011123 8540a9d612 update
2025-07-17 19:51:49 +08:00

828 lines
38 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 卡券信息管理
import { connect } from "umi";
import type { CurrentUser } from "umi";
import type { ConnectState } from "@/models/connect";
import React, { useRef, useState } from "react";
import ProCard from "@ant-design/pro-card";
import { ExclamationCircleOutlined, MenuFoldOutlined } from "@ant-design/icons";
import type { FormInstance } from "antd";
import { Button, Col, Divider, message, Modal, Popconfirm, Row, Space, Spin, Tree, Image } from "antd";
import useRequest from "@ahooksjs/use-request";
import { getFieldEnum, getServerpartTree } from "@/services/options";
import type { ActionType } from "@ant-design/pro-table";
import ProTable from "@ant-design/pro-table";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
import LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
import PageTitleBox from "@/components/PageTitleBox";
import { handleDeleteCOUPON, handleGetCOOPSHOP_RULEList, handleGetCOUPONList, handleSynchroCOUPONService } from "../service";
import ProForm, { ProFormDatePicker, ProFormSelect, ProFormText, ProFormTextArea, ProFormUploadButton } from "@ant-design/pro-form";
import session from "@/utils/session";
import './index.less'
import { handleSetlogSave } from "@/utils/format";
import moment from 'moment'
import { uploadPicture } from "@/services/picture";
import ModalFooter from "@/pages/travelMember/scenicSpotConfig/component/modalFooter";
const beforeUpload = (file: any) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('请上传JPEG、jpg、png格式的图片文件!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片大小不超过 2MB!');
}
return isJpgOrPng && isLt2M;
}
const CardInformationManager: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
const { confirm } = Modal;
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const ModalFormRef = useRef<FormInstance>();
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [collapsible, setCollapsible] = useState<boolean>(false)
const [treeView, setTreeView] = useState<any>()
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
const COUPONTYPEObj = session.get('COUPONTYPEObj')
const COUPONTYPEList = session.get('COUPONTYPEList')
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
// 是否显示打印的表格
const [showExportTable, setShowExportTable] = useState<boolean>(false)
// 查询的条件
const [searchParams, setSearchParams] = useState<any>()
// 显示详情的抽屉
const [showDetail, setShowDetail] = useState<boolean>(false)
// 当前行数据
const [currentRow, setCurrentRow] = useState<any>()
// 悬浮框 按钮加载的属性
const [modalLoading, setModalLoading] = useState<boolean>(false)
// 适用门店选择列表
const [COOPSHOPRULEIDOPTIONS, setCOOPSHOPRULEIDOPTIONS] = useState<any>()
// 文件列表
const [fileList, setFileList] = useState<any>([])
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false) // 预览图片
// 预览上传后的图片
const handlePreview = async () => {
setFileList(fileList)
setImagePreviewVisible(true)
};
const handleChangePreview = (val: any) => {
setImagePreviewVisible(val)
}
const columns: any = [
{
title: "序号",
dataIndex: "index",
width: 70,
hideInSearch: true,
valueType: 'index',
align: 'center',
},
{
title: "优惠券类型",
dataIndex: "COUPON_TYPES",
valueType: 'select',
valueEnum: COUPONTYPEObj,
hideInTable: true,
},
{
title: "卡券名称",
dataIndex: "COUPON_NAME",
align: 'left',
hideInSearch: true,
ellipsis: true,
render: (_, record) => {
return record?.COUPON_NAME ? <a onClick={() => {
setShowDetail(true)
setCurrentRow(record)
if (record.COUPON_IMAGEURL) {
setFileList([
{ name: "-", url: record.COUPON_IMAGEURL }
])
}
}}>{record?.COUPON_NAME}</a> : "-"
}
},
{
title: "运营单位",
dataIndex: "OPERATINGUNIT_NAME",
width: 200,
align: 'left',
hideInSearch: true,
ellipsis: true,
},
{
title: "发放数量",
dataIndex: "COUPON_QUOTA",
width: 120,
align: 'center',
hideInSearch: true,
ellipsis: true,
render: (_, record) => {
return record?.COUPON_QUOTA === -1 ? '不限量' : record?.COUPON_QUOTA
}
},
{
title: "活动开始时间",
dataIndex: "START_TIME",
width: 150,
align: 'center',
hideInSearch: true,
ellipsis: true,
},
{
title: "活动结束时间",
dataIndex: "END_TIME",
width: 150,
align: 'center',
hideInSearch: true,
ellipsis: true,
},
// {
// title: "操作",
// dataIndex: "options",
// width: 120,
// align: 'center',
// hideInSearch: true,
// render: (_, record) => {
// return <Space>
// <a onClick={() => {
// console.log('record', record);
// setShowDetail(true)
// setCurrentRow(record)
// if (record.COUPON_IMAGEURL) {
// setFileList([
// { name: "-", url: record.COUPON_IMAGEURL }
// ])
// }
// }}>
// 编辑
// </a>
// <Popconfirm title={"确认删除该规则?"} onConfirm={async () => {
// await handleDeleteShopRule(record?.COOPSHOP_RULE_ID)
// }}>
// <a>删除</a>
// </Popconfirm>
// </Space>
// }
// }
]
// 删除的方法
const handleDeleteShopRule = async (id: any) => {
const req: any = {
COUPONId: id
}
const data = await handleDeleteCOUPON(req)
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
actionRef.current?.reload()
ModalFormRef?.current?.resetFields()
setCurrentRow(null)
setShowDetail(false)
setFileList([])
} else {
message.error(data.Result_Desc)
}
}
// 同步的方法
const handleSynchroCOUPON = async (res: any) => {
let req: any = {}
if (currentRow?.COUPON_ID) {
req = {
...currentRow,
...res,
END_TIME: moment(res.END_TIME).format("YYYY-MM-DD"),
START_TIME: moment(res.START_TIME).format("YYYY-MM-DD"),
VALID_END_TIME: moment(res.VALID_END_TIME).format("YYYY-MM-DD"),
VALID_START_TIME: moment(res.VALID_START_TIME).format("YYYY-MM-DD"),
UPDATE_STAFF_ID: currentUser?.ID,
UPDATE_STAFF_NAME: currentUser?.Name,
UPDATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
COUPON_IMAGEURL: fileList && fileList.length > 0 ? fileList[0].url : "",
}
} else {
req = {
...res,
END_TIME: moment(res.END_TIME).format("YYYY-MM-DD"),
START_TIME: moment(res.START_TIME).format("YYYY-MM-DD"),
VALID_END_TIME: moment(res.VALID_END_TIME).format("YYYY-MM-DD"),
VALID_START_TIME: moment(res.VALID_START_TIME).format("YYYY-MM-DD"),
COUPON_IMAGEURL: fileList && fileList.length > 0 ? fileList[0].url : "",
CREATE_STAFF_ID: currentUser?.ID,
CREATE_STAFF_NAME: currentUser?.Name,
CREATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
}
}
console.log('reqreqreqreq', req);
const data = await handleSynchroCOUPONService(req)
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
ModalFormRef?.current?.resetFields()
setCurrentRow(undefined)
setShowDetail(false)
actionRef.current?.reload()
} else {
message.error(data.Result_Desc)
}
handleSetlogSave(currentRow?.COOPSHOP_RULE_ID ? '卡券的编辑' : '卡券的新增')
}
return (
<div ref={(el) => {
// 打印报表
if (!reqDetailList || reqDetailList.length === 0) return;
setPrintOut(el);
}} >
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<div style={{
width: '100%',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
expandable={{
expandRowByClick: true
}}
// headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>单品销售排行统计</span>}
headerTitle={<PageTitleBox props={props} />}
search={{ span: 6 }}
request={async (params) => {
const req: any = {
SearchParameter: {
OWNERUNIT_ID: 911,
COUPON_TYPES: params?.COUPON_TYPES || "",
COUPON_ISVALID: 1
},
PageIndex: 1,
PageSize: 999999
}
setSearchParams(params)
const data = await handleGetCOUPONList(req)
if (data && data.length > 0) {
return { data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<Button type="primary" onClick={() => {
setShowDetail(true)
}}>
</Button>
]
}}
/>
</div>
</div>
{/* 图片预览组件 */}
{fileList && fileList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
handleChangePreview(vis)
}
}}>
{
fileList.map((n) => <Image src={n.url} key={n.url} />)
}
</Image.PreviewGroup>
</div>}
<Modal
open={showDetail}
className={"CardInformationManager"}
onCancel={() => {
ModalFormRef?.current?.resetFields()
setCurrentRow(null)
setShowDetail(false)
setFileList([])
}}
confirmLoading={modalLoading}
width={900}
bodyStyle={{
height: '700px', // 你可以根据需要调整高度
overflowY: 'auto',
}}
destroyOnClose
title={currentRow?.COUPON_ID ? currentRow?.COUPON_NAME : "新增卡券"}
onOk={() => {
ModalFormRef?.current?.validateFields().then(async (res) => {
await handleSynchroCOUPON(res)
})
}}
footer={<ModalFooter
hideDelete={!currentRow?.COUPON_ID}
handleDelete={async () => {
await handleDeleteShopRule(currentRow?.COUPON_ID)
}}
handleCancel={() => {
ModalFormRef?.current?.resetFields()
setCurrentRow(null)
setShowDetail(false)
setFileList([])
}}
handleOK={() => {
ModalFormRef?.current?.validateFields().then(async (res) => {
await handleSynchroCOUPON(res)
})
}}
/>}
>
<div className="CardInformationManagerModalContent" style={{}}>
<ProForm formRef={ModalFormRef} layout={'horizontal'} submitter={false} labelCol={{ style: { width: 80 } }} initialValues={{
...currentRow,
OWNERUNIT_ID: currentRow?.OWNERUNIT_ID || currentUser?.OwnerUnitId,
COUPON_TYPE: currentRow?.COUPON_TYPE ? currentRow?.COUPON_TYPE : COUPONTYPEList && COUPONTYPEList.length > 0 ? COUPONTYPEList[0].value : "",
CATEGORY_RULE_ID: currentRow?.CATEGORY_RULE_ID || 0,
PAY_METHOD: currentRow?.PAY_METHOD || 1000,
COOPSHOP_RULE_ID: currentRow?.COOPSHOP_RULE_ID ? currentRow?.COOPSHOP_RULE_ID : (COOPSHOPRULEIDOPTIONS && COOPSHOPRULEIDOPTIONS.lengtg > 0 ? COOPSHOPRULEIDOPTIONS[0].value : ""),
VALID_TYPE: currentRow?.VALID_TYPE || 1000,
OVERLAY: currentRow?.OVERLAY || 0,
LIMIT_COUNT: currentRow?.LIMIT_COUNT || -1,
LIMIT_COUNT_PERDAY: currentRow?.LIMIT_COUNT_PERDAY || -1,
COUPON_ISVALID: currentRow?.COUPON_ISVALID || currentRow?.COUPON_ISVALID === 0 ? currentRow?.COUPON_ISVALID : 1
}}>
<Divider orientation="left"></Divider>
<Row gutter={8}>
<Col span={16}>
<ProFormSelect
label={"发券业主"}
name={"OWNERUNIT_ID"}
options={[
{ label: currentUser?.OwnerUnitName, value: currentUser?.OwnerUnitId }
]}
rules={[
{
required: true,
message: '请选择发券业主'
}
]}
disabled={currentRow?.COUPON_ID}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"卡券类型"}
name={"COUPON_TYPE"}
options={COUPONTYPEList}
rules={[
{
required: true,
message: '请选择卡券类型'
}
]}
/>
</Col>
<Col span={8}>
<ProFormText
label={"卡券名称"}
name={"COUPON_NAME"}
rules={[
{
required: true,
message: '请输入卡券名称'
}
]}
/>
</Col>
<Col span={8}>
<ProFormText
label={"卡券成本"}
name={"COST_AMOUNT"}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"发售即用"}
name={"CATEGORY_RULE_ID"}
rules={[
{
required: true,
message: '请选择发售类型'
}
]}
options={[
{ label: '是', value: 1 },
{ label: '否', value: 0 },
]}
/>
</Col>
<Col span={8}>
<Row>
<Col span={12}>
<ProFormText
label={"购买满:"}
name={"WITH_AMOUNT"}
rules={[
{
required: true,
message: '请输入满足条件'
}
]}
/>
</Col>
<Col span={12}>
<ProFormText
label={"减:"}
name={"USED_AMOUNT"}
rules={[
{
required: true,
message: '请输入减免金额'
}
]}
/>
</Col>
</Row>
</Col>
<Col span={8}>
<ProFormDatePicker
width="lg"
label={"活动时间"}
name={"START_TIME"}
rules={[
{
required: true,
message: '请选择活动时间'
}
]}
/>
</Col>
<Col span={8}>
<ProFormDatePicker
width="lg"
label={"截止时间"}
name={"END_TIME"}
rules={[
{
required: true,
message: '请选择截止时间'
}
]}
/>
</Col>
<Col span={8}>
<ProFormText
label={"发放数量"}
name={"COUPON_QUOTA"}
rules={[
{
required: true,
message: '请输入发放数量'
}
]}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"消费模式"}
name={"PAY_METHOD"}
options={[
{ label: "直接领取", value: 1000 },
{ label: "积分兑换", value: 2000 },
]}
rules={[
{
required: true,
message: '请选择消费模式'
}
]}
/>
</Col>
<Col span={8}>
<ProFormText
label={"积分兑换"}
name={"COUPON_POINT"}
/>
</Col>
<Col span={24}>
<ProFormTextArea
label={"使用说明"}
name={"COUPON_INSTRUCTIONS"}
rules={[
{
required: true,
message: '请输入使用说明'
}
]}
/>
</Col>
</Row>
<Divider orientation="left"></Divider>
<Row gutter={8}>
<Col span={8}>
<ProFormSelect
label={"适用门店"}
name={"COOPSHOP_RULE_ID"}
request={async () => {
const req: any = {
SearchParameter: {
OWNERUNIT_ID: 911,
ISVALID: 1
},
PageIndex: 1,
PageSize: 999999
}
const data = await handleGetCOOPSHOP_RULEList(req)
let list: any = []
console.log('data', data);
if (data && data.length > 0) {
data.forEach((item: any) => {
list.push({ label: item.COOPSHOP_RULE_NAME, value: item.COOPSHOP_RULE_ID })
})
}
setCOOPSHOPRULEIDOPTIONS(list)
return list
}}
rules={[
{
required: true,
message: '请选择适用门店'
}
]}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"使用期限"}
name={"VALID_TYPE"}
options={[
{ label: "固定时间段", value: 1000 },
{ label: "固定天数", value: 2000 },
]}
rules={[
{
required: true,
message: '请选择使用期限'
}
]}
/>
</Col>
<Col span={8}>
<Row gutter={16}>
<Col span={12}>
<ProFormDatePicker
label={"有效日期"}
name={"VALID_START_TIME"}
rules={[
{
required: true,
message: '请选择有效开始日期'
}
]}
/>
</Col>
<Col span={12}>
<ProFormDatePicker
label={""}
name={"VALID_END_TIME"}
rules={[
{
required: true,
message: '请选择有效结束日期'
}
]}
/>
</Col>
</Row>
</Col>
<Col span={8}>
<ProFormSelect
label={"允许叠加"}
name={"OVERLAY"}
options={[
{ label: "否", value: 0 },
{ label: "是", value: 1 },
]}
rules={[
{
required: true,
message: '请选择叠加规则'
}
]}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"限领数量"}
name={"LIMIT_COUNT"}
options={[
{ label: "不限量", value: -1 },
{ label: "1", value: 1 },
{ label: "2", value: 2 },
{ label: "3", value: 3 },
{ label: "4", value: 4 },
{ label: "5", value: 5 },
{ label: "6", value: 6 },
{ label: "7", value: 7 },
{ label: "8", value: 8 },
{ label: "9", value: 9 },
{ label: "10", value: 10 },
]}
rules={[
{
required: true,
message: '请选择限领数量'
}
]}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"每日限领"}
name={"LIMIT_COUNT_PERDAY"}
options={[
{ label: "不限量", value: -1 },
{ label: "1", value: 1 },
{ label: "2", value: 2 },
{ label: "3", value: 3 },
{ label: "4", value: 4 },
{ label: "5", value: 5 },
{ label: "6", value: 6 },
{ label: "7", value: 7 },
{ label: "8", value: 8 },
{ label: "9", value: 9 },
{ label: "10", value: 10 },
]}
rules={[
{
required: true,
message: '请选择每日限领'
}
]}
/>
</Col>
</Row>
<Divider orientation="left"></Divider>
<Row gutter={8}>
<Col span={8}>
<ProFormSelect
label={"小程序"}
name={"WECHATAPPSIGN_ID"}
options={[
{ label: "彩云驿", value: 37 },
{ label: "彩云驿商城", value: 38 },
]}
rules={[
{
required: true,
message: '请选择小程序'
}
]}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"是否有效"}
name={"COUPON_ISVALID"}
options={[
{ label: "否", value: 0 },
{ label: "是", value: 1 },
]}
rules={[
{
required: true,
message: '请选择是否有效'
}
]}
/>
</Col>
</Row>
<Divider orientation="left"></Divider>
<Row>
<Col span={24}>
<ProFormTextArea
label={"详情介绍"}
name={"COUPON_DESC"}
/>
</Col>
<Col span={24}>
<ProFormTextArea
label={"适用门店"}
name={"COOPSHOP_DESC"}
/>
</Col>
</Row>
<Divider orientation="left"></Divider>
<Row>
<Col span={24}>
<ProFormUploadButton
label={"卡券图标"}
name={"COUPON_IMAGEURL"}
fileList={fileList}
listType="picture-card"
accept="image/*"
fieldProps={{
beforeUpload,
maxCount: 1,
onPreview: handlePreview,
customRequest: async (info) => {
const formData = new FormData();
formData.append('files', info.file);
formData.append('TableType', '1208');
formData.append('ImageName', typeof info.file !== 'string' ? info.file?.name : '');
if (info.filename) {
const success = await uploadPicture(formData)
if (success) {
const list = [{
// uid: `${success.ImageId}`, // 注意这个uid一定不能少否则上传失败
name: success.Result_Data.ImageName,
// status: 'done',
url: success.Result_Data.ImageUrl, // url 是展示在页面上的绝对链接
// imgUrl: success.ImagePath // + success.ImageUrl,
}]
setFileList(list)
}
} else {
message.error("您上传的图片不存在.")
}
},
onChange: async (info: any) => {
if (info.file.status === 'removed') {
confirm({
title: '确认删除该图片吗?',
icon: <ExclamationCircleOutlined rev={undefined} />,
async onOk() {
console.log('infoinfoinfoinfo', info);
setFileList([])
// const deleteLoading = message.loading('正在删除...')
// try {
// const deleteIndex = fileList?.findIndex((n: any) => n.uid === info.file.uid)
// const success = await deletePicture(info.file?.ImagePath, info.file?.ImageId, '1208')
// if (deleteIndex !== -1) {
// const files = [...fileList]
// files.splice(deleteIndex, 1)
// setFileList(files)
// }
// deleteLoading()
// return true
// } catch (error) {
// deleteLoading()
// return false
// }
}
});
}
}
}}
/>
</Col>
</Row>
</ProForm>
</div>
</Modal>
</div>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(CardInformationManager);