Commit 52537533 authored by XieZhiXiong's avatar XieZhiXiong

chore: 添加 商家优惠券相关页面

parent 034ceb50
......@@ -6,11 +6,12 @@ import { selfManagementRoute } from './selfManagementRoute';
import { paltformSignRoute } from './paltformSignRoute';
import { selfbuiltexecutionRoute } from './selfbuiltexecutionRoute';
import { platformexecutionRoute } from './platformexecutionRoute';
import merchantCouponRoute from './merchantCouponRoute';
const MarketingRoute = {
path: "/memberCenter/marketingAbility",
name: "营销能力",
name: "marketingAbility",
icon: "commodity",
routes: [
/** 自建营销活动管理 */
......@@ -20,7 +21,8 @@ const MarketingRoute = {
/** 营销活动执行(自建) */
...platformexecutionRoute,
// /** 营销活动执行(平台) */
...selfbuiltexecutionRoute
...selfbuiltexecutionRoute,
...merchantCouponRoute,
],
}
......
/*
* @Author: XieZhiXiong
* @Date: 2021-06-21 18:18:41
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 16:05:58
* @Description: 商家优惠券相关路由
*/
import { RouterChild } from '../../utils/index';
const merchantCouponRoute: RouterChild[] = [
{
path: '/memberCenter/marketingAbility/merchantCoupon',
name: 'merchantCoupon',
icon: 'member',
routes: [
// 商家优惠劵查询
{
path: '/memberCenter/marketingAbility/merchantCoupon/query',
name: 'query',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponQuery'
},
// 商家优惠劵查询
{
path: '/memberCenter/marketingAbility/merchantCoupon/query/detail',
name: 'queryDetail',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponQuery/detail',
hideInMenu: true,
noMargin: true,
},
// 待提交审核商家优惠劵
{
path: '/memberCenter/marketingAbility/merchantCoupon/unsubmitted',
name: 'unsubmitted',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponUnsubmitted'
},
// 待审核商家优惠劵(一级)
{
path: '/memberCenter/marketingAbility/merchantCoupon/notVerify1',
name: 'notVerify1',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponNotVerify1'
},
// 待审核商家优惠劵(二级)
{
path: '/memberCenter/marketingAbility/merchantCoupon/notVerify2',
name: 'notVerify2',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponNotVerify2'
},
// 待提交商家优惠劵
{
path: '/memberCenter/marketingAbility/merchantCoupon/toConfirm',
name: 'toConfirm',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponToConfirm'
},
// 商家优惠劵执行
{
path: '/memberCenter/marketingAbility/merchantCoupon/analysis',
name: 'analysis',
component: '@/pages/transaction/marketingAbility/merchantCoupon/merchantCouponAnalysis'
},
],
}
];
export default merchantCouponRoute;
import React, { CSSProperties } from 'react';
import { Descriptions } from 'antd';
import React, { CSSProperties, ReactNode } from 'react';
import { Descriptions, Tooltip } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import MellowCard, { MellowCardProps } from '@/components/MellowCard';
import styles from './index.less';
......@@ -8,6 +9,14 @@ export interface ColumnProps {
span?: number,
contentStyle?: CSSProperties,
labelStyle?: CSSProperties,
/**
* 帮助提示
*/
tips?: boolean,
/**
* 帮助提示文本
*/
tipsText?: string,
}
export interface DataItem {
......@@ -50,6 +59,17 @@ const CustomizeColumn: React.FC<IProps> = (props: IProps) => {
const { className } = rest;
const mergeCls = classNames(styles['customize-column'], className);
const renderTips = (text: React.ReactNode, tips) => {
return React.createElement(
Tooltip,
{ title: tips },
<div>
<span>{text}</span>
<QuestionCircleOutlined style={{ margin: '0 4px' }} />
</div>
)
};
return (
<MellowCard
bodyStyle={{
......@@ -59,15 +79,19 @@ const CustomizeColumn: React.FC<IProps> = (props: IProps) => {
className={mergeCls}
>
<Descriptions column={column}>
{data.map((item, index) => (
<Descriptions.Item
key={index}
label={item.title}
{...({...defaultColumnProps, ...item.columnProps} || defaultColumnProps)}
>
{item.value}
</Descriptions.Item>
))}
{data.map((item, index) => {
const mergeColumns = Object.assign({}, defaultColumnProps, item.columnProps);
const { tips, tipsText, ...restColumns } = mergeColumns;
return (
<Descriptions.Item
key={index}
label={item.title}
{...restColumns}
>
{!tips ? item.value : renderTips(item.value, tipsText)}
</Descriptions.Item>
)
})}
</Descriptions>
</MellowCard>
);
......
......@@ -680,5 +680,14 @@ export default {
'menu.procurementAbility.callForBids.callForBidsSearch': '招标查询',
'menu.procurementAbility.purchaseInquiry': '采购询价',
// 营销能力
'menu.marketingAbility': '营销能力',
'menu.marketingAbility.merchantCoupon': '商家优惠劵管理',
'menu.marketingAbility.merchantCoupon.query': '商家优惠劵查询',
'menu.marketingAbility.merchantCoupon.queryDetail': '查看商家优惠劵',
'menu.marketingAbility.merchantCoupon.unsubmitted': '待提交审核商家优惠劵',
'menu.marketingAbility.merchantCoupon.notVerify1': '待审核商家优惠劵(一级)',
'menu.marketingAbility.merchantCoupon.notVerify2': '待审核商家优惠劵(二级)',
'menu.marketingAbility.merchantCoupon.toConfirm': '待提交商家优惠劵',
'menu.marketingAbility.merchantCoupon.analysis': '商家优惠劵执行',
};
.product {
&-img {
width: 32px;
height: 32px;
object-fit: contain;
}
}
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 17:12:38
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 17:30:47
* @Description: 适用商品
*/
import React from 'react';
import MellowCard, { MellowCardProps } from '@/components/MellowCard';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import styles from './index.less';
export type ListItemDataType = {
/**
* 数据id
*/
productId: number,
/**
* 商品图片
*/
productImg: string,
/**
* 商品图片
*/
productName: string,
/**
* 商品品类
*/
category: string,
/**
* 商品品牌
*/
brand: string,
/**
* 商品单位
*/
unit: string,
/**
* 商品单价
*/
price: number,
}
interface IProps extends MellowCardProps {
/**
* 数据
*/
dataSource: ListItemDataType[];
};
const ApplicableGoods: React.FC<IProps> = (props) => {
const {
dataSource,
...rest
} = props;
const columns: EditableColumns<ListItemDataType>[] = [
{
title: '商品ID',
dataIndex: 'productId',
align: 'center',
},
{
title: '商品图片',
dataIndex: 'productImg',
align: 'center',
render: (text) => <img src={text} className={styles['product-img']} />
},
{
title: '商品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '品类',
dataIndex: 'category',
},
{
title: '品牌',
dataIndex: 'brand',
},
{
title: '单位',
dataIndex: 'unit',
},
{
title: '商品价格',
dataIndex: 'price',
render: (text) => ${text}`,
},
];
return (
<MellowCard
title="适用商品"
{...rest}
>
<PolymericTable
rowKey="productId"
dataSource={dataSource}
columns={columns}
pagination={null}
/>
</MellowCard>
);
};
export default ApplicableGoods;
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 15:34:47
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 16:44:56
* @Description: 基本信息
*/
import React from 'react';
import { Badge } from 'antd';
import CustomizeColumn, { IProps as CustomizeColumnProps, DataItem } from '@/components/CustomizeColumn';
type PropsType = Omit<CustomizeColumnProps, 'data' | 'column'> & {
/**
* 数据,模拟数据
*/
dataSource: { [key: string]: any },
}
const CouponBacisInfo: React.FC<PropsType> = (props: PropsType) => {
const { dataSource, ...rest } = props;
const basicInfo: DataItem[] = [
{
title: '活动ID',
value: dataSource.id || '',
},
{
title: '优惠券类型',
value: '全品类通用优惠券',
columnProps: {
tips: true,
tipsText: '全品类通用优惠券',
},
},
{
title: '领(发)券开始时间',
value: '2020-09-25 09:00',
},
{
title: '活动名称',
value: '全品类通用优惠券',
},
{
title: '券面额',
value: '¥ 50.00',
},
{
title: '领(发)券结束时间',
value: '2020-09-25 09:00',
},
{
title: '内部状态',
value: (
<Badge color="blue" text="进行中" />
),
},
{
title: '发券数量',
value: '1,000',
},
];
return (
<CustomizeColumn
title="基本信息"
{...rest}
data={basicInfo}
/>
);
};
export default CouponBacisInfo;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 16:45:58
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 16:59:35
* @Description: 优惠券规则
*/
import React from 'react';
import CustomizeColumn, { IProps as CustomizeColumnProps, DataItem } from '@/components/CustomizeColumn';
type PropsType = Omit<CustomizeColumnProps, 'data' | 'column'> & {
/**
* 数据,模拟数据
*/
dataSource: { [key: string]: any },
}
const CouponRules: React.FC<PropsType> = (props: PropsType) => {
const { dataSource, ...rest } = props;
const basicInfo: DataItem[] = [
{
title: '领券方式',
value: '前台用户领券',
columnProps: {
tips: true,
tipsText: '全品类通用优惠券',
},
},
{
title: '有效期开始时间',
value: dataSource.startTime || '2020-09-25 09:00',
},
{
title: '使用条件',
value: '订单满 ¥ 50.01 使用',
},
{
title: '领取条件',
value: '每会员ID总共可领取 3 张,每日 1 张',
},
{
title: '有效期开始时间',
value: '2020-09-25 09:00',
},
{
title: '使用说明',
value: '全品类通用,订单金额满 ¥ 50.01 使用,有效时间:2014-08-08 12:00:00 ~ 2014-08-10 12:00:00',
},
];
return (
<CustomizeColumn
title="优惠券规则"
{...rest}
data={basicInfo}
/>
);
};
export default CouponRules;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 11:10:57
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 11:11:38
* @Description: 商家优惠劵执行
*/
import React from 'react';
import styles from './index.less';
const MerchantCouponAnalysis: React.FC = () => {
return (
<div>MerchantCouponAnalysis</div>
);
};
export default MerchantCouponAnalysis;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 11:09:02
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 11:09:02
* @Description: 待审核商家优惠劵(一级)
*/
import React from 'react';
import styles from './index.less';
const MerchantCouponNotVerify1: React.FC = () => {
return (
<div>MerchantCouponNotVerify1</div>
);
};
export default MerchantCouponNotVerify1;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 11:09:35
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 11:09:35
* @Description: 待审核商家优惠劵(二级)
*/
import React from 'react';
import styles from './index.less';
const MerchantCouponNotVerify2: React.FC = () => {
return (
<div>MerchantCouponNotVerify2</div>
);
};
export default MerchantCouponNotVerify2;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 15:55:02
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 17:28:55
* @Description: 商家优惠劵查询详情
*/
import React, { useState, useEffect } from 'react';
import {
Row,
Col,
Spin,
} from 'antd';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import { GetMemberAbilityMaintenanceDetailBasicResponse } from '@/services/MemberV2Api';
import AnchorPage from '@/layouts/AnchorPage';
import AuditProcess from '@/components/AuditProcess';
import BacisInfo from '../../components/BacisInfo';
import CouponRules from '../../components/CouponRules';
import ApplicableGoods from '../../components/ApplicableGoods';
const merchantCouponQueryDetail: React.FC<{}> = () => {
const { id } = usePageStatus();
const [memberInfo, setMemberInfo] = useState<GetMemberAbilityMaintenanceDetailBasicResponse>(null);
const [infoLoading, setInfoLoaading] = useState(false);
const getBasicInfo = () => {
if (!id) {
return;
}
setInfoLoaading(true);
PublicApi.getMemberAbilityMaintenanceDetailBasic({
validateId: id,
}).then(res => {
if (res.code === 1000) {
setMemberInfo(res.data);
}
}).finally(() => {
setInfoLoaading(false);
});
};
useEffect(() => {
getBasicInfo();
}, []);
const anchorsArr = [
{
key: 'verifySteps',
name: '流转进度',
},
{
key: 'basicInfo',
name: '基本信息',
},
{
key: 'couponRules',
name: '优惠券规则',
},
{
key: 'applicableGoods',
name: '适用商品',
},
].filter(Boolean);
return (
<Spin spinning={infoLoading}>
<AnchorPage
title={memberInfo?.name}
anchors={anchorsArr}
>
<Row gutter={[16, 16]}>
{/* 流转记录 */}
<Col span={24}>
<AuditProcess
innerVerifySteps={memberInfo?.innerVerifySteps}
innerVerifyCurrent={memberInfo?.currentInnerStep}
id="verifySteps"
/>
</Col>
{/* 基本信息 */}
<Col span={24}>
<BacisInfo
dataSource={{}}
id="basicInfo"
/>
</Col>
{/* 优惠券规则 */}
<Col span={24}>
<CouponRules
dataSource={{}}
id="couponRules"
/>
</Col>
{/* 适用商品 */}
<Col span={24}>
<ApplicableGoods
dataSource={[
{
productId: 1,
productName: '进口头层黄牛皮荔枝纹/红色/XL',
productImg: 'http://www.yyfun001.com/res/htmlLX/gunbo2.jpg',
category: '牛皮',
brand: 'PELLE',
unit: '尺',
price: 500,
},
{
productId: 2,
productName: '进口头层黄牛皮荔枝纹/红色/XL',
productImg: 'http://www.yyfun001.com/res/htmlLX/gunbo2.jpg',
category: '牛皮',
brand: 'PELLE',
unit: '尺',
price: 500,
},
{
productId: 3,
productName: '进口头层黄牛皮荔枝纹/红色/XL',
productImg: 'http://www.yyfun001.com/res/htmlLX/gunbo2.jpg',
category: '牛皮',
brand: 'PELLE',
unit: '尺',
price: 500,
},
]}
id="applicableGoods"
/>
</Col>
</Row>
</AnchorPage>
</Spin>
);
};
export default merchantCouponQueryDetail;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 09:49:42
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 16:18:11
* @Description: 商家优惠劵查询
*/
import React, { useState, useRef } from 'react';
import { history } from 'umi';
import {
Card,
Space,
Button,
} from 'antd';
import {
PlusOutlined,
} from '@ant-design/icons';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { createFormActions } from '@formily/antd';
import { DatePicker } from '@formily/antd-components';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import EyePreview from '@/components/EyePreview';
import NiceForm from '@/components/NiceForm';
import { PublicApi } from '@/services/api';
import useSpliceArray from '@/hooks/useSpliceArray';
import { querySchema } from './schema';
const formActions = createFormActions();
const MerchantCouponQuery: React.FC = () => {
const ref = useRef<any>({});
const fetchData = async (params: any) => {
let res = await PublicApi.getMemberAbilityMaintenancePage(params);
return res.data;
};
const defaultColumns: ColumnType<any>[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '优惠劵名称',
dataIndex: 'name',
align: 'center',
render: (text, record) => (
<EyePreview
url={`/memberCenter/marketingAbility/merchantCoupon/query/detail?id=${record.validateId}`}
>
{text}
</EyePreview>
),
},
{
title: '优惠劵类型',
dataIndex: 'memberTypeName',
align: 'center',
},
{
title: '领(发)劵起始时间',
dataIndex: 'registerTime',
align: 'center',
},
{
title: '领(发)劵截止时间',
dataIndex: 'registerTime',
align: 'center',
},
{
title: '劵有效期起始时间',
dataIndex: 'registerTime',
align: 'center',
},
{
title: '劵有效期截止时间',
dataIndex: 'registerTime',
align: 'center',
},
{
title: '领劵方式',
dataIndex: 'depositTime',
align: 'center',
},
{
title: '劵面额',
dataIndex: 'statusName',
},
{
title: '发劵数量',
dataIndex: 'statusName',
},
{
title: '内部状态',
dataIndex: 'statusName',
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (_, record) => (
<>
<Button
type="link"
onClick={() => {}}
>
取消
</Button>
<Button
type="link"
onClick={() => {}}
>
重启
</Button>
<Button
type="link"
onClick={() => {}}
>
修改
</Button>
</>
),
},
];
const [columns, columnsHandle] = useSpliceArray<ColumnType<any>>(defaultColumns);
// 初始化高级筛选选项
const fetchSelectOptions = async () => {
const res = await PublicApi.getMemberAbilityInfoPageitems();
if (res.code === 1000) {
const { data = {} }: any = res;
const {
outerStatus = [],
} = data;
const outerIndex = columns.findIndex((item) => item.dataIndex === 'memberTypeName');
if (outerIndex) {
columnsHandle.replace(outerIndex, {
...columns[outerIndex],
filters: outerStatus.map(item => ({ text: item.text, value: item.id })).filter(item => item.value !== 0),
});
}
return {
innerStatus: outerStatus.map(item => ({ label: item.text, value: item.id })),
};
}
return {};
};
const ControllerBtns = () => (
<Space>
<Button
type="primary"
onClick={() => {}}
>
<PlusOutlined />
增加会员角色
</Button>
</Space>
);
return (
<Card>
<StandardTable
tableProps={{
rowKey: 'validateId',
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchData(params)}
controlRender={
<NiceForm
actions={formActions}
components={{
ControllerBtns,
RangePicker: DatePicker.RangePicker,
}}
onSubmit={values => ref.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'name',
FORM_FILTER_PATH,
);
useAsyncInitSelect(
['outerStatus'],
fetchSelectOptions,
);
}}
schema={querySchema}
/>
}
/>
</Card>
);
};
export default MerchantCouponQuery;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 14:37:24
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 15:02:04
* @Description:
*/
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
export const querySchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
},
properties: {
ctl: {
type: 'object',
'x-component': 'ControllerBtns',
},
name: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
tip: '输入 优惠劵名称 进行搜索',
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
colStyle: {
marginLeft: 20,
},
},
properties: {
id: {
type: 'string',
'x-component-props': {
placeholder: '优惠劵ID',
allowClear: true,
style: {
width: 160,
},
},
},
'[startTime, endTime]': {
type: 'object',
'x-component': 'RangePicker',
'x-component-props': {
placeholder: ['领(发)劵起始时间', '领(发)劵截止时间'],
showTime: true,
},
},
'[startTime2, endTime2]': {
type: 'object',
'x-component': 'RangePicker',
'x-component-props': {
placeholder: ['劵有效期起始时间', '劵有效期截止时间'],
showTime: true,
},
},
type: {
type: 'string',
default: undefined,
enum: [],
'x-component-props': {
placeholder: '优惠劵类型(所有)',
allowClear: true,
},
},
mode: {
type: 'string',
default: undefined,
enum: [],
'x-component-props': {
placeholder: '领劵方式(所有)',
allowClear: true,
},
},
innerStatus: {
type: 'string',
default: undefined,
enum: [],
'x-component-props': {
placeholder: '内部状态(所有)',
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 11:10:04
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 11:10:24
* @Description: 待提交商家优惠劵
*/
import React from 'react';
import styles from './index.less';
const MerchantCouponToConfirm: React.FC = () => {
return (
<div>MerchantCouponToConfirm</div>
);
};
export default MerchantCouponToConfirm;
/*
* @Author: XieZhiXiong
* @Date: 2021-06-22 11:08:16
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-22 14:18:02
* @Description: 待提交审核商家优惠劵
*/
import React from 'react';
import styles from './index.less';
const MerchantCouponUnsubmitted: React.FC = () => {
return (
<div>MerchantCouponUnsubmitted</div>
);
};
export default MerchantCouponUnsubmitted;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment