Commit 3d3fcb6d authored by GuanHua's avatar GuanHua
parents b22d19ca 80d3df0c
......@@ -31,7 +31,7 @@ const Phone = (props) => {
delay: 1 * 1000
})
const { smsFn, ...componentProps } = schema.getExtendsComponentProps() || {}
const { smsFn, btnSize = 'large', inputSize = 'large', ...componentProps } = schema.getExtendsComponentProps() || {}
const [loading, setLoading] = useState(false)
const [isShowValidate, setIsShowValidate] = useState(false)
......@@ -186,11 +186,12 @@ const Phone = (props) => {
<Input
value={value || ''}
onChange={e => props.mutators.change(e.target.value)}
size={inputSize}
{...componentProps}
/>
</Col>
<Col style={{marginLeft: 8}}>
<Button disabled={isActive} style={{minWidth: 110, marginLeft: 8}} loading={loading} size='large' onClick={handleClickSms}>{text}</Button>
<Button disabled={isActive} style={{minWidth: 110, marginLeft: 8}} loading={loading} size={btnSize} onClick={handleClickSms}>{text}</Button>
</Col>
<Modal
title='滑动验证'
......
import React, { useState, useEffect, useRef } from 'react'
import { useState, useEffect, useRef } from 'react'
import { Select, Input, Row, Button } from 'antd';
import { useDebounceFn } from '@umijs/hooks';
import { ISchemaFieldComponentProps, FormPath, useFormEffects, createFormActions, createAsyncFormActions } from '@formily/antd'
import { ISchemaFieldComponentProps } from '@formily/antd'
import pinyin from 'pinyin'
import { query } from 'express';
const SelectContent = (props) => {
const { handleChange, multiple, confirm, resetField } = props
......
......@@ -189,6 +189,7 @@ export default {
'classAndProperty.class.classSchema.category.name': '对应平台品类',
'classAndProperty.class.classSchema.sort': '品类排序',
'classAndProperty.class.classSchema.sort.placeholder': '请输入品类排序',
'classAndProperty.class.classSchema.sort.placeholder1': '请输入排序数值',
'classAndProperty.propertyValue.syncSchema.attributeGroupName': '属性组名',
'classAndProperty.propertyValue.syncSchema.attributeName': '属性名称',
......
......@@ -181,7 +181,7 @@ export default {
'repositories.schema.repositDetailSchema.goodsName.default' : '暂无',
'repositories.schema.repositDetailSchema.noSUBMIT3' : '当前仓货品库存',
'repositories.schema.repositDetailSchema.inventory' : '分配仓位库存',
'repositories.schema.repositDetailSchema.inventory.message.1' : '仓位库存数值已超出最大限度',
'repositories.schema.repositDetailSchema.inventory.message.1' : '仓位库存数值不超过八位',
'repositories.schema.repositDetailSchema.inventory.message.2' : '仓位库存数值仅限三位小数',
'repositories.schema.repositDetailSchema.inventoryDeductWay' : '库存扣减方式',
'repositories.schema.repositDetailSchema.inventoryDeductWay.1' : '按仓位随机扣减',
......
......@@ -3,7 +3,7 @@ import { history, useIntl } from 'umi'
import { message, Modal, Row, Col, Alert, Upload, Radio } from 'antd'
import { EditOutlined, PlusOutlined } from '@ant-design/icons'
import styles from './index.less'
import { UploadFile } from 'antd/lib/upload/interface';
import { RcFile } from 'antd/lib/upload/interface';
import { UPLOAD_TYPE } from '@/constants'
import ImgCrop from 'antd-img-crop';
......@@ -151,7 +151,13 @@ const ProductImageForm: React.FC<{}> = (props) => {
});
}
const beforeUpload = (file: UploadFile) => {
const beforeUpload = (file: RcFile, fileLen: number) => {
const selectUuid = uploadFileSelectRef.current.uid
// 编辑图片会多占用一张
if(fileLen >= 6 && !selectUuid) {
message.error('最多上次六张图片')
return false
}
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
if (!isJpgOrPng) {
message.error(intl.formatMessage({ id: 'commodity.products.addProductsItem.productImageForm.error.1' }))
......@@ -294,7 +300,7 @@ const ProductImageForm: React.FC<{}> = (props) => {
action="/api/file/file/upload"
listType="picture-card"
fileList={item.commodityPic}
beforeUpload={beforeUpload}
beforeUpload={(f)=>beforeUpload(f, item.commodityPic.length)}
onPreview={handlePreview}
onChange={(files) => handleChange(files, index)}
onDownload={(file) => handlefileEdit(file, index)}
......@@ -303,7 +309,8 @@ const ProductImageForm: React.FC<{}> = (props) => {
className="uploadBox"
headers={{ token }}
>
{item.commodityPic.length >= 6 ? null : uploadButton}
{uploadButton}
{/* {item.commodityPic.length >= 6 ? null : uploadButton} */}
</Upload>
</ImgCrop>
</div>
......@@ -329,7 +336,7 @@ const ProductImageForm: React.FC<{}> = (props) => {
id='uploadEle0'
listType="picture-card"
fileList={commonImageList}
beforeUpload={beforeUpload}
beforeUpload={(f)=>beforeUpload(f, commonImageList.length)}
onPreview={handlePreview}
onChange={(files) => handleChange(files, 0)} //-1
onDownload={(file) => handlefileEdit(file, 0)}
......@@ -338,7 +345,8 @@ const ProductImageForm: React.FC<{}> = (props) => {
className="uploadBox"
headers={{ token }}
>
{commonImageList.length >= 6 ? null : uploadButton}
{uploadButton}
{/* {commonImageList.length >= 6 ? null : uploadButton} */}
</Upload>
</ImgCrop>
</div>
......
......@@ -4,7 +4,6 @@ import { ISchema } from '@formily/antd';
import { Badge } from 'antd';
import { ColumnType } from 'antd/lib/table';
import moment from 'moment';
import React, { ReactNode } from 'react'
/** 商品 渠道商品 快捷修改单价 共用常量 */
......@@ -152,7 +151,6 @@ export const orderlyLadderPrice = (data) => {
/** 校验阶梯价格函数 min参数判断是否校验最小起订 */
export const validatorNumberRange = (rule: any, value: any, callback: any, min?: any) => {
const intl = useIntl();
try {
if (Array.isArray(value)) {
let range = value.map(item => {
......@@ -165,8 +163,9 @@ export const validatorNumberRange = (rule: any, value: any, callback: any, min?:
[]
)
let result = range.map(Number).reduce((a, b) => { if (a < b) return b })
if (!result) throw new Error(intl.formatMessage({ id: 'commodity.products.constant.validatorNumberRange.error.1' }));
if (min && (Number(range[0]) !== Number(min))) throw new Error(intl.formatMessage({ id: 'commodity.products.constant.validatorNumberRange.error.2' }));
console.log(result, 'result', range)
if (!result) throw new Error(getIntl().formatMessage({ id: 'commodity.products.constant.validatorNumberRange.error.1' }));
if (min && (Number(range[0]) !== Number(min))) throw new Error(getIntl().formatMessage({ id: 'commodity.products.constant.validatorNumberRange.error.2' }));
callback()
}
} catch (err) {
......
import React, { ReactNode, useEffect, useRef, useState } from 'react'
import React, { ReactNode, useContext, useEffect, useRef, useState } from 'react'
import { Row, Col, Skeleton, Anchor } from 'antd'
import { history } from 'umi'
import { ArrowLeftOutlined } from '@ant-design/icons'
import style from './index.less'
import { useEDetail } from '../../effects/useEDetail'
import { EDetailContext } from '../../constant'
const { Link } = Anchor;
......@@ -11,14 +13,10 @@ export interface ILink {
id: string;
}
interface BackFn {
(): void;
}
export interface EDetailHeaderProps {
extraRight?: ReactNode,
anchorList?: ILink[],
backLink?: string | boolean | BackFn,
backLink?: any,
title: string,
}
......@@ -31,7 +29,8 @@ const EDetailHeader: React.FC<EDetailHeaderProps> = ({
backLink,
title
}) => {
// const isLoading = !!formContext.data
const eDetailContext = useContext(EDetailContext)
const { ctl } = eDetailContext
const flagRef = useRef({
flag: false,
......@@ -75,7 +74,7 @@ const EDetailHeader: React.FC<EDetailHeaderProps> = ({
}
const handleBack = () => {
typeof backLink === 'string' ? (typeof backLink === 'function' ? backLink() : history.push(backLink)) : history.goBack()
typeof backLink === 'function' ? backLink() : (typeof backLink === 'string' ? history.push(backLink) : history.goBack())
}
return (
......
import React, { useContext } from 'react'
import { useIntl } from 'umi';
import { Button, Col, Form, Input, Row, Select } from 'antd'
import React, { useContext, useState } from 'react'
import { Button, Col, Form, Input, message, Row, Select } from 'antd'
import MellowCard from '@/components/MellowCard';
import { BIND_PHONE, EDetailContext, formItemLayout, prefixSelector, tailFormItemLayout } from '../../constant';
import useCountDown from '@/utils/hooks';
import { PATTERN_MAPS } from '@/constants/regExp';
import { postPayAllInPayPersonalCrate, postPayAllInPaySendVerificationCode } from '@/services/PayV2Api';
import { postPayAllInPayBindPhone, postPayAllInPayPersonalCrate, postPayAllInPaySendVerificationCode, postPayAllInPaySetRealName } from '@/services/PayV2Api';
import { useIntl } from 'umi';
/** 个人 初始认证 */
const Personal: React.FC<{}> = () => {
......@@ -14,14 +14,27 @@ const Personal: React.FC<{}> = () => {
const [form] = Form.useForm();
const eDetailContext = useContext(EDetailContext)
const { ctl, reloadFormData } = eDetailContext
const [loading, setLoading] = useState<boolean>(false)
const onFinish = async (values: any) => {
const { code } = await postPayAllInPayPersonalCrate({ ...values })
if (code === 1000) {
reloadFormData()
}
console.log('Received values of form: ', values);
};
setLoading(true)
// 绑定手机
const p1 = await postPayAllInPayBindPhone({phone: values.phone, verificationCode: values.captcha}, {ctlType: 'none'})
// 实名认证
const p2 = await postPayAllInPaySetRealName({name: values.name, cardType: values.cardType, cardNo: values.cardNo, phone: values.phone}, {ctlType:'none'})
// 提交
const p3 = await postPayAllInPayPersonalCrate({...values}, { ctlType: "none" })
Promise.all([p1, p2, p3]).then(res => {
if(res.every(item => item['code'] === 1000)) {
reloadFormData()
message.success('操作成功')
} else {
message.error('接口请求异常')
}
setLoading(false)
})
}
const { text, isActive, start } = useCountDown({
maxTime: 60,
......@@ -145,8 +158,8 @@ const Personal: React.FC<{}> = () => {
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
{intl.formatMessage({ id: 'payandSettle.eAccountApprove.components.personal.submit' })}
<Button type="primary" htmlType="submit" loading={loading}>
提交
</Button>
</Form.Item>
</Form>
......
import React, { useEffect, useRef, useState } from 'react'
import { Row, Input, Col, Button, Result, message, Modal } from 'antd';
import useCountDown from '@/utils/hooks';
import { postPayAllInPaySendVerificationCode } from '@/services/PayV2Api';
import { UNBIND_PHONE } from '../../constant';
/**
* e账户认证 发送短信验证码
* @param props
* @returns
*/
const PhoneCode = (props) => {
const { value, form, schema } = props
const [loading, setLoading] = useState(false)
const {text, isActive, start} = useCountDown({
maxTime: 60,
minTime: 0,
initText: '获取验证码',
onEnd: () => {
setLoading(false)
},
decayRate: 1,
delay: 1 * 1000
})
// type 9绑定 6解绑
const { btnSize = 'large', inputSize = 'large', type, ...componentProps } = schema.getExtendsComponentProps() || {}
const handleClickSms = async () => {
// 短信正在读秒中
if (isActive) {
return false
}
setLoading(true)
form.validate('phone').then(result => {
console.log(result, type)
// 发送验证码
const phone = form.getFieldValue('phone')
postPayAllInPaySendVerificationCode({phone, verificationCodeType: type}).then(res => {
res.code === 1000 && start()
})
})
}
return (
<Row style={{width: '100%'}}>
<Col flex={1}>
<Input
value={value || ''}
onChange={e => props.mutators.change(e.target.value)}
size={inputSize}
{...componentProps}
/>
</Col>
<Col style={{marginLeft: 8}}>
<Button disabled={isActive} style={{minWidth: 110, marginLeft: 8}} loading={loading} size={btnSize} onClick={handleClickSms}>{text}</Button>
</Col>
</Row>
)
}
PhoneCode.defaultProps = {}
PhoneCode.isFieldComponent = true;
export default PhoneCode
import { createContext } from 'react';
import { Form, Select } from 'antd';
import { getManageCountryAreaGetTelCode } from '@/services/ManageV2Api';
const { Option } = Select;
/**
......@@ -63,10 +64,21 @@ export const tailFormItemLayoutCompany = {
},
};
export const prefixSelector = (
<Form.Item name="prefix" noStyle>
<Select style={{ width: 70 }}>
<Option value="86">+86</Option>
</Select>
</Form.Item>
);
// 获取手机code
export const fetchTelCode = async () => {
const { data = [] } = await getManageCountryAreaGetTelCode();
return data;
};
export const prefixSelector = async () => {
const options = await fetchTelCode()
return (
<Form.Item name="prefix" noStyle>
<Select style={{ width: 70 }}>
{
options.map(item => <Option value={item}>{item}</Option>)
}
</Select>
</Form.Item>
)
};
import { getPayAllInPayGetAuthMemberInfo, postPayAllInPayCreateMember, postPayAllInPayGetMemberInfo } from '@/services/PayV2Api';
import { getPayAllInPayGetAuthMemberInfo, postPayAllInPayCreateMember, postPayAllInPayGetMemberInfo, PostPayAllInPayGetMemberInfoResponse } from '@/services/PayV2Api';
import { getAuth } from '@/utils/auth';
import { message } from 'antd';
import { useCallback, useState, useEffect } from 'react'
......@@ -20,7 +20,7 @@ import { useCallback, useState, useEffect } from 'react'
export const useEDetail = () => {
const { memberRoleType } = getAuth() || {}
/** 详情数据 null从未认证*/
const [formData, setFormData] = useState<any>(null)
const [formData, setFormData] = useState<PostPayAllInPayGetMemberInfoResponse>(null)
/** 企业/个人 */
const [type, setType] = useState<'company'|'personal'>(MEMBER_TYPE[memberRoleType])
/** 是否需要完善 */
......
......@@ -8,6 +8,8 @@ import { useEDetail } from './effects/useEDetail'
import PersonalFinish from './components/personalFinish'
import Company from './components/company'
import CompanyFinish from './components/companyFinish'
import PreLoading from '@/components/PreLoading'
import { Modal } from 'antd'
const EAccountApprove: React.FC<{}> = () => {
const intl = useIntl();
......@@ -16,10 +18,8 @@ const EAccountApprove: React.FC<{}> = () => {
const {
type,
perfection,
finish,
backed,
showAnchor,
ctl,
data } = formContext
const personalLinkList = [
......@@ -33,18 +33,27 @@ const EAccountApprove: React.FC<{}> = () => {
{ title: intl.formatMessage({ id: 'payandSettle.eAccountApprove.companyLinkList.2' }), id: 'electricInfo' },
]
const handleBack = () => {
ctl.setPerfection(false)
ctl.setFinish(false)
ctl.setBacked(false)
}
return (
<div>
<EDetailContext.Provider value={formContext}>
<EDetailHeader
title={intl.formatMessage({ id: 'payandSettle.eAccountApprove.title' })}
anchorList={finish ? (type === "personal" ? personalLinkList : companyLinkList) : []}
title="通联账户"
anchorList={data?.bankNo ? (type === "personal" ? personalLinkList : companyLinkList) : []}
backLink={backed ? handleBack : false}
/>
<div className={styles.wrapper}>
{
type === 'personal' ? (data?.name ? <PersonalFinish /> : <Personal />) : (data ? <CompanyFinish /> : <Company />)
}
</div>
<PreLoading loading={!data} active paragraph={{rows: 6}}>
<div className={styles.wrapper}>
{
type === 'personal' ? (data?.name ? <PersonalFinish /> : <Personal />) : (data ? <CompanyFinish /> : <Company />)
}
</div>
</PreLoading>
</EDetailContext.Provider>
</div>
)
......
import { PATTERN_MAPS } from "@/constants/regExp";
export const bindSchema = {
type: 'object',
properties: {
NO_SUBMIT: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
labelAlign: 'top',
},
properties: {
NO_SUBMIT_LAYOUT_PHONE: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
grid: true,
label: '手机号',
columns: 6,
enableSafeWidth: false,
className: 'noMarbottom',
required: true,
},
properties: {
areaCode: {
type: 'string',
enum: [],
"x-component-props": {
placeholder: '+86'
},
"x-mega-props": {
span: 1,
},
"x-rules": [
{
required: true,
message: '请选择区号'
}
]
},
phone: {
type: 'number',
"x-mega-props": {
span: 5
},
"x-rules": [
{
pattern: PATTERN_MAPS.phone,
message: '请输入正确的手机号'
},
{
required: true,
message: '请输入手机号'
}
],
"x-component-props": {
placeholder: '输入你的手机号码',
style: { width: '100%' }
}
}
}
},
verificationCode: {
type: 'string',
"x-component": 'PhoneCode',
"x-rules": [
{
required: true,
message: '请填写验证码'
},
// {
// pattern: /^\d{6}$/,
// message: '请输入正确的6位验证码'
// }
],
"x-component-props": {
btnSize: 'middle',
inputSize: 'middle',
placeholder: '请输入短信验证码',
type: null
}
},
}
}
}
}
export const unbindSchema = {
type: 'object',
properties: {
NO_SUBMIT: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
labelAlign: 'top',
},
properties: {
NO_SUBMIT_LAYOUT_PHONE: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
grid: true,
label: '手机号',
columns: 6,
enableSafeWidth: false,
className: 'noMarbottom',
required: true,
},
properties: {
phone: {
type: 'number',
"x-mega-props": {
span: 6
},
"x-rules": [
{
pattern: PATTERN_MAPS.phone,
message: '请输入正确的手机号'
},
{
required: true,
message: '请输入手机号'
}
],
"x-component-props": {
placeholder: '输入你的手机号码',
style: { width: '100%' }
}
}
}
},
verificationCode: {
type: 'string',
"x-component": 'PhoneCode',
"x-rules": [
{
required: true,
message: '请填写验证码'
},
// {
// pattern: /^\d{6}$/,
// message: '请输入正确的6位验证码'
// }
],
"x-component-props": {
btnSize: 'middle',
inputSize: 'middle',
placeholder: '请输入短信验证码',
type: null
}
},
}
}
}
}
......@@ -512,9 +512,10 @@ export const repositDetailSchema: ISchema = padRequiredMessage({
title: getIntl().formatMessage({ id: 'repositories.schema.repositDetailSchema.inventory' }),
"x-rules": [
{
validator: value => {
return value > Number.MAX_SAFE_INTEGER
},
// validator: value => {
// return value > Number.MAX_SAFE_INTEGER
// },
pattern: /^[0-9]{1,8}$/,
message: getIntl().formatMessage({ id: 'repositories.schema.repositDetailSchema.inventory.message.1' }),
},
{
......@@ -684,9 +685,10 @@ export const batchRepositDetailSchema: ISchema = padRequiredMessage({
title: getIntl().formatMessage({ id: 'repositories.schema.batchRepositDetailSchema.inventory' }),
"x-rules": [
{
validator: value => {
return value > Number.MAX_SAFE_INTEGER
},
// validator: value => {
// return value > Number.MAX_SAFE_INTEGER
// },
pattern: /^[0-9]{1,8}$/,
message: getIntl().formatMessage({ id: 'repositories.schema.batchRepositDetailSchema.inventory.message.1' }),
},
{
......
......@@ -103,7 +103,7 @@ export const procurementProcessField = (value) => {
weight: item.logistics.weight,
stock: item.stockCount,
discount: item.isMemberPrice ? item.memberPrice : 1, // 字段需求 无折扣为1
price: item.isMemberPrice ? Number((item.money / item.purchaseCount / item.memberPrice).toFixed(2)) : Number((item.money / item.purchaseCoun).toFixed(2)),
price: item.isMemberPrice ? Number((item.money / item.purchaseCount / item.memberPrice).toFixed(2)) : Number((item.money / item.purchaseCount).toFixed(2)),
tax: item.taxRate > 0,
vendorMemberId: item.memberId,
vendorRoleId: item.memberRoleId,
......
......@@ -113,7 +113,7 @@ const SaleOrder: React.FC<SaleOrderProps> = () => {
useEffect(() => {
if(payModel === "web") {
payForm.setFieldsValue({'payChart': `/memberCenter/tranactionAbility/purchaseOrder/readyPayOrder/detail?id=${currentPayRef.current.orderId}`})
payForm.setFieldsValue({'payChart': `${window.location.origin}/memberCenter/tranactionAbility/purchaseOrder/readyPayOrder/detail?id=${currentPayRef.current.orderId}`})
} else if(payModel === "app") {
// 生成二维码
QRCode.toDataURL(JSON.stringify({path: 'MycommodityDetails', orderId: currentPayRef.current.orderId})).then((url:any) => {
......
......@@ -80,13 +80,14 @@ const cache = {}
// 请求拦截器
baseRequest.interceptors.request.use((url: string, options: RequestOptionsInit): { url: string, options: RequestOptionsInit } => {
// 判断是否有权限
const { userId, memberId, token } = getCookieAuth() || {}
const { userId, memberId, token, memberRoleId } = getCookieAuth() || {}
const headers: any = {
...options.headers
}
userId && (headers.userId = userId)
token && (headers.token = token)
memberId && (headers.memberId = memberId)
// memberRoleId && (headers.memberRoleId = memberRoleId)
options.paramsSerializer = params => {
return qs.stringify(params, { arrayFormat: 'indices' })
......
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