Commit 597a7d33 authored by GuanHua's avatar GuanHua

feat:发票接口对接和分类跳转

parent 99a99d6b
......@@ -241,22 +241,26 @@ const CommodityDetail = (props) => {
logistics: commodityDetail.logistics,
name: commodityDetail.name,
priceRange: commodityPriceInfo,
memberDiscount: parameter,
commodityPic: attrAndValList.commodityPic[0],
attribute: attrAndValList.attributeAndValueList
}
let buyOrderInfo = {
logistics: commodityDetail.logistics,
payWayList,
supplyMembersId: commodityDetail.memberId,
orderList: [{
id: shopInfo.id,
shopname: shopInfo.company,
orderList: [buyCommodityInfo]
}]
}
console.log(buyOrderInfo, "buyOrderInfo")
updateOrderInfo(buyOrderInfo).then(() => {
history.push(`/order?id=${selectCommodityId}&scence=prompt`)
})
clickFlag = true
} else {
}
}).catch(() => {
clickFlag = true
......
......@@ -49,6 +49,17 @@ const Category: React.FC<CategoryPropsType> = (props) => {
}, [props, mallTemplateId])
const getNavLink = (item) => {
switch (type) {
case LAYOUT_TYPE.shop:
return `/shop/commodity?categoryId=${item.id}&categoryName=${btoa(encodeURIComponent(item.title))}&shopId=${shopUrlParam}`
case LAYOUT_TYPE.channel:
return `/channelmall/commodity?categoryId=${item.id}&categoryName=${btoa(encodeURIComponent(item.title))}&id=${shopUrlParam}`
default:
return `/commodity?categoryId=${item.id}&categoryName=${btoa(encodeURIComponent(item.title))}`
}
}
return (
<div className={styles.category}>
<div className={styles.category_type}>
......@@ -65,7 +76,7 @@ const Category: React.FC<CategoryPropsType> = (props) => {
<div className={styles.sub_category}>
{
item.children.map((childCategory, childIndex) => childIndex < 3 && (
<Link to={`/commodity`} key={childCategory.id}>{childCategory.title}</Link>
<Link to={getNavLink(childCategory)} key={childCategory.id}>{childCategory.title}</Link>
))
}
</div>
......@@ -77,14 +88,14 @@ const Category: React.FC<CategoryPropsType> = (props) => {
item.children.map(childCategory => (
<div className={styles.second_category_type} key={childCategory.id}>
<div className={styles.title}>
<Link to={`/commodity`}>
<Link to={getNavLink(childCategory)}>
{childCategory.title} <RightOutlined />
</Link>
</div>
<ul className={styles.third_category_type_list}>
{
childCategory.children.map(thirdChildItem => (
<li key={thirdChildItem.id}><Link to={`/commodity`}>{thirdChildItem.title}</Link></li>
<li key={thirdChildItem.id}><Link to={getNavLink(thirdChildItem)}>{thirdChildItem.title}</Link></li>
))
}
</ul>
......
......@@ -105,28 +105,4 @@
}
}
}
}
.mallComfirm {
position: relative;
:global {
.ant-modal-confirm-btns {
.ant-btn {
&:hover {
color: var(--mall_main_color);
border-color: var(--mall_main_color);
}
}
.ant-btn-primary {
background-color: var(--mall_main_color);
border-color: var(--mall_main_color);
&:hover {
color: #ffffff;
}
}
}
}
}
\ No newline at end of file
......@@ -6,7 +6,12 @@ import { PublicApi } from '@/services/api'
import { GetLogisticsReceiverAddressPageResponseDetail, GetLogisticsReceiverAddressGetResponse } from '@/services/LogisticsApi'
import styles from './index.less'
const Address: React.FC = () => {
interface AddressPropsType {
onChange: Function
}
const Address: React.FC<AddressPropsType> = (props) => {
const { onChange } = props
const [selectKey, setSelectKey] = useState<number>()
const [expand, setExpand] = useState<boolean>(false)
const [addressFormVisible, setAddressFormVisible] = useState<boolean>(false)
......@@ -34,18 +39,32 @@ const Address: React.FC = () => {
})
}
const initDefaultAddress = (addressList: GetLogisticsReceiverAddressPageResponseDetail[]) => {
let defaultAddrKey
const initDefaultAddress = async (addressList: GetLogisticsReceiverAddressPageResponseDetail[]) => {
let selectItem
for (let item of addressList) {
if (item.isDefault === 1) {
defaultAddrKey = item.id
selectItem = item
}
}
defaultAddrKey && setSelectKey(defaultAddrKey)
if (selectItem) {
setSelectKey(selectItem.id)
let res = await PublicApi.getLogisticsReceiverAddressGet({ id: selectItem.id })
onChange(res.data)
}
}
const handleSelect = (e: any) => {
const handleSelect = async (e: any) => {
setSelectKey(e.target.value)
let selectItem
for (let item of addressList) {
if (item.id === e.target.value) {
selectItem = item
}
}
if (selectItem) {
let res = await PublicApi.getLogisticsReceiverAddressGet({ id: selectItem.id })
onChange(res.data)
}
}
/**
......@@ -55,6 +74,7 @@ const Address: React.FC = () => {
Modal.confirm({
className: styles.mallComfirm,
content: "是否确认删除该收货地址",
centered: true,
onOk: () => {
return new Promise((resolve, reject) => {
PublicApi.postLogisticsReceiverAddressDelete({ id }).then(res => {
......@@ -81,7 +101,6 @@ const Address: React.FC = () => {
fetchAddressList()
}
})
}
return (
......
......@@ -77,4 +77,28 @@
transition: all .2s;
}
}
}
.mallComfirm {
position: relative;
:global {
.ant-modal-confirm-btns {
.ant-btn {
&:hover {
color: var(--mall_main_color);
border-color: var(--mall_main_color);
}
}
.ant-btn-primary {
background-color: var(--mall_main_color);
border-color: var(--mall_main_color);
&:hover {
color: #ffffff;
}
}
}
}
}
\ No newline at end of file
......@@ -94,11 +94,7 @@ const AddAddress: React.FC<AddAddressPropsType> = (props) => {
{ label: <><img src={us} key='5' style={{ width: _width, height: _height }} /> +86</>, value: '5' }
]
let _Options: any = [], TelCodeList: any = []
/**
* @description: formilyjs表单赋值方法 actions.setFieldState(key,state=> {state.value= **})
* @param {type}
* @return:
*/
useEffect(() => {
PublicApi.getManageGetTelCode().then(res => {
......
......@@ -6,9 +6,12 @@ import {
createFormActions,
FormEffectHooks,
FormPath,
createAsyncFormActions,
} from '@formily/antd'
import { Input, Switch, Select, FormMegaLayout, Radio } from '@formily/antd-components'
import styles from './index.less'
import { PublicApi } from '@/services/api'
import { postSettleAccountsInvoiceMessageUpdate } from '@/services/SettlementApi'
//列表带来的参数
export interface ListProps {
......@@ -23,14 +26,17 @@ interface AddAddressPropsType {
onOk?: any;
onCancel?: any;
title?: string;
editItem?: any;
type: 'add' | 'edit'
}
const actions = createFormActions()
const { onFieldValueChange$ } = FormEffectHooks
const actions = createAsyncFormActions()
const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
const { visible = false, title, onOk, onCancel } = props
const { visible = false, title, onOk, onCancel, editItem, type } = props
const [state, setState] = useState({ editable: true })
const [confirmLoading, setConfirmLoading] = useState<boolean>(false)
/**
* @description: Form保存
......@@ -38,7 +44,25 @@ const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
* @return:
*/
const formSubmit = (values) => {
console.log(values)
values.isDefault ? values.isDefault = 1 : values.isDefault = 0
setConfirmLoading(true)
let postLogisticsFn
if (type === 'edit') {
values.id = editItem.id
postLogisticsFn = PublicApi.postSettleAccountsInvoiceMessageUpdate
} else {
postLogisticsFn = PublicApi.postSettleAccountsInvoiceMessageAdd
}
postLogisticsFn(values).then(res => {
if (res.code === 1000) {
onOk()
}
setConfirmLoading(false)
}).catch(() => {
setConfirmLoading(false)
})
}
const handleOk = () => {
......@@ -52,15 +76,16 @@ const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
onOk={handleOk}
width={600}
centered
confirmLoading={confirmLoading}
className={styles.common_add_modal}
onCancel={onCancel}
maskClosable={false}
>
<SchemaForm editable={state.editable}
actions={actions} // 要传递
initialValues={{
Radio2: '1',
fapiao: '1'
initialValues={type === 'edit' ? editItem : {
type: 1,
kind: 1
}}
components={{
Input, Select, TextArea: Input.TextArea, Switch,
......@@ -73,21 +98,21 @@ const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
<Field
required
title="开具类型"
name="Radio2"
name="type"
x-component="RadioGroup"
enum={[
{ label: '企业(默认)', value: '1' },
{ label: '个人', value: '2' },
{ label: '企业', value: 1 },
{ label: '个人', value: 2 },
]}
/>
<Field
required
title="发票种类"
name="fapiao"
name="kind"
x-component="RadioGroup"
enum={[
{ label: '增值税普通发票(默认)', value: '1' },
{ label: '增值税专用发票', value: '2' },
{ label: '增值税普通发票', value: 1 },
{ label: '增值税专用发票', value: 2 },
]}
/>
<Field
......@@ -96,7 +121,7 @@ const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
message: '请输入发票抬头',
}}
title="发票抬头"
name="receiverName"
name="invoiceTitle"
maxLength={40}
x-component="Input"
x-component-props={{
......@@ -109,7 +134,7 @@ const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
message: '请输入纳税号',
}}
title="纳税号"
name="receiverName2"
name="taxNo"
maxLength={40}
x-component="Input"
x-component-props={{
......@@ -118,25 +143,25 @@ const AddInvoice: React.FC<AddAddressPropsType> = (props) => {
/>
<Field
title="开户行"
name="receiverName3"
name="bankOfDeposit"
maxLength={40}
x-component="Input"
/>
<Field
title="账号"
name="receiverName4"
name="account"
maxLength={40}
x-component="Input"
/>
<Field
title="地址"
name="receiverName5"
name="addres"
maxLength={40}
x-component="Input"
/>
<Field
title="电话号码"
name="receiverName6"
name="tel"
maxLength={40}
x-component="Input"
/>
......
......@@ -3,8 +3,14 @@ import { Tooltip, Checkbox } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import styles from './index.less'
const Contract: React.FC = () => {
interface ContractPropsType {
state: boolean;
onChange: Function;
}
const Contract: React.FC<ContractPropsType> = (props) => {
const { state, onChange } = props
return (
<div className={styles.contract}>
<div className={styles.common_title}>
......@@ -14,7 +20,7 @@ const Contract: React.FC = () => {
</Tooltip>
</div>
<div className={styles.checkbox}>
<Checkbox>
<Checkbox checked={state} onChange={(e) => onChange(e.target.checked)}>
<span>我同意签订:</span>
</Checkbox>
<span className={styles.checkbox_contract_text}> 《广州白马皮具交易中心商品购销合同.pdf》</span>
......
......@@ -13,6 +13,9 @@ import Contract from './contract'
import Invoice from './invoice'
import styles from './index.less'
import { PublicApi } from '@/services/api'
import moment from 'moment'
import { GetLogisticsReceiverAddressGetResponse } from '@/services/LogisticsApi'
import { isEmpty } from 'lodash'
const Logistics_Type = {
1: '物流',
......@@ -28,9 +31,13 @@ const Order: React.FC<OrderPropsType> = (props) => {
const OrderStore = useLocalStore(() => store.OrderStore)
const { orderInfo, clearOrderInfo } = OrderStore
const [confirmLoading, setConfirmLoading] = useState(false)
const [selectPayWay, setSelectPayWay] = useState()
const [selectPayWay, setSelectPayWay] = useState<any>({})
const [spinningState, setSpinningState] = useState<boolean>(true)
const [orderList, setOrderList] = useState<any>()
const [needTheInvoice, setNeedTheInvoice] = useState<boolean>(false)
const [needTheContract, setneedTheContract] = useState<boolean>(false)
const [selectAddressInfo, setSelectAddressInfo] = useState<GetLogisticsReceiverAddressGetResponse>()
const [selectInvoiceInfo, setSelectInvoiceInfo] = useState<any>()
useEffect(() => {
if (!orderInfo) {
......@@ -104,7 +111,6 @@ const Order: React.FC<OrderPropsType> = (props) => {
amount += (orderItem.unitPrice * orderItem.count)
}
}
return amount
}
......@@ -121,7 +127,60 @@ const Order: React.FC<OrderPropsType> = (props) => {
* 提交订单
*/
const submitOrder = () => {
if (isEmpty(selectPayWay)) {
message.error('请选择支付方式')
return
}
let params: any = {
orderModel: 5, // 下单模式
deliveryAddresId: selectAddressInfo.id,
addresName: selectAddressInfo.receiverName,
isDefault: selectAddressInfo.isDefault,
province: selectAddressInfo.provinceName,
city: selectAddressInfo.cityName,
area: selectAddressInfo.districtName,
addres: selectAddressInfo.address,
tel: selectAddressInfo.phone,
needTheInvoice: needTheInvoice ? 1 : 0,
}
let orderProductRequests = []
for (let item of orderList) {
for (let orderItem of item.orderList) {
let temp: any = {}
temp.productId = orderItem.id
temp.productName = orderItem.name
temp.unit = orderItem.unitName
temp.price = orderItem.unitPrice
temp.purchaseCount = orderItem.count
temp.memberDiscount = orderItem.memberDiscount
orderProductRequests.push(temp)
}
}
params.supplyMembersId = orderInfo.supplyMembersId
params.deliveryType = orderInfo.logistics.deliveryType
params.orderProductRequests = orderProductRequests
params.paymentInformationResponses = [{
payPrice: 1,
payWay: selectPayWay.payType,
channel: selectPayWay.id
}]
if (needTheInvoice) {
params.theInvoiceId = selectInvoiceInfo.id
}
setConfirmLoading(true)
PublicApi.postOrderProcurementOrderAdd(params).then(res => {
if (res.code === 1000) {
const data = res.data
if (data.isPay === 1) {
history.push(`/pay?orderId=${data.orderId}`)
} else {
}
}
setConfirmLoading(false)
}).catch(() => {
setConfirmLoading(false)
})
}
return orderInfo && (
......@@ -129,11 +188,18 @@ const Order: React.FC<OrderPropsType> = (props) => {
<div className={styles.order}>
<CommonHeader title="订单结算" />
<div className={styles.order_container}>
<Address />
{
orderInfo.logistics.deliveryType === 1 && (
<Address onChange={(selectItem) => {
console.log(selectItem, "selectItem")
setSelectAddressInfo(selectItem)
}} />
)
}
<PayWay selectItem={selectPayWay} payWayList={orderInfo.payWayList} onChange={(val) => setSelectPayWay(val)} />
{/* <Delivery /> */}
< Invoice />
<Contract />
<Invoice state={needTheInvoice} onChange={(val) => setNeedTheInvoice(val)} onSelect={(val) => setSelectInvoiceInfo(val)} />
<Contract state={needTheContract} onChange={(val) => setneedTheContract(val)} />
<div className={styles.common_title}>
<span>订单信息</span>
</div>
......@@ -189,7 +255,6 @@ const Order: React.FC<OrderPropsType> = (props) => {
</div>
))
}
<div className={styles.settlement_box}>
<div className={styles.settlement_box_item}>
<div className={styles.settlement_box_item_price}>
......@@ -207,7 +272,7 @@ const Order: React.FC<OrderPropsType> = (props) => {
<b className={styles.settlement_box_item_price_total}>{getAmount()}</b>
<span>RMB</span>
</div>
<Button loading={confirmLoading} className={styles.settlement_box_item_btn}>提交订单</Button>
<Button loading={confirmLoading} className={styles.settlement_box_item_btn} onClick={() => submitOrder()}>提交订单</Button>
</div>
</div>
</div>
......
import React, { useState, useEffect } from 'react'
import { Checkbox, Radio } from 'antd'
import { Checkbox, Radio, Modal } from 'antd'
import AddInvoice from '../components/addInvoice'
import { PublicApi } from '@/services/api'
import { getAuth } from '@/utils/auth';
import { GetSettleAccountsInvoiceMessageListResponse } from '@/services/SettlementApi'
import cx from 'classnames'
import styles from './index.less'
const Invoice: React.FC = () => {
interface InvoicePropsType {
state: boolean;
onChange: Function;
onSelect: Function;
}
const Invoice: React.FC<InvoicePropsType> = (props) => {
const { state, onChange, onSelect } = props
const [selectKey, setSelectKey] = useState<number>()
const [invoiceFormVisible, setInvoiceFormVisible] = useState<boolean>(false)
const MockData = [
{
id: 1,
type: 1,
name: '温州市龙昌皮业有限公司',
userType: 1,
isDefault: 1
},
{
id: 2,
type: 2,
name: '温州市龙昌皮业有限公司',
userType: 1,
isDefault: 0
},
{
id: 3,
type: 2,
name: '温州市龙昌皮业有限公司',
userType: 1,
isDefault: 0
}
]
const [invoiceList, setInvoiceList] = useState<GetSettleAccountsInvoiceMessageListResponse>([])
const [editItem, setEditItem] = useState<any>()
const [type, setType] = useState<'add' | 'edit'>('add')
useEffect(() => {
fetchInvoiceList(true)
}, [])
const fetchInvoiceList = () => {
const fetchInvoiceList = (init = false) => {
const { memberId } = getAuth() || {}
//@ts-ignore
PublicApi.getSettleAccountsInvoiceMessageList().then(res => {
if (res.code === 1000) {
setInvoiceList(res.data)
if (init) {
initDefaultInvoice(res.data)
}
}
})
}
const initDefaultInvoice = (data: GetSettleAccountsInvoiceMessageListResponse) => {
let selectItem
for (let item of data) {
if (item.isDefault === 1) {
selectItem = item
}
}
if (selectItem) {
setSelectKey(selectItem.id)
onSelect(selectItem)
}
}
const handleSelect = (e: any) => {
setSelectKey(e.target.value)
let selectItem
for (let item of invoiceList) {
if (item.id === e.target.value) {
selectItem = item
}
}
if (selectItem) {
onSelect(selectItem)
}
}
const handleAddSuccess = () => {
fetchInvoiceList()
setInvoiceFormVisible(false)
setEditItem(null)
}
/**
* 删除发票
*/
const handleDelteInvoice = (id: number) => {
Modal.confirm({
className: styles.mallComfirm,
content: "是否确认删除该发票信息",
centered: true,
onOk: () => {
return new Promise((resolve, reject) => {
PublicApi.postSettleAccountsInvoiceMessageDelete({ id }).then(res => {
if (res.code === 1000) {
resolve()
fetchInvoiceList()
}
}).catch(() => {
reject()
})
})
}
})
}
/**
* 设置为默认
* @param item
*/
const handleSetDefault = (item) => {
let param = item
param.isDefault = 1
//@ts-ignore
PublicApi.postSettleAccountsInvoiceMessageUpdate(param).then(res => {
if (res.code === 1000) {
fetchInvoiceList()
}
})
}
const handleStateChange = (e) => {
onChange(e.target.checked)
}
return (
<div className={styles.invoice}>
<div className={styles.common_title}>
<span>发票信息</span>
<div className={styles.common_title_btn} onClick={() => setInvoiceFormVisible(true)}>新增发票信息</div>
<div className={styles.common_title_btn} onClick={() => {
setInvoiceFormVisible(true)
setType('add')
setEditItem(null)
}}>新增发票信息</div>
</div>
<div className={styles.checkbox}>
<Checkbox>需要发票</Checkbox>
<Checkbox checked={state} onChange={handleStateChange}>需要发票</Checkbox>
</div>
<Radio.Group className={styles.raido_group} value={selectKey} onChange={handleSelect}>
<div className={styles.invoice_list}>
{
MockData.map((item, index) => (
<Radio className={styles.list_radio} value={item.id} key={`address_list_radio_${item.id}`}>
<div className={styles.invoice_list_item} key={`invoice_list_item_${index}`}>
<div className={styles.invoice_list_item_content}>
<div className={cx(styles.invoice_list_item_content_tag, item.type !== 1 ? styles.special : '')}>{item.type === 1 ? '增值税普通发票' : '增值税专用发票'}</div>
<div className={styles.invoice_list_item_content_name}>
<span>{item.name}</span>
<span>(企业)</span>
{
state && (
<Radio.Group className={styles.raido_group} value={selectKey} onChange={handleSelect}>
<div className={styles.invoice_list}>
{
invoiceList.map((item, index) => (
<Radio className={styles.list_radio} value={item.id} key={`address_list_radio_${item.id}`}>
<div className={styles.invoice_list_item} key={`invoice_list_item_${index}`}>
<div className={styles.invoice_list_item_content}>
<div className={cx(styles.invoice_list_item_content_tag, item.kind !== 1 ? styles.special : '')}>{item.kind === 1 ? '增值税普通发票' : '增值税专用发票'}</div>
<div className={styles.invoice_list_item_content_name}>
<span>{item.invoiceTitle}</span>
<span>{item.type === 1 ? '(企业)' : '(个人)'}</span>
{
item.isDefault === 1 ? <div className={styles.default}>默认</div> :
<div className={styles.set_default} onClick={() => handleSetDefault(item)}>设为默认</div>
}
</div>
</div>
{
item.isDefault === 1 ? <div className={styles.default}>默认</div> :
<div className={styles.set_default}>设为默认</div>
selectKey === item.id && (
<div className={styles.invoice_list_item_btn_group}>
<div className={styles.invoice_list_item_btn} onClick={() => {
setEditItem(item)
setType('edit')
setInvoiceFormVisible(true)
}}>编辑</div>
<div className={styles.invoice_list_item_btn} onClick={() => handleDelteInvoice(item.id)}>删除</div>
</div>
)
}
</div>
</div>
{
selectKey === item.id && (
<div className={styles.invoice_list_item_btn_group}>
<div className={styles.invoice_list_item_btn}>编辑</div>
<div className={styles.invoice_list_item_btn}>删除</div>
</div>
)
}
</div>
</Radio>
))
}
</Radio>
))
}
</div>
</Radio.Group>
</div>
</Radio.Group>
)
}
<AddInvoice
title="新增发票信息"
title={type === 'add' ? "新增发票信息" : "编辑发票信息"}
type={type}
editItem={editItem}
visible={invoiceFormVisible}
onOk={() => handleAddSuccess()}
onCancel={() => setInvoiceFormVisible(false)}
/>
</div>
......
......@@ -7,12 +7,13 @@ import * as TemplateApi from './TemplateApi'
import * as PayApi from './PayApi'
import * as SearchApi from './SearchApi'
import * as OrderApi from './OrderApi'
import * as SettlementApi from './SettlementApi'
/**
* 可在这里写入自定义的接口
*/
export const CustomApi = {
}
// 公共的接口,从yapi拉下
......@@ -26,4 +27,5 @@ export const PublicApi = {
...PayApi,
...SearchApi,
...OrderApi,
...SettlementApi,
}
......@@ -115,8 +115,8 @@ class ApiRequest {
// 登录验证
if (res.code === 1101) {
removeAuth()
history.replace(`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`)
// window.location.href = `/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`
// history.replace(`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`)
window.location.replace(`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`)
message.destroy()
message.error(res.message)
return false
......
......@@ -8,6 +8,7 @@ const tokenList = [
{ name: 'Pay', token: '34608cd33222b1650795459d73b8eb0b260eb92cf5e8d1e646f85a4875e36f05' }, // 支付服务
{ name: 'Search', token: 'ca19f532efba91f7773cbfbd526b798c6ac83df670071e97d72c50dca1d53a48' }, // 搜索服务
{ name: 'Order', token: '5de0aaeaac12c8d911d86dada6cd128993e34cd6e13135fa79246aa5979a2bcd' }, //订单服务
{ name: 'Settlement', token: 'd84d311b0cb36383bef68017c9e7e51e4dde933b00d1321b60791f7a3e340021' }, //结算服务
// { name: '', token: 'c0e920f071595a73ba234b6fa6cfe42192d3d740d59f030caa2c7f0f08777d78' } // 商户会员管理服务
]
......
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