Commit fd3667de authored by Bill's avatar Bill

Merge branch 'v2' of 10.0.0.22:lingxi/lingxi-business-paltform into v2

parents 8a96cebd db702479
......@@ -36,13 +36,15 @@ const FetchDetailHoc = <P extends {}>(config: IConfig, WrapComponent: React.Comp
getDetail();
}, []);
return (props: Omit<P, ('dataSource' | 'loading')>): JSX.Element => {
return (
<div>
<WrapComponent {...props as any} dataSource={detail} loading={loading} />
</div>
);
};
return React.useMemo(() => {
return (props: Omit<P, ('dataSource' | 'loading')>): JSX.Element => {
return (
<div>
<WrapComponent {...props as any} dataSource={detail} loading={loading} />
</div>
);
};
}, [WrapComponent, detail, loading]);
};
export default FetchDetailHoc;
......@@ -2,10 +2,10 @@
* @Author: XieZhiXiong
* @Date: 2021-06-25 17:23:30
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-07-20 10:49:05
* @LastEditTime: 2021-07-23 15:16:09
* @Description: 商家优惠券页面详情组件
*/
import React from 'react';
import React, { useMemo } from 'react';
import {
Row,
Col,
......@@ -20,13 +20,21 @@ import {
} from '@/constants/marketing';
import AnchorPage from '@/layouts/AnchorPage';
import AuditProcess from '@/components/AuditProcess';
import {
normalizeCategoryList,
CategoryItemType,
normalizeShopList,
ShopItemType,
normalizeBrandList,
BrandItemType,
} from '../../utils';
import BacisInfo, { PropsType as BacisInfoPropsType } from '../../components/BacisInfo';
import CouponRules, { PropsType as CouponRulesPropsType } from '../../components/CouponRules';
import ApplicableGoods, { ListItemDataType } from '../../components/ApplicableGoods';
import ApplicableShopList from '../../components/ApplicableShopList';
import ApplicableCategories from '../../components/ApplicableCategories';
import ApplicableBrands from '../../components/ApplicableBrands';
import InnerFlowRecords, { FlowItem } from '../../components/InnerFlowRecords';
import InnerFlowRecords from '../../components/InnerFlowRecords';
export type DetailType = BacisInfoPropsType['dataSource'] & CouponRulesPropsType['dataSource'] & {
/**
......@@ -102,7 +110,19 @@ export type DetailType = BacisInfoPropsType['dataSource'] & CouponRulesPropsType
/**
* 适用商品
*/
suitableCommoditySkuList: ListItemDataType[],
suitableCommoditySkuList?: ListItemDataType[],
/**
* 适用品类
*/
suitableCategoryList?: CategoryItemType[][],
/**
* 适用品牌
*/
suitableBrandList?: BrandItemType[],
/**
* 适用商城
*/
suitableMallTypes?: ShopItemType[],
};
interface IProps {
......@@ -171,6 +191,18 @@ const MerchantCouponDetail: React.FC<IProps> = (props) => {
},
].filter(Boolean);
const categories = useMemo(() => {
return normalizeCategoryList(dataSource?.suitableCategoryList);
}, [dataSource?.suitableCategoryList]);
const shopList = useMemo(() => {
return normalizeShopList(dataSource?.suitableMallTypes);
}, [dataSource?.suitableMallTypes]);
const brandList = useMemo(() => {
return normalizeBrandList(dataSource?.suitableBrandList);
}, [dataSource?.suitableBrandList]);
return (
<Spin spinning={loading}>
<AnchorPage
......@@ -249,18 +281,7 @@ const MerchantCouponDetail: React.FC<IProps> = (props) => {
? (
<Col span={24}>
<ApplicableCategories
options={[
{
logo: 'http://www.yyfun001.com/res/htmlLX/gunbo1.jpg',
label: '成品皮-牛皮-头层牛皮',
value: 1,
},
{
logo: 'http://www.yyfun001.com/res/htmlLX/gunbo1.jpg',
label: '成品皮-牛皮-头层牛皮',
value: 2,
},
]}
options={categories}
id="applicableCategories"
/>
</Col>
......@@ -276,18 +297,7 @@ const MerchantCouponDetail: React.FC<IProps> = (props) => {
? (
<Col span={24}>
<ApplicableBrands
options={[
{
logo: 'http://www.yyfun001.com/res/htmlLX/gunbo4.jpg',
label: '头层牛皮',
value: 1,
},
{
logo: 'http://www.yyfun001.com/res/htmlLX/gunbo4.jpg',
label: '牛皮',
value: 2,
},
]}
options={brandList}
id="applicableBrands"
/>
</Col>
......@@ -299,18 +309,7 @@ const MerchantCouponDetail: React.FC<IProps> = (props) => {
{/* 适用商城 */}
<Col span={24}>
<ApplicableShopList
options={[
{
logo: 'http://www.yyfun001.com/res/htmlLX/gunbo3.jpg',
label: 'WEB-渠道商城',
value: 1,
},
{
logo: 'http://www.yyfun001.com/res/htmlLX/gunbo3.jpg',
label: 'H5-渠道商城',
value: 2,
},
]}
options={shopList}
id="applicableShopList"
/>
</Col>
......
......@@ -2,7 +2,7 @@
* @Author: XieZhiXiong
* @Date: 2021-06-24 14:04:16
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-07-19 17:26:55
* @LastEditTime: 2021-07-23 17:36:48
* @Description:
*/
import { FormEffectHooks, FormPath, IFormActions } from '@formily/antd';
......@@ -29,6 +29,23 @@ export const useBusinessEffects = (context, actions: IFormActions) => {
const linkage = useLinkageUtils();
// 优惠券类型
onFieldInputChange$('type').subscribe(state => {
const { value } = state;
const denominationValue = getFieldValue('denomination'); // 券面额
const useConditionMoneyValue = getFieldValue('useConditionMoney'); // 使用条件
// 0元抵扣券
if (value === MERCHANT_COUPON_TYPE_VOUCHER) {
} else {
setFieldState('getWay', fieldState => {
FormPath.setIn(fieldState, 'value', undefined);
FormPath.setIn(fieldState, 'props.x-component-props.disabled', false);
});
}
});
// 优惠券类型
onFieldValueChange$('type').subscribe(state => {
const { value } = state;
const denominationValue = getFieldValue('denomination'); // 券面额
......@@ -55,11 +72,6 @@ export const useBusinessEffects = (context, actions: IFormActions) => {
});
}
setFieldState('getWay', fieldState => {
FormPath.setIn(fieldState, 'value', undefined);
FormPath.setIn(fieldState, 'props.x-component-props.disabled', false);
});
// 非0元抵扣券,使用条件 必须大于 0
if (useConditionMoneyValue && +useConditionMoneyValue === 0) {
setFieldState('useConditionMoney', fieldState => {
......@@ -159,6 +171,15 @@ export const useBusinessEffects = (context, actions: IFormActions) => {
});
// 领券方式
onFieldInputChange$('getWay').subscribe(() => {
setFieldState('suitableMemberTypes', state => {
if (state.value && state.value.length) {
FormPath.setIn(state, 'value', []);
}
});
});
// 领券方式
onFieldValueChange$('getWay').subscribe(state => {
const { value } = state;
......@@ -181,9 +202,6 @@ export const useBusinessEffects = (context, actions: IFormActions) => {
});
setFieldState('suitableMemberTypes', state => {
if (state.value && state.value.length) {
FormPath.setIn(state, 'value', []);
}
FormPath.setIn(state, 'props.enum', newData);
});
});
......
......@@ -2,12 +2,12 @@
* @Author: XieZhiXiong
* @Date: 2021-06-24 13:47:47
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-07-19 18:30:06
* @LastEditTime: 2021-07-23 18:03:47
* @Description: 新增/修改 优惠券表单
*/
import React, { useState, useMemo } from 'react';
import React, { useState, useMemo, useEffect } from 'react';
import { Spin, Button, message } from 'antd';
import { PlusOutlined, DeleteOutlined, SaveOutlined } from '@ant-design/icons';
import { DeleteOutlined, SaveOutlined } from '@ant-design/icons';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { Radio, DatePicker, ArrayTable } from '@formily/antd-components';
import { history, Prompt } from 'umi';
......@@ -50,7 +50,7 @@ export type SubmitValueType = {
*/
name: string,
/**
* 优惠券名称
* 券面额
*/
denomination: string,
/**
......@@ -105,28 +105,24 @@ export type SubmitValueType = {
/**
* 使用说明
*/
userConditionDesc: string,
useConditionDesc: string,
/**
* 适用商品
*/
goodsList: ProductItemType[],
goodsList?: ProductItemType[],
/**
* 适用品类
*/
applicableCategories: {
category: string[],
applicableCategories?: {
category: number[][],
}[],
/**
* 适用品牌
*/
applicableBrands: {
brand: string,
applicableBrands?: {
brand: number,
}[],
/**
* 适用用户
*/
applicationUser: any[],
/**
* 适用用户角色
*/
applicationUserRole: any[],
......@@ -140,6 +136,8 @@ export type SubmitValueType = {
suitableMallTypes: number[],
}
export type CouponInfoType = SubmitValueType & {}
interface IProps {
/**
* 数据id
......@@ -156,10 +154,76 @@ const CouponForm: React.FC<IProps> = (props) => {
id,
editable = true,
} = props;
const [couponInfo, setCouponInfo] = useState<CouponInfoType>();
const [infoLoading, setInfoLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const [typeValue, setTypeValue] = useState<undefined | number>(undefined);
const [unsaved, setUnsaved] = useState(false);
const getCouponDetail = () => {
if (!id) {
return;
}
setInfoLoading(true);
PublicApi.getMarketingCouponWaitAuditGet({
id: `${id}`,
}).then((res) => {
if (res.code === 1000) {
const {
id,
status,
statusName,
suitableCommoditySkuList,
suitableCategoryList,
suitableBrandList,
suitableMallTypes,
suitableMemberLevelTypes,
denomination,
quantity,
releaseTimeStart,
releaseTimeEnd,
effectiveTimeStart,
effectiveTimeEnd,
invalidDay,
useConditionMoney,
conditionGetTotal,
conditionGetDay,
createTime,
taskSteps,
history,
...rest
} = res.data;
setCouponInfo({
goodsList: suitableCommoditySkuList as any,
applicableCategories: (suitableCategoryList as any)?.map((item) => ({ category: item.map((category) => `${category.id}`)})),
applicableBrands: suitableBrandList?.map((item) => ({ brand: item.id })),
applicationUserRole: [],
applicationMemberLevel: suitableMemberLevelTypes,
suitableMallTypes: suitableMallTypes?.map((item) => item.id),
denomination: `${denomination}`,
quantity: `${quantity}`,
releaseTimeStart: releaseTimeStart ? moment(releaseTimeStart).format('YYYY-MM-DD HH:mm:ss') : '',
releaseTimeEnd: releaseTimeEnd ? moment(releaseTimeEnd).format('YYYY-MM-DD HH:mm:ss') : '',
effectiveTimeStart: effectiveTimeStart ? moment(effectiveTimeStart).format('YYYY-MM-DD HH:mm:ss') : '',
effectiveTimeEnd: effectiveTimeEnd ? moment(effectiveTimeEnd).format('YYYY-MM-DD HH:mm:ss') : '',
invalidDay: invalidDay !== null ? `${invalidDay}` : undefined,
useConditionMoney: `${useConditionMoney}`,
receiveCondition: {
conditionGetTotal: `${conditionGetTotal}`,
conditionGetDay: `${conditionGetDay}`,
},
...rest,
});
}
}).finally(() => {
setInfoLoading(false);
});
};
useEffect(() => {
getCouponDetail();
}, []);
const anchorsArr = [
{
key: 'basicInfo',
......@@ -169,6 +233,10 @@ const CouponForm: React.FC<IProps> = (props) => {
key: 'couponRules',
name: '优惠券规则',
},
{
key: 'applicableShopList',
name: '适用商城',
},
(
typeValue === MERCHANT_COUPON_TYPE_PRODUCT
|| typeValue === MERCHANT_COUPON_TYPE_VOUCHER
......@@ -198,10 +266,6 @@ const CouponForm: React.FC<IProps> = (props) => {
key: 'applicableMember',
name: '适用用户',
},
{
key: 'applicableShopList',
name: '适用商城',
},
].filter(Boolean);
// 删除商品项
......@@ -240,26 +304,21 @@ const CouponForm: React.FC<IProps> = (props) => {
...restValue
} = values;
let applicationRelated: string[] = [];
if (applicableBrands && applicableBrands.length) {
applicationRelated = applicableBrands.map((item) => item.brand);
}
if (applicableCategories && applicableCategories.length) {
applicationRelated = applicableCategories.map((item) => item.category.join('.'));
}
const suitableCommoditySkuList = goodsList?.map((item) => ({
id: item.id,
commodityId: item.commodityId,
name: item.name,
mainPic: item.mainPic,
customerCategoryName: item.customerCategoryName,
brandName: item.brandName,
unitName: item.unitName,
unitPrice: item.unitPrice,
}));
const suitableCategoryList: any = applicableCategories?.map((item) => item.category);
const suitableBrandList: any = applicableBrands?.map((item) => item.brand);
const payload = {
conditionGetDay: +conditionGetDay,
conditionGetTotal: +conditionGetTotal,
......@@ -272,8 +331,9 @@ const CouponForm: React.FC<IProps> = (props) => {
effectiveTimeStart: effectiveTimeStart ? moment(effectiveTimeStart).valueOf() : undefined,
effectiveTimeEnd: effectiveTimeEnd ? moment(effectiveTimeEnd).valueOf() : undefined,
suitableMemberLevelTypes: applicationMemberLevel,
relevanceProductData: applicationRelated as any,
suitableCommoditySkuList,
suitableCategoryList,
suitableBrandList,
...restValue,
};
......@@ -297,6 +357,29 @@ const CouponForm: React.FC<IProps> = (props) => {
msg();
setSubmitLoading(false);
});
} else {
setSubmitLoading(true);
const msg = message.loading({
content: '正在修改,请稍候...',
duration: 0,
});
PublicApi.postMarketingCouponWaitAuditUpdate({
id,
...payload,
}, {
timeout: 0,
}).then((res) => {
if (res.code !== 1000) {
return;
}
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}).finally(() => {
msg();
setSubmitLoading(false);
});
}
};
......@@ -309,7 +392,7 @@ const CouponForm: React.FC<IProps> = (props) => {
);
return (
<Spin spinning={false}>
<Spin spinning={infoLoading}>
<AnchorPage
title="新增商家优惠券"
anchors={anchorsArr}
......@@ -329,7 +412,7 @@ const CouponForm: React.FC<IProps> = (props) => {
previewPlaceholder=" "
onSubmit={handleSubmit}
actions={formActions}
initialValues={{}}
initialValues={couponInfo}
components={{
RadioGroup: Radio.Group,
RangePicker: DatePicker.RangePicker,
......
......@@ -30,6 +30,10 @@ export type ProductItemType = {
*/
name: string,
/**
* 商品图片
*/
mainPic: string,
/**
* 会员分类名称
*/
customerCategoryName: string,
......
......@@ -2,15 +2,17 @@
* @Author: XieZhiXiong
* @Date: 2021-06-25 17:00:46
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-06-25 17:00:47
* @LastEditTime: 2021-07-23 17:09:45
* @Description: 编辑商家优惠券
*/
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import CouponForm from './components/CouponForm';
const MerchantCouponEdit: React.FC = () => {
const { id } = usePageStatus();
return (
<CouponForm />
<CouponForm id={+id} />
);
};
......
......@@ -2,10 +2,12 @@
* @Author: XieZhiXiong
* @Date: 2021-07-20 10:10:55
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-07-20 10:27:34
* @LastEditTime: 2021-07-23 15:00:55
* @Description:
*/
import { OptionItemType } from '../components/ApplicableList';
type OriginUnitPriceType = { [key: string]: any }
type UnitPriceType = {
/**
* 起始
......@@ -21,6 +23,51 @@ type UnitPriceType = {
price: number,
}
export type CategoryItemType = {
/**
* 品类id
*/
id: number,
/**
* 品类图片
*/
imageUrl: string,
/**
* 品类名称
*/
name: string,
}
export type ShopItemType = {
/**
* 商城id
*/
id: number,
/**
* 商城图片
*/
logoUrl: string,
/**
* 商城名称
*/
name: string,
}
export type BrandItemType = {
/**
* 品牌id
*/
id: number,
/**
* 品牌图片
*/
logoUrl: string,
/**
* 品牌名称
*/
name: string,
}
export function normalizeUnitPrice(unitPrice: UnitPriceType): UnitPriceType[] {
const ret = [];
const objKeys = Object.keys(unitPrice).sort((a, b) => parseFloat(a) - parseFloat(b));
......@@ -36,4 +83,49 @@ export function normalizeUnitPrice(unitPrice: UnitPriceType): UnitPriceType[] {
});
return ret;
};
export function normalizeCategoryList(origin: CategoryItemType[][]): OptionItemType[] {
const ret: OptionItemType[] = [];
if (!Array.isArray(origin)) {
return ret;
}
origin.forEach((item, index) => {
ret.push({
logo: item[item.length - 1]?.imageUrl,
label: item.map((item) => item.name).join('-'),
value: index,
});
});
return ret;
};
export function normalizeShopList(origin: ShopItemType[]): OptionItemType[] {
const ret: OptionItemType[] = [];
if (!Array.isArray(origin)) {
return ret;
}
origin.forEach((item) => {
ret.push({
logo: item.logoUrl,
label: item.name,
value: item.id,
});
});
return ret;
};
export function normalizeBrandList(origin: BrandItemType[]): OptionItemType[] {
const ret: OptionItemType[] = [];
if (!Array.isArray(origin)) {
return ret;
}
origin.forEach((item) => {
ret.push({
logo: item.logoUrl,
label: item.name,
value: item.id,
});
});
return ret;
};
\ No newline at end of file
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