Commit d3577472 authored by 前端-钟卫鹏's avatar 前端-钟卫鹏
parents 4aeb5a87 c5b0e03f
......@@ -29,6 +29,6 @@
}
}
.captchaBtn {
width: 102px;
}
\ No newline at end of file
// .captchaBtn {
// width: 102px;
// }
......@@ -82,7 +82,7 @@ const EditDataComponent = (props) => {
const postData = (
props.type == 'phone'
? {
countryCode: form.getFieldValue('country'),
countryCode: `+${form.getFieldValue('country')}`,
phone: form.getFieldValue('newPhone')
}
: { email: form.getFieldValue('email') }
......@@ -206,11 +206,11 @@ const EditDataComponent = (props) => {
: <>
<Form.Item label="新的手机号码">
<Row gutter={10}>
<Col span={4}>
<Col span={6}>
<Form.Item
name="country"
noStyle
rules={[{ required: true, message: '请填写验证码' }]}
rules={[{ required: true, message: '请填写手机号' }]}
>
<Select disabled={!inputCanEdit}>
{
......
.btn {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 32px;
border: 1px solid #d9d9d9;
width: 100%;
margin-right: 0px;
cursor: pointer;
}
.disabled {
background-color: #f5f5f5;
}
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Button } from 'antd';
import styles from './index.less';
import cx from 'classnames';
const GetCaptchaCode = (props) => {
const { disable = false } = props;
......@@ -28,23 +30,28 @@ const GetCaptchaCode = (props) => {
}
}, [time])
const isDisabled = disable || time > 0
const handleClick = useCallback(() => {
if (isDisabled) {
return;
}
const hasFn = !!props.getCode;
if(hasFn) {
props.getCode()
setTime(59)
}
}, [])
}, [isDisabled])
return (
<Button disabled={disable || !!time} onClick={handleClick} style={{width: '100%'}}>
<div onClick={handleClick} className={cx(styles.btn, {[styles.disabled]: isDisabled})} style={{width: '100%'}}>
{
time
time
? `${time} s`
: '获取验证码'
}
</Button>
</div>
)
}
export default GetCaptchaCode
\ No newline at end of file
export default GetCaptchaCode
......@@ -113,9 +113,7 @@ const EmailVerifyPanel = (props) => {
</Form.Item>
</Col>
<Col span={6}>
<div style={{width: '102px'}}>
<GetCaptchaCode getCode={getCode} />
</div>
<GetCaptchaCode getCode={getCode} />
</Col>
</Row>
</Form.Item>
......
......@@ -115,9 +115,7 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
</Form.Item>
</Col>
<Col span={6}>
<div style={{width: '102px'}}>
<GetCaptchaCode getCode={getCode} />
</div>
<GetCaptchaCode getCode={getCode} />
</Col>
</Row>
</Form.Item>
......@@ -127,18 +125,18 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
</>
: null
}
{
visible
? <>
<EditDataComponent type={pageType} form={form} />
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</>
: null
}
{
visible
? <>
<EditDataComponent type={pageType} form={form} />
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</>
: null
}
</Form>
</div>
......
......@@ -28,7 +28,7 @@ const AccountSetting = () => {
return (
<Col xxl={12} xl={12} lg={24} md={24} sm={24} xs={24} key={item}>
<TypeVerify
type={item}
type={item as 'phone'}
phone={account.phone}
email={account.email}
paycode={account.hasPayPassword}
......
/*
* @Author: XieZhiXiong
* @Date: 2021-05-11 10:46:57
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-05-18 15:47:20
* @Description: 申请单基础信息
*/
import React, { CSSProperties } from 'react';
import { Descriptions } from 'antd';
import MellowCard, { MellowCardProps } from '@/components/MellowCard';
import styles from './index.less';
export interface ColumnProps {
span?: number,
contentStyle?: CSSProperties,
labelStyle?: CSSProperties,
}
export interface DataItem {
/**
* 标题
*/
title: React.ReactNode,
/**
* 值
*/
value: React.ReactNode,
/**
* DescriptionItem 描述列 props
*/
columnProps?: ColumnProps,
}
interface IProps extends MellowCardProps {
/**
* 数据
*/
data: DataItem[],
};
const defaultColumnProps: ColumnProps = {
labelStyle: {
width: 104,
},
};
const AfterServiceBasicInfo: React.FC<IProps> = (props: IProps) => {
const { data, ...rest } = props;
return (
<MellowCard
title="基本信息"
bodyStyle={{
paddingBottom: 0,
}}
className={styles.basicInfo}
{...rest}
>
<Descriptions column={3}>
{data.map((item, index) => (
<Descriptions.Item
key={index}
label={item.title}
{...({...defaultColumnProps, ...item.columnProps} || defaultColumnProps)}
>
{item.value}
</Descriptions.Item>
))}
</Descriptions>
</MellowCard>
);
};
export default AfterServiceBasicInfo;
/*
* @Author: XieZhiXiong
* @Date: 2021-05-11 10:46:57
* @LastEditors: Crayon
* @LastEditTime: 2021-10-14 09:56:42
* @Description: 申请单基础信息
*/
import React, { CSSProperties } from 'react';
import { Descriptions } from 'antd';
import MellowCard, { MellowCardProps } from '@/components/MellowCard';
import styles from './index.less';
export interface ColumnProps {
span?: number,
contentStyle?: CSSProperties,
labelStyle?: CSSProperties,
}
export interface DataItem {
/**
* 标题
*/
title: React.ReactNode,
/**
* 值
*/
value: React.ReactNode,
/**
* DescriptionItem 描述列 props
*/
columnProps?: ColumnProps,
}
interface IProps extends MellowCardProps {
/**
* 数据
*/
data: DataItem[],
};
const defaultColumnProps: ColumnProps = {
labelStyle: {
width: 104,
},
};
const AfterServiceBasicInfo: React.FC<IProps> = (props: IProps) => {
const { data, ...rest } = props;
return (
<MellowCard
title="基本信息"
bodyStyle={{
paddingBottom: 0,
}}
className={styles.basicInfo}
{...rest}
>
<Descriptions column={3}>
{data.map((item, index) => (
<Descriptions.Item
key={index}
label={item.title}
{...({...defaultColumnProps, ...item.columnProps} || defaultColumnProps)}
>
{item.value}
</Descriptions.Item>
))}
</Descriptions>
</MellowCard>
);
};
export default AfterServiceBasicInfo;
......@@ -2,6 +2,8 @@ import React from 'react';
type Icontext = {
shopId: number,
/** 是否是自营商城 */
isSelfMall: boolean
}
export const context = React.createContext<Icontext | null>(null);
......
......@@ -7,7 +7,9 @@ import { usePageStatus } from '@/hooks/usePageStatus';
function useGetLayout() {
const [info, setInfo] = useState<any>(null);
const { id } = usePageStatus();
/** isSelf 判断自有商城 */
const { id, isSelf } = usePageStatus();
console.log(isSelf);
const [dataSourceFromRequest, setDataSourceFromRequest] = useState<any>(null);
useEffect(() => {
......@@ -15,8 +17,11 @@ function useGetLayout() {
setInfo({})
return
}
async function fetchData() {
const { code, data } = await PublicApi.getTemplateAdornAppChannelFind({
/** */
const service = isSelf ? PublicApi.getTemplateAdornAppSelfFind : PublicApi.getTemplateAdornAppChannelFind
const { code, data } = await service({
templateId: id
});
if(code === 1000) {
......@@ -24,7 +29,8 @@ function useGetLayout() {
}
}
fetchData();
}, [id]);
}, [id, isSelf]);
useEffect(() => {
if(info === null) {
return;
......
......@@ -6,7 +6,7 @@ import { StandardTable } from 'god';
import styles from './index.less';
import CommoditySchema from './schema';
import { searchBrandOptionEffect, searchCustomerCategoryOptionEffect } from './effect';
// import { searchBrandOptionEffect, searchCustomerCategoryOptionEffect } from './effect';
import { PublicApi } from '@/services/api';
import { FORM_FILTER_PATH } from '@/formSchema/const';
......@@ -17,6 +17,7 @@ import Submit from '@/components/NiceForm/components/Submit';
import StatusTag from '@/components/StatusTag';
import CustomInputSearch from '@/components/NiceForm/components/CustomInputSearch';
import CustomCategorySearch from '@/components/NiceForm/components/CustomCategorySearch';
// import { serviceAdvertConfig } from '@/pages/editor/channelEdit/defaultData';
interface CommodityDrawerProps {
visible: boolean,
......@@ -24,7 +25,9 @@ interface CommodityDrawerProps {
onConfirm?: (record) => void,
selectId?: string | number[],
filterParam?: any,
selectType?: 'radio' | 'checkbox'
selectType?: 'radio' | 'checkbox',
service?: ((data: any) => Promise<any>) | null,
formEffects?: (context: any, formAction: any) => void,
}
const _returnCategoryList = (list: any, obj: any) => {
......@@ -35,7 +38,7 @@ const _returnCategoryList = (list: any, obj: any) => {
};
const CommodityDrawer: React.FC<CommodityDrawerProps> = (props: CommodityDrawerProps) => {
const { visible, onClose, onConfirm, selectId, filterParam, selectType = 'radio' } = props;
const { visible, onClose, onConfirm, selectId, filterParam, selectType = 'radio', service = null, formEffects } = props;
const { query: { shopId } }: any = history.location;
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(selectId ? [selectId] : []);
const [selectedRows, setSelectedRows] = useState<any>([]);
......@@ -135,7 +138,8 @@ const CommodityDrawer: React.FC<CommodityDrawerProps> = (props: CommodityDrawerP
idNotInList: Array.isArray(selectId) ? selectId : [selectId],
...filterParam
};
const { data } = await PublicApi.getMarketingAdornChannelGoodsListAdorn(_params);
const fetchService = service || PublicApi.getMarketingAdornChannelGoodsListAdorn;
const { data } = await fetchService(_params);
setExpandedRowKeys(data?.data?.map((item) => item.id) || []);
return data;
};
......@@ -189,12 +193,13 @@ const CommodityDrawer: React.FC<CommodityDrawerProps> = (props: CommodityDrawerP
'name',
FORM_FILTER_PATH,
);
FormEffectHooks.onFieldChange$('brandId').subscribe(_ => {
searchBrandOptionEffect(shopId, actions, 'brandId');
});
FormEffectHooks.onFieldChange$('categoryId').subscribe(_ => {
searchCustomerCategoryOptionEffect(shopId, actions, 'categoryId');
});
formEffects?.($, actions);
// FormEffectHooks.onFieldChange$('brandId').subscribe(_ => {
// searchBrandOptionEffect(shopId, actions, 'brandId');
// });
// FormEffectHooks.onFieldChange$('categoryId').subscribe(_ => {
// searchCustomerCategoryOptionEffect(shopId, actions, 'categoryId');
// });
},
components: { ModalSearch: Search, DateRangePickerUnix, Submit, CustomInputSearch, CustomCategorySearch },
},
......
......@@ -20,6 +20,7 @@ import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { PublicApi } from '@/services/api';
import { getAuth } from '@/utils/auth';
import { useFilterSameOption } from '../../common/hooks/useFilterSameOption';
import omit from 'lodash/omit';
type SettingPanelType = {
selectedInfo: SelectedInfoType,
......@@ -42,10 +43,13 @@ const ComponentSchema = {
const formActions = createFormActions();
const { onFieldInputChange$ } = FormEffectHooks;
const EditPanel = () => {
const userAuth = getAuth();
const sameKeyState = useFilterSameOption();
const fixtureContext = useContext(context);
const isSelfMall = useMemo(() => fixtureContext.isSelfMall, [fixtureContext.isSelfMall]);
const { selectedInfo, pageConfig, activeKey, domKey } = useSelector<SettingPanelType, STATE_PROPS | "activeKey" | "domKey">(['selectedInfo', 'pageConfig', 'activeKey', "domKey"]);
const {state: visible, toggle: setVisible } = useToggle(true);
const [schema, setSchema] = useState<any>(null);
......@@ -231,11 +235,20 @@ const EditPanel = () => {
};
/** 获取一级导航 */
const fetchPrimaryOption = async () => {
const { data, code } = await PublicApi.getSearchChannelCommodityTemplateGetFirstCategoryListByMemberId({
const service = isSelfMall
? PublicApi.getSearchCommodityTemplateGetFirstCategoryListByMemberId
: PublicApi.getSearchChannelCommodityTemplateGetFirstCategoryListByMemberId;
/** 如果是自营商城,那么带上memberID, 和memberRoleId, 其实后台可以自己查 */
const commonPostData = {
shopId: fixtureContext!.shopId?.toString(),
memberId: userAuth.memberId,
});
memberId: userAuth.memberId.toString(),
}
const postData = isSelfMall ? { ...commonPostData, memberRoleId: userAuth.memberRoleId.toString() } : commonPostData
const { data, code } = await service(postData);
return data;
};
......@@ -250,7 +263,7 @@ const EditPanel = () => {
}
const hasSelectedTabKeys = Object.keys(sameKeyState).filter((_item) => /tabItem_\d+$/.test(_item));
formActions.setFieldState('layout.primary', (state) => {
const tempData = state.originAsyncData;
const tempData = state.originAsyncData || [];
console.log(state);
FormPath.setIn(state, 'props.enum', tempData.map((_item) => {
return {
......@@ -267,15 +280,23 @@ const EditPanel = () => {
if(!activeKey ) {
return;
}
/** 获取二级导航 */
async function fetchSecondaryOption() {
const { data, code } = await PublicApi.getSearchChannelCommodityTemplateGetSecondCategoryListByMemberId({
const service = isSelfMall
? PublicApi.getSearchCommodityTemplateGetSecondCategoryListByMemberId
: PublicApi.getSearchChannelCommodityTemplateGetSecondCategoryListByMemberId
const common = {
shopId: fixtureContext!.shopId?.toString(),
categoryId: activeKey!.toString(),
memberId: userAuth.memberId,
});
memberId: userAuth.memberId.toString(),
}
const postData = isSelfMall ? omit(common, 'memberId') : common
const { data, code } = await service(postData as any);
if (code === 1000) {
// const source = data.map((_item) => ({label: _item.name, value: _item.id}));
const source = data.map((_item) => ({label: _item.name, value: _item.id, disabled: sameKeyState[`tabItem_${activeKey}_secondary`].includes(_item.id)} ));
const source = data?.map((_item) => ({label: _item.name, value: _item.id, disabled: sameKeyState[`tabItem_${activeKey}_secondary`].includes(_item.id)} ));
formActions.setFieldState('secondary', (state) => {
state.originAsyncData = source;
......
......@@ -8,13 +8,17 @@ import { context } from '../../common/context/context';
import NiceForm from '@/components/NiceForm';
import { PublicApi } from '@/services/api';
import { useFilterSameOption } from '../../common/hooks/useFilterSameOption';
import { getAuth } from '@/utils/auth';
const actions = createFormActions();
const BranchList = (props) => {
const userAuth = getAuth();
const { visible, value, onCancel, onConfirm } = props;
const fixtureContext = useContext(context);
const sameKeyState = useFilterSameOption();
/** 是否是自营商城 */
const isSelfMall = useMemo(() => fixtureContext.isSelfMall, [fixtureContext.isSelfMall]);
const { activeKey: categoryId } = useSelector<any, "activeKey" >(['activeKey']);
const disabledBrandKeys = useMemo(() => sameKeyState[`tabItem_${categoryId}_brand`], [sameKeyState, categoryId]);
......@@ -61,23 +65,31 @@ const BranchList = (props) => {
const onPaginationChange = (page: number, pageSize?: number) => {
setCurrent(page);
setPageSize(pageSize || 10);
const params = getParams();
fetchData({
shopId: fixtureContext?.shopId.toString(),
customerCategoryId: categoryId.toString,
...params,
current: page.toString(),
pageSize: pageSize?.toString() || '10',
});
// fetchData({
// shopId: fixtureContext?.shopId.toString(),
// customerCategoryId: categoryId.toString,
// current: page.toString(),
// pageSize: pageSize?.toString() || '10',
// });
};
const onSubmit = (values) => {
const withName = values.name ? { name: values.name } : {};
fetchData({
shopId: fixtureContext?.shopId.toString(),
customerCategoryId: categoryId.toString(),
current: current.toString(),
pageSize: pageSize.toString(),
...withName,
});
const params = getParams();
fetchData({...params, ...withName});
// fetchData({
// shopId: fixtureContext?.shopId.toString(),
// customerCategoryId: categoryId.toString(),
// current: current.toString(),
// pageSize: pageSize.toString(),
// ...withName,
// });
};
const Submit = () => {
......@@ -86,9 +98,23 @@ const BranchList = (props) => {
);
};
const getParams = () => {
const common = {
shopId: fixtureContext?.shopId.toString(),
customerCategoryId: categoryId.toString(),
current: current.toString(),
pageSize: pageSize.toString(),
}
return isSelfMall ? { ...common, memberId: userAuth.memberId, memberRoleId: userAuth.memberRoleId } : common;
}
const fetchData = async (params: any) => {
console.log(params);
const { data, code } = await PublicApi.getSearchChannelCommodityTemplateGetBrandList(params);
const service = isSelfMall
? PublicApi.getSearchCommodityTemplateGetBrandList
: PublicApi.getSearchChannelCommodityTemplateGetBrandList
const { data, code } = await service(params);
if (code === 1000) {
setDataSource(data.data);
setTotal(data.totalCount);
......@@ -99,13 +125,9 @@ const BranchList = (props) => {
if (!visible) {
return;
}
console.log(categoryId);
fetchData({
shopId: fixtureContext?.shopId.toString(),
customerCategoryId: categoryId.toString(),
current: current.toString(),
pageSize: pageSize.toString(),
});
// console.log(categoryId);
const params = getParams();
fetchData(params);
}, [visible]);
const onSelect = (checked: boolean, options: { name: string, icon: string, id: number }) => {
......
......@@ -3,21 +3,22 @@ import { PublicApi } from '@/services/api';
// 高级筛选schema中用于输入搜索品牌的Effect
export const searchBrandOptionEffect = (
shopId: any,
serachParams: any,
API: (data: any) => Promise<any>,
context: any,
fieldName: string,
) => {
context.getFieldState(fieldName, state => {
PublicApi.getSearchCommodityTemplateGetBrandList({
API({
current: '1',
pageSize: '100',
name: state.props['x-component-props'].searchValue,
shopId,
...serachParams,
}).then(res => {
context.setFieldState(fieldName, state => {
state.props['x-component-props'].dataoption = res.data?.data?.map(item => {
return { label: item.name, value: item.id };
});
}) || [];
});
});
});
......@@ -26,19 +27,20 @@ export const searchBrandOptionEffect = (
// 高级筛选schema中用于输入搜索商品品类的Effect
export const searchCustomerCategoryOptionEffect = (
shopId: any,
serachParams: any,
API: (data: any) => Promise<any>,
context: any,
fieldName: string,
) => {
context.getFieldState(fieldName, state => {
PublicApi.getSearchCommodityTemplateGetFirstCategoryListByMemberId({
shopId,
API({
...serachParams,
}).then(res => {
// PublicApi.getProductPlatformGetCategoryTree().then(res => {
context.setFieldState(fieldName, state => {
state.props['x-component-props'].dataoption = res.data?.map(item => {
return { title: item.name, id: item.id };
});
}) || [];
});
});
});
......
......@@ -6,7 +6,8 @@ import { Product } from '@/pages/transaction/marketingAbility/marketingActivitie
import CommodityDrawer from '../CommodityDrawer';
import { getAuth } from '@/utils/auth';
import { useFilterSameOption } from '../../common/hooks/useFilterSameOption';
import { PublicApi } from '@/services/api';
import { searchBrandOptionEffect, searchCustomerCategoryOptionEffect } from './effect';
interface Iprops {
value: {
......@@ -38,6 +39,8 @@ const FormilyCommodity: React.FC<Iprops> & { isFieldComponent: boolean } = (prop
/** 1 级分类 id */
const { activeKey } = useSelector<any, "activeKey" >(['activeKey']);
const fixtureContext = useContext(context);
/** 是否是自营商城 */
const isSelfMall = useMemo(() => fixtureContext.isSelfMall, [fixtureContext.isSelfMall]);
/** 获取已经选择的id */
const sameKeyState = useFilterSameOption();
const disabledSaleRankingKeys = useMemo(() => sameKeyState[`tabItem_${activeKey}_saleRanking`], [sameKeyState, activeKey]);
......@@ -72,12 +75,40 @@ const FormilyCommodity: React.FC<Iprops> & { isFieldComponent: boolean } = (prop
const filterParam = useMemo(() => {
return {
shopId: fixtureContext?.shopId.toString(),
categoryId: activeKey,
customerCategoryId: activeKey,
memberId: userAuth.memberId,
memberRoleId: userAuth.memberRoleId,
idNotInList: [productProps?.id].concat(disabledSaleRankingKeys).filter(Boolean)
};
}, [fixtureContext?.shopId.toString(), activeKey, disabledSaleRankingKeys]);
}, [fixtureContext?.shopId.toString(), activeKey, disabledSaleRankingKeys, isSelfMall]);
const restProps = useMemo(() => {
const data = {
shopId: fixtureContext.shopId,
memberId: userAuth.memberId,
memberRoleId: userAuth.memberRoleId
}
return isSelfMall ? {
service: PublicApi.getMarketingAdornGoodsListAdorn,
formEffects: ($, actions) => {
$('onFieldChange', 'brandId').subscribe(_ => {
searchBrandOptionEffect({shopId: fixtureContext.shopId, customerCategoryId: activeKey}, PublicApi.getSearchCommodityTemplateGetBrandList, actions, 'brandId');
});
$('onFieldChange', 'categoryId').subscribe(_ => {
searchCustomerCategoryOptionEffect(data, PublicApi.getSearchCommodityTemplateGetFirstCategoryListByMemberId, actions, 'categoryId');
});
}
} : {
formEffects: ($, actions) => {
$('onFieldChange', 'brandId').subscribe(_ => {
searchBrandOptionEffect({shopId: fixtureContext.shopId, customerCategoryId: activeKey}, PublicApi.getSearchCommodityTemplateGetBrandList, actions, 'brandId');
});
$('onFieldChange', 'categoryId').subscribe(_ => {
searchCustomerCategoryOptionEffect(data, PublicApi.getSearchChannelCommodityTemplateGetFirstCategoryListByMemberId, actions, 'categoryId');
});
}
}
}, [isSelfMall])
const onLabelChange = (data) => {
mutators.change({...value, label: data.label});
......@@ -86,7 +117,14 @@ const FormilyCommodity: React.FC<Iprops> & { isFieldComponent: boolean } = (prop
return (
<div>
<Product activityImage={''} onEdit={onEdit} {...productProps} isWithLabels={componentProps.isWithLabels || false} onLabelChange={onLabelChange} />
<CommodityDrawer visible={productVisible} onClose={onClose} onConfirm={onOk} filterParam={filterParam} selectId={productProps?.id?.toString()} />
<CommodityDrawer
{...restProps}
visible={productVisible}
onClose={onClose}
onConfirm={onOk}
filterParam={filterParam}
selectId={productProps?.id?.toString()}
/>
</div>
);
};
......
......@@ -69,7 +69,7 @@ const FormilyActivityProduct: React.FC<Iprops> & { isFieldComponent: boolean } =
const common = {
...params,
shopId: fixtureContext?.shopId.toString(),
categoryId: activeKey,
// categoryId: activeKey,
...withActivityType
};
const isWithActivityType = common;
......
import React, { useContext, useState } from 'react';
import React, { useContext, useMemo, useState } from 'react';
import { Tabs } from 'antd';
import cs from 'classnames';
import {createActions, useSelector} from '@lingxi-disign/react';
......@@ -8,6 +8,7 @@ import styles from './index.less';
import { context } from '../../../common/context/context';
import { PublicApi } from '@/services/api';
import { getAuth } from '@/utils/auth';
import { usePageStatus } from '@/hooks/usePageStatus';
const { TabPane } = Tabs;
......@@ -76,6 +77,9 @@ const CustomizeTabs: React.FC<Iprops> & { TabItem: typeof TabItem } = (props: Ip
const { children } = props;
const auth = getAuth();
const { pageConfig, shopId } = useSelector(['pageConfig', 'shopId']);
const { isSelf } = usePageStatus();
/** 是否是自营商城 */
const isSelfMall = useMemo(() => !!isSelf, [isSelf]);
const [activeKey, setActiveKey] = useState<string>("2");
const [hasRequestTabKey, setHasRequestTabKey] = useState<string[]>([]);
......@@ -85,6 +89,7 @@ const CustomizeTabs: React.FC<Iprops> & { TabItem: typeof TabItem } = (props: Ip
// onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver
// };
/** 获取活动商品 */
const getActivityProduct = async (ids: number[]) => {
if (ids.length === 0) {
return null
......@@ -97,7 +102,10 @@ const CustomizeTabs: React.FC<Iprops> & { TabItem: typeof TabItem } = (props: Ip
if (ids.length === 0) {
return null
}
return PublicApi.getMarketingAdornChannelGoodsListAdorn({
const service = isSelfMall
? PublicApi.getMarketingAdornGoodsListAdorn
: PublicApi.getMarketingAdornChannelGoodsListAdorn
return service({
idInList: ids as any || [],
shopId: shopId,
current: 1,
......@@ -107,6 +115,7 @@ const CustomizeTabs: React.FC<Iprops> & { TabItem: typeof TabItem } = (props: Ip
} as any);
};
/** 获取品牌 */
const getBrand = async (ids: number[]) => {
if (ids.length === 0) {
return []
......@@ -116,9 +125,13 @@ const CustomizeTabs: React.FC<Iprops> & { TabItem: typeof TabItem } = (props: Ip
shopId: shopId,
current: 1,
pageSize: ids.length,
memberId: auth.memberId,
// memberId: auth.memberId,
};
return PublicApi.getSearchChannelCommodityTemplateGetBrandList(postData as any);
const service = isSelfMall
? PublicApi.getSearchCommodityTemplateGetBrandList
: PublicApi.getSearchChannelCommodityTemplateGetBrandList
return service(postData as any);
};
/** 并行请求 */
......
......@@ -64,7 +64,9 @@ const TITLE_MAP = {
const CategoryNavigation = () => {
const { info, dataSourceFromRequest } = useGetLayout();
const { shopId, id, preview } = usePageStatus();
const { shopId, id, preview, isSelf } = usePageStatus();
/** 是否是自营商城 */
const isSelfMall = useMemo(() => !!isSelf, [isSelf]);
const [loading, setLoading] = useState<boolean>(false);
useEffect(() => {
......@@ -118,7 +120,8 @@ const CategoryNavigation = () => {
return tabProps;
});
const postData = { style: 0, category: result.filter(Boolean) };
const { data, code } = await PublicApi.postTemplateAdornAppChannelSave({
const service = isSelfMall ? PublicApi.postTemplateAdornAppSelfSave : PublicApi.postTemplateAdornAppChannelSave;
const { data, code } = await service({
templateId: Number(id),
categoryAdornContent: postData as any,
});
......@@ -157,7 +160,7 @@ const CategoryNavigation = () => {
</div>
{
!isPreview && (
<FixtureContentProvider value={{shopId: shopId}}>
<FixtureContentProvider value={{shopId: shopId, isSelfMall}}>
<EditPanel />
</FixtureContentProvider>
)
......
......@@ -3,7 +3,7 @@ import { Image, Button, Form, Spin, Row, Col, Switch, Space, Input, Empty } from
import { FormOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api';
import { MALL_ENV, MALL_PROPERTY, ENV_COLOR, ENV_BG_COLOR } from './constant'
import { validatorByte } from '@/utils/regExp';
import { validatorByte, validatorAllTrim } from '@/utils/regExp';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import UploadImage from '@/components/UploadImage'
import styles from './index.less'
......@@ -48,6 +48,7 @@ const OwnMallConfigure = () => {
PublicApi.postManageActivityShopRuleUpdate({ id, ...values }).then(res => {
if (res.code === 1000) {
getMallList()
showEdit({ id }, false)
}
}).finally(() => {
setSaveLoading(false)
......@@ -109,7 +110,7 @@ const OwnMallConfigure = () => {
<Col>
{
item.isEdit ?
<Form.Item
<Form.Item
name='logoUrl'
rules={[{ required: true, message: "请上传商城LOGO" }]}
>
......@@ -130,11 +131,12 @@ const OwnMallConfigure = () => {
<Col className={styles.right}>
{
item.isEdit ?
<Form.Item
<Form.Item
name='name'
rules={[
{ required: true, message: '请填写商城名称' },
{ validator: (r, v, c) => validatorByte(r, v, c, 40) }
{ validator: (r, v, c) => validatorByte(r, v, c, 40) },
{ validator: (r, v, c) => validatorAllTrim(v, c, '商城名称') },
]}
>
<Input/>
......@@ -155,7 +157,7 @@ const OwnMallConfigure = () => {
<div className={styles.title}>商城描述:</div>
{
item.isEdit ?
<Form.Item
<Form.Item
name='describe'
rules={[
{ validator: (r, v, c) => validatorByte(r, v, c, 160) }
......
......@@ -79,6 +79,14 @@ const TemplateDetail: React.FC<TemplateDetailPropsType> = (props) => {
}
}
const handleCategoryJump = () => {
if (detailInfo?.environment === 1) {
message.info("暂不支持该类型模板装修")
return
}
window.location.href = `memberCenter/channelAbility/template/categoryNavigation?id=${detailInfo.id}&template=${detailInfo.fileName}&shopId=${detailInfo.shopId}&isSelf=1`
}
return (
<DetailPage
title="查看模板"
......@@ -120,6 +128,10 @@ const TemplateDetail: React.FC<TemplateDetailPropsType> = (props) => {
<LayoutOutlined />
<label>商城装修</label>
</div>
<div className={cx(styles.btn, styles.fit)} onClick={() => handleCategoryJump()}>
<LayoutOutlined />
<label>品类导航页装修</label>
</div>
<div className={cx(styles.btn, detailInfo?.use === 1 ? styles.use : '')} onClick={() => detailInfo?.use !== 1 ? setUseModalVisible(true) : {}}>
<PushpinOutlined />
<label>{detailInfo?.use === 1 ? '使用中' : '使用'}</label>
......
import { values } from 'mobx';
/**
* @param str:string 需要校验的字符串
* @param type:string 需要校验的类型
*/
export const checkRegExp = (str:string, type:string) => {
switch (type) {
case 'phone': //手机号码
return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
case 'tel': //座机
return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
case 'card': //身份证
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
case 'pwd': //密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线
return /^[a-zA-Z]\w{5,17}$/.test(str)
case 'postal': //邮政编码
return /[1-9]\d{5}(?!\d)/.test(str);
case 'QQ': //QQ号
return /^[1-9][0-9]{4,9}$/.test(str);
case 'email': //邮箱
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
case 'money': //金额(小数点2位)
return /^\d*(?:\.\d{0,2})?$/.test(str);
case 'URL': //网址
return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str)
case 'IP': //IP
return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str);
case 'date': //日期时间
return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) || /^(\d{4})\-(\d{2})\-(\d{2})$/.test(str)
case 'number': //数字
return /^[0-9]$/.test(str);
case 'english': //英文
return /^[a-zA-Z]+$/.test(str);
case 'chinese': //中文
return /^[\\u4E00-\\u9FA5]+$/.test(str);
case 'lower': //小写
return /^[a-z]+$/.test(str);
case 'upper': //大写
return /^[A-Z]+$/.test(str);
case 'HTML': //HTML标记
return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
default:
return true;
}
}
/**
* 区别校验 汉字 和 字符 长度
* @param rule
* @param value 表单输入的值
* @param callback
* @param maxByte:number 最大字符数
*/
export const validatorByte = (rule, value, callback, maxByte: number) => {
try {
if(value){
let str = value
str = str.replace(/[\u4e00-\u9fa5]/g, 'OO')
if(str.length > maxByte)
throw new Error(`最多输入${maxByte}个字符,${Math.floor(maxByte / 2)}个汉字`);
else
callback()
} else {
callback()
}
} catch (err) {
callback(err)
}
}
\ No newline at end of file
import { values } from 'mobx';
/**
* @param str:string 需要校验的字符串
* @param type:string 需要校验的类型
*/
export const checkRegExp = (str:string, type:string) => {
switch (type) {
case 'phone': //手机号码
return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
case 'tel': //座机
return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
case 'card': //身份证
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
case 'pwd': //密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线
return /^[a-zA-Z]\w{5,17}$/.test(str)
case 'postal': //邮政编码
return /[1-9]\d{5}(?!\d)/.test(str);
case 'QQ': //QQ号
return /^[1-9][0-9]{4,9}$/.test(str);
case 'email': //邮箱
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
case 'money': //金额(小数点2位)
return /^\d*(?:\.\d{0,2})?$/.test(str);
case 'URL': //网址
return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str)
case 'IP': //IP
return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str);
case 'date': //日期时间
return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) || /^(\d{4})\-(\d{2})\-(\d{2})$/.test(str)
case 'number': //数字
return /^[0-9]$/.test(str);
case 'english': //英文
return /^[a-zA-Z]+$/.test(str);
case 'chinese': //中文
return /^[\\u4E00-\\u9FA5]+$/.test(str);
case 'lower': //小写
return /^[a-z]+$/.test(str);
case 'upper': //大写
return /^[A-Z]+$/.test(str);
case 'HTML': //HTML标记
return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
default:
return true;
}
}
/**
* 区别校验 汉字 和 字符 长度
* @param rule
* @param value 表单输入的值
* @param callback
* @param maxByte:number 最大字符数
*/
export const validatorByte = (rule, value, callback, maxByte: number) => {
try {
if(value){
let str = value
str = str.replace(/[\u4e00-\u9fa5]/g, 'OO')
if(str.length > maxByte)
throw new Error(`最多输入${maxByte}个字符,${Math.floor(maxByte / 2)}个汉字`);
else
callback()
} else {
callback()
}
} catch (err) {
callback(err)
}
}
/**
* 校验内容是否为纯空格
* @param value 表单输入的值
* @param callback
* @param name 字段名称
*/
export const validatorAllTrim = (value, callback, name = '') => {
try {
if(value){
if(value.trim().length === 0)
throw new Error(`${name}不可为空`);
else
callback()
} else {
callback()
}
} catch (err) {
callback(err)
}
}
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