Commit 18681003 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫
parents 7eefcd4a 40f0f6d0
......@@ -5,6 +5,7 @@ export interface IBasicFormParam {
brandName: string;
commodityAreaList: string[][];
customerCategoryId: string[];
customerCategoryName: string;
name: string;
sellingPoint: string[];
slogan: string;
......
......@@ -18,6 +18,7 @@ import ProductDescFormCloud from './addProductsItem/productDescFormCloud'
import { useLocalStore, observer } from 'mobx-react'
import { store } from '@/store'
import { PublicApi } from '@/services/api'
import { CommodityType } from './constant';
const { TabPane } = Tabs
......@@ -90,6 +91,7 @@ const AddProducts: React.FC<{}> = (props) => {
title: data.title,
keywords: data.keywords,
description: data.description,
type: data.type,
})
setProductName(data?.name)
setProductPriceType(data?.priceType)
......@@ -169,6 +171,11 @@ const AddProducts: React.FC<{}> = (props) => {
}
}
}
if(productInfoByEdit?.type === CommodityType.UPPER_SUPPORTER_COMMODITY) {
// @ 上游商品 直接去原信息中的品类品牌id
_bacsicForm.customerCategoryId = productInfoByEdit?.customerCategory.fullId.split('.').map(item => Number(item) + '')
_bacsicForm.brandId = productInfoByEdit?.brand.id
}
_bacsicForm.customerCategoryId = _bacsicForm.customerCategoryId[_bacsicForm.customerCategoryId.length - 1]
// 移除描述中的空数组[]
let _productDescription = { ...productDescription }
......
......@@ -13,7 +13,7 @@ import { store } from '@/store'
import { validatorByte } from '@/utils/regExp';
import { GetProductCustomerGetCustomerCategoryTreeResponse } from '@/services/ProductApi';
import { GetManageAreaAllResponse } from '@/services/PassApi';
import { customerCategoryTypeLabel } from '../constant';
import { CommodityType, customerCategoryTypeLabel } from '../constant';
const { Option } = Select
const layout = {
......@@ -198,7 +198,76 @@ const BasicInfoForm: React.FC<Iprops> = (props) => {
ref={basicFormRef}
autoComplete="off"
>
<Form.Item
{/* 对来自于上游的商品 品类品牌仅做显示处理 */}
{
productInfoByEdit?.type === CommodityType.UPPER_SUPPORTER_COMMODITY
?
<Form.Item
name="customerCategoryName"
label="商品品类"
rules={[
{
required: true,
message: '请选择商品品类'
},
]}
>
<Input placeholder="请选择品类" disabled={history.location.query?.id} defaultValue={productInfoByEdit.customerCategory.fullName} />
</Form.Item>
:
<Form.Item
name="customerCategoryId"
label="商品品类"
rules={[
{
required: true,
message: '请选择商品品类'
},
]}
>
<Cascader
allowClear={false}
disabled={history.location.query?.id}
options={customerCategoryTree}
fieldNames={{ label: 'title', value: 'id', children: 'children' }}
onChange={onCustomerCategoryChange}
placeholder="请选择品类"
/>
</Form.Item>
}
{
productInfoByEdit?.type === CommodityType.UPPER_SUPPORTER_COMMODITY
?
<Form.Item
name="brandName"
label="商品品牌"
>
<Input placeholder="请选择商品品牌" disabled={!isUpdateAttribute} defaultValue={productInfoByEdit.brand.name} />
</Form.Item>
:
<Form.Item
name="brandId"
label="商品品牌"
>
<Select
disabled={!isUpdateAttribute}
showSearch={true}
showArrow={true}
placeholder="请输入或选择商品品牌"
allowClear
value={brandValue}
defaultActiveFirstOption={false}
filterOption={false}
onSearch={handleBrandSearch}
onChange={handleBrandChange}
onFocus={()=>handleBrandSearch(null)}
style={{ width: '100%' }}
>
{brandData.map(d => <Option value={d.id} key={d.id}>{d.name}</Option>)}
</Select>
</Form.Item>
}
{/* <Form.Item
name="customerCategoryId"
label="商品品类"
rules={[
......@@ -237,7 +306,7 @@ const BasicInfoForm: React.FC<Iprops> = (props) => {
>
{brandData.map(d => <Option value={d.id} key={d.id}>{d.name}</Option>)}
</Select>
</Form.Item>
</Form.Item> */}
<Form.Item
name="name"
label={
......
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { PublicApi } from '@/services/api';
import { ISchema } from '@formily/antd';
import { Badge } from 'antd';
import { ColumnType } from 'antd/lib/table';
import moment from 'moment';
import React, { ReactNode } from 'react'
......@@ -20,6 +20,18 @@ export const productStatusLabel = [
'未上架'
]
/** 商品状态对应的颜色 */
export const productStatusColor = [
'',
'blue',
'cyan',
'orange',
'green',
'green',
'purple',
'gold',
]
/** 品类类型 */
export const customerCategoryTypeLabel = [
'',
......@@ -52,6 +64,25 @@ export const carriageTypeLabel = [
'买家承担运费',
]
/** 商品类型枚举 */
export enum CommodityType {
/** 自营商品 */
SELF_SUPPORT_COMMODITY = 1,
/** 上游商品 */
UPPER_SUPPORTER_COMMODITY = 2,
/** 代销商品 */
AGENT_SALE_COMMODITY = 3,
}
/** 商品的操作文本 */
export const opeartionLabel = [
'',
'提交审核',
'修改商品',
'审核商品'
]
/** 查看商品 审核历史列 */
export const columns: ColumnType<any>[] = [
{
......@@ -69,31 +100,13 @@ export const columns: ColumnType<any>[] = [
title: '状态',
dataIndex: 'status',
key: 'status',
render: (text:any, record:any) => {
let component: ReactNode = null
if(record.status === 4)
component = (<><span className="commonStatusValid"></span>审核通过</>)
else if(record.status === 1)
component = (<><span className="commonStatusInvalid"></span>待提交审核</>)
else if(record.status === 2)
component = (<><span className="commonStatusModify"></span>待审核</>)
else if(record.status === 3)
component = (<><span className="commonStatusStop"></span>审核不通过</>)
return component
}
render: (t, r) => <Badge color={productStatusColor[t]} text={productStatusLabel[t]} />
},
{
title: '操作',
dataIndex: 'operation',
key: 'operation',
render: (text:any, record:any) => {
if(record.operation === 1)
return '提交审核'
else if(record.operation === 2)
return '修改商品'
else if(record.operation === 3)
return '审核商品'
}
render: text => opeartionLabel[text]
},
{
title: '操作时间',
......
import React, { useState, useEffect, useRef, ReactNode } from 'react'
import { history } from 'umi'
import { Button, Form, Card, Modal, Select, Row, Col, Dropdown, Tooltip, Menu, Space, message, Checkbox } from 'antd'
import { Button, Form, Card, Modal, Select, Row, Col, Dropdown, Tooltip, Menu, Space, message, Checkbox, Badge } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
PlusOutlined,
......@@ -27,7 +27,7 @@ import { searchBrandOptionEffect, searchCustomerCategoryOptionEffect } from './e
import EyePreview from '@/components/EyePreview'
import moment from 'moment'
import { GetProductChannelCommodityGetShopResponse } from '@/services/ProductApi'
import { productStatusLabel } from './constant'
import { productStatusColor, productStatusLabel } from './constant'
// 定义选择的行数据的类型
interface Item {
......@@ -146,7 +146,7 @@ const DirectChannel: React.FC<{}> = () => {
title: '商品状态',
dataIndex: 'status',
key: 'id',
render: (text: any, record: any) => <><span className="commonStatusModify"></span>{productStatusLabel[text]}</>
render: (t) => <Badge color={productStatusColor[t]} text={productStatusLabel[t]} />
},
{
title: '操作',
......
import React, { useState, useEffect, useRef, ReactNode } from 'react'
import { Button, Form, Card, Modal, Checkbox, Row, Col, Input, } from 'antd'
import { Button, Form, Card, Modal, Checkbox, Row, Col, Input, Badge, } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
PlusOutlined,
......@@ -16,7 +16,7 @@ import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilte
import { searchCustomerCategoryOptionEffect, searchBrandOptionEffect } from './effect'
import { fastSchema } from './schema/productSchema'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { priceTypeLabel, productStatusLabel, validatorNumberRange } from './constant'
import { priceTypeLabel, productStatusColor, productStatusLabel, validatorNumberRange } from './constant'
const formActions = createFormActions();
......@@ -103,7 +103,7 @@ const FastModifyPrice: React.FC<{}> = () => {
title: '状态',
dataIndex: 'status',
key: 'status',
render: (text: any, record: any) => <><span className="commonStatusModify"></span>{productStatusLabel[text]}</>
render: (text) => <Badge color={productStatusColor[text]} text={productStatusLabel[text]} />
},
{
title: '操作',
......
import React, { useState, useEffect, useRef, useMemo } from 'react'
import { history } from 'umi'
import { Button, Form, Card, Modal, Result, Progress, Select, Tooltip, Checkbox, Row, Col, Dropdown, Menu, Space, message } from 'antd'
import { Button, Form, Card, Modal, Result, Progress, Select, Tooltip, Checkbox, Row, Col, Dropdown, Menu, Space, message, Badge } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
PlusOutlined,
......@@ -28,7 +28,7 @@ import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilte
import { searchBrandOptionEffect, searchCustomerCategoryOptionEffect } from './effect'
import { getAuth } from '@/utils/auth'
import useSetSearchValueInTable from '@/hooks/useSetSearchValueInTable'
import { priceTypeLabel, productStatusLabel } from './constant'
import { priceTypeLabel, productStatusColor, productStatusLabel } from './constant'
import EyePreview from '@/components/EyePreview'
import UpperProductModalTable from './components/upperProductModalTable'
import { Item } from '@/components/ButtonTabs'
......@@ -130,7 +130,8 @@ const Products: React.FC<{}> = () => {
{
title: '供应会员',
dataIndex: 'upperMemberName',
key: 'upperMemberName'
key: 'upperMemberName',
render: t => t ? t : '—'
},
{
title: '价格',
......@@ -163,7 +164,7 @@ const Products: React.FC<{}> = () => {
title: '商品状态',
dataIndex: 'status',
key: 'status',
render: text => <><span className="commonStatusModify"></span>{productStatusLabel[text]}</>
render: t => <Badge color={productStatusColor[t]} text={productStatusLabel[t]} />
},
{
title: '操作',
......
import React, { useState, ReactNode, useEffect } from 'react'
import { history } from 'umi'
import { Steps, Card, Space, Tooltip, Row, Col, Descriptions, Table, Tabs, Tag, Divider } from 'antd'
import { Steps, Card, Space, Tooltip, Row, Col, Descriptions, Table, Tabs, Tag, Divider, Badge } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
QuestionCircleOutlined,
......@@ -15,7 +15,7 @@ import {
GetProductCommodityGetCommodityResponse,
GetProductCommodityGetCommodityCheckRecordResponse,
} from '@/services/ProductApi'
import { carriageTypeLabel, columns, customerCategoryTypeLabel, deliveryTypeLabel, priceTypeLabel, productStatusLabel } from './constant'
import { carriageTypeLabel, columns, customerCategoryTypeLabel, deliveryTypeLabel, priceTypeLabel, productStatusColor, productStatusLabel } from './constant'
interface IAttributeByValue {
groupName: string;
......@@ -112,8 +112,12 @@ const viewProducts: React.FC<{}> = () => {
<Descriptions colon={true} style={{paddingLeft:128}}>
<Descriptions.Item label="商品品牌">{productDetail?.brand?.name}</Descriptions.Item>
<Descriptions.Item label="商品品类">{productDetail?.customerCategory?.fullName}</Descriptions.Item>
<Descriptions.Item label="商品状态"><span className="commonStatusModify"></span>{productStatusLabel[productDetail?.status]}</Descriptions.Item>
<Descriptions.Item label="商品类型"><span className="commonStatusValid"></span>{customerCategoryTypeLabel[productDetail?.customerCategory?.type]}</Descriptions.Item>
<Descriptions.Item label="商品状态">
<Badge color={productStatusColor[productDetail?.status]} text={productStatusLabel[productDetail?.status]} />
</Descriptions.Item>
<Descriptions.Item label="商品类型">
<Badge color={productStatusColor[productDetail?.customerCategory?.type]} text={customerCategoryTypeLabel[productDetail?.customerCategory?.type]} />
</Descriptions.Item>
{
productDetail?.commodityShopList?.length>0 &&
<Descriptions.Item label="上架商城">
......
......@@ -178,7 +178,7 @@ const Details = (props: any) => {
return (
<div>
<EyePreview
url={`/memberCenter/afterService/returnApplication/returnQuery/detail?id=${record.orderId}`}
url={record.orderType === 1 ? `/memberCenter/tranactionAbility/purchaseOrder/orderList/preview?id=${record.orderId}` : `/memberCenter/afterService/returnApplication/returnQuery/detail?id=${record.orderId}`}
>
{text}
</EyePreview>
......
......@@ -120,7 +120,7 @@ const FormList = (props: any) => {
if (res.code === 1000) {
let data = res.data.data.map((item, index) => {
return {
materielId: _filterArr(sourceType, item, ['', 'productId', 'id', '']),
materielId: _filterArr(sourceType, item, ['', 'goodsId', 'id', '']),
code: _filter(sourceType, item, ['', 'number', 'code', 'number']),// 物料编号
name: _filter(sourceType, item, ['', 'name', 'name', 'name']),//物料名称
type: _filter(sourceType, item, ['', 'model', 'type', 'model']),//物料规格
......
.textOverflowMulti2(@line: 3) {
display: -webkit-box;
/* autoprefixer: off */
-webkit-box-orient:vertical;
/* autoprefixer: on */
-webkit-line-clamp: @line;
overflow: hidden;
}
.section {
display: flex;
flex-direction: row;
align-items: center;
padding: 16px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px 0 rgba(0,0,0,0.04);
transition: width 0.5s;
overflow: hidden;
width: 72px;
height: 72px;
border: 1px solid transparent;
.img {
width: 40px;
height: 40px;
margin-right: 16px;
flex-shrink: 0;
}
&:hover {
width: 384px;
border: 1px solid @primary-color;
}
.info {
display: flex;
flex-direction: column;
flex: 1;
.titleContainer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.title {
font-size: 14px;
color: #252D37;
flex: 1;
.textOverflowMulti2(1)
}
}
.footer {
margin-top: 4px;
overflow: hidden;
.id {
margin-right: 16px;
font-size: 12px;
color: #909399;
}
}
}
}
.indeterminate {
border: 1px solid #1890ff;
}
.active {
width: 384px;
border: 1px solid @primary-color;
}
import React from 'react';
import StatusTag from '@/components/StatusTag';
import cx from 'classnames';
import styles from './activityItem.less';
interface Iprops {
id: number,
activityName: string,
activityTypeName: string,
statusName: string,
isActive: boolean,
onSelect?: ( (id: number) => void) | null,
hasChildSelected?: boolean,
activityImage: string,
}
const ActivityItem: React.FC<Iprops> = (props: Iprops) => {
const { id, activityName, activityTypeName, statusName, isActive = false, onSelect = null, hasChildSelected = false, activityImage } = props;
const triggerSelect = () => {
onSelect?.(id);
};
const mergeClasses = cx(styles.section, {
[styles.indeterminate]: hasChildSelected,
[styles.active]: isActive,
})
return (
<div onClick={triggerSelect} className={mergeClasses}>
<img className={styles.img} src={activityImage}/>
<div className={styles.info}>
<div className={styles.titleContainer}>
<span className={styles.title}>{activityName}</span>
<StatusTag title={statusName} type="success" />
</div>
<div className={styles.footer}>
<span className={styles.id}>ID: {id}</span>
<StatusTag type="default" title={activityTypeName} />
</div>
</div>
</div>
);
};
export default ActivityItem;
.productImg {
width: 64px;
height: 64px;
border-radius: 8px;
overflow: hidden;
}
.productName {
font-size: 14px;
color: #252D37;
line-height: 20px
}
.priceInfo {
font-size: 14px;
color: #D32F2F;
.unit {
color: #909399;
font-size: 12px;
}
}
.container {
display: flex;
flex-direction: column;
height: 100%;
.form {}
.table {
display: flex;
flex-direction: row;
align-items: center;
.activeItem + .activeItem {
margin-left: 8px;
}
}
.expandableTable {
margin-top: 16px;
}
.pagination {
margin-top: auto;
display: flex;
flex-direction: row-reverse;
}
}
.drawerFooter {
display: flex;
flex-direction: row-reverse;
}
/* eslint-disable react/display-name */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Drawer, Table, Button, Space, Pagination, Spin } from 'antd';
import NiceForm from '@/components/NiceForm';
import { createFormActions } from '@formily/antd';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { unstable_batchedUpdates as batchedUpdates } from 'react-dom';
import { ColumnsType } from 'antd/es/table';
import { GetMarketingPlatformActivityListAdornResponseDetail } from '@/services/MaketingV2Api';
import StatusTag from '@/components/StatusTag';
import schema from './schema';
import styles from './activityProductDrawer.less';
import ActivityItem from './activityItem';
const actions = createFormActions();
interface Iprops {
visible: boolean,
onCancel: (() => void) | null,
fetchData?: ((params: any) => Promise<any>) | null,
onOk?: ((data: any) => void) | null,
/** 传入的已选择的活动商品 */
products: any[],
activityImage: string,
mode?: 'radio' | 'checked',
}
type SubmitType = {
id: number,
activityName: string,
}
const columns: ColumnsType<GetMarketingPlatformActivityListAdornResponseDetail["productList"][0]> = [
{
title: '商品信息',
dataIndex: 'productInfo',
render: (_text, _record) => {
return (
<Space align="center">
<img src={_record.productImgUrl} className={styles.productImg} />
<span className={styles.productName}>{_record.productName}</span>
</Space>
);
}
},
{
title: '品类',
dataIndex:'category',
render: (_text) => {
return <StatusTag title={_text} type="default" />;
}
},
{
title: '品牌',
dataIndex: 'brand'
},
{
title: '商家名称',
dataIndex: 'memberName',
},
{
title: '单价',
dataIndex: 'unit',
render: (_text, _record) => {
return (
<div className={styles.priceInfo}>
<span>{_record.price}</span>
<span className={styles.unit}>({_record.unit})</span>
</div>
);
}
},
{
title: '活动价',
dataIndex: 'activityPrice',
render: (_text, _record) => {
return (
<div className={styles.priceInfo}>
<span>{_record.activityPrice}</span>
<span className={styles.unit}>({_record.unit})</span>
</div>
);
}
}
];
const ActivityProductDrawer: React.FC<Iprops> = (props: Iprops) => {
const { visible, onCancel, fetchData = null, onOk, products = [], activityImage, mode = 'checked' } = props;
const [current, setPage] = useState<number>(1);
const [currentPageSize, setPageSize] = useState<number>(10);
const [dataSource, setDataSource] = useState<GetMarketingPlatformActivityListAdornResponseDetail[]>([]);
const [totalCount, setTotalCount] = useState<number>(0);
const [selectedKey, setSelectKey] = useState<number | null>(null);
const [selectedActivityProductList, setSelectedActivityProductList] = useState<GetMarketingPlatformActivityListAdornResponseDetail["productList"]>();
const [checkedProduct, setCheckedProduct] = useState<GetMarketingPlatformActivityListAdornResponseDetail["productList"]>([]);
const [loading, setLoading] = useState<boolean>(false);
const selectedRowKeys = useMemo(() => checkedProduct.map((_item) => `${_item.activityId!}-${_item.id!}`), [checkedProduct]);
const fetchList = useCallback(async (params: any) => {
if (fetchData === null) {
return;
}
setLoading(true);
const { data, code } = await fetchData(params);
if (code === 1000) {
batchedUpdates(() => {
setLoading(false);
setDataSource(data.data);
setTotalCount(data.totalCount);
});
}
}, [fetchData]);
useEffect(() => {
if (!visible) {
return ;
}
setCheckedProduct(products);
fetchList({ current, pageSize: currentPageSize });
}, [current, currentPageSize, visible,]);
const onSubmit = (value: SubmitType) => {
console.log(value);
fetchList({ current, pageSize: currentPageSize, ...value });
};
const onReset = () => {
// actions.reset();
fetchList({ current, pageSize: currentPageSize });
};
// useEffect(() => {})
const handleCancel = () => {
onCancel?.();
};
const onChange = (page: number, pageSize?: number) => {
batchedUpdates(() => {
setPage(page);
setPageSize(pageSize || 10);
});
};
const onSelect = (id: number) => {
setSelectKey(id);
const target = dataSource.filter((_item) => _item.id === id)[0];
setSelectedActivityProductList(target.productList);
};
const handleOk = () => {
onOk?.(checkedProduct);
};
const handleRowSelect = (record: GetMarketingPlatformActivityListAdornResponseDetail["productList"][0], selected: boolean, selectedRows: GetMarketingPlatformActivityListAdornResponseDetail["productList"]) => {
if (mode === 'checked') {
if (selected) {
setCheckedProduct((prev) => prev.concat(record));
} else {
const key = `${record.activityId!}-${record.id!}`;
setCheckedProduct((prev) => prev.filter((_item) => {
const tempKey = `${_item.activityId}-${_item.id}`;
return key !== tempKey;
}));
}
return;
}
setCheckedProduct([record]);
};
const rowSelection = {
type: mode,
onSelect: handleRowSelect,
selectedRowKeys: selectedRowKeys
};
const drawerStyle = { background: '#FAFBFC' };
return (
<Drawer
onClose={handleCancel}
headerStyle={drawerStyle}
bodyStyle={drawerStyle}
footerStyle={drawerStyle}
title="选择活动商品"
visible={visible}
width={950}
footer={
<div className={styles.drawerFooter}>
<Space>
<Button onClick={handleCancel}>取消</Button>
<Button onClick={handleOk}>确定</Button>
</Space>
</div>
}
>
<div className={styles.container}>
<div className={styles.form}>
<NiceForm
schema={schema}
actions={actions}
onReset={onReset}
onSubmit={onSubmit}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'id', FORM_FILTER_PATH);
}}
></NiceForm>
</div>
<div className={styles.table}>
{
dataSource?.map((_item) => {
const { outerStatusName, id, activityName, activityTypeName } = _item;
const isActive = selectedKey === id;
const hasChildSelected = selectedRowKeys.some((_rowKey) => _rowKey.split("-")[0] === id.toString());
return (
<div key={_item.id} className={styles.activeItem}>
<ActivityItem
onSelect={onSelect}
isActive={isActive}
id={id}
activityName={activityName}
statusName={outerStatusName}
activityTypeName={activityTypeName}
hasChildSelected={hasChildSelected}
activityImage={activityImage}
/>
</div>
);
})
}
</div>
<div className={styles.expandableTable}>
<Table
rowSelection={rowSelection as any}
rowKey={(_record) => `${_record.activityId!}-${_record.id!}` }
loading={loading}
columns={columns} dataSource={selectedActivityProductList}></Table>
</div>
<div className={styles.pagination}>
<Pagination pageSize={currentPageSize} current={current} showQuickJumper total={totalCount} onChange={onChange}/>
</div>
</div>
</Drawer>
);
};
export default ActivityProductDrawer;
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { ISchema } from '@formily/antd';
const schema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
id: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
tip: '输入活动ID进行搜索',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
aotoRow: true,
},
properties: {
activityName: {
type: 'string',
"x-component-props": {
placeholder: '活动名称'
}
},
activityType: {
type: 'string',
enum: [],
"x-component-props": {
placeholder: '活动类型'
}
},
'[startTime, endTime]': {
"x-mega-props": {
span: 2,
},
type: 'daterange',
'x-component-props': {
placeholder: ['活动开始时间', "活动结束时间"]
}
},
product: {
type: 'string',
"x-component-props": {
placeholder: '活动名称'
}
},
merchantName: {
type: 'string',
"x-component-props": {
placeholder: '商家名称'
}
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
export default schema;
......@@ -13,8 +13,8 @@ import Search from '@/components/NiceForm/components/Search';
import Submit from '@/components/NiceForm/components/Submit'
import StatusTag from '@/components/StatusTag'
import CouponPlatformIcon from '@/pages/pageCustomized/icons/coupon_platform.png';
import CouponShopIcon from '@/pages/pageCustomized/icons/coupon_shop.png';
import CouponPlatformIcon from '@/assets/couponIcons/coupon_platform.png';
import CouponShopIcon from '@/assets/couponIcons/coupon_shop.png';
import * as tableSchemas from './schema';
......@@ -33,9 +33,9 @@ interface CouponsDrawerProps {
}
const CouponsDrawer: React.FC<CouponsDrawerProps> = (props: CouponsDrawerProps) => {
const { visible, onClose, onConfirm, selectId, belongType } = props;
const { visible, onClose, onConfirm, selectId } = props;
const { query: { shopId } }: any = history.location
const [type, setType] = useState(belongType || 1);
const [type, setType] = useState(2);
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(selectId ? [selectId] : []);
const [selectedRows, setSelectedRows] = useState<any>([]);
const ref = useRef<any>({});
......@@ -129,16 +129,7 @@ const CouponsDrawer: React.FC<CouponsDrawerProps> = (props: CouponsDrawerProps)
const fetchTableData = async (params: any) => {
const _params = { ...params, shopId };
let _fetch: any;
switch (type) {
case 1:
_fetch = PublicApi.getMarketingCouponPlatformActivityPageSelectPage
break;
case 2:
_fetch = PublicApi.getMarketingCouponPlatformActivityPageSelectMerchantPage
break;
}
const { data } = await _fetch(_params);
const { data } = await PublicApi.getMarketingCouponActivityPageSelectPage(_params);
return data;
}
const rowSelection: any = {
......@@ -197,22 +188,22 @@ const CouponsDrawer: React.FC<CouponsDrawerProps> = (props: CouponsDrawerProps)
span: 16
}
}}
formilyChilds={{
children: (
<div style={{ textAlign: 'right' }}>
<Radio.Group
options={options}
onChange={_onRadioChange}
value={type}
optionType="button"
/>
</div>
),
layouts: {
order: 2,
span: 8
}
}}
// formilyChilds={{
// children: (
// <div style={{ textAlign: 'right' }}>
// <Radio.Group
// options={options}
// onChange={_onRadioChange}
// value={type}
// optionType="button"
// />
// </div>
// ),
// layouts: {
// order: 2,
// span: 8
// }
// }}
/>
</Drawer>
)
......
......@@ -79,13 +79,6 @@ export const CouponSchema2: ISchema = {
allowClear: true,
},
},
memberName: {
type: 'string',
'x-component-props': {
placeholder: '商家名称',
allowClear: true,
},
},
sumbit: {
'x-component': 'Submit',
'x-mega-props': {
......
......@@ -4,7 +4,7 @@ import { cloneDeep } from 'lodash';
import { updatePageConfig, STATE_PROPS, SelectedInfoType, PageConfigType } from '@lingxi-disign/core';
import { useSelector } from '@lingxi-disign/react';
import * as MarketingConfigs from '../../../mobileTemplate/shopTemplateEdit/page_config';
import * as MarketingConfigs from '../../../mobileTemplate/shopTemplateEdit/marketing_config';
import styles from './index.less';
......
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const BottomNavigation: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const BottomNavigationItems: ComponentSchemaType = {
fatherNodesRule: ['BottomNavigation.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.bottomNavigationItems,
},
},
};
export default {
BottomNavigation,
'BottomNavigation.Items': BottomNavigationItems,
};
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const CouponsModal: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.couponsModal,
},
},
};
const CouponsItem: ComponentSchemaType = {
fatherNodesRule: ['CouponsModal.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardCoupon,
},
},
};
export default {
CouponsModal,
'CouponsModal.CouponsItem': CouponsItem,
};
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const MarketingCard: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const Header: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardHeader,
},
},
};
const ShopHeader: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardHeader,
},
},
};
const CommonContainer: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const VerticalContainer: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const CollageContainer: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const PackageContainer: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const PackageContainerTabs: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.PackageContainer.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const PackageContainerTabsTabPane: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.PackageContainerTabs.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const DetailItem: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.PackageContainer.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardDetailItem,
},
},
};
const CollageContainerItem: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.CollageContainer.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardGood,
},
},
};
const GoodsItem: ComponentSchemaType = {
fatherNodesRule: [
'MarketingCard.CommonContainer.children',
'MarketingCard.PackageContainerTabsTabPane.children',
],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardGood,
},
},
};
const CouponsItem: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.CommonContainer.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardCoupon,
},
},
};
export default {
MarketingCard,
'MarketingCard.Header': Header,
'MarketingCard.ShopHeader': ShopHeader,
'MarketingCard.CommonContainer': CommonContainer,
'MarketingCard.VerticalContainer': VerticalContainer,
'MarketingCard.CollageContainer': CollageContainer,
'MarketingCard.PackageContainer': PackageContainer,
'MarketingCard.PackageContainerTabs': PackageContainerTabs,
'MarketingCard.PackageContainerTabsTabPane': PackageContainerTabsTabPane,
'MarketingCard.DetailItem': DetailItem,
'MarketingCard.CollageContainerItem': CollageContainerItem,
'MarketingCard.GoodsItem': GoodsItem,
'MarketingCard.CouponsItem': CouponsItem,
};
......@@ -47,6 +47,9 @@ import MobileShopHeader from './MobileShopHeader'
import MobileNavCard from './MobileNavCard'
import Banner from './Banner'
import MobileShopCommodity from './MobileShopCommodity'
import CouponsModal from './CouponsModal'
import MarketingCard from './MarketingCard'
import BottomNavigation from './BottomNavigation'
export default {
View,
......@@ -89,4 +92,7 @@ export default {
...MobileNavCard,
...Banner,
...MobileShopCommodity,
...CouponsModal,
...MarketingCard,
...BottomNavigation
}
......@@ -6,15 +6,18 @@ import cx from 'classnames'
import { Tabs } from 'antd'
import StyleSettings from './styleSettings'
import PropsSettings from './propsSettings'
import { LAYOUT_TYPE } from '@/constants'
import styles from './index.less'
type SettingPanelType = {
selectedInfo: SelectedInfoType,
pageConfig: PageConfigType,
}
interface MobileSettingPanelProps {
shopId: number
shopId: number,
layoutType: LAYOUT_TYPE
}
const { TabPane } = Tabs
......@@ -34,7 +37,6 @@ const MobileSettingPanel: React.FC<MobileSettingPanelProps> = (props)=> {
setNewSelectInfo(updateSelectInfo)
}
}
updateSelectInfo()
}, [selectedInfo, pageConfig])
......@@ -47,7 +49,7 @@ const MobileSettingPanel: React.FC<MobileSettingPanelProps> = (props)=> {
{
(propsConfig && propsConfig.componentType) && (
<TabPane tab="编辑" key="props">
<PropsSettings selectedInfo={newSelectInfo} {...props} />
<PropsSettings selectedInfo={newSelectInfo} pageConfig={pageConfig} {...props} />
</TabPane>
)
}
......
@import "../../common.less";
.bottomNavigationClient {
&-box {
margin-bottom: 16px;
:global {
.ant-upload {
width: 100%;
}
}
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&>img {
width: 40px;
height: 40px;
}
&-add{
font-size: 40px;
}
&:hover {
.bottomNavigationClient-box-icon-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
}
&-bottom {
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
}
}
}
import React, { useMemo } from 'react';
import { Input, Select } from 'antd';
import { PlusCircleOutlined, DeleteOutlined } from '@ant-design/icons';
import { changeProps } from '@lingxi-disign/core';
import UploadImage from '@/components/UploadImage';
import uploadImgIcon from '@/assets/icons/upload_img_icon.svg'
import styles from './index.less';
interface BottomNavigationClientProps {
// 默认icon
defaultIcon?: any,
// 选中icon
selectIcon?: any,
// 导航标题
name?: any,
// 链接类型
/** 类型:1-首页 2-分类 3-进货单 4-工作台 5-我的 6-找现货 7-找供应 8-求购 9-换积分 10-找店铺 */
type?: any,
// 当前选中组件的key
selectedKey?: any,
// 1.B端 2.C端 3.SRM
property?: 1 | 2 | 3
}
const RedirectTypeList_B = [
{
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,
label: '找店铺',
},
];
const RedirectTypeList_C = [
{
value: 1,
label: '首页',
},
{
value: 2,
label: '分类',
},
{
value: 3,
label: '购物车',
},
{
value: 4,
label: '我的',
},
{
value: 5,
label: '消息',
},
{
value: 6,
label: '积分兑换',
},
{
value: 7,
label: '在线客服',
},
];
const BottomNavigationClient: React.FC<BottomNavigationClientProps> = (props: BottomNavigationClientProps) => {
const { defaultIcon, selectIcon, name, type, property = 2, selectedKey } = props;
const _isNull = (list) => {
let _number = 0;
for (let key in list) {
if (list[key]) {
_number += 1
}
}
return _number === list.length ? false : true;
}
const _onChangeName = (e: any) => {
const _val = e.target.value;
changeProps({
title: _val || '',
props: Object.assign({ ...props }, { name: _val, isnull: _isNull([defaultIcon, selectIcon, _val, type]) })
});
}
const _onChangeType = (value: any) => {
changeProps({
props: Object.assign({ ...props }, { type: value, isnull: _isNull([defaultIcon, selectIcon, name, value]) })
});
}
const _onChangeDefaultIcon = (url: any) => {
changeProps({
props: Object.assign({ ...props }, { defaultIcon: url, isnull: _isNull([url, selectIcon, name, type]) })
});
}
const _onChangeSelectIcon = (url: any) => {
changeProps({
props: Object.assign({ ...props }, { selectIcon: url, isnull: _isNull([defaultIcon, url, name, type]) })
});
}
const RedirectTypeList = useMemo(() => {
if(property === 1){
return RedirectTypeList_B
}else if(property === 2){
return RedirectTypeList_C
}
}, [property])
return (
<div className={styles['bottomNavigationClient']}>
<div className={styles['bottomNavigationClient-box']}>
<div className={styles['bottomNavigationClient-box-label']}>名称</div>
<Input key={`${selectedKey}-name`} defaultValue={name} onBlur={_onChangeName} />
</div>
<div className={styles['bottomNavigationClient-box']}>
<div className={styles['bottomNavigationClient-box-label']}>链接</div>
<Select key={`${selectedKey}-type`} defaultValue={type} onChange={_onChangeType} style={{ width: '100%' }} >
{
RedirectTypeList?.map(selectItem => <Select.Option value={selectItem.value} key={`redirect_type_${selectItem.value}`}>{selectItem.label}</Select.Option>)
}
</Select>
</div>
<div className={styles['bottomNavigationClient-box']}>
<div className={styles['bottomNavigationClient-box-label']}>图标-默认</div>
{defaultIcon ? (
<div className={styles['bottomNavigationClient-box-icon']}>
<img src={defaultIcon} />
<div className={styles['bottomNavigationClient-box-icon-cover']}>
<UploadImage
onChange={(url) => { _onChangeDefaultIcon(url) }}
listType="text"
>
<div className={styles['bottomNavigationClient-box-icon-cover-bottom']}>
添加图像
</div>
<DeleteOutlined className={styles['bottomNavigationClient-box-icon-cover-delete']} onClick={(e) => { e.stopPropagation(); e.preventDefault(); _onChangeDefaultIcon('') }} />
</UploadImage>
</div>
</div>
) : (
<UploadImage
onChange={(url) => { _onChangeDefaultIcon(url) }}
listType="text"
>
<div className={styles['bottomNavigationClient-box-icon']}>
<img src={uploadImgIcon} className={styles['bottomNavigationClient-box-icon-add']} />
<div className={styles['bottomNavigationClient-box-icon-cover']}>
<div className={styles['bottomNavigationClient-box-icon-cover-bottom']}>
添加图像
</div>
</div>
</div>
</UploadImage>
)}
</div>
<div className={styles['bottomNavigationClient-box']}>
<div className={styles['bottomNavigationClient-box-label']}>图标-选中</div>
{selectIcon ? (
<div className={styles['bottomNavigationClient-box-icon']}>
<img src={selectIcon} />
<div className={styles['bottomNavigationClient-box-icon-cover']}>
<UploadImage
onChange={(url) => { _onChangeSelectIcon(url) }}
listType="text"
>
<div className={styles['bottomNavigationClient-box-icon-cover-bottom']}>
添加图像
</div>
<DeleteOutlined className={styles['bottomNavigationClient-box-icon-cover-delete']} onClick={(e) => { e.stopPropagation(); e.preventDefault(); _onChangeSelectIcon('') }} />
</UploadImage>
</div>
</div>
) : (
<UploadImage
onChange={(url) => { _onChangeSelectIcon(url) }}
listType="text"
>
<div className={styles['bottomNavigationClient-box-icon']}>
<img src={uploadImgIcon} className={styles['bottomNavigationClient-box-icon-add']} />
<div className={styles['bottomNavigationClient-box-icon-cover']}>
<div className={styles['bottomNavigationClient-box-icon-cover-bottom']}>
添加图像
</div>
</div>
</div>
</UploadImage>
)}
</div>
</div>
)
}
export default BottomNavigationClient
@import "../../common.less";
.couponsModal {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
&>img {
width: 40px;
height: 40px;
}
}
}
}
import React, { useEffect } from 'react';
import { Input } from 'antd';
import { changeProps, changeStylesByKey } from '@lingxi-disign/core';
import styles from './index.less';
interface CouponsModalProps {
// 自定title
title?: string
// 当前选中组件的key
selectedKey?: any
}
const CouponsModal: React.FC<CouponsModalProps> = (props: CouponsModalProps) => {
const { title, selectedKey } = props;
useEffect(() => {
changeStylesByKey({
key: '8',
style: {
display: 'block'
}
})
return () => {
changeStylesByKey({
key: '8',
style: {
display: 'none'
}
})
}
}, [])
const _onChangeTitle = (e: any) => {
const _val = e.target.value;
changeProps({
props: Object.assign({ ...props }, { title: _val })
})
}
return (
<div className={styles['couponsModal']}>
<div className={styles['couponsModal-box']}>
<div className={styles['couponsModal-box-label']}>标题</div>
<Input key={`${selectedKey}-title`} defaultValue={title} onBlur={_onChangeTitle} />
</div>
</div>
);
}
export default CouponsModal;
@import "../../common.less";
.marketingCardCoupon {
&-box {
margin-top: 16px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 12px;
&-label {
color: #91959B;
width: 80px;
}
&-content {
flex: 1;
color: #303133;
}
}
}
import React, { useState, useEffect } from 'react';
import { Button } from 'antd';
import { changeProps, changeStylesByKey } from '@lingxi-disign/core';
import moment from 'moment';
import { formatTimeString } from '@/utils'
import { priceFormat } from '@/utils/numberFomat'
import { PublicApi } from '@/services/api';
import CouponsDrawer from '@/pages/editor/components/drawer/couponsDrawer';
import styles from './index.less';
interface MarketingCardCouponProps {
id?: number,
belongType?: 1 | 2,
// 当前选中组件的key
selectedKey?: any,
}
const MarketingCardCoupon: React.FC<MarketingCardCouponProps> = (props: MarketingCardCouponProps) => {
const { id, belongType, selectedKey } = props;
const [drawerVisible, setDrawerVisible] = useState(false);
const [record, setRecord] = useState<any>();
useEffect(() => {
changeStylesByKey({
key: '8',
style: {
display: 'block'
}
})
return () => {
changeStylesByKey({
key: '8',
style: {
display: 'none'
}
})
}
}, [])
const _onClose = () => {
setDrawerVisible(false);
}
useEffect(() => {
if (id && id != record?.id) {
PublicApi.postMarketingCouponPlatformActivityPageSelectDetail({ couponList: [{ couponType: belongType, id: id }] }).then((res) => {
if (res.code === 1000) {
setRecord(res.data[0]);
}else{
setRecord('')
}
}).catch(_ => setRecord(''))
}else if(!id){
setRecord('');
}
}, [id, belongType])
const _onChooseConfirm = (record) => {
setRecord(record);
changeProps({
title: record?.name,
props: Object.assign({ ...props }, { ...record, expiredDay: moment(record?.releaseTimeEnd || moment()).diff(moment(), 'days'), isnull: false })
})
_onClose();
}
return (
<div className={styles['marketingCardCoupon']}>
<Button onClick={() => { setDrawerVisible(true) }}>选择</Button>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>优惠券ID:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.id}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>优惠券名称:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.name}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>类型:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.typeName}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>领劵方式:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.getWayName}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>商家名称:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.belongName}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>面额:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.denomination ? `¥ ${priceFormat(record?.denomination)}` : ''}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>使用条件:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.useConditionMoney ? `满 ${record?.useConditionMoney} 元使用` : ''}</div>
</div>
<div className={styles['marketingCardCoupon-box']}>
<div className={styles['marketingCardCoupon-box-label']}>有效期:</div>
<div className={styles['marketingCardCoupon-box-content']}>{record?.releaseTimeStart ? `${formatTimeString(record?.releaseTimeStart)} 至 ${formatTimeString(record?.releaseTimeEnd)}` : ''}</div>
</div>
<CouponsDrawer
visible={drawerVisible}
belongType={belongType}
onClose={_onClose}
onConfirm={_onChooseConfirm}
selectId={id}
/>
</div>
);
}
export default MarketingCardCoupon;
@import "../../common.less";
.suggestProductCommodity {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
}
&-detail {
height: 80px;
border: 1px solid #F7F8FA;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 6px 8px;
margin-bottom: 16px;
position: relative;
overflow: hidden;
img {
height: 60px;
width: 60px;
margin-right: 10px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
&-title {
color: #303133;
font-size: 12px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示。
-webkit-box-orient: vertical; //从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
-webkit-line-clamp: 2; // 结合上面两个属性,表示显示的行数。
}
&-price {
color: #D32F2F;
font-size: 14px;
}
}
&:hover {
.suggestProductCommodity-detail-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
cursor: pointer;
&-bottom {
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
}
&-activityList {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-bottom: 8px;
cursor: pointer;
img {
width: 24px;
height: 24px;
}
&-name {
flex: 1;
font-size: 12px;
color: #303133;
margin: 0 8px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
}
}
}
.site-tag-plus {
background: #fff;
border-style: dashed;
}
.edit-tag {
user-select: none;
}
.tag-input {
width: 78px;
margin-right: 8px;
vertical-align: top;
}
@import "../../common.less";
.marketingCardHeader {
&-box {
margin-bottom: 16px;
:global {
.ant-upload {
width: 100%;
}
}
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&>img {
width: 40px;
height: 40px;
border-radius: 50%;
}
&-add {
font-size: 40px;
}
&:hover {
.marketingCardHeader-box-icon-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
}
&-bottom {
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
}
}
}
import React from 'react';
import { Input } from 'antd';
import { PlusCircleOutlined, DeleteOutlined } from '@ant-design/icons';
import { changeProps } from '@lingxi-disign/core';
import UploadImage from '@/components/UploadImage';
import { LAYOUT_TYPE } from '@/constants'
import ICONS_CONFIG from '../../../../components/mobileClientEditLeft/iconsConfig';
import styles from './index.less';
interface MarketingCardHeaderProps {
// 活动类型
type: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19,
// 自定title
title?: string,
// 自定info
explain?: string,
// 自定icon
icon?: any,
// 倒计时数组[时,分,秒]
countDown?: string[],
selectedKey?: any,
layoutType: LAYOUT_TYPE
}
const MarketingCardHeader: React.FC<MarketingCardHeaderProps> = (props: MarketingCardHeaderProps) => {
const { type, title, explain, icon, selectedKey, layoutType } = props;
const _defaultInfo = ICONS_CONFIG.filter((item) => item.type === type)[0]
const _onChangeTitle = (e: any) => {
const _val = e.target.value;
changeProps({
props: Object.assign({ ...props }, { title: _val })
});
}
const _onChangeExplain = (e: any) => {
const _val = e.target.value;
changeProps({
props: Object.assign({ ...props }, { explain: _val })
});
}
const _onChangeIcon = (url: any) => {
changeProps({
props: Object.assign({ ...props }, { icon: url })
});
}
return (
<div className={styles['marketingCardHeader']}>
<div className={styles['marketingCardHeader-box']}>
<div className={styles['marketingCardHeader-box-label']}>标题</div>
<Input key={`${selectedKey}-title`} defaultValue={title || _defaultInfo?.title} onBlur={_onChangeTitle} />
</div>
{
layoutType !== LAYOUT_TYPE.shop && (
<div className={styles['marketingCardHeader-box']}>
<div className={styles['marketingCardHeader-box-label']}>标题说明</div>
<Input key={`${selectedKey}-explain`} defaultValue={explain || _defaultInfo?.explain} onBlur={_onChangeExplain} />
</div>
)
}
<div className={styles['marketingCardHeader-box']}>
<div className={styles['marketingCardHeader-box-label']}>图标</div>
{icon ? (
<div className={styles['marketingCardHeader-box-icon']}>
<img src={icon} />
<div className={styles['marketingCardHeader-box-icon-cover']}>
<UploadImage
onChange={(url) => { _onChangeIcon(url) }}
listType="text"
>
<div className={styles['marketingCardHeader-box-icon-cover-bottom']}>
添加图像
</div>
</UploadImage>
<DeleteOutlined className={styles['marketingCardHeader-box-icon-cover-delete']} onClick={() => { _onChangeIcon('') }} />
</div>
</div>
) : (
<UploadImage
onChange={(url) => { _onChangeIcon(url) }}
listType="text"
>
<div className={styles['marketingCardHeader-box-icon']}>
<img src={_defaultInfo.icon} />
<div className={styles['marketingCardHeader-box-icon-cover']}>
<div className={styles['marketingCardHeader-box-icon-cover-bottom']}>
添加图像
</div>
</div>
</div>
</UploadImage>
)}
</div>
</div>
);
}
export default MarketingCardHeader;
import React from 'react'
import { SelectedInfoType, PROPS_SETTING_TYPES } from '@lingxi-disign/core';
import { SelectedInfoType, PROPS_SETTING_TYPES, PageConfigType } from '@lingxi-disign/core';
import HeaderNav from './components/headerNav'
import Banner from './components/banner'
import QuickNav from './components/quickNav'
......@@ -9,18 +9,26 @@ import BottomNavigation from './components/bottomNavigation'
import MobileChannelGoods from './components/channelGoods'
import MobileChannelInformation from './components/channelInformation'
import CardNavItem from './components/cardNavItem'
import CouponsModal from './components/couponsModal'
import MarketingCardCoupon from './components/marketingCardCoupon';
import MarketingCardGood from './components/marketingCardGood'
import MarketingCardHeader from './components/marketingCardHeader'
import BottomNavigationClient from './components/bottomNavigationClient'
import { LAYOUT_TYPE } from '@/constants'
import styles from './index.less'
interface PropsSettingsPropsType {
selectedInfo: SelectedInfoType | undefined,
pageConfig: PageConfigType,
layoutType: LAYOUT_TYPE,
shopId: number,
}
const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
const { selectedInfo, } = props
const { selectedInfo, pageConfig } = props
const renderSettingItem = () => {
const { props: initProps, propsConfig } = selectedInfo || {};
const { props: initProps, propsConfig, parentKey } = selectedInfo || {};
const _props = { ...initProps, ...props, selectedKey: selectedInfo?.selectedKey }
const componentType = propsConfig?.componentType
......@@ -46,6 +54,20 @@ const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
return <BottomNavigation {..._props} />
case PROPS_SETTING_TYPES.mobileNavCardNavItem:
return <CardNavItem {..._props} />
case PROPS_SETTING_TYPES.couponsModal:
return <CouponsModal {..._props} />
case PROPS_SETTING_TYPES.marketingCardHeader:
return <MarketingCardHeader {..._props} />
case PROPS_SETTING_TYPES.marketingCardCoupon:
return <MarketingCardCoupon />
case PROPS_SETTING_TYPES.marketingCardGood:
case PROPS_SETTING_TYPES.marketingCardDetailItem:
const _parentKey: any = parentKey;
const _type = pageConfig?.[_parentKey]?.props?.type;
const _exType = pageConfig?.[_parentKey]?.props?.exType;
return <MarketingCardGood {..._props} actType={_type} exType={_exType} pageConfig={pageConfig} />
case PROPS_SETTING_TYPES.bottomNavigationItems:
return <BottomNavigationClient {..._props} />
default:
return null
}
......
import { PROPS_SETTING_TYPES, PageConfigType } from '@lingxi-disign/core'
import categoryNavTemplateDefault from './img/category_template_default.png'
import RED_PACKAGE from './img/red_package.png';
export const defaultConfig: PageConfigType = {
export const mallLayoutConfig : PageConfigType = {
'0': {
componentName: 'MallLayout',
props: {
......@@ -13,7 +14,7 @@ export const defaultConfig: PageConfigType = {
"paddingBottom": "50px",
}
},
childNodes: ['1', '2', '4', '6']
childNodes: ['1', '2', '4']
},
'1': {
componentName: 'MobileShopHeader',
......@@ -80,6 +81,9 @@ export const defaultConfig: PageConfigType = {
isnull: false,
},
},
}
export const defaultConfig: PageConfigType = {
'6': {
componentName: 'MobileShopCommodity',
title: '推荐商品',
......@@ -100,135 +104,50 @@ export const defaultConfig: PageConfigType = {
dataList: '${item.dataList}',
num: '${item.num}',
},
}
}
export const mallLayoutConfig = {
key: "0",
"0": {
"componentName": "MallLayout",
"props": {
"style": {
"width": "100%",
"minHeight": "100%",
"background": "#F7F8FA",
"overflowX": "hidden",
"paddingBottom": "50px",
}
},
"childNodes": ["1", "2", "5"]
},
}
export const mobileShopHeaderNav = {
key: "1",
"1": {
"componentName": "MobileShopHeaderNav",
"componentType": PROPS_SETTING_TYPES.mobileShopHeaderNav,
"title": "背景图编辑",
"canEdit": true,
"canHide": false,
"props": {},
}
}
export const divWrap = {
key: "2",
"2": {
"componentName": "div",
"props": {
"style": {
position: "relative",
marginTop: -24,
backgroundColor: "#FFF",
borderTopLeftRadius: '16px',
borderTopRightRadius: '16px',
zIndex: 6,
padding: '2px 4px',
}
'8': {
title: '优惠券弹窗',
componentName: 'CouponsModal',
props: {
style: {
display: "none",
position: 'absolute',
backgroundImage: `url(${RED_PACKAGE})`,
width: 312,
height: 425,
top: 0,
left: 0,
bottom: 0,
right: 0,
margin: 'auto',
zIndex: 1,
},
},
"childNodes": ["3", "4"]
}
}
export const mobileBanner = {
key: "3",
"3": {
"componentName": "MobileBanner",
"componentType": PROPS_SETTING_TYPES.mobileBanner,
"title": "轮播广告",
"canEdit": true,
"canHide": false,
"props": {
dataList: []
}
}
}
export const mobileQuickNav = {
key: "4",
"4": {
"componentName": "MobileQuickNav",
"componentType": PROPS_SETTING_TYPES.mobileQuickNav,
"title": "导航模块",
"canEdit": true,
"canHide": false,
"props": {
dataList: [
{
"id":1,
"expand":false,
"icon":"https://shushangyun-lingxi.oss-cn-shenzhen.aliyuncs.com/c5d66f1488cc47d0a73279ce1ef11c991610677462848.png",
"type":1,
"name":"商城",
"url":""
},
{
"id":2,
"expand":false,
"icon":"https://shushangyun-lingxi.oss-cn-shenzhen.aliyuncs.com/9f105bdebcfb4010b5827f7b64fb53281610696444606.png",
"type":2,
"name":"分类",
"url":""
},
{
"id":3,
"expand":false,
"icon":"https://shushangyun-lingxi.oss-cn-shenzhen.aliyuncs.com/d4383c684c6e4707b405f46f281796d71610696469970.png",
"type":3,
"name":"积分兑换",
"url":""
},
{
"id":4,
"expand":false,
"icon":"https://shushangyun-lingxi.oss-cn-shenzhen.aliyuncs.com/d4383c684c6e4707b405f46f281796d71610696469970.png",
"type":4,
"name":"公司介绍",
"url":""
},
{
"id":5,
"expand":false,
"icon":"https://shushangyun-lingxi.oss-cn-shenzhen.aliyuncs.com/441a66ebeb3b45e6a64ecfa9977f411c1610696489991.png",
"type":5,
"name":"成为会员",
"url":""
},
]
}
}
}
export const mobileShopCommodityList = {
key: "5",
"5": {
"componentName": "MobileShopCommodityList",
"componentType": PROPS_SETTING_TYPES.mobileShopCommodity,
"title": "商品推荐",
"canEdit": true,
"canHide": false,
"props": {}
}
childNodes: [],
childComponentName: 'CouponsModal.CouponsItem',
addBtnText: '添加优惠券',
canEdit: true,
canHide: false,
},
// '9': {
// title: '底部标签栏',
// componentName: 'BottomNavigation',
// props: {},
// childNodes: ['10'],
// childComponentName: 'BottomNavigation.Items',
// addBtnText: '添加标签',
// maxLength: 5,
// },
// '10': {
// loop: '${bottom}',
// title: '${item.name}',
// componentName: 'BottomNavigation.Items',
// props: {
// defaultIcon: '${item.defaultIcon}',
// selectIcon: '${item.selectIcon}',
// name: '${item.name}',
// type: '${item.type}',
// isnull: false,
// },
// },
}
......@@ -10,34 +10,6 @@ export interface StatusColorsProps {
color: string,
}
// className映射
const classNameMap = [
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
]
// 订单内部状态显示
const CustomBadge: React.FC<StatusColorsProps> = (props) => {
// const { status, type } = props
......
......@@ -232,22 +232,6 @@ const AddBrand: React.FC<{}> = () => {
>
<Input disabled={banSomeField} placeholder="输入品牌名称" />
</Form.Item>
{/* <Form.Item
label='审核状态'
name="status"
initialValue={1}
style={{display:'none'}}
>
<span className="commonStatusModify"></span>待提交审核
</Form.Item>
<Form.Item
label='是否有效'
name="isEnable"
initialValue={true}
style={{display:'none'}}
>
<span className="commonStatusValid"></span>有效
</Form.Item> */}
<Form.Item
name="logoUrl"
label={<span>品牌LOGO&nbsp;&nbsp;</span>}
......@@ -261,19 +245,6 @@ const AddBrand: React.FC<{}> = () => {
]}
className={styles.uploadForm}
>
{/* <Upload
disabled={banSomeField}
name="file"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
action="/api/file/file/upload"
beforeUpload={beforeLogoUpload}
onChange={handleUploadLogoChange}
data={{ fileType: UPLOAD_TYPE }}
>
{logoUrl ? <img src={logoUrl} alt="avatar" style={{ width: 102, height: 102, objectFit: 'cover' }} /> : uploadLogoButton}
</Upload> */}
<UploadImage
disabled={banSomeField}
listType="picture-card"
......@@ -297,19 +268,6 @@ const AddBrand: React.FC<{}> = () => {
name="proveUrl"
// valuePropName="fileList"
>
{/* <Upload
name="file"
listType="picture-card"
className="avatar-uploader"
action="/api/file/file/upload"
fileList={fileList}
beforeUpload={beforeUpload}
onChange={handleChange}
data={{ fileType: UPLOAD_TYPE }}
showUploadList={{ showPreviewIcon: false }}
>
{fileList.length >= 20 ? null : uploadButton}
</Upload> */}
<UploadImage
listType="picture-card"
fileList={fileList}
......
import React, { ReactNode, useRef, useEffect, useMemo } from 'react'
import { history } from 'umi'
import { Button, Popconfirm, Card, message, Dropdown, Menu, Modal, Space } from 'antd'
import { Button, Popconfirm, Card, message, Dropdown, Menu, Modal, Space, Badge } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
PlusOutlined,
......@@ -20,6 +20,7 @@ import { FORM_FILTER_PATH } from '@/formSchema/const'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import Submit from '@/components/NiceForm/components/Submit'
import useSetSearchValueInTable from '@/hooks/useSetSearchValueInTable'
import { productStatusColor, productStatusLabel } from '../commodity/products/constant'
const { confirm } = Modal
......@@ -114,18 +115,7 @@ const Trademark: React.FC<{}> = () => {
title: '审核状态',
dataIndex: 'status',
key: 'status',
render: (text: any, record: any) => {
let component: ReactNode = null
if (record.status === 1)
component = (<><span className="commonStatusInvalid"></span>待提交审核</>)
else if (record.status === 2)
component = (<><span className="commonStatusModify"></span>待审核</>)
else if (record.status === 3)
component = (<><span className="commonStatusStop"></span>审核不通过</>)
else if (record.status === 4)
component = (<><span className="commonStatusValid"></span>审核通过</>)
return component
}
render: (t) => <Badge color={productStatusColor[t]} text={productStatusLabel[t]} />
},
{
title: '操作',
......
This diff is collapsed.
......@@ -26,7 +26,11 @@ export const useOrderDetail = (options: OrderDetailHookProps) => {
const { orderNo } = history.location.query
const { type } = options
const dataRef = useRef<any>([
{ label: '对应报价单号', name: 'quoteNo', span: 8, render: text => <Link to={'/'}>{text}</Link> },
{ label: '对应报价单号', name: 'quoteNo', span: 8, render: (text, record) => <Link
to={type[0] === 's' ? `/memberCenter/tranactionAbility/inquiryOffer/offerSearch/offer/preview?id=${record?.quoteId}` : `/memberCenter/tranactionAbility/confirmOffer/offerSearch/offer/preview?id=${record?.quoteId}`}>
{text}
</Link>
},
{ label: '订单摘要', name: 'digest', span: 8 },
{ label: type[0] === 's' ? '采购会员' : '供应会员', name: type[0] === 's' ? 'buyerMemberName' : 'vendorMemberName', span: 8 },
{ label: '下单模式', name: 'orderModeName', span: 8 },
......
......@@ -4,7 +4,7 @@ import { Popover, Row, Space } from 'antd'
export const AddressPop = (props) => {
const { pickInfo = null, children } = props
return pickInfo && pickInfo.deliverType === 2 ? <Space>
return pickInfo && pickInfo.deliveryType === 2 ? <Space>
<EnvironmentOutlined style={{marginRight: 8}}/>
<Popover content={
<Row>
......
......@@ -18,7 +18,8 @@ export const useProductTable = (ctx: ISchemaFormActions | ISchemaFormAsyncAction
const handleSave = row => {
return new Promise((resolve, reject) => {
const newData = [...ctx.getFieldValue('products')];
const index = newData.findIndex(item => row.productId === item.productId);
// srm订单已productId为唯一key b2b订单以skuId为唯一
const index = newData.findIndex(item => row.skuId ? row.skuId === item.skuId : row.productId === item.productId);
const item = newData[index];
newData.splice(index, 1, {
...item,
......
......@@ -24,12 +24,14 @@ const OrderPayTabs:React.FC<OrderPayTabsProps> = () => {
// 简单流程为24
const processEnum = data.processEnum
const payments = data.payments.sort((a, b) => a.batchNo - b.batchNo)
useEffect(() => {
// 过滤支付信息 取第一个待支付或者未到账的id
if(data?.payments?.length) {
let payments = data.payments.sort((a, b) => a.batchNo - b.batchNo).filter(item => item.showPayment)
if(payments.length) {
ctl.setPayId(payments[0].paymentId)
if(payments.length) {
let payment = payments.filter(item => item.showPayment)
if(payment.length) {
ctl.setPayId(payment[0].paymentId)
}
}
}, [])
......@@ -61,7 +63,7 @@ const OrderPayTabs:React.FC<OrderPayTabsProps> = () => {
// const canCtlData = data.payments.find(v => v.showView) || {} //@todo 需后端提供showView字段支持
const canCtlData = data.payments.find(v => v.vouchers.length) || {}
const canCtlData = payments.find(v => v.vouchers.length) || {}
const urlsDatas = canCtlData.vouchers || []
return (
......@@ -71,9 +73,9 @@ const OrderPayTabs:React.FC<OrderPayTabsProps> = () => {
<MellowCard bordered={false} fullHeight>
<Tabs defaultActiveKey='1'>
{
data.payments.length
payments.length
?
data.payments.map(v => <TabPane key={v.paymentId} tab={<TabHeader dataSource={v}/>}>
payments.map(v => <TabPane key={v.paymentId} tab={<TabHeader dataSource={v}/>}>
<Row>
<Col className={style.fontGray} span={4}>支付环节: </Col>
<Col>{v.payNode}</Col>
......
......@@ -47,18 +47,12 @@ const InquiryModalTable:React.FC<InquiryModalTableProps> = (props) => {
id: item.inquiryListId
})
// 将询价报价单的id字段 冗余给商品列表
// schemaAction.setFieldValue('orderProductRequests', data.map((v: any) => {
// v.memberId = item.offerMemberId
// v.memberRoleId = item.offerMemberRoleId
// return v
// }))
let newData = data.map((v: any) => {
v.memberId = item.offerMemberId
v.memberRoleId = item.offerMemberRoleId
return v
})
// 把地址信息冗余给商品字段render
schemaAction.setFieldValue('products', await filterProductDataById([], newData))
schemaAction.setFieldValue('vendorMemberName', item.offerMemberName)
schemaAction.setFieldValue('vendorMemberId', item.offerMemberId)
......
......@@ -87,13 +87,13 @@ export const filterProductDataById = (data, targetData) => {
const { code, data } = await PublicApi.getLogisticsShipperAddressGet({
id: logistics.sendAddress
}, { ttl: 60 * 1000, useCache: true })
logistics.render = {...data, deliverType: logistics.deliveryType}
logistics.render = {...data, deliveryType: logistics.deliveryType}
} else {
logistics.render = DELIVERY_TYPE[logistics.deliveryType]
}
// 配送方式外置, 用于接口字段冗余
next.deliverType = logistics.deliveryType
next.deliveryType = logistics.deliveryType
// id 存在集合中, 采用target中的数据, 否则采用data中的数据
const findResult = data.find(v => v.id === next.id)
......
......@@ -59,6 +59,7 @@ export const procurementRenderField = (data) => {
productId: item.skuId,
productName: item.name,
logistics: item.deliverType,
deliveryType: item.deliverType,
unitPrice: item.price,
purchaseCount: item.quantity,
taxInclusive: item.tax,
......@@ -351,11 +352,10 @@ export const productInfoColumns: any[] = [
// 接口调用
{
title: '配送方式',
dataIndex: 'deliverType',
dataIndex: 'deliveryType',
align: 'center',
key: 'deliverType',
key: 'deliveryType',
render: (t, r) => {
console.log(r, 'rr')
if(t === 1)
return "物流(默认)"
else if(t === 2)
......
......@@ -81,9 +81,9 @@ export const useProductTableChangeForPay = (ctx: ISchemaFormActions | ISchemaFor
if (value && value.length > 0 && !state.loading){ // 添加loading判断避免二次调用
// 请求一次并复制给支付信息
const productItem = value[0]
// if(pageStatus === PageStatus.EDIT) { // 编辑下 支付信息联动实现
if(pageStatus === PageStatus.EDIT) { // 编辑下 支付信息联动实现
// } else if(pageStatus === PageStatus.ADD) { // 新增下 需要支付信息生成支付次数
} else if(pageStatus === PageStatus.ADD) { // 新增下 需要支付信息生成支付次数
const shopId = ctx.getFieldValue('shopId')
const products = value.map(item => ({ productId: item.commodityId, skuId: item.productId }))
if(shopId && products?.length) {
......@@ -108,7 +108,7 @@ export const useProductTableChangeForPay = (ctx: ISchemaFormActions | ISchemaFor
})
}
// }
}
}
// 确认后 需根据商品id请求会员折扣接口, 以及配送方式
......
......@@ -22,7 +22,6 @@ import { useProductTable } from './model/useProductTable'
import styled from 'styled-components'
import { useUpdate } from '@umijs/hooks'
import { PublicApi } from '@/services/api'
import { formatTimeString } from '@/utils'
import { changeRouterTitleByStatus } from '../../_public/order/utils'
import { ReadyAddOrderDetailContext } from '../context'
import { help } from '../../common'
......@@ -138,7 +137,6 @@ const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
// 订单商品
const { productAddButton, productRef, productColumns, productComponents, ...sectionProps } = useProductTable(addSchemaAction)
let timerSignature = null
// 页面进入时, 当前所处的下单模式
useEffect(() => {
if (id) {
......@@ -161,11 +159,6 @@ const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
shopDataRef.current.orderMode = parseInt(modelType)
}
return () => {
clearInterval(timerSignature)
timerSignature = null
}
}, [])
const handleSubmit = async (value) => {
......@@ -218,7 +211,7 @@ const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
setBtnLoading(true)
/** 字段转换 */
// 合同下单 取供应商默认的发货地址
// 取供应商默认的发货地址
const { data: deliveryAddress} = await PublicApi.getLogisticsSelectListMemberShipperAddress({
memberId: params.vendorMemberId,
roleId: params.vendorRoleId
......@@ -282,8 +275,6 @@ const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
}
}
const _params = procurementProcessField(params)
const shops = addSchemaAction.getFieldState('shopId').props.enum || []
......@@ -292,8 +283,6 @@ const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
params.shopEnvironment = shop['environment']
params.shopName = shop['label']
console.log(_params)
if(id) {
fnResult = await PublicApi.postOrderBuyerCreateB2bUpdate({..._params, orderId: id})
} else {
......@@ -411,10 +400,8 @@ const PurchaseOrderDetail:React.FC<PurchaseOrderDetailProps> = (props) => {
<NiceForm
loading={formLoading}
previewPlaceholder=' '
// editable={pageStatus !== PageStatus.PREVIEW}
value={initFormValue}
actions={addSchemaAction}
// schema={mergeAllSchemas[page_type]}
schema={initFormSchema}
onSubmit={handleSubmit}
components={{
......
......@@ -23,46 +23,7 @@ export const sortByKey = (params) => {
export const getUnitPriceTotal = (record) => {
const purchaseCount = Number(record['purchaseCount']) || 0
// fix 当没有传递unitPrice字段时 自动容错, 单价显示为0
// fix 编辑订单取price
record.unitPrice = pageStatus === PageStatus.EDIT ? record.price : record.unitPrice || record.price || 0
if (typeof record.unitPrice === 'number') {
return record.isMemberPrice ?
Number((record.unitPrice * purchaseCount * record.memberPrice).toFixed(2))
:
Number((record.unitPrice * purchaseCount).toFixed(2))
}
if(record.unitPrice) {
record.unitPrice = sortByKey(record.unitPrice)
}
// fix 当没有传递unitPrice字段时 但有price字段时 补全unitPrice字段
if(record.price && JSON.stringify(record.unitPrice) === "{}") {
record.unitPrice = {'0-0': record.price}
}
// fix 当有unitPrice字段时 没有price字段时 补全price字段
if(!record?.price && JSON.stringify(record.unitPrice) !== "{}") {
if(Object.keys(record.unitPrice)[0] === '0-0') record.price = record.unitPrice['0-0']
}
let unitPrice = 0
Object.entries(record.unitPrice).forEach(([key, value]) => {
const [min, max] = key.split('-').map(v => Number(v))
if (min === 0 && max === 0) {
unitPrice = Number(value)
return false
}
if ((purchaseCount >= min && purchaseCount <= max) || (purchaseCount > max)) {
// 处于该区间或者大于该区间
unitPrice = Number(value)
return false
}
})
// 考虑会员折扣
let memberPrice = record.memberPrice
if(record.isMemberPrice) {
return Number((unitPrice * purchaseCount * memberPrice).toFixed(2))
} else {
return Number((unitPrice * purchaseCount).toFixed(2))
}
return Number((record.price * purchaseCount).toFixed(2))
}
/**
......@@ -150,11 +111,10 @@ export const useProductTable = (ctx: ISchemaFormActions | ISchemaFormAsyncAction
}
return new Promise((resolve, reject) => {
const newData = [...ctx.getFieldValue('products')];
const index = newData.findIndex(item => row.id === item.id);
console.log(newData, row)
const index = newData.findIndex(item => row.productId === item.productId);
const item = newData[index];
row['money'] = getUnitPriceTotal(row)
// 通过下单模式判断 是否是手工或者渠道手工下单
let addModel = ctx.getFieldValue("orderMode")
row['productId'] = row.productId
newData.splice(index, 1, {
...item,
......
......@@ -231,7 +231,6 @@ export const payInfo: ISchema = {
}
}
// 交付信息
const submitInfo: ISchema = {
"x-index": 1,
......@@ -249,7 +248,7 @@ const submitInfo: ISchema = {
labelAlign: 'left',
grid: true,
columns: 2,
full: true
// full: true
},
properties: {
FLEX_LAYOUT_LEFT: {
......@@ -264,7 +263,8 @@ const submitInfo: ISchema = {
"x-component-props": {
disabledDate: current => {
return current && current < moment().startOf('day')
}
},
style: { width: 400 }
}
},
}
......@@ -272,11 +272,11 @@ const submitInfo: ISchema = {
deliveryAddresId: {
type: 'string',
"x-component": 'SelectAddress',
"x-mega-props": {
style: {
full: true
}
},
// "x-mega-props": {
// style: {
// full: true
// }
// },
"x-component-props": {
dataSource: [],
times: 0,
......
......@@ -29,6 +29,7 @@ import * as EnhanceV2Api from './EnhanceV2Api';
import * as MessageV2 from './MessageV2Api';
import * as LogiticsV2 from './LogiticsV2Api';
import * as MarketingApi from './MarketingApi';
import * as MaketingV2Api from './MaketingV2Api'
import * as AfterServiceV2Api from './AfterServiceV2Api';
......@@ -72,5 +73,6 @@ export const PublicApi = {
...MessageV2,
...LogiticsV2,
...MarketingApi,
...MaketingV2Api,
...AfterServiceV2Api,
}
......@@ -43,8 +43,8 @@ class ProductStore implements IProductModule {
slogan: this.productInfoByEdit?.slogan,
sellingPoint: this.productInfoByEdit?.sellingPoint,
commodityAreaList: this.productInfoByEdit?.commodityAreaList.map(item => [item.provinceCode, item.cityCode]),
customerCategoryId: this.productInfoByEdit?.customerCategory.fullId.split('.').map(item => Number(item) + '')
// customerCategoryId: this.productInfoByEdit?.customerCategory.parentId ? [this.productInfoByEdit?.customerCategory.parentId + '', this.productInfoByEdit?.customerCategory.id + ''] : [this.productInfoByEdit?.customerCategory.id + '']
customerCategoryId: this.productInfoByEdit?.customerCategory.fullId.split('.').map(item => Number(item) + ''),
customerCategoryName: this.productInfoByEdit?.customerCategory.fullName
}
}
......
......@@ -31,6 +31,7 @@ const tokenList = [
{ name: 'MessageV2', token: '69a667ec9861e8bdc25b89238d0b908a2123d9fce26e72fec3cdf6cd0b1f2681', categoryIds: [0], }, // 消息中心v2
{ name: 'LogiticsV2', token: '732fb8e33970ff5dee830423a630e8e85c3ef3293abba7581b16749dfce8608b', categoryIds: [0], }, // 物流能力v2
{ name: 'Marketing', token: 'd952d25c4e8272a6dff69245dbddf983dc886521e2623464e476922fc95f43af', categoryIds: [0], }, // 营销能力
{ name: 'MaketingV2', token: 'f6d5cee2383ca203dfa2882b84dfa02a1d79de3c3ad892b42f030437fdc5ea21', categoryIds: [0] }, // 营销活动v2
{ name: 'AfterServiceV2', token: '58748fc89dcdb33ec5cac520c00293ba92abca362a8ddb979df589effd0db9bd', categoryIds: [0], }, // 售后能力V2
]
......
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