diff --git a/package.json b/package.json index 09d3003..79e9f30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ant-design-pro", - "version": "4.5.13", + "version": "4.5.15", "private": true, "description": "An out-of-box UI solution for enterprise applications", "scripts": { @@ -19,7 +19,7 @@ "lint:prettier": "prettier --check \"src/**/*\" --end-of-line auto", "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less", "prettier": "prettier -c --write \"src/**/*\"", - "start": "cross-env NODE_OPTIONS=--max-old-space-size=8192 UMI_ENV=dev umi dev", + "start": "set NODE_OPTIONS=--max-old-space-size=8192 && umi dev", "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev", "start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev", "start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev", @@ -63,6 +63,7 @@ "@umijs/route-utils": "^1.0.33", "ahooks": "^2.10.3", "antd": "^4.17.0", + "aws-sdk": "^2.1692.0", "classnames": "^2.2.6", "compression-webpack-plugin": "^11.1.0", "crypto-js": "^4.1.1", diff --git a/src/assets/ai/editIcon.png b/src/assets/ai/editIcon.png new file mode 100644 index 0000000..292118c Binary files /dev/null and b/src/assets/ai/editIcon.png differ diff --git a/src/pages/CardInformation/CardHaveCollection/index.tsx b/src/pages/CardInformation/CardHaveCollection/index.tsx index a5f5886..c5db437 100644 --- a/src/pages/CardInformation/CardHaveCollection/index.tsx +++ b/src/pages/CardInformation/CardHaveCollection/index.tsx @@ -1,15 +1,234 @@ -// 卡券兑换统计 -import { ConnectState } from "@/models/connect"; -import { connect, CurrentUser } from "umi"; +// 卡券领取统计 +import { connect } from "umi"; +import type { CurrentUser } from "umi"; +import type { ConnectState } from "@/models/connect"; +import React, { useRef, useState } from "react"; +import { Drawer, Modal, type FormInstance } from "antd"; +import type { ActionType } from "@ant-design/pro-table"; +import ProTable from "@ant-design/pro-table"; +import PageTitleBox from "@/components/PageTitleBox"; +import { handeGetCouponStockList } from "@/pages/travelMember/service"; +import moment from 'moment' +import CardVoucherSearch from "../CardVoucherSearch"; + + +const CardHaveCollection: React.FC<{ currentUser: CurrentUser }> = (props) => { + const { currentUser } = props + const actionRef = useRef(); + const formRef = useRef(); + const [reqDetailList, setReqDetailList] = useState(); // 合计项数据源 + const [printOut, setPrintOut] = useState(); // 打印数据的内容 + const [collapsible, setCollapsible] = useState(false) + const [treeView, setTreeView] = useState() + const [printIndex, setPrintIndex] = useState(new Date().getTime()) + + + // 树相关的属性和方法 + const [selectedId, setSelectedId] = useState() + // 导出的加载效果 + const [showLoading, setShowLoading] = useState(false) + // 是否显示打印的表格 + const [showExportTable, setShowExportTable] = useState(false) + // 查询的条件 + const [searchParams, setSearchParams] = useState() + + // 点击行的数据 + const [currentRow, setCurrentRow] = useState() + // 显示详情 + const [showDetial, setShowDetail] = useState() + + const columns: any = [ + { + title: "卡券类型", + dataIndex: "COUPON_TYPE", + width: 120, + align: 'center', + ellipsis: true, + valueType: 'select', + valueEnum: { + "1000": "满减券", + "2000": "折扣券", + "3000": "抵扣券", + "4000": "兑换券", + "5000": "代金券", + "9000": "实物券" + } + }, + { + title: '领取时间', + dataIndex: 'search_date', + valueType: 'dateRange', + hideInTable: true, + hideInDescriptions: true, + search: { + transform: (value) => { + return { + STARTDATE: value[0], + ENDDATE: value[1], + }; + }, + }, + initialValue: [moment().startOf('M').format('YYYY-MM-DD'), moment().add(-1, 'day').format('YYYY-MM-DD')], + }, + { + title: "卡券名称", + width: 250, + dataIndex: "COUPON_NAME", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "发放数量", + dataIndex: "COUPON_QUOTA", + width: 120, + align: 'center', + sorter: (a, b) => a.COUPON_QUOTA - b.COUPON_QUOTA, + hideInSearch: true, + ellipsis: true, + }, + { + title: "领取数量", + dataIndex: "TAKE_COUNT", + width: 120, + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: (a, b) => a.TAKE_COUNT - b.TAKE_COUNT, + render: (_, record) => { + return record?.TAKE_COUNT ? { + setCurrentRow(record) + setShowDetail(true) + }}>{record?.TAKE_COUNT} : "-" + } + }, + { + title: "剩余数量", + dataIndex: "LAST_COUNT", + width: 120, + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: (a, b) => a.LAST_COUNT - b.LAST_COUNT, + }, + { + title: "发放金额", + dataIndex: "QUOTA_AMOUNT", + width: 120, + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: (a, b) => a.QUOTA_AMOUNT - b.QUOTA_AMOUNT, + }, + { + title: "领取金额", + dataIndex: "TAKE_AMOUNT", + width: 120, + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: (a, b) => a.TAKE_AMOUNT - b.TAKE_AMOUNT, + }, + { + title: "活动开始时间", + dataIndex: "START_TIME", + width: 180, + align: 'center', + hideInSearch: true, + ellipsis: true, + render: (_, record) => { + return record?.START_TIME ? moment(record?.START_TIME).format('YYYY-MM-DD') : "-" + } + }, + { + title: "活动结束时间", + dataIndex: "END_TIME", + width: 180, + align: 'center', + hideInSearch: true, + ellipsis: true, + render: (_, record) => { + return record?.END_TIME ? moment(record?.END_TIME).format('YYYY-MM-DD') : "-" + } + }, + ] -const CardHaveCollection: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => { return ( -
+
{ + // 打印报表 + if (!reqDetailList || reqDetailList.length === 0) return; + setPrintOut(el); + }} > +
+
+ 单品销售排行统计} + headerTitle={} + search={{ span: 6 }} + request={async (params) => { + const req: any = { + SearchParameter: { + COUPON_TYPES: params?.COUPON_TYPE || "", + TAKE_TIME_Start: params?.STARTDATE || "",// 开始时间 + TAKE_TIME_End: params?.ENDDATE || "",// 结束时间 + COUPON_ISVALID: 1 + }, + PageIndex: 1, + PageSize: 999999, + sortStr: "END_TIME desc" + } + setSearchParams(params) + const data = await handeGetCouponStockList(req) + console.log('datadatadatadatadata', data); + if (data.List && data.List.length > 0) { + return { data: data.List, success: true } + } + return { data: [], success: true } -
+ }} + toolbar={{ + actions: [ + + ] + }} + /> +
+
+ + + { + setCurrentRow(null) + setShowDetail(false) + }} + > + + +
) } export default connect(({ user }: ConnectState) => ({ currentUser: user.currentUser -}))(CardHaveCollection); \ No newline at end of file +}))(CardHaveCollection); diff --git a/src/pages/CardInformation/CardVoucherCollection/index.tsx b/src/pages/CardInformation/CardVoucherCollection/index.tsx index 6bef61f..18f3ff3 100644 --- a/src/pages/CardInformation/CardVoucherCollection/index.tsx +++ b/src/pages/CardInformation/CardVoucherCollection/index.tsx @@ -1,4 +1,4 @@ -// 卡券库存管理 +// 卡券库存管理 卡券库存查询 import { connect } from "umi"; import type { CurrentUser } from "umi"; import type { ConnectState } from "@/models/connect"; @@ -44,6 +44,8 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => "2000": "折扣券", "3000": "抵扣券", "4000": "兑换券", + "5000": "代金券", + "9000": "实物券" } }, { @@ -79,15 +81,6 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => hideInSearch: true, ellipsis: true, }, - { - title: "发放金额", - dataIndex: "QUOTA_AMOUNT", - width: 120, - align: 'center', - hideInSearch: true, - ellipsis: true, - sorter: (a, b) => a.QUOTA_AMOUNT - b.QUOTA_AMOUNT, - }, { title: "领取数量", dataIndex: "TAKE_COUNT", @@ -97,15 +90,6 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => ellipsis: true, sorter: (a, b) => a.TAKE_COUNT - b.TAKE_COUNT, }, - { - title: "领取金额", - dataIndex: "TAKE_AMOUNT", - width: 120, - align: 'center', - hideInSearch: true, - ellipsis: true, - sorter: (a, b) => a.TAKE_AMOUNT - b.TAKE_AMOUNT, - }, { title: "剩余数量", dataIndex: "LAST_COUNT", @@ -115,6 +99,24 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => ellipsis: true, sorter: (a, b) => a.LAST_COUNT - b.LAST_COUNT, }, + { + title: "发放金额", + dataIndex: "QUOTA_AMOUNT", + width: 120, + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: (a, b) => a.QUOTA_AMOUNT - b.QUOTA_AMOUNT, + }, + { + title: "领取金额", + dataIndex: "TAKE_AMOUNT", + width: 120, + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: (a, b) => a.TAKE_AMOUNT - b.TAKE_AMOUNT, + }, { title: "活动开始时间", dataIndex: "START_TIME", @@ -122,6 +124,9 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => align: 'center', hideInSearch: true, ellipsis: true, + render: (_, record) => { + return record?.START_TIME ? moment(record?.START_TIME).format('YYYY-MM-DD') : "-" + } }, { title: "活动结束时间", @@ -130,6 +135,9 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => align: 'center', hideInSearch: true, ellipsis: true, + render: (_, record) => { + return record?.END_TIME ? moment(record?.END_TIME).format('YYYY-MM-DD') : "-" + } }, ] @@ -166,6 +174,7 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => request={async (params) => { const req: any = { SearchParameter: { + OWNERUNIT_ID: currentUser?.OwnerUnitId, COUPON_TYPES: params?.COUPON_TYPE || "", END_TIME_Start: params?.STARTDATE || "",// 开始时间 START_TIME_End: params?.ENDDATE || "",// 结束时间 @@ -173,6 +182,7 @@ const CardVoucherCollection: React.FC<{ currentUser: CurrentUser }> = (props) => }, PageIndex: 1, PageSize: 999999, + sortStr: "END_TIME desc" } setSearchParams(params) const data = await handeGetCouponStockList(req) diff --git a/src/pages/CardInformation/CardVoucherRedemption/index.tsx b/src/pages/CardInformation/CardVoucherRedemption/index.tsx index e84196d..37aee3b 100644 --- a/src/pages/CardInformation/CardVoucherRedemption/index.tsx +++ b/src/pages/CardInformation/CardVoucherRedemption/index.tsx @@ -1,11 +1,169 @@ -// 卡券领取统计 +// 卡券发放统计 卡券兑换统计 import { ConnectState } from "@/models/connect"; import { connect, CurrentUser } from "umi"; +import SelectCardVouch from "../CardVoucherSearch/components/selectCardVouch"; +import { useRef, useState } from "react"; +import ProTable, { ActionType } from "@ant-design/pro-table"; +import PageTitleBox from "@/components/PageTitleBox"; +import { FormInstance } from "antd"; +import { handeGetCouponExchangeSummary } from "@/pages/travelMember/service"; +import moment from 'moment' const CardVoucherRedemption: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => { + const { currentUser } = props + const actionRef = useRef(); + const formRef = useRef(); + // 树相关的属性和方法 + const [selectedId, setSelectedId] = useState() + const [collapsible, setCollapsible] = useState(false) + + const columns: any = [ + { + title: "卡券类型", + dataIndex: "CouponType", + width: 200, + align: 'center', + ellipsis: true, + valueType: 'select', + valueEnum: { + "1000": "满减券", + "2000": "折扣券", + "3000": "抵扣券", + "4000": "兑换券", + "5000": "代金券", + "9000": "实物券" + } + }, + { + title: '统计时间', + dataIndex: 'search_date', + valueType: 'dateRange', + hideInTable: true, + hideInDescriptions: true, + search: { + transform: (value: any) => { + return { + STARTDATE: value[0], + ENDDATE: value[1], + }; + }, + }, + initialValue: [moment().startOf('M').format('YYYY-MM-DD'), moment().add(-1, 'day').format('YYYY-MM-DD')], + }, + { + title: "卡券名称", + width: 250, + dataIndex: "CouponName", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "服务区名称", + width: 250, + dataIndex: "Serverpart_Name", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "门店名称", + width: 250, + dataIndex: "ServerpartShop_Name", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "使用数量", + width: 150, + dataIndex: "UsedCount", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "订单金额", + width: 150, + dataIndex: "OrderAmount", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "优惠金额", + width: 150, + dataIndex: "CouponAmount", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + { + title: "实付金额", + width: 150, + dataIndex: "PayAmount", + align: 'center', + hideInSearch: true, + ellipsis: true, + }, + ] + return (
+
+ +
+ { + return `${record?.CouponId}-${record?.Serverpart_Id}-${record?.ServerpartShop_Id}` + }} + bordered + expandable={{ + expandRowByClick: true + }} + scroll={{ x: "100%", y: "calc(100vh - 430px)" }} + headerTitle={} // 列表表头 + search={{ span: 6 }} + request={async (params) => { + if (!selectedId) { + return + } + + let req: any = { + OwnerUnitId: currentUser?.OwnerUnitId, + ServerpartId: "", + StartDate: params?.STARTDATE || "", + EndDate: params?.ENDDATE || "", + CouponType: params?.CouponType || "" + } + + let data: any = await handeGetCouponExchangeSummary(req) + + if (data && data.length > 0) { + return { data: data, success: true } + } + return { data: [], success: true } + }} + toolbar={{ + actions: [ + + ] + }} + /> + + + +
+
) } diff --git a/src/pages/CardInformation/CardVoucherSearch/components/selectCardVouch.tsx b/src/pages/CardInformation/CardVoucherSearch/components/selectCardVouch.tsx index a512d6c..d62e1bf 100644 --- a/src/pages/CardInformation/CardVoucherSearch/components/selectCardVouch.tsx +++ b/src/pages/CardInformation/CardVoucherSearch/components/selectCardVouch.tsx @@ -68,13 +68,13 @@ const selectCardVouch = ({ setSelectedId, reload, actionRef, currentUser, width, setTreeView([]) const list: any = [] resList.forEach((item: any) => { - if (item.label.indexOf(value) !== -1) { + if (item.COUPON_NAME.indexOf(value) !== -1) { list.push(item) } else { if (item.children && item.children.length > 0) { const childrenList: any = [] item.children.forEach((subItem: any) => { - if (subItem.label.indexOf(value) !== -1) { + if (subItem.COUPON_NAME.indexOf(value) !== -1) { childrenList.push(subItem) } }) diff --git a/src/pages/CardInformation/CardVoucherSearch/index.tsx b/src/pages/CardInformation/CardVoucherSearch/index.tsx index ede8c77..89ba44a 100644 --- a/src/pages/CardInformation/CardVoucherSearch/index.tsx +++ b/src/pages/CardInformation/CardVoucherSearch/index.tsx @@ -19,8 +19,8 @@ import { handeGetCOUPON_SENDList } from "@/pages/travelMember/service"; import moment from 'moment' -const CardVoucherSearch: React.FC<{ currentUser: CurrentUser }> = (props) => { - const { currentUser } = props +const CardVoucherSearch: React.FC<{ currentUser: CurrentUser, isComponent?: boolean, parentRow?: any }> = (props) => { + const { currentUser, isComponent, parentRow } = props const downloadBtnRef = useRef() const actionRef = useRef(); const formRef = useRef(); @@ -176,10 +176,13 @@ const CardVoucherSearch: React.FC<{ currentUser: CurrentUser }> = (props) => {
+ { + isComponent ? '' : + + } {/* */} -
= (props) => { }} scroll={{ x: "100%", y: "calc(100vh - 410px)" }} headerTitle={} // 列表表头 - search={{ span: 6 }} + search={isComponent ? false : { span: 6 }} request={async (params) => { console.log('selectedIdselectedIdselectedIdselectedId', selectedId); - if (!selectedId) { + if (!selectedId && !isComponent) { return } - const req: any = { - SearchParameter: { - COUPON_IDS: selectedId, - WECHATAPP_APPID: "wxee018fb96955552a", - // 领取时间 - CREATE_DATE_Start: params?.searchType === '1' ? params?.STARTDATE : '', - CREATE_DATE_End: params?.searchType === '1' ? params?.ENDDATE : '', - // 核销时间 - USED_DATE_Start: params?.searchType === '2' ? params?.STARTDATE : '', - USED_DATE_End: params?.searchType === '2' ? params?.ENDDATE : '', - COUPON_STATE: params?.COUPON_STATE || "" - }, - PageIndex: 1, - PageSize: 999999, - // keyWord: { - // Key: "SELLER_NAME,MEMBERSHIP_NAME", - // Value: params?.searchText || "" - // }, - // SortStr: "CREATE_DATE desc" + let req: any = {} + if (isComponent) { + parentRow + req = { + SearchParameter: { + COUPON_IDS: parentRow?.COUPON_ID, + WECHATAPP_APPID: "wxee018fb96955552a", + }, + PageIndex: 1, + PageSize: 999999, + } + } else { + req = { + SearchParameter: { + COUPON_IDS: selectedId, + WECHATAPP_APPID: "wxee018fb96955552a", + // 领取时间 + CREATE_DATE_Start: params?.searchType === '1' ? params?.STARTDATE : '', + CREATE_DATE_End: params?.searchType === '1' ? params?.ENDDATE : '', + // 核销时间 + USED_DATE_Start: params?.searchType === '2' ? params?.STARTDATE : '', + USED_DATE_End: params?.searchType === '2' ? params?.ENDDATE : '', + COUPON_STATE: params?.COUPON_STATE || "" + }, + PageIndex: 1, + PageSize: 999999, + } } setSearchParams(params) diff --git a/src/pages/reports/ConfirmationDifference/index.tsx b/src/pages/reports/ConfirmationDifference/index.tsx index d836f41..f202623 100644 --- a/src/pages/reports/ConfirmationDifference/index.tsx +++ b/src/pages/reports/ConfirmationDifference/index.tsx @@ -6,7 +6,7 @@ import type { ConnectState } from "@/models/connect"; import { useState } from "react"; import ProCard from "@ant-design/pro-card"; import { MenuFoldOutlined } from "@ant-design/icons"; -import type { FormInstance} from "antd"; +import type { FormInstance } from "antd"; import { Modal, Popconfirm } from "antd"; import { Button, Drawer, message, Spin, Tree, Typography, Tooltip } from "antd"; import { getMoney, getServerpartTree } from "@/services/options"; @@ -91,6 +91,7 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p const [defaultTableData, setDefaultTableData] = useState() // 判断是否有不一样的税率 const [differentRate, setDifferentRate] = useState() + const [showDifference, setShowDifference] = useState(false) const columns: any = [ // { @@ -278,7 +279,7 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p width: 100, hideInSearch: true, render: (_, record) => { - const rightTaxRate = record?.errorTaxRate ? `${record?.errorTaxRate }%` : '' + const rightTaxRate = record?.errorTaxRate ? `${record?.errorTaxRate}%` : '' return
{ record?.isErrorTaxRate ? @@ -415,7 +416,33 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p align: 'right', hideInSearch: true, render: (_, record) => { - return numeral(record?.DiffRevenueAmount).format('0,0.00') + // return numeral(record?.DiffRevenueAmount).format('0,0.00') + return { + if (record?.SERVERPARTSHOP_ID) { + console.log('record', record); + const obj: any = { + ...record, + } + let [monthStartTime, monthEndTime] = record?.IndexDesc.split('-') + monthStartTime = moment(monthStartTime).format('YYYY-MM-DD') + monthEndTime = moment(monthEndTime).format('YYYY-MM-DD') + const startDate: any = moment(searchParams?.MonthDate).startOf('months').format('YYYY-MM-DD') + const endDate: any = moment(searchParams?.MonthDate).endOf('months').format('YYYY-MM-DD') + obj.startTime = monthStartTime + obj.Id = record.SERVERPARTSHOP_ID + if (new Date(monthEndTime).getTime() < new Date(endDate).getTime()) { + obj.endTime = monthEndTime + } else { + obj.endTime = endDate + } + console.log('objobjobjobj', obj); + + setCurrentRow(obj) + setShowDifference(true) + } + }} style={{ color: record?.SERVERPARTSHOP_ID ? '#0e9976' : '#000' }}> + {record?.DiffRevenueAmount ? numeral(getMoney(record?.DiffRevenueAmount)).format('0,0.00') : '0.00'} + } }, { @@ -1012,6 +1039,151 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p } setShowCompareDrawer(true) } + // 要传递的columns + const childrenColumns: any = [ + { + title: '累计营业额', + dataIndex: '', + hideInSearch: true, + children: [ + { + title:
{'项目拆分'}
, + dataIndex: 'TotalRevenueAmount', + width: 130, + valueType: 'digit', + align: 'right', + hideInSearch: true, + render: (_, record) => { + return record?.TotalRevenueAmount ? + record?.BUSINESSPROJECT_ID ? + {numeral(getMoney(record?.TotalRevenueAmount || 0)).format('0,0.00')} : {numeral(getMoney(record?.TotalRevenueAmount || 0)).format('0,0.00')} + : + '-' + } + }, + { + title:
{'自然日营收'}
, + dataIndex: 'DailyRevenueAmount', + width: 130, + valueType: 'digit', + align: 'right', + hideInSearch: true, + render: (_, record) => { + return numeral(getMoney(record?.DailyRevenueAmount || 0)).format('0,0.00') + } + }, + { + title:
{'营收差额'}
, + dataIndex: 'DiffRevenueAmount', + width: 130, + valueType: 'digit', + align: 'right', + hideInSearch: true, + render: (_, record) => { + return 0 ? '#0e9976' : record?.DiffRevenueAmount < 0 ? '#e83944' : '#000' }}> + {record?.DiffRevenueAmount ? numeral(getMoney(record?.DiffRevenueAmount)).format('0,0.00') : ''} + + } + }, + ] + }, + { + title: '已确认营业额', + hideInSearch: true, + children: [ + { + title: '项目拆分', + width: 130, + valueType: 'digit', + align: 'right', + dataIndex: 'LastMonthRevenue', + hideInSearch: true, + render: (_, record) => { + return + {numeral(getMoney(record?.LastMonthRevenue || 0)).format('0,0.00')} + + } + }, + { + title: '自然日', + width: 130, + valueType: 'digit', + align: 'right', + dataIndex: 'DailyLastMonthRevenue', + hideInSearch: true, + render: (_, record) => { + return + {numeral(getMoney(record?.LastMonthRevenue || 0)).format('0,0.00')} + + } + }, + { + title: '差额', + width: 130, + valueType: 'digit', + align: 'right', + dataIndex: 'DiffLastMonthRevenue', + hideInSearch: true, + render: (_, record) => { + return { + + }} style={{ color: record?.DiffLastMonthRevenue > 0 ? '#0e9976' : record?.DiffLastMonthRevenue < 0 ? '#e83944' : '#000' }}> + {record?.DiffLastMonthRevenue ? numeral(getMoney(record?.DiffLastMonthRevenue)).format('0,0.00') : ''} + + } + } + ] + + }, + { + title: '本月营业额', + hideInSearch: true, + children: [ + { + title: '项目拆分', + width: 130, + valueType: 'digit', + align: 'right', + dataIndex: 'CurMonthRevenue', + hideInSearch: true, + render: (_, record) => { + return + {numeral(getMoney(record?.CurMonthRevenue || 0)).format('0,0.00')} + + } + }, + { + title: '自然日', + width: 130, + valueType: 'digit', + align: 'right', + dataIndex: 'DailyCurMonthRevenue', + hideInSearch: true, + render: (_, record) => { + return + {numeral(getMoney(record?.DailyCurMonthRevenue || 0)).format('0,0.00')} + + } + }, + { + title: '差额', + width: 130, + valueType: 'digit', + align: 'right', + dataIndex: 'DiffCurMonthRevenue', + hideInSearch: true, + render: (_, record) => { + return { + + }} style={{ color: record?.DiffCurMonthRevenue > 0 ? '#0e9976' : record?.DiffCurMonthRevenue < 0 ? '#e83944' : '#000' }}> + {record?.DiffCurMonthRevenue ? numeral(getMoney(record?.DiffCurMonthRevenue)).format('0,0.00') : ''} + + } + } + ] + }, + ] + return (
{ @@ -1620,6 +1792,25 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p + + + {/* 点击差额出现的抽屉 */} + { // 关闭抽屉 则在清空选中行数据 并 设置抽屉状态为关闭 + setCurrentRow(undefined); + setShowDifference(false); + }} + bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }} + closable={false} + > + {showDifference && } +
) } diff --git a/src/pages/reports/revenueConfirmation/components/compareList.tsx b/src/pages/reports/revenueConfirmation/components/compareList.tsx index 3ada094..7e6ed3a 100644 --- a/src/pages/reports/revenueConfirmation/components/compareList.tsx +++ b/src/pages/reports/revenueConfirmation/components/compareList.tsx @@ -1211,7 +1211,7 @@ const compareList: React.FC<{ console.log('data212', data) // 已经发起申请了的 就不去请求下面表格的数据了 // 也不会显示 请求上面那个接口是因为要拿到顶部的详情数据 - if (compareCurrent?.Approvalstate > 0) { + if (compareCurrent?.Approvalstate > 0 && come !== 'ConfirmationDifference') { if (res) { setTopProjectDetail(res.RevenueRecognition) } @@ -1219,8 +1219,8 @@ const compareList: React.FC<{ let detailObj: any = {} console.log('compareCurrent', compareCurrent) let detail: any = {} - if (compareCurrent?.BUSINESSAPPROVAL_ID) { - detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID }) + if (compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId) { + detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId }) } console.log('detail', detail); if (detail?.BUSINESSPROCESS_ID) { @@ -1259,8 +1259,8 @@ const compareList: React.FC<{ let detailObj: any = {} console.log('compareCurrent', compareCurrent) let detail: any = {} - if (compareCurrent?.BUSINESSAPPROVAL_ID) { - detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID }) + if (compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId) { + detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId }) } console.log('detail', detail); if (detail?.BUSINESSPROCESS_ID) { @@ -1367,8 +1367,8 @@ const compareList: React.FC<{ let detailObj: any = {} console.log('compareCurrent', compareCurrent) let detail: any = {} - if (compareCurrent?.BUSINESSAPPROVAL_ID) { - detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID }) + if (compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId) { + detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId }) } console.log('detail', detail); if (detail?.BUSINESSPROCESS_ID) { @@ -1410,8 +1410,8 @@ const compareList: React.FC<{ let detailObj: any = {} console.log('compareCurrent', compareCurrent) let detail: any = {} - if (compareCurrent?.BUSINESSAPPROVAL_ID) { - detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID }) + if (compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId) { + detail = await handleGetBUSINESSAPPROVALDetail({ BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId }) } if (detail?.BUSINESSPROCESS_ID) { const res = await handleGetBIZPSPLITMONTHDetail({ BIZPSPLITMONTHId: detail?.BUSINESSPROCESS_ID }) @@ -2546,7 +2546,7 @@ const compareList: React.FC<{ setPrintData(res) const reqProgress: any = { - BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID + BUSINESSAPPROVALId: compareCurrent?.BUSINESSAPPROVAL_ID || compareCurrent?.BusinessApprovalId } const dataProgress = await handleGetGetBUSINESSAPPROVALDetail(reqProgress) console.log('datahandleGetProcessProgress', dataProgress); @@ -2568,7 +2568,7 @@ const compareList: React.FC<{ confirmationName: '',// 商户确认签名 confirmationRealName: '',// 商户确认签名(只有人名) developManagerName: dataProgress.STAFF_NAME,// 经发人签名 - developManagerRealName: `${dataProgress.STAFF_NAME.split('【')[0]} ${data.BUSINESS_STARTDATE || ''}`,// 经发人签名(只有人名) + developManagerRealName: `${dataProgress.STAFF_NAME ? dataProgress.STAFF_NAME.split('【')[0] : ""} ${data.BUSINESS_STARTDATE || ''}`,// 经发人签名(只有人名) } if (dataProgress.approveList && dataProgress.approveList.length > 0) { @@ -2642,125 +2642,127 @@ const compareList: React.FC<{ {/*
初始月度结算表
*/} { - showMoreBtn ? - { - return
-
-
- {`${compareCurrent?.Serverpart_Name || compareCurrent?.SERVERPART_NAME || ''}-${topProjectDetail?.SERVERPARTSHOP_NAME || ''}-${compareCurrent?.STATISTICS_MONTH || monthTime || ''}月度结算`} + + come !== 'ConfirmationDifference' ? + showMoreBtn ? + { + return
+
+
+ {`${compareCurrent?.Serverpart_Name || compareCurrent?.SERVERPART_NAME || ''}-${topProjectDetail?.SERVERPARTSHOP_NAME || ''}-${compareCurrent?.STATISTICS_MONTH || monthTime || ''}月度结算`} +
+
- -
- - - - {/* {topProjectDetail?.MERCHANTS_NAME} */} - {/* {`${topProjectDetail?.COMPACT_STARTDATE ? moment(topProjectDetail?.COMPACT_STARTDATE).format('YYYY/MM/DD') : ''}${topProjectDetail?.COMPACT_ENDDATE ? `-${moment(topProjectDetail?.COMPACT_ENDDATE).format('YYYY/MM/DD')}` : ''}`} */} - {`${topProjectDetail?.COMPACT_STARTDATE ? moment(topProjectDetail?.COMPACT_STARTDATE).format('YYYY/MM/DD') : ''}`} - {`${topProjectDetail?.COMPACT_ENDDATE ? moment(topProjectDetail?.COMPACT_ENDDATE).format('YYYY/MM/DD') : ''}`} - {SETTLEMENT_MODESObj[topProjectDetail?.SettlementModes]} - - - {topProjectDetail?.IndexStr} - {topProjectDetail?.DecorateDesc} - {topProjectDetail?.SECURITYDEPOSIT ? `${getMoney(topProjectDetail?.SECURITYDEPOSIT / 10000)}万元` : ''} - - - {/* + + + {/* {topProjectDetail?.MERCHANTS_NAME} */} + {/* {`${topProjectDetail?.COMPACT_STARTDATE ? moment(topProjectDetail?.COMPACT_STARTDATE).format('YYYY/MM/DD') : ''}${topProjectDetail?.COMPACT_ENDDATE ? `-${moment(topProjectDetail?.COMPACT_ENDDATE).format('YYYY/MM/DD')}` : ''}`} */} + {`${topProjectDetail?.COMPACT_STARTDATE ? moment(topProjectDetail?.COMPACT_STARTDATE).format('YYYY/MM/DD') : ''}`} + {`${topProjectDetail?.COMPACT_ENDDATE ? moment(topProjectDetail?.COMPACT_ENDDATE).format('YYYY/MM/DD') : ''}`} + {SETTLEMENT_MODESObj[topProjectDetail?.SettlementModes]} + + + {topProjectDetail?.IndexStr} + {topProjectDetail?.DecorateDesc} + {topProjectDetail?.SECURITYDEPOSIT ? `${getMoney(topProjectDetail?.SECURITYDEPOSIT / 10000)}万元` : ''} + + + {/* {topProjectDetail?.RENTFEE?`${getMoney(topProjectDetail?.RENTFEE / 10000)}万元`:''} */} - {topProjectDetail?.GUARANTEERATIO ? `${topProjectDetail?.GUARANTEERATIO}%` : '-'} - {topProjectDetail?.TaxRate ? `${topProjectDetail?.TaxRate}%` : '-'} - {topProjectDetail?.MINTURNOVER ? `${getMoney(topProjectDetail?.MINTURNOVER / 10000)}万元` : ''} - - {/* */} - {/* {topProjectDetail?.MonthlyIncome} */} - {/* {topProjectDetail?.MonthlyCount} */} - {/* {compareCurrent?.SERVERPARTSHOP_NAME} */} + {topProjectDetail?.GUARANTEERATIO ? `${topProjectDetail?.GUARANTEERATIO}%` : '-'} + {topProjectDetail?.TaxRate ? `${topProjectDetail?.TaxRate}%` : '-'} + {topProjectDetail?.MINTURNOVER ? `${getMoney(topProjectDetail?.MINTURNOVER / 10000)}万元` : ''} + + {/* */} + {/* {topProjectDetail?.MonthlyIncome} */} + {/* {topProjectDetail?.MonthlyCount} */} + {/* {compareCurrent?.SERVERPARTSHOP_NAME} */} - {/* */} - {/* */} - {/* {topProjectDetail?.MonthlyTotalIncome} */} - {/* */} - + {/* */} + {/* */} + {/* {topProjectDetail?.MonthlyTotalIncome} */} + {/* */} + - - -} - valueStyle={{ color: "#00000075", fontSize: 14 }} - value={'项目金额'} - /> - + + -} + valueStyle={{ color: "#00000075", fontSize: 14 }} + value={'项目金额'} + /> + - - {topProjectDetail?.MERCHANTS_NAME}} - valueStyle={{ color: "#00000075", fontSize: 14, marginTop: 10 }} - value={"经营商户"} - /> - - {/* + + {topProjectDetail?.MERCHANTS_NAME}} + valueStyle={{ color: "#00000075", fontSize: 14, marginTop: 10 }} + value={"经营商户"} + /> + + {/* {topProjectDetail?.Remark} */} - - { - noticeRowData ? -
- 项目拆分移动支付 - {noticeRowData?.CURMOBILEPAY_AMOUNT ? `(${numeral(getMoney(noticeRowData?.CURMOBILEPAY_AMOUNT)).format('0,0.00')})` : ''} - {noticeRowData?.CURMOBILEPAY_AMOUNT > noticeRowData?.MobilePay_Amount ? '>' : noticeRowData?.CURMOBILEPAY_AMOUNT === noticeRowData?.MobilePay_Amount ? '=' : '<'} - {'自然日移动支付'} - {noticeRowData?.MobilePay_Amount ? `(${numeral(getMoney(noticeRowData?.MobilePay_Amount)).format('0,0.00')})` : ''} - ,以 - {noticeRowData?.CURMOBILEPAY_AMOUNT >= noticeRowData?.MobilePay_Amount ? '项目拆分移动支付' : '自然日拆分移动支付'} - 为准; - 自然日现金支付 - {noticeRowData?.CashPay_Amount ? `(${numeral(getMoney(noticeRowData?.CashPay_Amount)).format('0,0.00')})` : ''} - {noticeRowData?.CashPay_Amount > noticeRowData?.CURCASHPAY_AMOUNT ? '>' : noticeRowData?.CashPay_Amount === noticeRowData?.CURCASHPAY_AMOUNT ? '=' : '<'} - {'项目拆分现金支付'} - {noticeRowData?.CURCASHPAY_AMOUNT ? `(${numeral(getMoney(noticeRowData?.CURCASHPAY_AMOUNT)).format('0,0.00')})` : ''} - ,以 - {noticeRowData?.CashPay_Amount >= noticeRowData?.CURCASHPAY_AMOUNT ? '项目拆分现金支付' : '自然日现金支付'} - 为准, - {noticeRowData?.CashPay_Amount && noticeRowData?.CURCASHPAY_AMOUNT && noticeRowData?.CashPay_Amount - noticeRowData?.CURCASHPAY_AMOUNT > 0 ? `建议现金冲正${numeral(getMoney(noticeRowData?.CashPay_Amount - noticeRowData?.CURCASHPAY_AMOUNT)).format('0,0.00')}元` : ''} -
: '' - } + + { + noticeRowData ? +
+ 项目拆分移动支付 + {noticeRowData?.CURMOBILEPAY_AMOUNT ? `(${numeral(getMoney(noticeRowData?.CURMOBILEPAY_AMOUNT)).format('0,0.00')})` : ''} + {noticeRowData?.CURMOBILEPAY_AMOUNT > noticeRowData?.MobilePay_Amount ? '>' : noticeRowData?.CURMOBILEPAY_AMOUNT === noticeRowData?.MobilePay_Amount ? '=' : '<'} + {'自然日移动支付'} + {noticeRowData?.MobilePay_Amount ? `(${numeral(getMoney(noticeRowData?.MobilePay_Amount)).format('0,0.00')})` : ''} + ,以 + {noticeRowData?.CURMOBILEPAY_AMOUNT >= noticeRowData?.MobilePay_Amount ? '项目拆分移动支付' : '自然日拆分移动支付'} + 为准; + 自然日现金支付 + {noticeRowData?.CashPay_Amount ? `(${numeral(getMoney(noticeRowData?.CashPay_Amount)).format('0,0.00')})` : ''} + {noticeRowData?.CashPay_Amount > noticeRowData?.CURCASHPAY_AMOUNT ? '>' : noticeRowData?.CashPay_Amount === noticeRowData?.CURCASHPAY_AMOUNT ? '=' : '<'} + {'项目拆分现金支付'} + {noticeRowData?.CURCASHPAY_AMOUNT ? `(${numeral(getMoney(noticeRowData?.CURCASHPAY_AMOUNT)).format('0,0.00')})` : ''} + ,以 + {noticeRowData?.CashPay_Amount >= noticeRowData?.CURCASHPAY_AMOUNT ? '项目拆分现金支付' : '自然日现金支付'} + 为准, + {noticeRowData?.CashPay_Amount && noticeRowData?.CURCASHPAY_AMOUNT && noticeRowData?.CashPay_Amount - noticeRowData?.CURCASHPAY_AMOUNT > 0 ? `建议现金冲正${numeral(getMoney(noticeRowData?.CashPay_Amount - noticeRowData?.CURCASHPAY_AMOUNT)).format('0,0.00')}元` : ''} +
: '' + } +
+ }} + /> + : +
+
+
+ {`${compareCurrent?.Serverpart_Name || compareCurrent?.SERVERPART_NAME || ''}-${topProjectDetail?.SERVERPARTSHOP_NAME || ''}-${compareCurrent?.STATISTICS_MONTH || monthTime || ''}月度结算`} +
+
- }} - /> - : -
-
-
- {`${compareCurrent?.Serverpart_Name || compareCurrent?.SERVERPART_NAME || ''}-${topProjectDetail?.SERVERPARTSHOP_NAME || ''}-${compareCurrent?.STATISTICS_MONTH || monthTime || ''}月度结算`} -
- -
-
+
: "" } { @@ -2779,8 +2781,11 @@ const compareList: React.FC<{ /> */} - - + { + come !== 'ConfirmationDifference' ? + + : "" + } @@ -3028,7 +3033,7 @@ const compareList: React.FC<{ }}>查看月度结算单 : '' } { - compareCurrent?.Approvalstate === 9 ? + compareCurrent?.Approvalstate === 9 && come !== 'ConfirmationDifference' ? + + + + + + + + { + handleChangePreview(vis) + } + }}> + { + imgList.map((n) => ) + } + */}
) } diff --git a/src/pages/travelMember/BookingMealOrder/index.tsx b/src/pages/travelMember/BookingMealOrder/index.tsx index a920526..978c316 100644 --- a/src/pages/travelMember/BookingMealOrder/index.tsx +++ b/src/pages/travelMember/BookingMealOrder/index.tsx @@ -6,7 +6,7 @@ import ProTable, { ActionType } from "@ant-design/pro-table"; import PageTitleBox from "@/components/PageTitleBox"; import { Button, Col, FormInstance, message, Modal, Popconfirm, Row, Space } from "antd"; import { PlusOutlined } from "@ant-design/icons"; -import { handeDeleteMERCHANTS, handeGetMERCHANTSList, handeGetSALEBILLDetail, handeGetSALEBILLList, handeGetSaleBillWholeList, handeGetSALEDETAILList, handeSynchroMERCHANTS } from "../service"; +import { handeDeleteMERCHANTS, handeGetMERCHANTSList, handeGetNestingAUTOTYPEList, handeGetSALEBILLDetail, handeGetSALEBILLList, handeGetSaleBillWholeList, handeGetSALEDETAILList, handeSynchroMERCHANTS } from "../service"; import Draggable from "react-draggable"; import React from "react"; import ProForm, { ProFormSelect, ProFormText, ProFormTextArea } from "@ant-design/pro-form"; @@ -154,6 +154,39 @@ const BookingMealOrder: React.FC<{ currentUser: CurrentUser | undefined }> = (pr }, initialValue: "0" }, + + { + title: '会员标签', + dataIndex: "MEMBERSHIP_TARGET", + valueType: 'treeSelect', + request: async () => { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + return data + }, + hideInTable: true, + fieldProps: { + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.AUTOTYPE_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + } + } + }, + { dataIndex: 'ORDER_AMOUNT', title: '订单金额', @@ -306,7 +339,7 @@ const BookingMealOrder: React.FC<{ currentUser: CurrentUser | undefined }> = (pr bordered headerTitle={} // 列表表头 actionRef={actionRef} - search={{ span: 6, labelWidth: 'auto' }} + search={{ span: 6, labelWidth: 'auto', defaultCollapsed: false }} // 请求数据 request={async (params, sorter) => { if (!selectedId) { @@ -319,7 +352,8 @@ const BookingMealOrder: React.FC<{ currentUser: CurrentUser | undefined }> = (pr ORDER_DATE_Start: params?.ORDER_DATE_Start || "", ORDER_DATE_End: params?.ORDER_DATE_End || "", SALEBILL_STATES: params?.SALEBILL_STATE === "0" ? "1010,2000,3000" : params?.SALEBILL_STATE, - SearchKeyValue: params?.searchText || "" + SearchKeyValue: params?.searchText || "", + MEMBERSHIP_TARGET: params?.MEMBERSHIP_TARGET || "" }, PageIndex: 1, PageSize: 999999, diff --git a/src/pages/travelMember/MallOrderManage/index.tsx b/src/pages/travelMember/MallOrderManage/index.tsx index b6f2d11..41195c6 100644 --- a/src/pages/travelMember/MallOrderManage/index.tsx +++ b/src/pages/travelMember/MallOrderManage/index.tsx @@ -8,7 +8,7 @@ import type { ActionType } from "@ant-design/pro-table"; import ProTable from "@ant-design/pro-table"; import PageTitleBox from "@/components/PageTitleBox"; import moment from 'moment' -import { handeGetSALEBILLList, handeGetSaleBillWholeList, handeGetSALEDETAILList } from "../service"; +import { handeGetMERCHANTSList, handeGetNestingAUTOTYPEList, handeGetSALEBILLList, handeGetSaleBillWholeList, handeGetSALEDETAILList } from "../service"; import './style.less' import Draggable from "react-draggable"; import ProForm, { ProFormSelect, ProFormText } from "@ant-design/pro-form"; @@ -290,7 +290,69 @@ const MallOrderManage: React.FC<{ currentUser: CurrentUser }> = (props) => { ellipsis: true, align: "center", }, - + { + title: '会员标签', + dataIndex: "MEMBERSHIP_TARGET", + valueType: 'treeSelect', + request: async () => { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + return data + }, + hideInTable: true, + fieldProps: { + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.AUTOTYPE_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + } + } + }, + { + title: '供应商', + dataIndex: "MERCHANTS_IDS", + valueType: 'select', + request: async () => { + const req = { + searchParameter: { + OWNERUNIT_ID: currentUser?.OwnerUnitId, + PROVINCE_CODE: currentUser?.ProvinceCode, + MERCHANTS_TYPE: "" + }, + PageIndex: 1, + PageSize: 999999, + } + const data = await handeGetMERCHANTSList(req); + return data.List + }, + hideInTable: true, + fieldProps: { + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.MERCHANTS_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'MERCHANTS_NAME', + value: 'MERCHANTS_ID', + } + } + }, // { // title: "订单编号", // dataIndex: "SALEBILL_CODE", @@ -390,7 +452,10 @@ const MallOrderManage: React.FC<{ currentUser: CurrentUser }> = (props) => { }} scroll={{ x: "100%", y: "calc(100vh - 410px)" }} headerTitle={} // 列表表头 - search={{ span: 6 }} + search={{ + span: 6, + defaultCollapsed: false + }} request={async (params) => { console.log('paramsparamsparams', params); @@ -403,7 +468,9 @@ const MallOrderManage: React.FC<{ currentUser: CurrentUser }> = (props) => { ORDER_DATE_End: params?.ORDER_DATE_End || "", SALEBILL_STATES: params?.orderStatus === "0" ? "1010,2010,3000" : params?.orderStatus, CHANNEL_TYPE: params?.PAY_METHOD === "0" ? "" : params?.PAY_METHOD, - SearchKeyValue: params?.searchText || "" + SearchKeyValue: params?.searchText || "", + MERCHANTS_IDS: params?.MERCHANTS_IDS || "", + MEMBERSHIP_TARGET: params?.MEMBERSHIP_TARGET || "" }, PageIndex: 1, PageSize: 999999, diff --git a/src/pages/travelMember/MemberSummaryStatistics/index.tsx b/src/pages/travelMember/MemberSummaryStatistics/index.tsx index 9417ce8..f451e50 100644 --- a/src/pages/travelMember/MemberSummaryStatistics/index.tsx +++ b/src/pages/travelMember/MemberSummaryStatistics/index.tsx @@ -1,17 +1,17 @@ -// 会员汇总统计 +// 会员汇总统计 //会员积分报表 import { ConnectState } from "@/models/connect"; import { connect, CurrentUser } from "umi"; import './MemberSummaryStatistics.less' import ProTable, { ActionType } from "@ant-design/pro-table"; import { useEffect, useRef, useState } from "react"; import { Button, Col, FormInstance, Row, Tooltip } from "antd"; -import { handeGetPointGrowthSummary, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../service"; +import { handeGetNestingAUTOTYPEList, handeGetPointGrowthSummary, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../service"; import moment from 'moment' import addIcon from '@/assets/detail/addIcon.png' import reduceIcon from '@/assets/detail/reduceIcon.png' import staticSumTotalBg from '@/assets/detail/staticSumTotalBg.png' import session from "@/utils/session"; -import ProForm, { ProFormDateRangePicker } from "@ant-design/pro-form"; +import ProForm, { ProFormDateRangePicker, ProFormTreeSelect } from "@ant-design/pro-form"; import { handleSetlogSave } from "@/utils/format"; import OrderDetailModal from "../BookingMealOrder/components/orderDetailModal"; import MemberDetail from "../memberInfor/component/memberDetail"; @@ -354,7 +354,7 @@ const MemberSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined } handleGetTopData() }, []) // 获取顶部的数据 - const handleGetTopData = async (StartDate?: string, EndDate?: string) => { + const handleGetTopData = async (StartDate?: string, EndDate?: string, MEMBERSHIP_TARGET?: string) => { const req: any = { CalcType: 1, // 1 汇总 2 会员等级 3 会员类型 OwnerUnitId: currentUser?.OwnerUnitId, @@ -365,7 +365,7 @@ const MemberSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined } MemberShipId: "", MembershipType: "", MembershipLevel: "", - MembershipTarget: "" + MembershipTarget: MEMBERSHIP_TARGET || "" } const data = await handeGetPointGrowthSummary(req) console.log('datadatadatadatadata', data); @@ -385,7 +385,8 @@ const MemberSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined } OPERATE_DATE_End: searchParams?.EndDate || "", OWNERUNIT_ID: 911, POINT_TYPE: value === 1 ? '' : value === 2 ? '1' : value === 3 ? '-1' : '', - POINT_SOURCE: '' + POINT_SOURCE: '', + MEMBERSHIP_TARGET: searchParams?.MEMBERSHIP_TARGET || "" }, keyWord: { Key: "MEMBERSHIP_NAME", @@ -404,7 +405,8 @@ const MemberSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined } OWNERUNIT_ID: 911, SCORESETTING_STATE: 1, GROWTH_SOURCES: "", - GROWTH_TYPE: value === 4 ? '' : value === 5 ? '1' : value === 6 ? '-1' : '' + GROWTH_TYPE: value === 4 ? '' : value === 5 ? '1' : value === 6 ? '-1' : '', + MEMBERSHIP_TARGET: searchParams?.MEMBERSHIP_TARGET || "" }, PageIndex: searchParams?.current, PageSize: 20, @@ -450,7 +452,7 @@ const MemberSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined } if (values.searchTime && values.searchTime.length > 0) { [StartDate, EndDate] = values.searchTime } - handleGetTopData(StartDate, EndDate) + handleGetTopData(StartDate, EndDate, values.MEMBERSHIP_TARGET) setSearchParams({ StartDate: StartDate, EndDate: EndDate @@ -459,19 +461,54 @@ const MemberSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined } PointsRecordSearchRef.current?.actionRef?.current?.reload() }} > - + + + + + + { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + return data + }} + fieldProps={{ + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.AUTOTYPE_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + } + }} + /> + + diff --git a/src/pages/travelMember/MembershipLevelDistribution/components/LeftSelectMemberLevel.tsx b/src/pages/travelMember/MembershipLevelDistribution/components/LeftSelectMemberLevel.tsx new file mode 100644 index 0000000..a616613 --- /dev/null +++ b/src/pages/travelMember/MembershipLevelDistribution/components/LeftSelectMemberLevel.tsx @@ -0,0 +1,238 @@ +import { connect } from "umi"; +import type { ConnectState } from "@/models/connect"; +import ProCard from "@ant-design/pro-card"; +import searchIcon from '@/assets/ai/searchIcon.png' +import { useRef, useState } from "react"; +import { MenuFoldOutlined } from "@ant-design/icons"; +import ProForm, { ProFormText } from "@ant-design/pro-form"; +import { Button, Col, FormInstance, Row, Tree } from "antd"; +import close from '@/assets/ai/close.png' +import { getServerpartTree } from "@/services/options"; +import useRequest from "@ahooksjs/use-request"; +import './style.less' +import { getMerchantShopTree } from "@/pages/Setting/Users/service"; +import session from "@/utils/session"; +import { handeGetNestingFIELDENUMList, handleGetCOOPSHOP_RULEList, handleGetCOUPONList } from "../../service"; + + +type DetailProps = { + setSelectedId: any; // 把选择的服务区 可以带给外层 + reload?: boolean; // 选择服务区 是否可以刷新组件之外的内容 + actionRef?: any; // 和reload配合使用 确认要刷新的内容 + currentUser: any; // 当前用户的信息 + width?: number; // 组件的宽度 + otherFun?: any; // 点击之后要进行的其他操作 多个操作可以写在一个方法里面传进来 + setCollapsible: any; // 是否收缩组件 + collapsible: boolean; // 收缩组件的判断依据 + haveTest?: boolean;// 是否有测试服务区 + handleGetLeftTreeData?: any // 拿到树数据的方法 必须要有输出值的 + noWj?: any // 把万佳商贸隐藏 + selectOnly?: boolean// 传入的时候 仅支持单选 +} +const LeftSelectMemberLevel = ({ setSelectedId, reload, actionRef, currentUser, width, otherFun, setCollapsible, collapsible, haveTest, handleGetLeftTreeData, noWj, selectOnly }: DetailProps) => { + const searchTreeRef = useRef(); + // 默认的服务区树 + const [allTreeViews, setAllTreeViews] = useState() + // 是否要显示全部 + const [isShowAllInTree, setIsShowAllInTree] = useState(false) + // 加载服务区树 + const { loading: treeLoading, data: treeViews } = useRequest(async () => { + + const req = { + FIELDEXPLAIN_FIELD: 'MEMBERSHIP_LEVEL_YN', + FIELDEXPLAIN_ID: "", + FIELDENUM_PID: "", + FIELDENUM_STATUS: 1, + SearchKey: "" + } + const data = await handeGetNestingFIELDENUMList(req); + + let list: any = data.filter((item: any) => item.FIELDENUM_VALUE !== '1') + + setAllTreeViews(list) + setTreeView(list) + }) + // 显示服务区树搜索框 + const [showServiceSearchBox, setShowServiceSearchBox] = useState(false) + // 实际显示在左侧的服务区树 + const [treeView, setTreeView] = useState() + // 树要展开的行 + const [treeShowRow, setTreeShowRow] = useState() + // 筛选左侧的服务区树 + const handleFilterServiceTree = async (value?: string) => { + const resList: any = JSON.parse(JSON.stringify(allTreeViews)) + setSelectedId('') + if (resList && resList.length > 0 && value) { + setTreeView([]) + const list: any = [] + resList.forEach((item: any) => { + if (item.FIELDENUM_NAME.indexOf(value) !== -1) { + list.push(item) + } else { + if (item.children && item.children.length > 0) { + const childrenList: any = [] + item.children.forEach((subItem: any) => { + if (subItem.FIELDENUM_NAME.indexOf(value) !== -1) { + childrenList.push(subItem) + } + }) + item.children = childrenList + if (childrenList && childrenList.length > 0) { + list.push(item) + } + } + } + }) + if (list && list.length > 0) { + const keyList: any = ['0-0'] + list.forEach((item: any) => { + keyList.push(item.key) + }) + setTreeShowRow(keyList) + } + setTimeout(() => { + setTreeView(list) + }, 100) + } else { + setTreeView([]) + setTreeShowRow([]) + setTreeView(allTreeViews) + } + } + // 根据传入的服务区id筛选剔除掉这个服务区 + const handleFilterList = (list: any, id: any) => { + let res: any = [] + list.forEach((item: any) => { + if (item.value === id) { + + } else { + res.push(item) + } + }) + console.log('res', res); + return res + } + + // 仅支持单选一个服务区的时候 调用的方法 + const convertTreeForSelectOnly = (treeData: any[]): any[] => { + return treeData.map(item => { + const newItem = { + ...item, + disabled: item.type !== 1, + }; + if (item.children) { + newItem.children = convertTreeForSelectOnly(item.children); + } + return newItem; + }); + }; + + return ( +
+ + { + setShowServiceSearchBox(true) + }} /> + { + setCollapsible(!collapsible); + }} /> +
+ { + return [] + } + }} + isKeyPressSubmit + onFinish={(values: any) => { + return handleFilterServiceTree(values?.searchValue || '') + }} + > + + + + + + + + + + + + { + setShowServiceSearchBox(false) + }} /> +
+
} + colSpan={!collapsible ? "300px" : "60px"} + title={!collapsible ? "请选择服务区" : ""} + headerBordered + collapsed={collapsible} + > + {treeView && treeView.length > 0 ? 0 ? treeShowRow : ['0-0'] : []} + onCheck={(checkedKeys: React.Key[] | any, info) => { + if (selectOnly) { + // 只允许单选且只允许type为1 + const checked = Array.isArray(checkedKeys.checked) ? checkedKeys.checked : checkedKeys; + const node = info.node; + if (node.type === 1) { + setSelectedId(node.value); + if (reload) { + actionRef?.current?.reload(); + } + if (otherFun) { + otherFun(info); + } + } else { + // 取消非type=1的勾选 + setSelectedId(''); + } + } else { + // 多选逻辑 + const selectedIds = info.checkedNodes.filter((n: any) => n?.FIELDENUM_VALUE > 0) + setSelectedId(selectedIds.map((n: any) => n?.FIELDENUM_VALUE)?.toString() || '') + if (reload) { + actionRef?.current?.reload() + } + if (otherFun) { + otherFun(info) + } + } + }} + fieldNames={{ + title: "FIELDENUM_NAME", + key: "FIELDENUM_VALUE" + }} + /> : ''} + +
+ ) +} + +export default connect(({ user }: ConnectState) => ({ + currentUser: user.currentUser, +}))(LeftSelectMemberLevel); diff --git a/src/pages/travelMember/MembershipLevelDistribution/components/style.less b/src/pages/travelMember/MembershipLevelDistribution/components/style.less new file mode 100644 index 0000000..2b979a6 --- /dev/null +++ b/src/pages/travelMember/MembershipLevelDistribution/components/style.less @@ -0,0 +1,29 @@ +.pageTable-leftnav{ + .leftSelectBox{ + position: relative; + .searchIcon{ + width: 20px; + height: 20px; + cursor: pointer; + margin-right: 15px; + } + .fixedBox{ + position: absolute; + width: 275px; + background: #fff; + right: -10px; + box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); + border-radius: 8px; + box-sizing: border-box; + padding: 12px; + z-index: 2; + display: flex; + align-items: center; + .noBottom{ + .ant-form-item{ + margin-bottom: 0!important; + } + } + } + } + } \ No newline at end of file diff --git a/src/pages/travelMember/MembershipLevelDistribution/index.tsx b/src/pages/travelMember/MembershipLevelDistribution/index.tsx index 2989f2d..e39b918 100644 --- a/src/pages/travelMember/MembershipLevelDistribution/index.tsx +++ b/src/pages/travelMember/MembershipLevelDistribution/index.tsx @@ -1,11 +1,370 @@ // 会员等级分布 -import { ConnectState } from "@/models/connect"; +import { ConnectState } from "@/models/connect"; import { connect, CurrentUser } from "umi"; +import LeftSelectMemberLevel from "./components/LeftSelectMemberLevel"; +import { useRef, useState } from "react"; +import ProTable, { ActionType } from "@ant-design/pro-table"; +import { FormInstance } from "antd"; +import PageTitleBox from "@/components/PageTitleBox"; +import moment from 'moment' +import { handleSetlogSave } from "@/utils/format"; +import session from "@/utils/session"; +import { handleGetMEMBERSHIPList } from "../service"; const MembershipLevelDistribution: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => { + + const actionRef = useRef(); + const formRef = useRef(); + // 树相关的属性和方法 + const [selectedId, setSelectedId] = useState() + const [collapsible, setCollapsible] = useState(false) + // 当前行数据 + const [currentRow, setCurrentRow] = useState() + // 显示详情抽屉 + const [showDetailDrawer, setShowDetailDrawer] = useState(false) + + let MEMBERSHIPTYPEYNObj = session.get('MEMBERSHIPTYPEYNObj'); + let CONSUMPTIONRECORDTYPEObj = session.get('CONSUMPTIONRECORDTYPEObj') + let MEMBERSHIPLEVELYNObj = session.get('MEMBERSHIPLEVELYNObj') + + const columns: any = [ + { + title: "用户昵称", + width: 200, + dataIndex: "MEMBERSHIP_NAME", + ellipsis: true, + align: 'center', + fixed: 'left', + render: (_, record) => { + return { + setCurrentRow(record) + setShowDetailDrawer(true) + handleSetlogSave(`查看${record?.MEMBERSHIP_NAME}【${record?.MEMBERSHIP_ID}】会员信息`) + }}> + {record?.MEMBERSHIP_NAME || ""} + + }, + fieldProps: { + placeholder: "请输入用户昵称/联系电话/证件号/车牌号" + } + }, + { + title: "会员类型", + width: 120, + dataIndex: "MEMBERSHIP_TYPE", + ellipsis: true, + hideInTable: true, + align: 'center', + valueType: 'select', + // request: () => { + // let MEMBERSHIPTYPEYNList = session.get('MEMBERSHIPTYPEYNList') + // let newList: any = [] + // if (MEMBERSHIPTYPEYNList && MEMBERSHIPTYPEYNList.length > 0) { + // MEMBERSHIPTYPEYNList.forEach((item: any) => { + // if (item.value !== 1) { + // // && item.value < 9000 + // newList.push(item) + // } + // }) + // } + // return newList + // } + valueEnum: { + ...MEMBERSHIPTYPEYNObj, + }, + initialValue: "1" + }, + { + title: "会员类型", + width: 120, + dataIndex: "MEMBERSHIP_TYPE", + ellipsis: true, + hideInSearch: true, + align: 'center', + valueType: 'select', + valueEnum: { + ...MEMBERSHIPTYPEYNObj, + }, + }, + { + title: "会员编码", + width: 120, + dataIndex: "MEMBERSHIP_CODE", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + { + title: "会员性别", + width: 120, + dataIndex: "MEMBERSHIP_SEX", + hideInSearch: true, + ellipsis: true, + align: 'center', + valueType: 'select', + valueEnum: { + 0: '男', + 1: '女', + } + }, + { + title: "联系电话", + width: 120, + dataIndex: "MEMBERSHIP_MOBILEPHONE", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + { + title: "会员等级", + width: 120, + dataIndex: "MEMBERSHIP_LEVEL", + hideInSearch: true, + ellipsis: true, + align: 'center', + valueType: 'select', + valueEnum: MEMBERSHIPLEVELYNObj, + initialValue: "1" + // request: () => { + // let MEMBERSHIPLEVELYNList = session.get('MEMBERSHIPLEVELYNList') + // let newList: any = [] + // if (MEMBERSHIPLEVELYNList && MEMBERSHIPLEVELYNList.length > 0) { + // MEMBERSHIPLEVELYNList.forEach((item: any) => { + // if (item.value !== '1') { + // // && item.value < 9000 + // newList.push(item) + // } + // }) + // } + // return newList + // } + }, + { + title: "会员积分", + width: 120, + dataIndex: "MEMBERSHIP_POINT", + hideInSearch: true, + ellipsis: true, + sorter: true, + align: 'center', + }, + { + title: "会员成长值", + width: 120, + dataIndex: "MEMBERGROWTH_VALUE", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + { + title: "账户余额", + width: 120, + dataIndex: "ACCOUNT_BALANCE", + hideInSearch: true, + ellipsis: true, + sorter: true, + align: 'center', + }, + { + title: "会员生日", + width: 150, + dataIndex: "MEMBERSHIP_BIRTHDAY", + hideInSearch: true, + ellipsis: true, + align: 'center', + render: (_, record) => { + return record?.MEMBERSHIP_BIRTHDAY ? moment(record?.MEMBERSHIP_BIRTHDAY).format('YYYY-MM-DD') : '-' + } + }, + { + title: "证件号码", + width: 150, + dataIndex: "CERTIFICATE_NUMBER", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + { + title: "会员卡号", + width: 120, + dataIndex: "MEMBERSHIP_CARD", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + // { + // title: "会员头像", + // width: 120, + // dataIndex: "MEMBERSHIP_HEADIMAGEURL", + // hideInSearch: true, + // ellipsis: true, + // align: 'center', + // render: (_, record) => { + // return record?.MEMBERSHIP_HEADIMAGEURL ? { + // window.open(record?.MEMBERSHIP_HEADIMAGEURL) + // }}>点击查看 : "" + // } + // }, + { + title: "联系地址", + width: 180, + dataIndex: "MEMBERSHIP_ADDRESS", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + { + title: "车牌号", + width: 150, + dataIndex: "PLATE_NUMBER", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + // { + // title: "付费会员", + // width: 120, + // dataIndex: "ISPLUS", + // hideInSearch: true, + // ellipsis: true, + // align: 'center', + // valueType: 'select', + // valueEnum: { + // 0: "否", + // 1: "是" + // } + // }, + { + title: "付费有效期", + width: 120, + dataIndex: "PLUS_EXPIRYDATE", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + { + title: "推荐人", + width: 120, + dataIndex: "RECOMMEND_NAME", + hideInSearch: true, + ellipsis: true, + align: 'center', + }, + // { + // title: "会员状态", + // width: 120, + // dataIndex: "MEMBERSHIP_STATE", + // ellipsis: true, + // align: 'center', + // valueType: 'select', + // valueEnum: COMPANY_STATEObj, + // initialValue: "1000" + // }, + { + title: "最后活跃时间", + width: 150, + // BEHAVIORRECORD_TIME 用于排序 ACTIVE_LASTTIME 用于显示 + dataIndex: "BEHAVIORRECORD_TIME", + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: true, + // defaultSortOrder: 'descend', + render: (_, record) => { + return record?.ACTIVE_LASTTIME ? moment(record?.ACTIVE_LASTTIME).format('YYYY-MM-DD HH:mm:ss') : '-' + } + }, + { + title: "注册时间", + width: 150, + dataIndex: "ADDTIME", + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: true, + // sorter: (a, b) => { + // const timeA = new Date(a.ADDTIME).getTime(); + // const timeB = new Date(b.ADDTIME).getTime(); + // return timeB - timeA; // 倒序排序 + // }, + // 默认排序配置 + // defaultSortOrder: 'descend', + render: (_, record) => { + return record?.ADDTIME ? moment(record?.ADDTIME).format('YYYY-MM-DD HH:mm:ss') : '-' + } + }, + { + title: "备注", + width: 120, + dataIndex: "MEMBERSHIP_DESC", + hideInSearch: true, + ellipsis: true, + }, + ] + return (
+
+ +
+ } // 列表表头 + search={{ span: 6 }} + request={async (params, sorter) => { + if (!selectedId) { + return + } + const sortstr = Object.keys(sorter).map(n => { + const value = sorter[n] + return value ? `${n} ${value.replace('end', '')}` : '' + }) + + console.log('selectedIdselectedIdselectedId', selectedId); + const req: any = { + SearchParameter: { + OWNERUNIT_ID: 911, + MEMBERSHIP_LEVELS: selectedId, + MEMBERSHIP_STATE: params?.MEMBERSHIP_STATE, + }, + keyWord: { + Key: "MEMBERSHIP_NAME,MEMBERSHIP_MOBILEPHONE,CERTIFICATE_NUMBER,MEMBERSHIP_CARD,MEMBERSHIP_ADDRESS,PLATE_NUMBER", + value: params?.MEMBERSHIP_NAME || "" + }, + PageIndex: params.current || 1, + PageSize: params?.pageSize, + sortstr: sortstr.length ? sortstr.toString() === "MEMBERGROWTH_VALUE asc" || sortstr.toString() === "MEMBERGROWTH_VALUE desc" ? "" : sortstr.toString() : "", + } + + handleSetlogSave(`查看了会员账户管理列表`) + + const data = await handleGetMEMBERSHIPList(req) + if (data.List && data.List.length > 0) { + return { data: data.List, success: true, total: data.TotalCount } + } + return { data: [], success: true } + }} + toolbar={{ + actions: [ + + ] + }} + /> +
+
) } diff --git a/src/pages/travelMember/MembershipLevelStatistics/index.tsx b/src/pages/travelMember/MembershipLevelStatistics/index.tsx index 9416efa..9017043 100644 --- a/src/pages/travelMember/MembershipLevelStatistics/index.tsx +++ b/src/pages/travelMember/MembershipLevelStatistics/index.tsx @@ -1,16 +1,16 @@ -// 会员汇总统计 +// 会员汇总统计 // 会员等级统计 import { ConnectState } from "@/models/connect"; import { connect, CurrentUser } from "umi"; import './MembershipLevelStatistics.less' import ProTable, { ActionType } from "@ant-design/pro-table"; import { useEffect, useRef, useState } from "react"; import { Button, Col, Drawer, FormInstance, Row, Spin, Tabs, Tooltip } from "antd"; -import { handeGetPointGrowthSummary, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../service"; +import { handeGetNestingAUTOTYPEList, handeGetPointGrowthSummary, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../service"; import moment from 'moment' import addIcon from '@/assets/detail/addIcon.png' import reduceIcon from '@/assets/detail/reduceIcon.png' import session from "@/utils/session"; -import ProForm, { ProFormDateRangePicker } from "@ant-design/pro-form"; +import ProForm, { ProFormDateRangePicker, ProFormTreeSelect } from "@ant-design/pro-form"; import { handleSetlogSave } from "@/utils/format"; import PointsRecordSearch from "../PointsRecordSearch"; import GrowthValueRecordSearch from "../GrowthValueRecordSearch"; @@ -289,7 +289,7 @@ const MembershipLevelStatistics: React.FC<{ currentUser: CurrentUser | undefined }, []) // 获取顶部的数据 - const handleGetTopData = async (StartDate?: string, EndDate?: string) => { + const handleGetTopData = async (StartDate?: string, EndDate?: string, MEMBERSHIP_TARGET?: string) => { const req: any = { CalcType: 2, // 1 汇总 2 会员等级 3 会员类型 OwnerUnitId: currentUser?.OwnerUnitId, @@ -300,7 +300,7 @@ const MembershipLevelStatistics: React.FC<{ currentUser: CurrentUser | undefined MemberShipId: "", MembershipType: "", MembershipLevel: "", - MembershipTarget: "" + MembershipTarget: MEMBERSHIP_TARGET || "" } setTopLoading(true) const data = await handeGetPointGrowthSummary(req) @@ -458,7 +458,7 @@ const MembershipLevelStatistics: React.FC<{ currentUser: CurrentUser | undefined if (values.searchTime && values.searchTime.length > 0) { [StartDate, EndDate] = values.searchTime } - handleGetTopData(StartDate, EndDate) + handleGetTopData(StartDate, EndDate, values.MEMBERSHIP_TARGET) setSearchParams({ StartDate: StartDate, EndDate: EndDate @@ -466,19 +466,55 @@ const MembershipLevelStatistics: React.FC<{ currentUser: CurrentUser | undefined actionRef.current?.reload() }} > - + + + + + + { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + return data + }} + fieldProps={{ + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.AUTOTYPE_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + } + }} + /> + + + diff --git a/src/pages/travelMember/MembershipTypeStatistics/index.tsx b/src/pages/travelMember/MembershipTypeStatistics/index.tsx index 50ead18..c45c4c1 100644 --- a/src/pages/travelMember/MembershipTypeStatistics/index.tsx +++ b/src/pages/travelMember/MembershipTypeStatistics/index.tsx @@ -1,16 +1,16 @@ -// 会员汇总统计 +// 会员汇总统计 // 会员类型统计 import { ConnectState } from "@/models/connect"; import { connect, CurrentUser } from "umi"; import './MembershipTypeStatistics.less' import ProTable, { ActionType } from "@ant-design/pro-table"; import { useEffect, useRef, useState } from "react"; import { Button, Col, Drawer, FormInstance, Row, Spin, Tabs, Tooltip } from "antd"; -import { handeGetPointGrowthSummary, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../service"; +import { handeGetNestingAUTOTYPEList, handeGetPointGrowthSummary, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../service"; import moment from 'moment' import addIcon from '@/assets/detail/addIcon.png' import reduceIcon from '@/assets/detail/reduceIcon.png' import session from "@/utils/session"; -import ProForm, { ProFormDateRangePicker } from "@ant-design/pro-form"; +import ProForm, { ProFormDateRangePicker, ProFormTreeSelect } from "@ant-design/pro-form"; import { handleSetlogSave } from "@/utils/format"; import PointsRecordSearch from "../PointsRecordSearch"; import GrowthValueRecordSearch from "../GrowthValueRecordSearch"; @@ -375,7 +375,7 @@ const MembershipTypeStatistics: React.FC<{ currentUser: CurrentUser | undefined initData(); }, []) // 获取顶部的数据 - const handleGetTopData = async (StartDate?: string, EndDate?: string) => { + const handleGetTopData = async (StartDate?: string, EndDate?: string, MEMBERSHIP_TARGET?: string) => { const req: any = { CalcType: 3, // 1 汇总 2 会员等级 3 会员类型 OwnerUnitId: currentUser?.OwnerUnitId, @@ -386,7 +386,7 @@ const MembershipTypeStatistics: React.FC<{ currentUser: CurrentUser | undefined MemberShipId: "", MembershipType: "", MembershipLevel: "", - MembershipTarget: "" + MembershipTarget: MEMBERSHIP_TARGET || "" } setTopLoading(true) const data = await handeGetPointGrowthSummary(req) @@ -542,7 +542,7 @@ const MembershipTypeStatistics: React.FC<{ currentUser: CurrentUser | undefined if (values.searchTime && values.searchTime.length > 0) { [StartDate, EndDate] = values.searchTime } - handleGetTopData(StartDate, EndDate) + handleGetTopData(StartDate, EndDate, values.MEMBERSHIP_TARGET) setSearchParams({ StartDate: StartDate, EndDate: EndDate @@ -550,19 +550,55 @@ const MembershipTypeStatistics: React.FC<{ currentUser: CurrentUser | undefined actionRef.current?.reload() }} > - + + + + + + + { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + return data + }} + fieldProps={{ + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.AUTOTYPE_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + } + }} + /> + + diff --git a/src/pages/travelMember/SummaryOfReservation/index.tsx b/src/pages/travelMember/SummaryOfReservation/index.tsx index aec1f49..18ef923 100644 --- a/src/pages/travelMember/SummaryOfReservation/index.tsx +++ b/src/pages/travelMember/SummaryOfReservation/index.tsx @@ -2,9 +2,9 @@ import { ConnectState } from "@/models/connect"; import { useEffect, useRef, useState } from "react"; import { connect, CurrentUser } from "umi"; -import { handeGetGetOnlineOrderSummary, handeGetSaleBillWholeList } from "../service"; +import { handeGetGetOnlineOrderSummary, handeGetNestingAUTOTYPEList, handeGetSaleBillWholeList } from "../service"; import { Button, Col, FormInstance, Row, Tooltip } from "antd"; -import ProForm, { ProFormDateRangePicker } from "@ant-design/pro-form"; +import ProForm, { ProFormDateRangePicker, ProFormTreeSelect } from "@ant-design/pro-form"; import ProTable, { ActionType } from "@ant-design/pro-table"; import moment from 'moment' import './SummaryOfReservation.less' @@ -260,25 +260,62 @@ const SummaryOfReservation: React.FC<{ currentUser: CurrentUser | undefined }> = handleGetTopData(StartDate, EndDate) setSearchParams({ StartDate: StartDate, - EndDate: EndDate + EndDate: EndDate, + MEMBERSHIP_TARGET: values.MEMBERSHIP_TARGET || "" }) actionRef.current?.reload() }} > - + + + + + + + { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + return data + }} + fieldProps={{ + allowClear: true, + showSearch: true, + filterTreeNode: (input, node) => { + // ✅ 输入时根据 AUTOTYPE_NAME 模糊匹配 + return node?.AUTOTYPE_NAME?.toLowerCase()?.includes(input.toLowerCase()); + }, + treeDefaultExpandAll: true, + fieldNames: { + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + } + }} + /> + + @@ -567,7 +604,8 @@ const SummaryOfReservation: React.FC<{ currentUser: CurrentUser | undefined }> = selectTab == 8 ? '' : selectTab == 9 ? '' : selectTab == 10 ? '' : '', - SearchKeyValue: params?.searchText || "" + SearchKeyValue: params?.searchText || "", + MEMBERSHIP_TARGET: searchParams?.MEMBERSHIP_TARGET || "", }, PageIndex: 1, PageSize: 999999, diff --git a/src/pages/travelMember/memberInfor/component/memberDetail.tsx b/src/pages/travelMember/memberInfor/component/memberDetail.tsx index 97af06f..0cc0a70 100644 --- a/src/pages/travelMember/memberInfor/component/memberDetail.tsx +++ b/src/pages/travelMember/memberInfor/component/memberDetail.tsx @@ -1,7 +1,7 @@ // 会员详情组件 -import { connect } from "umi"; +import { connect, useRequest } from "umi"; import type { ConnectState } from "@/models/connect"; -import { Button, Col, FormInstance, message, Modal, Row } from "antd"; +import { Button, Col, FormInstance, message, Modal, Row, Select, TreeSelect } from "antd"; import { useEffect, useRef, useState } from "react"; import Draggable from "react-draggable"; import React from "react"; @@ -12,7 +12,7 @@ import closeIcon from '@/assets/detail/closeIcon.png' import session from "@/utils/session"; import memberDetailIcon from '@/assets/detail/memberDetailIcon.png' import ProTable from "@ant-design/pro-table"; -import { handeDeleteMembershipRecord, handeGetMEMBERSHIPDetail, handleGetCONSUMPTIONRECORDList, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../../service"; +import { handeDeleteMembershipRecord, handeGetMEMBERSHIPDetail, handeGetNestingAUTOTYPEList, handeGetSynchroMEMBERSHIP, handleGetCONSUMPTIONRECORDList, handleGetMEMBERGROWTHList, handleGetPOINTRECORDList } from "../../service"; import AddressDetail from "../../MemberAddress/components/addressDetail"; import './style.less' import ConsumptionRecordSearch from "../../ConsumptionRecordSearch"; @@ -25,6 +25,7 @@ import CollectProducts from "./CollectProducts"; import MerchantEvaluationManage from "../../MerchantEvaluationManage"; import MallEvaluationManage from "../../MallEvaluationManage"; import { handleSetlogSave } from "@/utils/format"; +import editIcon from '@/assets/ai/editIcon.png' type DetailProps = { @@ -48,11 +49,49 @@ const MemberDetail = ({ showDetailDrawer, currentRow, handleCloseModal, currentU let SCORETYPETree = session.get('SCORETYPETree') let CONSUMPTIONRECORDTYPEObj = session.get('CONSUMPTIONRECORDTYPEObj') + // 把树形的数据 全部层级的value 和label都匹配上 + const flattenGrowthType = (list: any[], nameKey: string, valueKey: any) => { + const result: Record = {} + + function traverse(items: any[]) { + items.forEach(item => { + result[item[valueKey]] = item[nameKey] + if (Array.isArray(item.children) && item.children.length > 0) { + traverse(item.children) + } + }) + } + + traverse(list) + return result + } // 会员详情信息 const [userDetailInfo, setUserDetailInfo] = useState({}) - // 当前选中在详情里面要查看的内容 const [selectTab, setSelectTab] = useState(1) + // 会员标签枚举 + const [labelConfig, setLabelConfig] = useState() + const [labelConfigTreeList, setLabelConfigTreeList] = useState() + // 选择的会员标签 + const [selectUserLabel, setSelectUserLabel] = useState() + // 变得可以编辑 + const [showEdit, setShowEdit] = useState(false) + + const { loading: headerTitleLoading, data: tableHeaderObj } = useRequest(async () => { + const req = { + AUTOTYPE_TYPEID: '2000', + AUTOTYPE_PID: "", + OWNERUNIT_ID: currentUser?.OwnerUnitId, + AUTOTYPE_VALID: 1, + SearchKey: "" + } + const data = await handeGetNestingAUTOTYPEList(req); + console.log('datadatadatadatadata', data); + setLabelConfigTreeList(data) + + let obj: any = flattenGrowthType(data, 'AUTOTYPE_NAME', 'AUTOTYPE_ID') + setLabelConfig(obj) + }) const onDraggaleStart = (event, uiData) => { const { clientWidth, clientHeight } = window.document.documentElement; @@ -297,9 +336,28 @@ const MemberDetail = ({ showDetailDrawer, currentRow, handleCloseModal, currentU useEffect(() => { if (showDetailDrawer) { setSelectTab(1) + } else { + setShowEdit(false) } }, [showDetailDrawer]) + // 保存标签 + const handleSaveLabelConfig = async () => { + const req: any = { + ...userDetailInfo, + MEMBERSHIP_TARGET: selectUserLabel + } + const data = await handeGetSynchroMEMBERSHIP(req) + if (data.Result_Code === 100) { + message.success('同步成功!') + setShowEdit(false) + setUserDetailInfo(data.Result_Data) + } else { + message.error(data.Result_Desc) + setSelectUserLabel(null) + } + } + return ( {MEMBERSHIPLEVELYNObj[userDetailInfo?.MEMBERSHIP_LEVEL]} : "" } + { + + showEdit ? +
+ { + console.log('eeee', e); + setSelectUserLabel(e) + }} + treeData={labelConfigTreeList} + fieldNames={{ + label: 'AUTOTYPE_NAME', + value: 'AUTOTYPE_ID', + }} + /> +
: userDetailInfo?.MEMBERSHIP_TARGET && labelConfig && labelConfig[userDetailInfo?.MEMBERSHIP_TARGET] ? +
+ {labelConfig[userDetailInfo?.MEMBERSHIP_TARGET]} +
+ : "" + } + { + showEdit ? +
+ +
: + { + setShowEdit(!showEdit) + }} /> + } +
diff --git a/src/pages/travelMember/memberInfor/component/style.less b/src/pages/travelMember/memberInfor/component/style.less index 50bdc7f..7d026ac 100644 --- a/src/pages/travelMember/memberInfor/component/style.less +++ b/src/pages/travelMember/memberInfor/component/style.less @@ -83,6 +83,10 @@ padding: 8px 0; .topDetailRightTop { + display: flex; + align-items: center; + height: 28px; + .detailName { font-family: PingFangSC, PingFang SC; font-weight: 600; @@ -108,12 +112,14 @@ font-family: PingFangSC, PingFang SC; font-size: 14px; color: #fff; - line-height: 14px; + line-height: 24px; text-align: left; font-style: normal; padding: 2px 8px; background: linear-gradient(0deg, #A13B00 0%, #D7AB0E 100%); border-radius: 4px; + height: 100%; + box-sizing: border-box; } } diff --git a/src/pages/travelMember/memberInfor/index.tsx b/src/pages/travelMember/memberInfor/index.tsx index f770488..72db1f4 100644 --- a/src/pages/travelMember/memberInfor/index.tsx +++ b/src/pages/travelMember/memberInfor/index.tsx @@ -33,9 +33,11 @@ import { request } from "express"; // isComponent 判断是不是以组件形式 // noMemberType 判断是否隐藏 会员类型得筛选条件 // noMemberLevel 判断是否隐藏 会员等级得筛选条件 +// come 具体来自哪个页面 +// comeParams 来自哪个页面 可能需要带上那个页面的查询参数 -const memberInfor: React.FC<{ currentUser: CurrentUser, searchType?: any, valueType?: any, isComponent?: boolean, noMemberType?: boolean, noMemberLevel?: boolean }> = (props) => { - const { currentUser, searchType, valueType, isComponent, noMemberType, noMemberLevel } = props +const memberInfor: React.FC<{ currentUser: CurrentUser, searchType?: any, valueType?: any, isComponent?: boolean, noMemberType?: boolean, noMemberLevel?: boolean, come?: string, comeParams?: any }> = (props) => { + const { currentUser, searchType, valueType, isComponent, noMemberType, noMemberLevel, come, comeParams } = props const downloadBtnRef = useRef() const draggleRef = React.createRef() const actionRef = useRef(); @@ -337,6 +339,20 @@ const memberInfor: React.FC<{ currentUser: CurrentUser, searchType?: any, valueT // valueEnum: COMPANY_STATEObj, // initialValue: "1000" // }, + { + title: "最后活跃时间", + width: 150, + // BEHAVIORRECORD_TIME 用于排序 ACTIVE_LASTTIME 用于显示 + dataIndex: "BEHAVIORRECORD_TIME", + align: 'center', + hideInSearch: true, + ellipsis: true, + sorter: true, + // defaultSortOrder: 'descend', + render: (_, record) => { + return record?.ACTIVE_LASTTIME ? moment(record?.ACTIVE_LASTTIME).format('YYYY-MM-DD HH:mm:ss') : '-' + } + }, { title: "注册时间", width: 150, @@ -351,9 +367,9 @@ const memberInfor: React.FC<{ currentUser: CurrentUser, searchType?: any, valueT // return timeB - timeA; // 倒序排序 // }, // 默认排序配置 - defaultSortOrder: 'descend', + // defaultSortOrder: 'descend', render: (_, record) => { - return record?.ADDTIME ? moment(record?.ADDTIME).format('YYYY-MM-DD') : '-' + return record?.ADDTIME ? moment(record?.ADDTIME).format('YYYY-MM-DD HH:mm:ss') : '-' } }, { @@ -706,6 +722,7 @@ const memberInfor: React.FC<{ currentUser: CurrentUser, searchType?: any, valueT search={{ span: 6 }} request={async (params, sorter) => { console.log('paramsparamsparams', params); + console.log('searchTypesearchTypesearchType', searchType); console.log('sortersortersortersorter', sorter); const sortstr = Object.keys(sorter).map(n => { @@ -720,8 +737,10 @@ const memberInfor: React.FC<{ currentUser: CurrentUser, searchType?: any, valueT // PROVINCE_CODE: currentUser?.ProvinceCode || "", OWNERUNIT_ID: 911, MEMBERSHIP_TYPE: searchType === 1 ? valueType : '', - MEMBERSHIP_LEVEL: searchType === 2 ? valueType : '', - MEMBERSHIP_STATE: 1000 + MEMBERSHIP_LEVEL: come === 'ActiveMemberStatistics' ? comeParams?.MEMBERSHIP_LEVEL || '' : searchType === 2 ? valueType : '', + MEMBERSHIP_STATE: 1000, + ACTIVE_DATE_Start: come === 'ActiveMemberStatistics' ? comeParams?.start || '' : '', + ACTIVE_DATE_End: come === 'ActiveMemberStatistics' ? comeParams?.end || '' : '', }, keyWord: { // PLATE_NUMBER diff --git a/src/pages/travelMember/service.ts b/src/pages/travelMember/service.ts index d963286..6e3557f 100644 --- a/src/pages/travelMember/service.ts +++ b/src/pages/travelMember/service.ts @@ -1219,4 +1219,30 @@ export async function handeSynchroSUGGESTION(params: any) { return data } return data +} + + +// 查询卡券兑换统计表 +export async function handeGetCouponExchangeSummary(params: any) { + const data = await requestEncryption(`/Coupon/GetCouponExchangeSummary`, { + method: 'POST', + data: { ...params, requestEncryption: true } + }) + if (data.Result_Code !== 100) { + return data + } + return wrapTreeNode(data.Result_Data.List) +} + + +// 同步会员信息表 +export async function handeGetSynchroMEMBERSHIP(params: any) { + const data = await requestEncryption(`/Member/SynchroMEMBERSHIP`, { + method: 'POST', + data: { ...params, requestEncryption: true } + }) + if (data.Result_Code !== 100) { + return data + } + return data } \ No newline at end of file diff --git a/src/utils/uploadFile.ts b/src/utils/uploadFile.ts new file mode 100644 index 0000000..1abe35e --- /dev/null +++ b/src/utils/uploadFile.ts @@ -0,0 +1,75 @@ +// 封装上传文件的方法 http://121.5.37.142:9001/browser/file-upload 后台查看的网址 +import AWS from 'aws-sdk' + +// 地址路径 +let endpoint: string = 'http://121.5.37.142:9000' +// 账号 +let accessKeyId: string = 'admin' +// 密码 +let secretAccessKey: string = 'minio123456' + + +// 上传文件的基础配置 +const s3 = new AWS.S3({ + endpoint: endpoint, + accessKeyId: accessKeyId, + secretAccessKey: secretAccessKey, + region: 'us-east-1', // 写死就行 + s3ForcePathStyle: true +}); + +// 上传图片的方法 +// 传入的 肯定是一个 proform 的 上传图片的数组格式 +export async function handleMinIOUpload(fileList: any) { + let fileRes: any = [] + for (let i = 0; i < fileList.length; i++) { + let file: any = fileList[i] + const key = `${new Date().getTime()} ${file.name.toString()}`; + + + const result = await s3.upload({ + Bucket: 'file-upload', + Key: key, + Body: file.originFileObj, + }).promise(); + console.log('上传成功:', result); + fileRes.push({ + name: file.name.toString(), + key: key, + url: result.Location + }) + } + + return fileRes +}; + +// 删除图片的方法 +export async function handleMinIODelete(fileKey: string) { + // 文件的key名称 + const result = await s3.deleteObject({ + Bucket: 'file-upload', // 你的桶名 + Key: fileKey, // 上传时的文件名(路径+文件名) + }).promise(); + return result +} + + +// 读取文件 +export async function handleMinIOPriview(fileName: string[]) { + + let resultList = [] + for (let i = 0; i < fileName.length; i++) { + const url = await s3.getSignedUrlPromise('getObject', { + Bucket: 'file-upload', + Key: fileName[i], + Expires: 3600 + }); + resultList.push({ + url: url, + name: fileName[i] + }) + } + return resultList + // window.open(url); +} + diff --git a/src/versionEnv.ts b/src/versionEnv.ts index 20c7dcb..1834447 100644 --- a/src/versionEnv.ts +++ b/src/versionEnv.ts @@ -1,4 +1,4 @@ // 由 scripts/writeVersion.js 自动生成 -export const VERSION = "4.5.13"; -export const GIT_HASH = "524c0ab"; -export const BUILD_TIME = "2025-08-04T10:43:20.278Z"; +export const VERSION = "4.5.15"; +export const GIT_HASH = "a14b50b"; +export const BUILD_TIME = "2025-08-05T03:04:59.319Z";