Commit e1cc7343 authored by XieZhiXiong's avatar XieZhiXiong
parents 0f2ccf96 dd70f367
......@@ -5,41 +5,41 @@
*/
export const selfManagementRoute = [
// 自建营销活动管理
{
/** 自建营销活动管理 */
path: '/memberCenter/marketingAbility/selfManagement',
name: '自建营销活动管理',
routes: [
// 营销活动查询
{
/** 营销活动查询 */
path: '/memberCenter/marketingAbility/selfManagement/search',
name: '营销活动查询',
component: '@/pages/transaction/marketingAbility/selfManagement/search'
},
// 营销活动查询详情
{
/** 营销活动查询详情 */
path: '/memberCenter/marketingAbility/selfManagement/search/preview',
name: '营销活动查询详情',
component: '@/pages/transaction/marketingAbility/selfManagement/detail',
hideInMenu: true,
noMargin: true,
},
// 待提交审核营销活动
{
/** 待提交审核营销活动 */
path: '/memberCenter/marketingAbility/selfManagement/readySubmitExamine',
name: '待提交审核营销活动',
component: '@/pages/transaction/marketingAbility/selfManagement/readySubmitExamine'
},
// 新增营销活动
{
/** 新增营销活动 */
path: '/memberCenter/marketingAbility/selfManagement/readySubmitExamine/add',
name: '新增营销活动',
component: '@/pages/transaction/marketingAbility/selfManagement/readySubmitExamine/add',
hideInMenu: true,
noMargin: true,
},
// 修改营销活动
{
/** 修改营销活动 */
path: '/memberCenter/marketingAbility/selfManagement/readySubmitExamine/modify',
name: '修改营销活动',
component: '@/pages/transaction/marketingAbility/selfManagement/readySubmitExamine/add',
......@@ -54,8 +54,8 @@ export const selfManagementRoute = [
hideInMenu: true,
noMargin: true,
},
// 待审核营销活动(一级)
{
/** 待审核营销活动(一级) */
path: '/memberCenter/marketingAbility/selfManagement/readyExamineOne',
name: '待审核营销活动(一级)',
component: '@/pages/transaction/marketingAbility/selfManagement/readyExamineOne'
......@@ -76,14 +76,14 @@ export const selfManagementRoute = [
hideInMenu: true,
noMargin: true,
},
// 待审核营销活动(二级)
{
/** 待审核营销活动(二级) */
path: '/memberCenter/marketingAbility/selfManagement/readyExamineTwo',
name: '待审核营销活动(二级)',
component: '@/pages/transaction/marketingAbility/selfManagement/readyExamineTwo'
},
// 待审核营销活动(二级)详情
{
/** 待审核营销活动(二级)详情 */
path: '/memberCenter/marketingAbility/selfManagement/readyExamineTwo/preview',
name: '待审核营销活动(二级)详情',
component: '@/pages/transaction/marketingAbility/selfManagement/detail',
......@@ -91,34 +91,35 @@ export const selfManagementRoute = [
noMargin: true,
},
{
/** 待审核营销活动(二级)详情 */
path: '/memberCenter/marketingAbility/selfManagement/readyExamineTwo/detail',
name: '待审核营销活动(二级)详情',
component: '@/pages/transaction/marketingAbility/selfManagement/detail',
hideInMenu: true,
noMargin: true,
},
// 待提交营销活动
{
/** 待提交营销活动 */
path: '/memberCenter/marketingAbility/selfManagement/readySubmit',
name: '待提交营销活动',
component: '@/pages/transaction/marketingAbility/selfManagement/readySubmit'
},
// 待提交营销活动详情
{
/** 待提交营销活动详情 */
path: '/memberCenter/marketingAbility/selfManagement/readySubmit/preview',
name: '待提交营销活动详情',
component: '@/pages/transaction/marketingAbility/selfManagement/detail',
hideInMenu: true,
noMargin: true,
},
// 待上线营销活动
{
/** 待上线营销活动 */
path: '/memberCenter/marketingAbility/selfManagement/readyLive',
name: '待上线营销活动',
component: '@/pages/transaction/marketingAbility/selfManagement/readyLive'
},
// 待上线营销活动详情
{
/** 待上线营销活动详情 */
path: '/memberCenter/marketingAbility/selfManagement/readyLive/preview',
name: '待上线营销活动详情',
component: '@/pages/transaction/marketingAbility/selfManagement/detail',
......
......@@ -64,8 +64,8 @@ const ConfirmOfferDetail = () => {
{
col: [
{ label: '单据时间', extra: format(data.voucherTime) },
{ label: '价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
{ label: '价联系人', extra: data.contactName },
{ label: '联系人电话', extra: <>+{data.phoneCode}&nbsp;{data.contactPhone}</> }
]
},
])
......
......@@ -72,7 +72,7 @@ const ConfirmOfferPreview = () => {
{ label: '交付地址', extra: data.fullAddress },
{ label: '报价截止时间', extra: format(data.quotationAsTime) },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
{ label: '联系人电话', extra: <>+{data.phoneCode}&nbsp;{data.contactPhone}</> }
]
},
{
......
......@@ -66,6 +66,8 @@ const InquiryOfferDetail = () => {
{
col: [
{ label: '单据时间', extra: format(data.voucherTime) },
{ label: '报价联系人', extra: data.contactName },
{ label: '联系人电话', extra: <>+{data.phoneCode}&nbsp;{data.contactPhone}</> }
]
},
])
......@@ -90,8 +92,6 @@ const InquiryOfferDetail = () => {
{
col: [
{ label: '其他说明', extra: data.otherRequire },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
]
},
])
......
......@@ -82,7 +82,7 @@ const InquirySearch = () => {
dataIndex: 'options',
render: (_text: any, record: any) => <>
{record.isShowQuote && (
<Button onClick={() => history.push(`/memberCenter/tranactionAbility/inquiryOffer/waitAddOffer/offer?id=${record.id}`)} type='link'>报价</Button>
<Button disabled={record.isQuoted === 1} onClick={() => history.push(`/memberCenter/tranactionAbility/inquiryOffer/waitAddOffer/offer?id=${record.id}`)} type='link'>报价</Button>
)}
{(record.isShowSecondInquiry === true) && (
<Button type='link' onClick={() => secondInquiry(record.id)}>二次询价</Button>
......
......@@ -15,6 +15,7 @@ import GeneralLayout from '@/pages/transaction/components/detailLayout/component
import RecordLyout from '@/pages/transaction/components/detailLayout/components/recordLyout';
import EyePreview from '@/components/EyePreview';
import { ENTERPRISE_CENTER_URL } from '@/constants';
import { GlobalConfig } from '@/global/config';
const TABLINK = [
{ id: 'progressLayout', title: '流转进度' },
......@@ -47,6 +48,11 @@ const InquiryOfferPreview = () => {
col: [
{ label: '询价单号', extra: data.inquiryListNo },
{ label: '询价摘要', extra: data.details },
{ label: '询价商城', extra: GlobalConfig.web.shopInfo.map(item => {
if (item.id === data.shopId) {
return item.name
}
}) },
]
},
{
......@@ -72,7 +78,7 @@ const InquiryOfferPreview = () => {
{ label: '交付地址', extra: data.fullAddress },
{ label: '报价截止时间', extra: format(data.quotationAsTime) },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
{ label: '联系人电话', extra: <>+{data.phoneCode}&nbsp;{data.contactPhone}</> }
]
},
{
......
......@@ -181,7 +181,7 @@ const AddedFormLayout: React.FC<AddedFormLayoutProps> = (props: any) => {
form.setFieldsValue({
"contactName": value.name,
'contactPhone': value.phone,
'phoneCode': value.phoneCode,
'phoneCode': value.phoneCode || 86,
});
}
......
......@@ -102,9 +102,9 @@ const OtherExplainLayout: React.FC<OtherExplainLayoutProps> = (props: any) => {
<InputNumber min={0} style={{ width: '100%' }} />
</Form.Item>
<Form.Item
label='价联系人'
label='价联系人'
name='contactName'
rules={[{ required: true, message: '请选择价联系人' }]}
rules={[{ required: true, message: '请选择价联系人' }]}
>
<Input.Search onSearch={() => toggle(true)} readOnly enterButton={<Button style={{ height: '31.19px' }} icon={<LinkOutlined />}>选择</Button>} />
</Form.Item>
......
import React, { Fragment, useEffect, useState } from 'react';
import { Button, Tag, Badge, Typography } from 'antd';
import { history } from 'umi';
import { GlobalConfig } from '@/global/config'
import { ColumnType } from 'antd/lib/table/interface';
import PeripheralLayout from '@/pages/transaction/components/detailLayout';
import { Context } from '@/pages/transaction/components/detailLayout/components/context';
......@@ -50,6 +51,11 @@ const ProductInquiryDetail = () => {
col: [
{ label: '询价单号', extra: data.inquiryListNo },
{ label: '询价摘要', extra: data.details },
{ label: '询价商城', extra: GlobalConfig.web.shopInfo.map(item => {
if (item.id === data.shopId) {
return item.name
}
}) },
]
},
{
......@@ -75,7 +81,7 @@ const ProductInquiryDetail = () => {
{ label: '交付地址', extra: data.fullAddress },
{ label: '报价截止时间', extra: format(data.quotationAsTime) },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
{ label: '联系人电话', extra: <>+{data.phoneCode}&nbsp;{data.contactPhone}</> }
]
},
{
......@@ -151,8 +157,8 @@ const ProductInquiryDetail = () => {
const columns: ColumnType<any>[] = [
{
title: 'ID',
key: 'id',
dataIndex: 'id',
key: 'commodityId',
dataIndex: 'commodityId',
},
{
title: '商品名称',
......
......@@ -103,8 +103,8 @@ const InquiryProductLayout: React.FC<InquiryProductLayoutProps> = (props: any) =
const productColumns: any[] = [
{
title: 'ID',
dataIndex: 'productId',
key: 'productId',
dataIndex: 'commodityId',
key: 'commodityId',
},
{
title: '商品名称',
......
......@@ -122,6 +122,7 @@ const ReadySubmit = () => {
reload={ref}
columns={columns}
effects="id"
rowKey="activityId"
fetch={PublicApi.getMarketingPlatformActivitySignupPageTobeSubmitSignUp}
selectedRow={true}
fetchRowkeys={(e) => setRowKeys(e)}
......
......@@ -28,7 +28,8 @@ const TABLINK = [
]
const DetialLayout = () => {
const { query: { activityId, signUpId } } = history.location;
const { query: { activityId, signUpId }, pathname } = history.location;
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const [loading, setLoading] = useState<boolean>(false)
const [unsaved, setUnsaved] = useState<boolean>(false);
const [productList, setProductList] = useState<any[]>([]);
......@@ -107,7 +108,8 @@ const DetialLayout = () => {
signUpId !== null && (params.id = signUpId)
if (!isEmpty(productList)) {
setLoading(true)
PublicApi.postMarketingPlatformActivitySignupSave({ ...params }).then(res => {
const fieldApi = (path === 'add' ? PublicApi.postMarketingPlatformActivitySignupSave : PublicApi.postMarketingPlatformActivitySignupUpdate)
fieldApi({ ...params }).then(res => {
if (res.code !== 1000) {
setLoading(false)
return
......
......@@ -89,19 +89,15 @@ const ReadySubmitExamine = () => {
dataIndex: 'state',
render: (text, record) => (
<>
{record.button === 7 && <Button type='link' onClick={() => history.push(`/memberCenter/marketingAbility/paltformSign/readySubmitExamine/edit?activityId=${record.activityId}&signUpId=${record.id}`)}>修改报名资料</Button>}
{
record.button === 6 && (
<>
<Popconfirm title="确定要提交吗?" disabled={!record.id} okText="是" cancelText="否" onConfirm={() => handleSubmit(record.id)}>
<Button type='link' disabled={!record.id}>
提交审核
</Button>
</Popconfirm>
<Button type='link' onClick={() => history.push(`/memberCenter/marketingAbility/paltformSign/readySubmitExamine/add?activityId=${record.activityId}`)}>填写报名资料</Button>
</>
)}
{record.update && <Button type='link' onClick={() => history.push(`/memberCenter/marketingAbility/paltformSign/readySubmitExamine/edit?activityId=${record.activityId}&signUpId=${record.id}`)}>修改报名资料</Button>}
{record.submit && (
<Popconfirm title="确定要提交吗?" disabled={!record.id} okText="是" cancelText="否" onConfirm={() => handleSubmit(record.id)}>
<Button type='link' disabled={!record.id}>
提交审核
</Button>
</Popconfirm>
)}
{record.save && <Button type='link' onClick={() => history.push(`/memberCenter/marketingAbility/paltformSign/readySubmitExamine/add?activityId=${record.activityId}`)}>填写报名资料</Button>}
</>
)
},
......
......@@ -102,6 +102,7 @@ const Search = () => {
<TableLayout
columns={columns}
effects="id"
rowKey="activityId"
fetch={PublicApi.getMarketingPlatformActivitySignupPage}
useStateEffects={useStateEffects}
schema={{
......
import React, { useEffect, useState, useRef } from 'react';
import { Button } from 'antd';
import React, { useState } from 'react';
import { Form, Button } from 'antd';
import { history } from 'umi';
import { useEventEmitter } from '@umijs/hooks';
import { SaveOutlined } from '@ant-design/icons';
import PeripheralLayout from '@/pages/transaction/components/detailLayout';
import AddFormGoodsItem from '../../components/addFormGoods';
import ProgressBar from './components/progressBar';
import AddFormBasicItem from './components/addFormBasic';
import AddFormRuleItem from './components/addFormRule';
import AddFormUserItem from './components/addFormUser';
import AddFormShopItem from './components/addFormShop';
import BasicInfoLayout from './components/basicInfoLayout';
import RulesLayout from './components/rulesLayout';
import ShopLayout from './components/shopLayout';
import ProductListLayout from '../../paltformSign/readySubmitExamine/components/productListLayout';
import PartakeUserLayout from './components/partakeUserLayout';
const layout: any = {
colon: false,
labelCol: { style: { width: "144px" } },
labelAlign: "left"
};
const TABLINK = [
{ id: 'basicLayout', title: '基本信息' },
{ id: 'rulesLayout', title: '活动规则' },
{ id: 'goodsLayout', title: '活动商品' },
{ id: 'usersLayout', title: '参与用户' },
{ id: 'shopsLayout', title: '适用商城' },
]
const AddedMarketing = () => {
const { query: { activityId, signUpId } } = history.location;
const focus$ = useEventEmitter();
const [form] = Form.useForm();
const [unsaved, setUnsaved] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);
const [shopList, setShopList] = useState<any[]>([]);
const [dataSource, setDataSource] = useState<any>({});
const [productList, setProductList] = useState<any[]>([]);
const [memberLevelList, setMemberLevelList] = useState<any[]>([]);
const [memberType, setMemberType] = useState<any[]>([]);
const Add = () => {
const { query: { id } } = history.location;
const [ruleType, setRuleType] = useState(1);
const [extraType, setExtraType] = useState(1);
const basicForm = useRef<any>({});
const rulesForm = useRef<any>({});
const goodsForm = useRef<any>({});
const usersForm = useRef<any>({});
const shopsForm = useRef<any>({});
const handleGetShopList = (mall) => {
console.log(mall, 10086)
const shopList = mall.filter(item => item.checked)
form.setFieldsValue({
"shopList": shopList.map(item => {
return {
shopId: item.id,
shopName: item.name,
logo: item.logoUrl,
}
})
})
}
useEffect(() => {
setExtraType(1)
}, [ruleType])
const handleGetDataSoure = (e) => {
if (!unsaved) {
setUnsaved(true)
}
setProductList([...e])
}
const _handleSave = async () => {
const basicRef = await basicForm.current.get();
const rulesRef = await rulesForm.current.get()
console.log(basicRef, rulesRef)
const handleGetLevel = (levels) => {
const list = levels.map(item => {
return {
id: item.id,
memberLevelId: item.id,
memberType: item.memberType,
memberTypeName: item.memberTypeName,
roleType: item.roleId,
roleTypeName: item.roleName,
level: item.level,
levelTypeName: item.levelTypeName,
levelTag: item.levelTag,
}
})
setMemberLevelList([...list])
}
return (
<PeripheralLayout
detail={`${id ? '编辑' : '新增'}营销活动`}
no={<ProgressBar ratio={85} />}
tabLink={TABLINK}
effect={<Button type="primary" onClick={_handleSave}><SaveOutlined /> 保存</Button>}
detail='新增营销活动'
tabLink={[
{ id: 'basicInfoLayout', title: '基本信息' },
{ id: 'rulesLayout', title: '活动规则' },
{ id: 'activityProductLayout', title: '活动商品' },
{ id: 'partakeUserLayout', title: '参与用户' },
{ id: 'shopLayout', title: '适用商城' },
]}
effect={
<Button
loading={loading}
icon={<SaveOutlined />}
type="primary"
>
保存
</Button>
}
hideBreak={true}
components={
<>
<AddFormBasicItem currentRef={basicForm} setRuleType={setRuleType} />
<AddFormRuleItem currentRef={rulesForm} ruleType={ruleType} extraType={extraType} setExtraType={setExtraType} />
<AddFormGoodsItem currentRef={goodsForm} ruleType={ruleType} />
<AddFormUserItem currentRef={usersForm} />
<AddFormShopItem currentRef={shopsForm} />
</>
<Form
form={form}
{...layout}
>
<BasicInfoLayout form={form} focus$={focus$} />
<RulesLayout form={form} focus$={focus$} />
<ProductListLayout signUpId={signUpId !== 'null' && signUpId} data={dataSource} getDataSource={handleGetDataSoure} />
<PartakeUserLayout onGetLevel={handleGetLevel} onSetLevel={memberLevelList} setMemberType={memberType} />
<ShopLayout onGetShopList={handleGetShopList} onSetShopList={shopList} />
</Form>
}
/>
);
}
export default Add;
export default AddedMarketing;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, Space } from 'antd';
import moment from 'moment';
import Card from '@/pages/transaction/components/card';
import formStyle from '../../style/add.less';
interface AddFormBasicProps {
currentRef?: any,
layoutId?: string,
layoutTitle?: string,
setRuleType?: Function
}
const { RangePicker } = DatePicker;
const { Option } = Select;
const ACTIVITY_TYPE = [
{ lable: '特价促销', value: 1 },
{ lable: '直降促销', value: 2 },
{ lable: '折价促销', value: 3 },
{ lable: '满量促销', value: 4 },
{ lable: '满额促销', value: 5 },
{ lable: '赠送促销', value: 6 },
{ lable: '多件促销', value: 7 },
{ lable: '组合促销', value: 8 },
{ lable: '拼团', value: 9 },
{ lable: '抽奖', value: 10 },
{ lable: '砍价', value: 11 },
{ lable: '秒杀', value: 12 },
{ lable: '换购', value: 13 },
{ lable: '预售', value: 14 },
{ lable: '套餐', value: 15 },
{ lable: '试用', value: 16 },
]
const AddFormBasic: React.FC<AddFormBasicProps> = (props: any) => {
const { currentRef, layoutId, layoutTitle, setRuleType } = props;
const [form] = Form.useForm();
useEffect(() => {
currentRef.current = {
get: () => new Promise((resolve: any) => {
form.validateFields().then(res => {
resolve({
state: true,
name: 'basic',
data: { ...res },
})
}).catch(err => {
console.log(err)
})
})
}
})
return (
<Card
id={layoutId}
title={layoutTitle}
>
<Form
form={form}
initialValues={{ type: 1 }}
className={formStyle.addForm}
onValuesChange={(changedValues, allValues) => {
if (Object.keys(changedValues).includes('type')) {
setRuleType(changedValues.type)
}
}}
>
<Row gutter={[8, 8]}>
<Col span={12}>
<Form.Item
name='name'
label="活动名称"
rules={[{ required: true, message: '请输入活动名称' }]}>
<Input placeholder="最长60个字符,30个汉字" maxLength={30} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="活动时间"
style={{margin: 0}}
required>
<Space style={{ display: 'flex' }} align='baseline'>
<Form.Item
name='startTime'
rules={[
{ required: true, message: '请选择活动开始时间!' }, () => ({
async validator(_, value) {
let _exVal = await form.getFieldValue('endTime');
if (_exVal && moment(value).isAfter(_exVal)) {
return Promise.reject(new Error('活动开始时间需要早于活动结束时间'));
}
return Promise.resolve();
}
})
]}>
<DatePicker
showTime
allowClear
disabledDate={(current) => {
const _endTime = form.getFieldValue('endTime');
if (_endTime) {
return current && ((moment(current).diff(moment(_endTime), 'day') > 0) || current < moment().startOf('second'))
} else {
return current && current < moment().startOf('second')
}
}} />
</Form.Item>
~
<Form.Item
name='endTime'
rules={[
{ required: true, message: '请选择活动结束时间!' }, () => ({
async validator(_, value) {
let _exVal = await form.getFieldValue('startTime');
if (_exVal && moment(value).isBefore(_exVal)) {
return Promise.reject(new Error('活动结束时间需要晚于活动开始时间'));
}
return Promise.resolve();
}
})
]}>
<DatePicker
showTime
allowClear
disabledDate={(current) => {
const _startTime = form.getFieldValue('startTime');
if (_startTime) {
return current && current < moment(_startTime).startOf('second')
} else {
return current && current < moment().startOf('second')
}
}} />
</Form.Item>
</Space>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name='type'
label="活动类型"
rules={[{ required: true, message: '请选择活动类型!' }]}>
<Select placeholder="请选择活动类型">
{ACTIVITY_TYPE.map((item) => <Option key={'ACTIVITY_TYPE' + item.value} value={item.value}>{item.lable}</Option>)}
</Select>
</Form.Item>
</Col>
</Row>
</Form>
</Card>
);
}
AddFormBasic.defaultProps = {
layoutId: 'basicLayout',
layoutTitle: '基本信息',
}
export default AddFormBasic;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
import styles from './index.less';
interface ActiveTypeButtonProps {
value?: any,
onChange?: any,
extra?: any
}
const ActiveTypeButton: React.FC<ActiveTypeButtonProps> = (props: any) => {
const { value, onChange, extra } = props;
const [activeType, setActiveType] = useState(value || []);
const [isFirst, setIsFirst] = useState<boolean>(true);
useEffect(() => {
if (!isFirst) {
onChange?.(activeType.length > 0 ? activeType : null);
}
}, [activeType, isFirst])
const _buttonsClick = (value: number) => {
let _activeType = [...activeType];
const _i = _activeType.indexOf(value)
if (_i >= 0) {
_activeType.splice(_i, 1);
} else {
_activeType.push(value);
}
setActiveType(_activeType);
isFirst && setIsFirst(false);
}
const _checkInList = (value: number) => {
return activeType.includes(value);
}
return (
<Row gutter={[8, 8]}>
{extra.enum.map((items) => {
return (
<Col key={`buttons_${items.value}`}>
<Button className={_checkInList(items.value) ? styles.buttonAct : ''} onClick={() => { _buttonsClick(items.value) }}>{items.label}</Button>
</Col>
)
})}
</Row>
);
}
export default ActiveTypeButton;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface BargainMoneyProps {
value?: any,
onChange?: any,
extra?: any
}
const BargainMoney: React.FC<BargainMoneyProps> = (props: any) => {
const { value = {}, onChange, extra } = props;
const [num, setNum] = useState(0);
const _onNumberChange = (value: any) => {
setNum(value)
onChange?.(value);
}
return (
<Space direction='vertical'>
<Radio.Group value={num} onChange={(e) => { _onNumberChange(e.target.value) }}>
{extra.enum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
{num > 0 && <Space style={{ display: 'flex' }}>
{extra[num].header}
<Input style={{ width: extra[num].inputWidth1 }} placeholder={extra[num].placeholder} addonAfter={extra[num].addonAfter1} />
{num === 1 && <>
<span>~</span>
<Input style={{ width: extra[num].inputWidth2 }} placeholder={extra[num].placeholder} addonAfter={extra[num].addonAfter2} />
</>}
</Space>}
</Space>
);
}
export default BargainMoney;
import React, { useEffect, useState, useMemo } from 'react';
import { Typography, Radio, Input, Space } from 'antd';
interface LimitRadioInputProps {
value?: any,
onChange?: any,
extra?: any
}
const LimitRadioInput: React.FC<LimitRadioInputProps> = (props: any) => {
const { value = {}, onChange, extra } = props;
const [isLimit, setIsLimit] = useState(0);
const [num, setNum] = useState(0);
const [inputNum, setInputNum] = useState<string | number>('');
const _onIsLimitChage = (value: any) => {
setIsLimit(value);
if (value === 1) {
setNum(0);
setInputNum('');
}
onChange?.({ isLimit: value })
}
const _onNumberChange = (value: any, type: number) => {
const newNumber = parseInt(value || '0', 10);
if (Number.isNaN(value)) {
return;
}
if (type === 1) {
setNum(newNumber);
setInputNum('');
} else {
setInputNum(newNumber);
setNum(0);
}
onChange?.({ isLimit, number: newNumber });
}
return (
<>
<Space style={{ display: 'flex', marginBottom: 8 }} align="center">
<Radio.Group value={value.isLimit || isLimit} onChange={(e) => { _onIsLimitChage(e.target.value) }}>
{extra.limitEnum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
{isLimit === 2 && <Input.Group compact>
<Radio.Group value={value.number || num} onChange={(e) => { _onNumberChange(e.target.value, 1) }}>
{extra.enum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
<Input value={inputNum} onChange={(e) => { _onNumberChange(e.target.value, 2) }} style={{ width: extra.inputWidth }} addonAfter={extra.addonAfter} placeholder={extra.placeholder} />
</Input.Group>}
</Space>
<Typography.Text>{extra.tips}</Typography.Text>
</>
);
}
export default LimitRadioInput;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface LotteryTypeProps {
value?: any,
onChange?: any,
extra?: any
}
const LotteryType: React.FC<LotteryTypeProps> = (props: any) => {
const { value = {}, onChange, extra } = props;
const [num, setNum] = useState(0);
const _onNumberChange = (value: any) => {
setNum(value)
onChange?.({ type: value });
}
return (
<Space direction='vertical'>
<Radio.Group value={value?.type || num} onChange={(e) => { _onNumberChange(e.target.value) }} >
{extra.enum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
{num === 1 && <Space style={{ display: 'flex' }} align="center">
{extra[num].header}
<Input style={{ width: extra[num].inputWidth }} addonAfter={extra[num].addonAfter} />
{extra[num].footer}
</Space>}
{num === 2 && <Space style={{ display: 'flex' }} align="center">
{extra[num].header}
<Input style={{ width: extra[num].inputWidth }} addonAfter={extra[num].addonAfter} />
</Space>}
{num === 3 && <Space style={{ display: 'flex' }} align="center">
{extra[num].header}
<Select style={{ width: extra[num].inputWidth }} options={extra[num].enum}></Select>
{extra[num].footer}
</Space>}
</Space>
);
}
export default LotteryType;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface PreSaleTimeProps {
value?: any,
onChange?: any,
extra?: any
}
const PreSaleTime: React.FC<PreSaleTimeProps> = (props: any) => {
const { value, onChange, extra } = props;
const [timeType, setTimeType] = useState<string | number>('');
const [tips, setTips] = useState<string | number>('');
const _radioChange = (value: number) => {
setTimeType(value);
setTips(value)
}
return (
<Space direction='vertical'>
<Radio.Group value={timeType} onChange={(e) => { _radioChange(e.target.value) }}>
{extra.enum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
{timeType === 0 && <Space style={{ display: 'flex' }}>
<DatePicker showTime />
~
<DatePicker showTime />
</Space>}
{extra.tips.replace('$',tips)}
</Space>
);
}
export default PreSaleTime;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface RadioInputProps {
value?: any,
onChange?: any,
extra?: any
}
const RadioInput: React.FC<RadioInputProps> = (props: any) => {
const { value, onChange, extra } = props;
const [num, setNum] = useState(0);
const [inputNum, setInputNum] = useState<string | number>('');
const _onNumberChange = (value: any, type: number) => {
const newNumber = parseInt(value || '0', 10);
if (Number.isNaN(value)) {
return;
}
if (type === 1) {
setNum(newNumber);
setInputNum('');
} else {
setInputNum(newNumber);
setNum(0);
}
onChange?.(newNumber);
}
return (
<Input.Group compact>
<Radio.Group value={value || num} onChange={(e) => { _onNumberChange(e.target.value, 1) }} >
{extra.enum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
<Input value={inputNum} onChange={(e) => { _onNumberChange(e.target.value, 2) }} style={{ width: extra.inputWidth }} addonAfter={extra.addonAfter} placeholder={extra.placeholder} />
</Input.Group>
);
}
export default RadioInput;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, TimePicker, Space } from 'antd';
interface SeckillTimeProps {
value?: any,
onChange?: any,
extra?: any
}
const SeckillTime: React.FC<SeckillTimeProps> = (props: any) => {
const { value, onChange, extra } = props;
const [vals, setVals] = useState<any>(0);
console.log(vals)
const _selectOptions = [
{ label: '自定义', value: 0 },
{ label: '00:00:00 ~ 00:59:59', value: '00:00:00 ~ 00:59:59' },
{ label: '01:00:00 ~ 01:59:59', value: '01:00:00 ~ 01:59:59' },
{ label: '02:00:00 ~ 02:59:59', value: '02:00:00 ~ 02:59:59' },
{ label: '03:00:00 ~ 03:59:59', value: '03:00:00 ~ 03:59:59' },
{ label: '04:00:00 ~ 04:59:59', value: '04:00:00 ~ 04:59:59' },
{ label: '05:00:00 ~ 05:59:59', value: '05:00:00 ~ 05:59:59' },
{ label: '06:00:00 ~ 06:59:59', value: '06:00:00 ~ 06:59:59' },
{ label: '07:00:00 ~ 07:59:59', value: '07:00:00 ~ 07:59:59' },
{ label: '08:00:00 ~ 08:59:59', value: '08:00:00 ~ 08:59:59' },
{ label: '09:00:00 ~ 09:59:59', value: '09:00:00 ~ 09:59:59' },
{ label: '10:00:00 ~ 10:59:59', value: '10:00:00 ~ 10:59:59' },
{ label: '11:00:00 ~ 11:59:59', value: '11:00:00 ~ 11:59:59' },
{ label: '12:00:00 ~ 12:59:59', value: '12:00:00 ~ 12:59:59' },
{ label: '13:00:00 ~ 13:59:59', value: '13:00:00 ~ 13:59:59' },
{ label: '14:00:00 ~ 14:59:59', value: '14:00:00 ~ 14:59:59' },
{ label: '15:00:00 ~ 15:59:59', value: '15:00:00 ~ 15:59:59' },
{ label: '16:00:00 ~ 16:59:59', value: '16:00:00 ~ 16:59:59' },
{ label: '17:00:00 ~ 17:59:59', value: '17:00:00 ~ 17:59:59' },
{ label: '18:00:00 ~ 18:59:59', value: '18:00:00 ~ 18:59:59' },
{ label: '19:00:00 ~ 19:59:59', value: '19:00:00 ~ 19:59:59' },
{ label: '20:00:00 ~ 20:59:59', value: '20:00:00 ~ 20:59:59' },
{ label: '21:00:00 ~ 21:59:59', value: '21:00:00 ~ 21:59:59' },
{ label: '22:00:00 ~ 22:59:59', value: '22:00:00 ~ 22:59:59' },
{ label: '23:00:00 ~ 23:59:59', value: '23:00:00 ~ 23:59:59' },
]
return (
<Space direction='vertical'>
<Select value={vals} options={_selectOptions} onChange={(value) => { setVals(value) }} style={{ width: extra.selectWidth }} />
{vals === 0 && <Space style={{ display: 'flex' }}>
<TimePicker placeholder={extra.startPlaceholder} style={{ width: extra.timeWidth }} />
<TimePicker placeholder={extra.endPlaceholder} style={{ width: extra.timeWidth }} />
</Space>}
</Space>
);
}
export default SeckillTime;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface SelectInputProps {
value?: any,
onChange?: any,
extra?: any
}
const SelectInput: React.FC<SelectInputProps> = (props: any) => {
const { value = {}, onChange, extra } = props;
return (
<Space style={{ display: 'flex' }}>
<Select options={extra.enum} style={{ width: extra.selectWidth }}></Select>
<Input addonAfter={extra.addonAfter} style={{ width: extra.inputWidth }} placeholder={extra.inputPlaceholder} />
</Space>
);
}
export default SelectInput;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface SpaceInputProps {
value?: any,
onChange?: any,
extra?: any
}
const SpaceInput: React.FC<SpaceInputProps> = (props: any) => {
const { value, onChange, extra } = props;
return (
<Space style={{ display: 'flex' }}>
{extra.header}
<Input addonAfter={extra.addonAfter} placeholder={extra.placeholder} style={{ width: extra.inputWidth }} />
</Space>
);
}
export default SpaceInput;
import React, { useEffect, useState, useMemo } from 'react';
import { Checkbox, Radio, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance, Space } from 'antd';
interface TrialTimeProps {
value?: any,
onChange?: any,
extra?: any
}
const TrialTime: React.FC<TrialTimeProps> = (props: any) => {
const { value, onChange, extra } = props;
const [timeType, setTimeType] = useState<string | number>('');
const [tips, setTips] = useState<string | number>('');
const _radioChange = (value: number) => {
setTimeType(value);
if (value === 0) {
setTips(extra.enum[0].label)
} else {
setTips(`${value}小时后`)
}
}
const _inputChange = (value: any) => {
if (value) {
setTips(`${value}小时后`)
}
}
return (
<Space direction='vertical'>
<Input.Group compact>
<Radio.Group value={timeType} onChange={(e) => { _radioChange(e.target.value) }}>
{extra.enum.map((items) => {
return (
<Radio.Button key={items.value} value={items.value}>{items.label}</Radio.Button>
)
})}
</Radio.Group>
<Input style={{ width: extra.inputWidth }} onChange={(e) => { _inputChange(e.target.value) }} placeholder={extra.placeholder} addonAfter={extra.addonAfter} />
</Input.Group>
{extra.tips.replace('$', tips)}
</Space>
);
}
export default TrialTime;
.shopBtn{
text-align: left;
height: auto;
.imgShop{
width: 32px;
height: 32px;
border-radius: 16px;
margin-right: 8px;
}
}
\ No newline at end of file
import React, { Fragment, useEffect, useState } from 'react';
import { Tag, Badge, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance } from 'antd';
import company_img from '@/assets/imgs/company_img.png';
import Card from '@/pages/transaction/components/card';
import formStyle from '../../style/add.less';
import styles from './index.less';
interface AddFormShopProps {
currentRef?: any,
layoutId?: string,
layoutTitle?: string,
}
const AddFormShop: React.FC<AddFormShopProps> = (props: any) => {
const { currentRef, layoutId, layoutTitle } = props;
const [form] = Form.useForm();
const SHOP_TYPE = [
{ label: 'WEB-渠道商城', value: 1 },
{ label: 'H5-渠道商城', value: 2 },
{ label: '小程序-渠道商城', value: 3 },
{ label: 'APP-渠道商城', value: 4 },
{ label: 'WEB-渠道自有商品商城', value: 5 },
]
return (
<Card
id={layoutId}
title={layoutTitle}
>
<Form
form={form}
className={formStyle.addForm}
>
<Form.Item
name='shop'
noStyle
rules={[{ required: true, message: '请选择适用商城!' }]}>
<Row gutter={[8, 8]}>
{SHOP_TYPE.map((items) => {
return (
<Col span={6} key={`buttons_${items.value}`}>
<Button className={styles.shopBtn} size='large' block><img className={styles.imgShop} src={company_img} alt={items.label} />{items.label}</Button>
</Col>
)
})}
</Row>
</Form.Item>
</Form>
</Card>
);
}
AddFormShop.defaultProps = {
layoutId: 'shopsLayout',
layoutTitle: '适用商城',
}
export default AddFormShop;
import React, { Fragment, useEffect, useState } from 'react';
import { Tag, Badge, Button, Form, Input, Row, Col, DatePicker, Select, FormInstance } from 'antd';
import Card from '@/pages/transaction/components/card';
import formStyle from '../../style/add.less';
interface AddFormUserProps {
currentRef?: any,
layoutId?: string,
layoutTitle?: string,
}
const AddFormUser: React.FC<AddFormUserProps> = (props: any) => {
const { currentRef, layoutId, layoutTitle } = props;
const [form] = Form.useForm();
const FORM_ITEMS = [
{
label: '适用用户',
name: 'user',
rules: [{ required: true, message: '请选择适用用户!' }],
buttons: [
{ label: '全部', value: 1 },
{ label: '新用户', value: 2 },
{ label: '老用户', value: 3 },
]
},
{
label: '适用用户角色',
name: 'userRoles',
rules: [{ required: true, message: '请选择适用用户角色!' }],
buttons: [
{ label: '全部', value: 1 },
{ label: '会员用户', value: 2 },
{ label: '普通用户', value: 3 },
]
},
{
label: '会员等级标签',
name: 'memberTags',
rules: [{ required: true, message: '请选择会员等级标签!' }],
buttons: [
{ label: '全部', value: 1 },
{ label: '青铜会员', value: 2 },
{ label: '白银会员', value: 3 },
{ label: '黄金会员', value: 4 },
{ label: '钻石会员', value: 5 },
]
},
{
label: '会员等级类型',
name: 'memberLevels',
rules: [{ required: true, message: '请选择会员等级类型!' }],
buttons: [
{ label: '全部', value: 1 },
{ label: '商户会员', value: 2 },
{ label: '渠道会员', value: 3 },
]
},
{
label: '会员类型',
name: 'memberType',
rules: [{ required: true, message: '请选择会员类型!' }],
buttons: [
{ label: '全部', value: 1 },
{ label: '企业会员', value: 2 },
{ label: '个人会员', value: 3 },
{ label: '渠道企业会员', value: 4 },
{ label: '渠道个人会员', value: 5 },
]
},
{
label: '会员角色',
name: 'memberType',
rules: [{ required: true, message: '请选择会员角色!' }],
buttons: [
{ label: '全部', value: 1 },
{ label: '采购商', value: 2 },
{ label: '个人消费者', value: 3 },
{ label: '渠道采购商', value: 4 },
{ label: '渠道个人消费者', value: 5 },
{ label: '渠道自有采购商', value: 6 },
{ label: '渠道自有个人消费者', value: 7 },
{ label: '渠道个人消费者', value: 8 },
{ label: '渠道自有采购商', value: 9 },
]
}
]
return (
<Card
id={layoutId}
title={layoutTitle}
>
<Form
form={form}
className={formStyle.addForm}
>
{FORM_ITEMS.map((item, index) => {
return (
<Form.Item
key={`${item.name}_${index}`}
name={item.name}
label={item.label}
rules={item.rules}>
<Row gutter={[8, 8]}>
{item.buttons.map((items) => {
return (
<Col key={`${item.name}_buttons_${items.value}`}>
<Button>{items.label}</Button>
</Col>
)
})}
</Row>
</Form.Item>
)
})}
</Form>
</Card>
);
}
AddFormUser.defaultProps = {
layoutId: 'usersLayout',
layoutTitle: '参与用户',
}
export default AddFormUser;
import React from 'react';
import { Form, Row, Col, Input, Select, Space, DatePicker } from 'antd';
import { FormInstance } from 'antd/es/form/Form';
import { EventEmitter } from '@umijs/hooks/lib/useEventEmitter'
import moment from 'moment';
import CardLayout from '../card';
interface BasicInfoProps {
focus$?: EventEmitter<void>,
/** FormInstance */
form?: FormInstance,
}
const avtivityTypes = [
{ lable: '特价促销', value: 1 },
{ lable: '直降促销', value: 2 },
{ lable: '折价促销', value: 3 },
{ lable: '满量促销', value: 4 },
{ lable: '满额促销', value: 5 },
{ lable: '赠送促销', value: 6 },
{ lable: '多件促销', value: 7 },
{ lable: '组合促销', value: 8 },
{ lable: '拼团', value: 9 },
{ lable: '抽奖', value: 10 },
{ lable: '砍价', value: 11 },
{ lable: '秒杀', value: 12 },
{ lable: '换购', value: 13 },
{ lable: '预售', value: 14 },
{ lable: '套餐', value: 15 },
{ lable: '试用', value: 16 },
]
const BasicInfoLayout: React.FC<BasicInfoProps> = (props: any) => {
const { focus$, form } = props;
const startTimeDisabled = (current, name) => {
const _endTime = form.getFieldValue(name);
if (_endTime) {
return (
current &&
(current <
moment()
.max(_endTime)
.startOf('second') ||
moment(current).diff(moment(_endTime), 'second') > 0)
);
} else {
return current && current < moment().startOf('second');
}
};
const endTimeDisabled = (current, name) => {
const _startTime = form.getFieldValue(name);
if (_startTime) {
return (
current &&
(current <
moment()
.min(_startTime)
.startOf('second') ||
moment(current).diff(moment(_startTime), 'second') < 0)
);
} else {
return current && current < moment().startOf('second');
}
};
const handleChange = (e, option) => {
focus$.emit(option)
}
return (
<CardLayout
id="basicInfoLayout"
title="基本信息"
weight
bodyStyle={{ paddingBottom: '0px' }}
>
<Row gutter={[48, 24]}>
<Col span={12}>
<Form.Item
label="活动名称"
name="activityName"
rules={[{ required: true, message: '请输入活动名称' }]}
>
<Input maxLength={30} placeholder="最长60字符,30个汉字" />
</Form.Item>
<Form.Item
label="活动类型"
name="activityType"
rules={[{ required: true, message: '请输入活动名称' }]}
>
<Select onChange={handleChange}>
{avtivityTypes.map((item) => <Select.Option key={'ACTIVITY_TYPE' + item.value} value={item.value}>{item.lable}</Select.Option>)}
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="活动时间"
style={{ margin: 0 }}
required>
<Space style={{ display: 'flex' }} align='baseline'>
<Form.Item
name='startTime'
validateFirst
rules={[
{
required: true,
validator: (_, value) => {
const _signUpEndTime = form.getFieldValue('signUpEndTime');
if (!value) {
return Promise.reject(new Error('请选择活动开始时间'));
}
if (_signUpEndTime && !moment(value).isAfter(_signUpEndTime)) {
return Promise.reject(new Error('活动开始时间必须大于报名结束时间'));
}
return Promise.resolve();
}
}
]}>
<DatePicker
showTime
allowClear
disabledDate={(current) => startTimeDisabled(current, 'endTime')}
/>
</Form.Item>
~
<Form.Item
name='endTime'
rules={[{ required: true, message: '请选择活动结束时间' }]}>
<DatePicker
showTime
allowClear
disabledDate={(current) => endTimeDisabled(current, 'startTime')}
/>
</Form.Item>
</Space>
</Form.Item>
</Col>
</Row>
</CardLayout>
)
}
export default BasicInfoLayout;
.cardLayout {
margin-bottom: 24px;
border-radius: 8px;
background-color: #FFF;
.card_title {
padding: 12px 16px;
}
.card_title_weight {
font-size: 14px;
font-weight: 600;
}
.card_body {
padding: 16px;
}
}
import React, { CSSProperties } from 'react';
import style from './index.less';
import cx from 'classnames';
export interface cardProps {
/** 瞄点id */
id?: string,
/** 标题 */
title?: string,
/** 加粗标题 */
weight?: boolean,
/** body样式修改 */
bodyStyle?: CSSProperties,
/** calssName */
classNames?: string
}
const CardLayout: React.FC<cardProps> = (props: any) => {
const { id, title, weight, children, bodyStyle, classNames } = props;
return (
<div id={id} className={cx(style.cardLayout, classNames && classNames)}>
{title && (
<div className={cx(style.card_title, weight && style.card_title_weight)}>{title}</div>
)}
<div className={style.card_body} style={bodyStyle && bodyStyle}>
{children}
</div>
</div>
)
}
export default CardLayout;
.rulesLayout {
:global {
.ant-checkbox {
display: none;
}
.ant-checkbox-wrapper {
min-width: 56px;
text-align: center;
color: rgba(0, 0, 0, 0.85);
font-weight: 400;
padding: 5.6px 0px;
border: 1px solid transparent;
box-shadow: 0 2px 0 rgb(0 0 0 / 2%);
border-color: #d9d9d9;
}
.ant-checkbox-wrapper-checked {
color: @main-color;
border-color: @main-color;
}
}
}
.cell {
display: flex;
align-items: center;
h5 { margin-bottom: 2em; }
.label {
flex: 0 0 25%;
color: #909399;
}
.content {
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
.selector {
width: 68px;
height: 32px;
color: #252D37;
background: #FAFBFC;
text-align: center;
line-height: 32px;
}
}
}
.colStyle {
position: relative;
padding: 10px 16px;
border-color: transparent;
background-color: #FAFBFC;
cursor: pointer;
.cell {
h5 { margin-bottom: 0px; }
.label,
.content {
flex: 1;
}
}
:global {
.ant-checkbox-wrapper {
width: 100%;
height: 100%;
display: block;
position: absolute;
left: 0;
top: 0;
.ant-checkbox {
display: none;
}
}
.ant-checkbox-wrapper-checked {
border: 1px solid @main-color;
}
}
}
.shopLevelConfigChecked {
border: 1px solid;
border-color: @main-color;
box-sizing: border-box;
}
import React, { useCallback, useState, useEffect } from 'react';
import { Form, Checkbox, Row, Col, Image } from 'antd';
import CardLayout from '../card';
import cx from 'classnames';
import style from './index.less';
import { PublicApi } from '@/services/api';
import { isEmpty } from '@/components/NiceForm/components/AntUpload/shared';
import IMG_LEVEL1 from '@/assets/imgs/level1.png';
import IMG_LEVEL2 from '@/assets/imgs/level2.png';
import IMG_LEVEL3 from '@/assets/imgs/level3.png';
import IMG_LEVEL4 from '@/assets/imgs/level4.png';
const PIC_MAP = {
1: IMG_LEVEL1,
2: IMG_LEVEL2,
3: IMG_LEVEL3,
4: IMG_LEVEL4,
};
interface PartakeUserLayoutProps {
/** 返回等级 */
onGetLevel?: (e: any) => void,
/** 回显数据 */
onSetLevel?: any[],
/** 会员类型 */
setMemberType?: any[]
}
const PartakeUserLayout: React.FC<PartakeUserLayoutProps> = (props: any) => {
const { onGetLevel, onSetLevel, setMemberType } = props
const [allUser, setAllUser] = useState<any[]>([]);
const [user, setUser] = useState<Number[]>([]);
const [levelConfig, setLevelConfig] = useState<any[]>([]);
const suitableMemberTypeList = useCallback(async () => {
await PublicApi.getMarketingCouponSuitableMemberTypeList().then(res => {
if (res.code !== 1000) {
return
}
setAllUser(res.data)
})
}, [])
const handleChange = (e) => {
setUser(e.filter(_item => _item !== 1 && _item !== 2))
}
useEffect(() => {
suitableMemberTypeList()
}, [])
useEffect(() => {
if (!isEmpty(user)) {
PublicApi.getMemberManageMarketingSuitableLevelConfigPage({ levelConfigIds: '', roleIds: '', memberTypes: '', current: '1', pageSize: '999' }).then(res => {
if (res.code !== 1000) {
return
}
setLevelConfig(res.data.data)
})
}
}, [user])
const handleLevelConfig = (e) => {
const data = [...levelConfig]
onGetLevel(data.filter(item => e.includes(item.id)))
}
return (
<CardLayout
id="partakeUserLayout"
title="参与用户"
weight
>
<Form.Item
name="allUser"
label="适用新老会员"
tooltip="当天平台审核通过的平台会员为新会员,非当天审核通过的平台会员为老会员"
rules={[{ required: true, message: '请选择适用新老会员' }]}
className={style.rulesLayout}
>
<Checkbox.Group onChange={handleChange}>
{allUser.map(item => (
<Checkbox key={`allUser${item.value}`} value={item.value}>{item.name}</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
{!isEmpty(user) && (
<Form.Item
name="memberLevelList"
>
<Checkbox.Group onChange={handleLevelConfig}>
<Row gutter={[24, 24]}>
{levelConfig.map(item => (
<Col span={12} key={item.id}>
<div className={style.colStyle}>
<Row>
<Col span={6}>
<div className={style.cell}>
<h5 className={style.label}>会员类型: </h5>
<h5 className={style.content}>{item.memberTypeName}</h5>
</div>
</Col>
<Col span={6}>
<div className={style.cell}>
<h5 className={style.label}>会员角色: </h5>
<h5 className={style.content}>{item.roleName}</h5>
</div>
</Col>
<Col span={6}>
<div className={style.cell}>
<h5 className={style.label}>等级类型: </h5>
<h5 className={style.content}>{item.levelTypeName}</h5>
</div>
</Col>
<Col span={6}>
<div className={style.cell}>
<h5 className={style.label}>等级标签: </h5>
<h5 className={style.content}><Image width={56} height={16} preview={false} src={PIC_MAP[item.level]} /></h5>
</div>
</Col>
</Row>
<Checkbox value={item.id} />
</div>
</Col>
))}
</Row>
</Checkbox.Group>
</Form.Item>
)}
</CardLayout>
)
}
export default PartakeUserLayout;
.processBar{
width: 400px;
font-size: 14px;
border-radius: 15px;
padding-left: 15px;
display: inline-block;
background-color: #E4F7EF;
color: @primary-color;
}
\ No newline at end of file
import React from 'react';
import styles from './index.less';
interface ProcessBarProps {
ratio?: number
}
const ProcessBar: React.FC<ProcessBarProps> = (props: any) => {
return (
<div className={styles.processBar}>
信息完整度 {props.ratio}%
</div>
);
}
export default ProcessBar;
.rulesLayout {
:global {
.ant-radio-button-wrapper {
min-width: 80px;
max-width: 80px;
text-align: center;
padding-left: 0px;
padding-right: 0px;
}
.ant-checkbox {
display: none;
}
.ant-checkbox-wrapper {
min-width: 80px;
max-width: 80px;
text-align: center;
color: rgba(0, 0, 0, 0.85);
font-weight: 400;
padding: 5.6px 0px;
border: 1px solid transparent;
// box-shadow: 0 2px 0 rgb(0 0 0 / 2%);
border-color: #d9d9d9;
justify-content: center;
}
.ant-checkbox-wrapper-checked {
color: @main-color;
border-color: @main-color;
}
.inputWidth {
width: 160px;
}
}
}
.shopListLayout {
display: flex;
align-items: center;
border: 1px solid transparent;
border-color: #5C626A;
padding: 8px 16px;
cursor: pointer;
.shopListLogo {
width: 32px;
height: 32px;
border-radius: 50%;
overflow: hidden;
}
.shopListName {
color: #5C626A;
margin-left: 10px;
}
}
.shopListLayoutChecked {
border-color: @main-color;
.shopListName {
color: @main-color;
}
}
import React, { useEffect, useState } from 'react';
import { Form, Row, Col, Image } from 'antd';
import cx from 'classnames';
import CardLayout from '../card';
import style from './index.less';
import { isEmpty } from 'lodash';
import { PublicApi } from '@/services/api';
type ShopItem = {
describe?: string
environment?: number,
id?: number,
isDefault?: number,
logoUrl?: string,
name?: string
state?: number,
type?: number,
url?: string,
checked?: boolean,
}
interface shopListProps {
/** 返回选择商城 */
onGetShopList?: (e: any) => void,
/** 回显数据 */
onSetShopList?: any[],
}
const ShopLayout: React.FC<shopListProps> = (props: any) => {
const { onGetShopList, onSetShopList } = props;
const [mallList, setMallList] = useState<ShopItem[]>([]);
useEffect(() => {
PublicApi.getManageShopFindByMemberType().then(res => {
if (res.code !== 1000) {
return
}
setMallList(res.data)
})
}, [])
const handleShopList = (index) => {
let mall = [...mallList]
const newData = mall.map((_item, _i) => {
if (_i === index) {
return {
..._item,
checked: !_item.checked
}
}
return _item;
})
setMallList(newData)
onGetShopList(newData)
}
useEffect(() => {
if (!isEmpty(onSetShopList)) {
mallList.forEach(item => {
onSetShopList.filter(_item => _item.shopId === item.id).forEach(v => {
if (v.shopId === item.id) {
item.checked = true
}
})
})
setMallList([...mallList]);
onGetShopList([...mallList])
}
console.log(onSetShopList, mallList)
}, [onSetShopList])
return (
<CardLayout
id="shopLayout"
title="适用商城"
weight
>
<Form.Item
name="shopList"
>
<Row gutter={[16, 16]}>
{mallList.map((item: ShopItem, index: number ) => (
<Col span={6} key={item.id}>
<div className={cx(style.shopListLayout, item.checked && style.shopListLayoutChecked)} onClick={() => handleShopList(index)}>
<div className={style.shopListLogo}>
<Image width={32} height={32} src={item.logoUrl} preview={false} />
</div>
<span className={style.shopListName}>{item.name}</span>
</div>
</Col>
))}
</Row>
</Form.Item>
</CardLayout>
)
}
export default ShopLayout
/**
* 活动类型
*/
type activityType = {
lable: string,
value: number,
}[]
export const ACTIVITYTYPEARRAY: activityType = [
{ lable: '特价促销', value: 1 },
{ lable: '直降促销', value: 2 },
{ lable: '折价促销', value: 3 },
{ lable: '满量促销', value: 4 },
{ lable: '满额促销', value: 5 },
{ lable: '赠送促销', value: 6 },
{ lable: '多件促销', value: 7 },
{ lable: '组合促销', value: 8 },
{ lable: '拼团', value: 9 },
{ lable: '抽奖', value: 10 },
{ lable: '砍价', value: 11 },
{ lable: '秒杀', value: 12 },
{ lable: '换购', value: 13 },
{ lable: '预售', value: 14 },
{ lable: '套餐', value: 15 },
{ lable: '试用', value: 16 },
]
/** 叠加活动类型 */
export const OVERLAYACTIVITYTYPE = (int) => {
switch (Number(int)) {
case 1:
case 2:
case 3:
return [
{ label: '满量促销', value: 4 },
{ label: '满额促销', value: 5 },
{ label: '赠送促销', value: 6 },
{ label: '换购', value: 13 },
]
case 4:
case 5:
return [
{ label: '特价促销', value: 1 },
{ label: '直降促销', value: 2 },
{ label: '折扣促销', value: 3 },
{ label: '赠送促销', value: 6 },
{ label: '换购', value:13 },
]
case 6:
return [
{ label: '特价促销', value: 1 },
{ label: '直降促销', value: 2 },
{ label: '折扣促销', value: 3 },
{ label: '满量促销', value: 4 },
{ label: '满额促销', value: 5 },
{ label: '多件促销', value: 7 },
{ label: '组合促销', value: 8 },
{ label: '换购', value: 13 },
]
case 7:
case 8:
return [
{ label: '赠送促销', value: 6 },
{ label: '换购', value: 13 },
]
case 13:
return [
{ label: '特价促销', value: 1 },
{ label: '直降促销', value: 2 },
{ label: '折扣促销', value: 3 },
{ label: '满量促销', value: 4 },
{ label: '满额促销', value: 5 },
{ label: '多件促销', value: 6 },
{ label: '组合促销', value: 7 },
{ label: '换购', value: 8 },
]
}
}
/** 超限规则 */
export const OVERRUNRULETYPE = (int) => {
switch (Number(int)) {
case 1:
case 2:
case 3:
case 8:
case 12:
return [
{ label: '原价购买', value: 1 },
{ label: '不可购买', value: 2 },
]
case 4:
case 5:
case 6:
case 7:
case 13:
return [
{ label: '不可购买', value: 2 },
{ label: '按个人限购最高级享受优惠', value: 1 },
]
}
}
/** 满量/满额/赠送促销类型 */
export const PROMOTIONTYPE = (int) => {
switch (Number(int)) {
case 4:
return {
name: "type",
tooltip: "满量减为订单满足要求购买的数量后,订单金额减去设定的优惠金额,满量折则为订单金额乘以设定的折扣",
label: "满量促销类型",
message: "请选择满量促销类型",
radio: [
{ label: '满量减', value: 1 },
{ label: '满量折', value: 2 },
]
}
case 5:
return {
name: "type",
tooltip: "满额减为订单满足要求购买的总额后,订单金额减去设定的优惠金额,满额折则为订单金额乘以设定的折扣",
label: "满额促销类型",
message: "请选择满额促销类型",
radio: [
{ label: '满额减', value: 1 },
{ label: '满额折', value: 2 },
]
}
case 6:
return {
name: "giveType",
tooltip: "满额赠为订单满足要求购买的金额后,赠送商品或优惠劵,买商品赠为购买活动商品时,赠送商品或优惠劵",
label: "赠送促销类型",
message: "请选择赠送促销类型",
radio: [
{ label: '满额赠', value: 1 },
{ label: '买商品赠', value: 2 },
]
}
}
}
/** 满量/额减 */
export const LADDERBOLIST = (int, type=1) => {
switch (Number(int)) {
case 4:
return {
tooltip: type === 1 ? '优惠金额为最后订单总额减去的优惠金额' : '折扣为最后订单总额的折扣,输入数字,如85折,输入85,9折输入90',
label: `满量${type ===1 ? '减' : '折'}`,
message: `请新增满量${type ===1 ? '减' : '折'}`,
addon: '数量' ,
addonAfter: type === 1 ? '减' : '打',
addonBefore: type === 1 ? '元' : '折',
}
case 5:
return {
tooltip: type === 1 ? '优惠金额为最后订单总额减去的优惠金额' : '折扣为最后订单总额的折扣,输入数字,如85折,输入85,9折输入90',
label: `满额${type ===1 ? '减' : '折'}`,
message: `请新增满额${type ===1 ? '减' : '折'}`,
addon: '元' ,
addonAfter: type === 1 ? '减' : '打',
addonBefore: type === 1 ? '元' : '折',
}
case 7:
return {
tooltip: '折扣为最后订单总额的折扣,输入数字,如85折,输入85,9折输入90',
label: '优惠规则',
addon: '件',
message: '请新增优惠规则',
addonAfter: '打',
addonBefore: '折',
}
}
}
......@@ -193,7 +193,7 @@ const ReadySubmitExamine = () => {
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => history.push(`/marketing/waitAddedMarketing/add`)}
onClick={() => history.push(`/memberCenter/marketingAbility/selfManagement/readySubmitExamine/add`)}
>
新增
</Button>
......
.addForm{
:global{
.ant-form-item-label > label{
width: 150px;
&::after{
content: '';
}
}
}
}
\ 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