Commit f04b5204 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫
parents 4a7c7e29 0914afdb
......@@ -112,14 +112,6 @@ const CommodityRoute: RouterChild = {
},
// 品牌-新增
{
path: '/memberCenter/commodityAbility/trademark/addBrand',
name: 'addBrand',
icon: 'smile',
hideInMenu: true,
component: '@/pages/trademark/addBrand',
},
// 品牌-新增
{
path: '/memberCenter/commodityAbility/trademark/add',
name: 'addBrand',
icon: 'smile',
......@@ -188,14 +180,6 @@ const CommodityRoute: RouterChild = {
},
// 商品-新增
{
path: '/memberCenter/commodityAbility/commodity/products/addProducts',
name: 'addProducts',
hideInMenu: true,
icon: 'smile',
component: '@/pages/commodity/products/addProducts',
},
// 商品-新增
{
path: '/memberCenter/commodityAbility/commodity/products/add',
name: 'addProducts',
icon: 'smile',
......
......@@ -194,6 +194,13 @@ const MemberRoute: RouterChild = {
hideInMenu: true,
component: '@/pages/member/memberLevel/addEquity',
},
// 会员等级-详情
{
path: '/memberCenter/memberAbility/manage/level/detail',
name: 'editMemberLevel',
hideInMenu: true,
component: '@/pages/member/memberLevel/equityDetail',
},
]
},
// 会员信息查询
......
......@@ -453,7 +453,7 @@ const TranactionRoute: RouterChild = {
// 销售订单
...saleOrder,
// 交易规则
// 交易规则列表
{
path: '/memberCenter/tranactionAbility/transactionRules',
name: 'transactionRules',
......@@ -462,12 +462,28 @@ const TranactionRoute: RouterChild = {
// 新增交易规则
{
path: '/memberCenter/tranactionAbility/transactionRules/addRule',
path: '/memberCenter/tranactionAbility/transactionRules/add',
name: 'addRule',
hideInMenu: true,
component: '@/pages/transaction/transactionRules/addRule',
},
// 编辑交易规则
{
path: '/memberCenter/tranactionAbility/transactionRules/edit',
name: 'editRule',
hideInMenu: true,
component: '@/pages/transaction/transactionRules/addRule',
},
// 交易规则详情
{
path: '/memberCenter/tranactionAbility/transactionRules/detail',
name: 'ruleDetail',
hideInMenu: true,
component: '@/pages/transaction/transactionRules/addRule',
},
// 供应会员评价管理
{
path: '/memberCenter/tranactionAbility/supplierEvaluation',
......
......@@ -6,7 +6,7 @@ import OrderProcess from './components/orderProcess'
import ReplaceGoods from './components/replaceGoods'
import ReturnGoods from './components/returnGoods'
import ReplaceDetail from './components/replaceDetail'
import HistoryLog from './components/HistoryLog'
import HistoryLog from './components/historyLog'
interface OrderPreviewPropsType { }
......
......@@ -4,6 +4,7 @@ import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import cx from 'classnames'
import { COMMODITY_TYPE, LAYOUT_TYPE } from '@/constants'
import { priceFormat, numFormat } from '@/utils/numberFomat'
import { arrayGroupsByCount } from '@/utils'
import ImageBox from '@/components/ImageBox'
import styles from './index.less'
......@@ -19,18 +20,9 @@ const BrowseRecords: React.FC<BrowseRecordsPropsType> = (props) => {
const actionRef = useRef<any>()
const arrGroup = (array, subGroupLength) => {
let index = 0;
let newArray = [];
while (index < array.length) {
newArray.push(array.slice(index, index += subGroupLength));
}
return newArray;
}
useEffect(() => {
if (dataList) {
setList(arrGroup(dataList, 3))
setList(arrayGroupsByCount(dataList, 3))
}
}, [dataList])
......
import React from 'react'
import styles from '../../index.less'
interface NewTradePropsType {
}
const NewTrade: React.FC<NewTradePropsType> = (props) => {
const buy_dynamic_list = [
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
]
return (
<div className={styles.new_trade}>
<div className={styles.find_more_title}>
<label>最新成交</label>
</div>
<div className={styles.new_trade_list}>
{
buy_dynamic_list.map((item, index) => index < 4 && (
<div className={styles.new_trade_list_item} key={`new_trade_list_item_${index}`}>
<div className={styles.new_trade_list_item_header}>
<span>{item.title}</span>
<div className={styles.price}>2000</div>
</div>
<div className={styles.new_trade_list_item_content}>
<span className={styles.content_text}>{item.date}</span>
<span className={styles.content_time}>平方英尺</span>
</div>
</div>
))
}
</div>
</div>
)
}
export default NewTrade
import React from 'react'
import styles from '../../index.less'
interface PopularShopsPropsType {
}
const PopularShops: React.FC<PopularShopsPropsType> = (props) => {
return (
<div className={styles.popular_shops}>
<div className={styles.find_more_title}>
<label>人气店铺</label>
<span>排名每天凌晨更新</span>
</div>
<div className={styles.popular_shops_list}>
<div className={styles.popular_shops_list_item}>
<div className={styles.popular_shops_rank}>01</div>
<div className={styles.popular_shops_logo}>
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className={styles.popular_shops_name}> <a href="/">无锡市群明钢业有限公司</a></div>
</div>
<div className={styles.popular_shops_list_item}>
<div className={styles.popular_shops_rank}>02</div>
<div className={styles.popular_shops_logo}>
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className={styles.popular_shops_name}>无锡市群明钢业有限公司</div>
</div>
<div className={styles.popular_shops_list_item}>
<div className={styles.popular_shops_rank}>03</div>
<div className={styles.popular_shops_logo}>
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className={styles.popular_shops_name}>无锡市群明钢业有限公司</div>
</div>
<div className={styles.popular_shops_list_item}>
<div className={styles.popular_shops_rank}>04</div>
<div className={styles.popular_shops_logo}>
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className={styles.popular_shops_name}>无锡市群明钢业有限公司</div>
</div>
<div className={styles.popular_shops_list_item}>
<div className={styles.popular_shops_rank}>05</div>
<div className={styles.popular_shops_logo}>
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className={styles.popular_shops_name}>无锡市群明钢业有限公司</div>
</div>
</div>
</div>
)
}
export default PopularShops
import React from 'react'
import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import cx from 'classnames'
import styles from '../../index.less'
interface ShoppingNewsPropsType {
}
const ShoppingNews: React.FC<ShoppingNewsPropsType> = (props) => {
const buy_dynamic_list = [
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
]
return (
<div className={styles.popular_buy_dynamic}>
<div className={styles.find_more_title}>
<label className={styles.blue}>求购动态</label>
<span>买家求购,卖家快速报价</span>
<div className={styles.find_more_title_page}>
<div className={cx(styles.page_item, styles.prev)}><LeftOutlined /></div>
<div className={cx(styles.page_item, styles.next)}><RightOutlined /></div>
</div>
</div>
<div className={styles.popular_buy_dynamic_list}>
{
buy_dynamic_list.map((item, index) => (
<div className={styles.popular_buy_dynamic_list_item} key={`popular_buy_dynamic_list_item_${index}`}>
<div className={styles.popular_buy_dynamic_list_item_header}>
<span>{item.title}</span>
<div className={cx(styles.status_tag, item.state === 1 ? styles.success : '')}>{item.state === 1 ? '已完成' : '比价中'}</div>
</div>
<div className={styles.popular_buy_dynamic_list_item_content}>
<span className={styles.content_text}>{item.content}</span>
<span className={styles.content_time}>{item.date}</span>
</div>
</div>
))
}
</div>
</div>
)
}
export default ShoppingNews
......@@ -17,219 +17,222 @@
.find_more_main {
display: flex;
.find_more_title {
height: 60px;
line-height: 60px;
padding-left: 20px;
display: flex;
&>label {
color: #E44E46;
margin-right: 10px;
font-size: 16px;
font-weight: 500;
&.blue {
color: #6386D1;
}
}
}
}
.find_more_title {
height: 60px;
line-height: 60px;
padding-left: 20px;
display: flex;
&>label {
color: #E44E46;
margin-right: 10px;
font-size: 16px;
font-weight: 500;
&.blue {
color: #6386D1;
}
}
&>span {
color: #909399;
font-size: 12px;
}
.find_more_title_page {
display: flex;
padding: 0 20px;
align-items: center;
margin-left: auto;
&>.page_item {
width: 24px;
height: 24px;
background-color: #F4F5F7;
line-height: 24px;
font-size: 14px;
color: #979797;
text-align: center;
cursor: pointer;
&:hover {
opacity: .8;
}
&.prev {
margin-right: 16px;
}
}
}
}
.popular_shops {
width: 315px;
background: #ffffff;
.popular_shops_list {
padding: 20px 25px;
padding-bottom: 12px;
&_item {
display: flex;
margin-bottom: 20px;
align-items: center;
.popular_shops_rank {
width: 22px;
height: 32px;
line-height: 32px;
font-size: 14px;
color: #606266;
font-weight: 500;
margin-right: 20px;
}
.popular_shops_logo {
width: 36px;
height: 36px;
overflow: hidden;
margin-right: 10px;
&>img {
width: 100%;
height: 100%;
}
}
.popular_shops_name {
color: #303133;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&>a {
color: #303133;
}
}
}
}
}
.popular_buy_dynamic {
flex: 1;
margin: 0 20px;
background: #ffffff;
.popular_buy_dynamic_list {
display: flex;
flex-wrap: wrap;
&_item {
width: 50%;
padding: 20px;
&_header {
display: flex;
align-items: center;
&>span {
color: #909399;
flex: 1;
display: block;
color: #303133;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
}
.status_tag {
height: 20px;
padding: 0 6px;
line-height: 20px;
text-align: center;
color: #ffffff;
font-size: 12px;
background-color: #5988D5;
&.success {
color: #606266;
background-color: #EEF0F3;
}
}
}
.find_more_title_page {
display: flex;
padding: 0 20px;
align-items: center;
margin-left: auto;
&>.page_item {
width: 24px;
height: 24px;
background-color: #F4F5F7;
line-height: 24px;
font-size: 14px;
color: #979797;
text-align: center;
cursor: pointer;
&:hover {
opacity: .8;
}
&.prev {
margin-right: 16px;
}
&_content {
display: flex;
margin-top: 24px;
}
.content_text {
flex: 1;
color: #303133;
font-size: 14px;
line-height: 14px;
}
.content_time {
font-size: 12px;
color: #909399;
}
}
}
}
}
.popular_shops {
width: 315px;
background: #ffffff;
.popular_shops_list {
padding: 20px 25px;
padding-bottom: 12px;
&_item {
display: flex;
margin-bottom: 20px;
align-items: center;
.popular_shops_rank {
width: 22px;
height: 32px;
line-height: 32px;
font-size: 14px;
color: #606266;
font-weight: 500;
margin-right: 20px;
}
.popular_shops_logo {
width: 36px;
height: 36px;
overflow: hidden;
margin-right: 10px;
&>img {
width: 100%;
height: 100%;
}
}
.popular_shops_name {
color: #303133;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&>a {
color: #303133;
}
}
}
.new_trade {
width: 285px;
background: #ffffff;
.new_trade_list {
&_item {
padding: 12px 20px;
&_header {
display: flex;
align-items: center;
&>span {
flex: 1;
display: block;
color: #303133;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
}
}
.popular_buy_dynamic {
flex: 1;
margin: 0 20px;
background: #ffffff;
.popular_buy_dynamic_list {
display: flex;
flex-wrap: wrap;
&_item {
width: 50%;
padding: 20px;
&_header {
display: flex;
align-items: center;
&>span {
flex: 1;
display: block;
color: #303133;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
}
.status_tag {
height: 20px;
padding: 0 6px;
line-height: 20px;
text-align: center;
color: #ffffff;
font-size: 12px;
background-color: #5988D5;
&.success {
color: #606266;
background-color: #EEF0F3;
}
}
}
&_content {
display: flex;
margin-top: 24px;
.content_text {
flex: 1;
color: #303133;
font-size: 14px;
line-height: 14px;
}
.content_time {
font-size: 12px;
color: #909399;
}
}
}
.price {
font-size: 16px;
color: #D32F2F;
font-weight: 500;
}
}
.new_trade {
width: 285px;
background: #ffffff;
.new_trade_list {
&_item {
padding: 12px 20px;
&_header {
display: flex;
align-items: center;
&>span {
flex: 1;
display: block;
color: #303133;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
}
.price {
font-size: 16px;
color: #D32F2F;
font-weight: 500;
}
}
&_content {
display: flex;
margin-top: 12px;
font-size: 12px;
color: #909399;
.content_text {
flex: 1;
}
}
}
&_content {
display: flex;
margin-top: 12px;
font-size: 12px;
color: #909399;
.content_text {
flex: 1;
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import cx from 'classnames'
import PopularShops from './components/popularShops'
import NewTrade from './components/newTrade'
import ShoppingNews from './components/shoppingNews'
import './index.less'
const FindMore: React.FC = () => {
......@@ -49,98 +50,9 @@ const FindMore: React.FC = () => {
<div className="find_more_container">
<div className="find_more_header">发现更多</div>
<div className="find_more_main">
<div className="popular_shops">
<div className="find_more_title">
<label>人气店铺</label>
<span>排名每天凌晨更新</span>
</div>
<div className="popular_shops_list">
<div className="popular_shops_list_item">
<div className="popular_shops_rank">01</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name"> <a href="/">无锡市群明钢业有限公司</a></div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">02</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">03</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">04</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">05</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
</div>
</div>
<div className="popular_buy_dynamic">
<div className="find_more_title">
<label className="blue">求购动态</label>
<span>买家求购,卖家快速报价</span>
<div className="find_more_title_page">
<div className="page_item prev"><LeftOutlined /></div>
<div className="page_item next"><RightOutlined /></div>
</div>
</div>
<div className="popular_buy_dynamic_list">
{
buy_dynamic_list.map((item, index) => (
<div className="popular_buy_dynamic_list_item" key={`popular_buy_dynamic_list_item_${index}`}>
<div className="popular_buy_dynamic_list_item_header">
<span>{item.title}</span>
<div className={cx("status_tag", item.state === 1 ? 'success' : '')}>{item.state === 1 ? '已完成' : '比价中'}</div>
</div>
<div className="popular_buy_dynamic_list_item_content">
<span className="content_text">{item.content}</span>
<span className="content_time">{item.date}</span>
</div>
</div>
))
}
</div>
</div>
<div className="new_trade">
<div className="find_more_title">
<label>最新成交</label>
</div>
<div className="new_trade_list">
{
buy_dynamic_list.map((item, index) => index < 4 && (
<div className="new_trade_list_item" key={`new_trade_list_item_${index}`}>
<div className="new_trade_list_item_header">
<span>{item.title}</span>
<div className="price">2000</div>
</div>
<div className="new_trade_list_item_content">
<span className="content_text">{item.date}</span>
<span className="content_time">平方英尺</span>
</div>
</div>
))
}
</div>
</div>
<PopularShops />
<ShoppingNews />
<NewTrade />
</div>
</div>
......
......@@ -122,6 +122,14 @@
flex: 1;
text-align: center;
&:hover {
.navList_item_text {
a {
color: var(--mall_main_color);
}
}
}
&_count {
font-size: 20px;
line-height: 20px;
......
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import {
Button,
Popconfirm,
Card,
Input,
Slider,
Spin,
message,
} from 'antd';
import classNames from 'classnames';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { ContainerOutlined } from '@ant-design/icons';
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import { PublicApi } from '@/services/api';
import StatusSwitch from '@/components/StatusSwitch';
import { EditableCellTable } from '@/components/PolymericTable';
import { EditableCellProps, EditableColumns } from '@/components/PolymericTable/interface';
import { GetMemberAbilityLevelGetResponse } from '@/services';
import styles from './addEquity.less';
import DetailInfo from './components/DetailInfo';
const AddEquity: React.FC<[]> = () => {
const AddEquity: React.FC = () => {
const { id } = usePageStatus();
const [levelInfo, setLevelInfo] = useState<GetMemberAbilityLevelGetResponse>(null);
const [thresholdValue, setThresholdValue] = useState(100);
const [infoLoading, setInfoLoading] = useState(true);
const [submitLoading, setSubmitLoading] = useState(false);
const marks = {
0: '0',
5000: '5000',
10000: '10000',
15000: '15000',
20000: '20000',
50000: '50000',
};
const getMemberLevelInfo = () => {
setInfoLoading(true);
PublicApi.getMemberAbilityLevelGet({
id,
}).then(res => {
if (res.code === 1000) {
const { point = 0 } = res.data;
setLevelInfo(res.data);
setThresholdValue(point);
}
}).finally(() => {
setInfoLoading(false);
});
};
const handleChangeStatus = record => {
const disabled = record.status === 0;
PublicApi.postMemberAbilityRightUpdatestatus({
id: record.id,
status: disabled ? 1 : 0,
}, {
ctlType: 'none',
}).then(res => {
if (res.code === 1000) {
const msg = disabled ? '启用成功' : '禁用成功'
message.success(msg);
getMemberLevelInfo();
}
});
};
const columns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'name',
align: 'center',
},
{
title: '会员权益说明',
dataIndex: 'remark',
align: 'center',
},
{
title: '权益获取方式',
dataIndex: 'acquireWay',
align: 'center',
},
{
title: '参数设置方式',
dataIndex: 'paramWay',
align: 'center',
},
{
title: '参数',
dataIndex: 'param',
align: 'center',
width: '20%',
editable: true,
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
render: (_, record: any) => (
<StatusSwitch
handleConfirm={() => handleChangeStatus(record)}
record={record}
fieldNames="status"
/>
)
}
];
useEffect(() => {
getMemberLevelInfo();
}, []);
const handleThresholdChange = e => {
const { value } = e.target;
setThresholdValue(+value);
};
// 重新保存 dataSource
const handleSave = row => {
const { rights = [] } = levelInfo;
const newData = [...rights];
const index = newData.findIndex(item => item.id === row.id);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
param: +row.param,
});
setLevelInfo({
...levelInfo,
rights: newData,
});
};
const updateThreshold = () => {
return PublicApi.postMemberAbilityLevelUpdatepoint({
id,
point: thresholdValue,
}, {
ctlType: 'none',
});
};
const updateRightsParam = () => {
if (!levelInfo.rights || !levelInfo.rights.length) {
return;
}
const payload = levelInfo.rights.map(item => ({
id: item.id,
param: item.param,
}));
return PublicApi.postMemberAbilityRightUpdateparam({
items: payload,
}, {
ctlType: 'none',
});
};
const handleSubmit = async () => {
const promises = [updateThreshold(), updateRightsParam()];
setSubmitLoading(true);
try {
const resArr = await Promise.all(promises);
if (resArr.every((item: { code: number }) => item.code === 1000)) {
message.success('保存成功');
getMemberLevelInfo();
}
} catch (errInfo) {
}
setSubmitLoading(false);
};
const newColumns: any = columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record, index): EditableCellProps => ({
onSave: handleSave,
record,
index,
dataIndex: col.dataIndex,
title: col.title,
editable: col.editable || false,
rules: [
{
required: true,
message: '请输入相应值',
},
{
pattern: /^([0]|[1-9]+[0-9]*)(\.[0-9]+)?$/,
message: '请输入整数或小数',
},
],
addonAfter: '%',
}),
};
});
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
title={
<>
<div className={styles.headerTop}>
<div className={styles['headerTop-icon']}>
{ levelInfo && levelInfo.levelTag.length ? levelInfo.levelTag[0] : '' }
</div>
<div className={styles['headerTop-level']}>{ levelInfo?.levelTag }</div>
<div className={styles['headerTop-identity']}>{ levelInfo?.memberLevelTypeName }</div>
</div>
</>
}
content={
<div className={styles.headerMain}>
<div className={styles['headerMain-left']}>
<div className={styles['headerMain-left-option']}>
<div>会员等级:</div>
<div>{ levelInfo?.level }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>升级分值标签:</div>
<div>{ levelInfo?.scoreTag }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>角色类型:</div>
<div>{ levelInfo?.roleTypeName }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员等级说明:</div>
<div>{ levelInfo?.levelRemark }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员角色名称:</div>
<div>{ levelInfo?.roleName }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员类型:</div>
<div>{ levelInfo?.memberTypeName }</div>
</div>
</div>
<div className={styles['headerMain-right']}>
<Button
type="primary"
icon={<ContainerOutlined />}
loading={submitLoading}
onClick={handleSubmit}
>
保存
</Button>
</div>
</div>
}
>
<Card
title="升级阀值"
headStyle={{
borderBottom: 'none',
}}
bordered={false}
>
<div className={styles.extra}>
<div className={styles['extra-main']}>
<div className={classNames(styles['extra-main-content'], styles.left)}>
<div className={styles.icon}>当前阀值</div>
<div className={styles.input}>
<div className={styles['input-main']}>
<Input
className={styles['input-main-com']}
value={`${thresholdValue}`}
onChange={handleThresholdChange}
/>
</div>
</div>
</div>
{/* <div className={classNames(styles['extra-main-content'], styles.right)}>
<Slider
marks={marks}
max={50000}
value={thresholdValue}
disabled
/>
</div> */}
</div>
</div>
</Card>
<Card
title="会员权益"
headStyle={{
borderBottom: 'none',
}}
style={{
marginTop: 24,
}}
bordered={false}
>
<EditableCellTable
dataSource={levelInfo?.rights}
columns={newColumns}
loading={false}
pagination={null}
/>
</Card>
</PageHeaderWrapper>
</Spin>
)
}
<DetailInfo id={id} isEdit />
);
};
export default AddEquity;
\ No newline at end of file
.headerTop {
display: flex;
align-items: center;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
&-icon {
width: 48px;
height: 48px;
line-height: 48px;
border-radius: 4px;
border: 1px solid #DFE1E6;
color: #fff;
text-align: center;
background-color: #8777D9;
}
&-level {
color: #303133;
margin: 0 8px 0 12px;
}
&-identity {
width: 72px;
height: 24px;
line-height: 24px;
background-color: #FFEBE6;
border-radius: 4px;
color: #E63F3B;
font-size: 12px;
font-weight: 400;
text-align: center;
}
}
.headerMain {
display: flex;
&-left {
flex: 6;
display: flex;
flex-wrap: wrap;
padding-left: 90px;
&-option {
display: flex;
width: calc(100% / 3);
margin-bottom: 17px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #909399;
padding-right: 20px;
&:nth-of-type(n + 4) {
margin: 0;
}
div {
flex: 1;
&:nth-last-of-type(1) {
flex: 2;
}
}
}
}
&-right {
flex: 1;
text-align: right;
}
}
.extra {
&-main {
display: flex;
&-content {
position: relative;
flex: 1;
&:nth-last-of-type(1) {
flex: 2.5;
}
}
.left {
display: flex;
align-items: center;
padding: 35px 0 28px 8%;
background: rgba(250, 251, 252, 1);
border-radius: 4px;
.icon {
position: absolute;
left: 0;
top: 0;
width: 72px;
height: 24px;
color: #fff;
background-color: #606266;
border-radius: 4px 0px 4px 0px;
text-align: center;
}
.input {
display: flex;
justify-content: center;
&-main {
position: relative;
width: 128px;
height: 38px;
padding-bottom: 8px;
&::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background-color: #DFE1E6;
}
// :global {
// .ant-input {
// border: none;
// box-shadow: none;
// background-color: transparent;
// }
// }
&-com {
width: 100%;
height: 100%;
border: 0;
outline: none;
background-color: rgba(0, 0, 0, 0);
font-size: 32px;
font-weight: 500;
color: #303133;
&:focus {
border: none;
box-shadow: none;
background-color: transparent;
}
}
}
}
}
.right {
padding: 27px 40px;
}
}
}
import React, { useState, useEffect } from 'react';
import { history } from 'umi';
import {
Button,
Popconfirm,
Card,
Input,
Slider,
Spin,
message,
} from 'antd';
import classNames from 'classnames';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { ContainerOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api';
import StatusSwitch from '@/components/StatusSwitch';
import { EditableCellTable } from '@/components/PolymericTable';
import { EditableCellProps, EditableColumns } from '@/components/PolymericTable/interface';
import { GetMemberAbilityLevelGetResponse } from '@/services';
import styles from './index.less';
interface DetailInfoProps {
id?: number;
// 是否是编辑的
isEdit?: boolean;
};
const DetailInfo: React.FC<DetailInfoProps> = ({
id,
isEdit = false,
}) => {
const [levelInfo, setLevelInfo] = useState<GetMemberAbilityLevelGetResponse>(null);
const [thresholdValue, setThresholdValue] = useState(100);
const [infoLoading, setInfoLoading] = useState(true);
const [submitLoading, setSubmitLoading] = useState(false);
const marks = {
0: '0',
5000: '5000',
10000: '10000',
15000: '15000',
20000: '20000',
50000: '50000',
};
const getMemberLevelInfo = () => {
setInfoLoading(true);
PublicApi.getMemberAbilityLevelGet({
id: `${id}`,
}).then(res => {
if (res.code === 1000) {
const { point = 0 } = res.data;
setLevelInfo(res.data);
setThresholdValue(point);
}
}).finally(() => {
setInfoLoading(false);
});
};
const handleChangeStatus = record => {
if (!isEdit) {
return;
}
const disabled = record.status === 0;
PublicApi.postMemberAbilityRightUpdatestatus({
id: record.id,
status: disabled ? 1 : 0,
}, {
ctlType: 'none',
}).then(res => {
if (res.code === 1000) {
const msg = disabled ? '启用成功' : '禁用成功'
message.success(msg);
getMemberLevelInfo();
}
});
};
const columns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'name',
align: 'center',
},
{
title: '会员权益说明',
dataIndex: 'remark',
align: 'center',
},
{
title: '权益获取方式',
dataIndex: 'acquireWay',
align: 'center',
},
{
title: '参数设置方式',
dataIndex: 'paramWay',
align: 'center',
},
{
title: '参数',
dataIndex: 'param',
align: 'center',
width: '20%',
editable: isEdit,
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
render: (_, record: any) => (
isEdit ? (
<StatusSwitch
handleConfirm={() => handleChangeStatus(record)}
record={record}
fieldNames="status"
/>
) : (
_ === 1 ? '有效' : '失效'
)
)
}
];
useEffect(() => {
getMemberLevelInfo();
}, []);
const handleThresholdChange = e => {
const { value } = e.target;
setThresholdValue(+value);
};
// 重新保存 dataSource
const handleSave = row => {
const { rights = [] } = levelInfo;
const newData = [...rights];
const index = newData.findIndex(item => item.id === row.id);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
param: +row.param,
});
setLevelInfo({
...levelInfo,
rights: newData,
});
};
const updateThreshold = () => {
return PublicApi.postMemberAbilityLevelUpdatepoint({
id,
point: thresholdValue,
}, {
ctlType: 'none',
});
};
const updateRightsParam = () => {
if (!levelInfo.rights || !levelInfo.rights.length) {
return;
}
const payload = levelInfo.rights.map(item => ({
id: item.id,
param: item.param,
}));
return PublicApi.postMemberAbilityRightUpdateparam({
items: payload,
}, {
ctlType: 'none',
});
};
const handleSubmit = async () => {
if (!isEdit) {
return;
}
const promises = [updateThreshold(), updateRightsParam()];
setSubmitLoading(true);
try {
const resArr = await Promise.all(promises);
if (resArr.every((item: { code: number }) => item.code === 1000)) {
message.success('保存成功');
getMemberLevelInfo();
}
} catch (errInfo) {
}
setSubmitLoading(false);
};
const newColumns: any = columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record, index): EditableCellProps => ({
onSave: handleSave,
record,
index,
dataIndex: col.dataIndex,
title: col.title,
editable: col.editable || false,
rules: [
{
required: true,
message: '请输入相应值',
},
{
pattern: /^([0]|[1-9]+[0-9]*)(\.[0-9]+)?$/,
message: '请输入整数或小数',
},
],
addonAfter: '%',
}),
};
});
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
title={
<>
<div className={styles.headerTop}>
<div className={styles['headerTop-icon']}>
{ levelInfo && levelInfo.levelTag.length ? levelInfo.levelTag[0] : '' }
</div>
<div className={styles['headerTop-level']}>{ levelInfo?.levelTag }</div>
<div className={styles['headerTop-identity']}>{ levelInfo?.memberLevelTypeName }</div>
</div>
</>
}
content={
<div className={styles.headerMain}>
<div className={styles['headerMain-left']}>
<div className={styles['headerMain-left-option']}>
<div>会员等级:</div>
<div>{ levelInfo?.level }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>升级分值标签:</div>
<div>{ levelInfo?.scoreTag }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>角色类型:</div>
<div>{ levelInfo?.roleTypeName }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员等级说明:</div>
<div>{ levelInfo?.levelRemark }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员角色名称:</div>
<div>{ levelInfo?.roleName }</div>
</div>
<div className={styles['headerMain-left-option']}>
<div>会员类型:</div>
<div>{ levelInfo?.memberTypeName }</div>
</div>
</div>
<div className={styles['headerMain-right']}>
{isEdit && (
<Button
type="primary"
icon={<ContainerOutlined />}
loading={submitLoading}
onClick={handleSubmit}
>
保存
</Button>
)}
</div>
</div>
}
>
<Card
title="升级阀值"
headStyle={{
borderBottom: 'none',
}}
bordered={false}
>
<div className={styles.extra}>
<div className={styles['extra-main']}>
<div className={classNames(styles['extra-main-content'], styles.left)}>
<div className={styles.icon}>当前阀值</div>
<div className={styles.input}>
<div className={styles['input-main']}>
<Input
className={styles['input-main-com']}
value={`${thresholdValue}`}
onChange={handleThresholdChange}
disabled={!isEdit}
/>
</div>
</div>
</div>
{/* <div className={classNames(styles['extra-main-content'], styles.right)}>
<Slider
marks={marks}
max={50000}
value={thresholdValue}
disabled
/>
</div> */}
</div>
</div>
</Card>
<Card
title="会员权益"
headStyle={{
borderBottom: 'none',
}}
style={{
marginTop: 24,
}}
bordered={false}
>
<EditableCellTable
dataSource={levelInfo?.rights}
columns={newColumns}
loading={false}
pagination={null}
/>
</Card>
</PageHeaderWrapper>
</Spin>
)
}
export default DetailInfo;
\ No newline at end of file
import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const EquityDetail: React.FC = () => {
const { id } = usePageStatus();
return (
<DetailInfo id={id} />
);
};
export default EquityDetail;
\ No newline at end of file
......@@ -49,7 +49,7 @@ const MemberLevel: React.FC<[]> = () => {
key: 'levelTag',
render: (text: any, record: any) => (
<EyePreview
url={`/memberCenter/memberAbility/manage/level/edit?id=${record.id}&preview=1`}
url={`/memberCenter/memberAbility/manage/level/detail?id=${record.id}`}
>
{text}
</EyePreview>
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { usePageStatus } from '@/hooks/usePageStatus';
import DetailInfo from './components/DetailInfo';
const PrComfirmDetail: React.FC = () => {
const AuditPrComfirm: React.FC = () => {
const { id, validateId, pageStatus } = usePageStatus();
return (
......@@ -10,4 +10,4 @@ const PrComfirmDetail: React.FC = () => {
);
};
export default PrComfirmDetail;
\ No newline at end of file
export default AuditPrComfirm;
\ No newline at end of file
import React, { useState, useEffect, useRef } from 'react'
import { Card, Space, Button, Popconfirm } from 'antd'
import { Card, Space, Button, Input, Modal, Form } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { StandardTable } from 'god'
import { ColumnType } from 'antd/lib/table/interface'
......@@ -16,11 +16,17 @@ import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect'
import StatusTag from '@/components/StatusTag'
import { accountStatusMap, memberStatusMap } from '../../constant'
import LevelBrand from '@/pages/member/components/LevelBrand'
import { validatorByte } from '@/utils/regExp'
import { GetPayMemberAssetAccountGetMemberAssetAccountListResponseDetail } from '@/services/PayApi'
const formActions = createFormActions();
const { TextArea } = Input;
const AccountLists: React.FC<{}> = () => {
const ref = useRef<any>({})
const [checkForm] = Form.useForm()
const [currentRecord, setCurrentRecord] = useState<GetPayMemberAssetAccountGetMemberAssetAccountListResponseDetail>()
const [visibleModal, setVisibleModal] = useState<boolean>(false)
const columns: ColumnType<any>[] = [
{
......@@ -30,11 +36,10 @@ const AccountLists: React.FC<{}> = () => {
className: 'commonPickColor',
render: (text, record) => <>
<EyePreview
url={`/memberCenter/payandSettle/amountAccountManage/memberAccountManage/memberAccountDetail?id=${record.id}`}
url={`/memberCenter/payandSettle/amountAccountManage/memberAccountManage/detail?id=${record.id}`}
>
{text}
</EyePreview>
{/* <LevelBrand level={record.level} /> */}
</>
},
{
......@@ -49,8 +54,9 @@ const AccountLists: React.FC<{}> = () => {
},
{
title: '会员等级',
dataIndex: 'memberLevelName',
key: 'memberLevelName',
dataIndex: 'memberLevel',
key: 'memberLevel',
render: (t, r) => <LevelBrand level={r.level} />
},
{
title: '账户余额',
......@@ -68,7 +74,7 @@ const AccountLists: React.FC<{}> = () => {
title: '可用余额',
dataIndex: 'usableBalance',
key: 'usableBalance',
render: text => `¥${text}`
render: (t, r) => `¥${r.accountStatus - r.lockBalance}`
},
{
title: '会员状态',
......@@ -80,25 +86,22 @@ const AccountLists: React.FC<{}> = () => {
title: '账户状态',
dataIndex: 'accountStatus',
key: 'accountStatus',
render: (t, r) => (<span className={memberStatusMap[t]['className']}>{accountStatusMap[t]['title']}</span>)
render: (t, r) => (<><span className={accountStatusMap[t]['className']}></span>{accountStatusMap[t]['title']}</>)
},
{
title: '操作',
dataIndex: 'option',
render: (text: any, record: any) => (
<Popconfirm
title="确定要执行这个操作?"
onConfirm={() => clickHandle(record)}
onCancel={cancel}
okText="是"
cancelText="否"
>
<Button type='link'>{record.accountStatus===1?'冻结':'解除'}</Button>
</Popconfirm>
render: (t: any, r: any) => (
<Button type='link' onClick={() => handleRow(r)}>{r.accountStatus===1?'冻结':'解除'}</Button>
)
}
]
const handleRow = (data: any) => {
setCurrentRecord(data)
setVisibleModal(true)
}
const fetchData = (params: any) => {
console.log(params)
return new Promise((resolve, reject) => {
......@@ -129,12 +132,18 @@ const AccountLists: React.FC<{}> = () => {
return {}
}
const cancel = () => {
console.log('cancel')
const handleCancel = () => {
setVisibleModal(false)
}
const clickHandle = (r: any) => {
console.log(r,'操作r')
const handleOK = () => {
checkForm.validateFields().then(values => {
setVisibleModal(false)
PublicApi.postPayMemberAssetAccountUpdateMemberAssetAccountEnable({ id: currentRecord.id, status: currentRecord.accountStatus === 1 ? 2 : 1, ...values }).then(res => {
if(res.code === 1000)
ref.current.reload()
})
})
}
return (
......@@ -169,6 +178,33 @@ const AccountLists: React.FC<{}> = () => {
}
/>
</Card>
<Modal
title={currentRecord?.accountStatus === 1 ? '会员冻结' : '会员解冻'}
visible={visibleModal}
onOk={handleOK}
onCancel={handleCancel}
>
<Form
layout="vertical"
form={checkForm}
>
<Form.Item
name="remark"
label={currentRecord?.accountStatus === 1 ? '会员冻结原因' : '会员解冻原因'}
rules={[
{
required: true,
message: '请填写原因'
},
{
validator: (r, v, c) => validatorByte(r, v, c, 120)
}
]}
>
<TextArea rows={6} placeholder="请填写原因" />
</Form.Item>
</Form>
</Modal>
</PageHeaderWrapper>
)
}
......
......@@ -8,9 +8,11 @@ import StatusTag from '@/components/StatusTag'
import cx from 'classnames'
import moment from 'moment'
import { ColumnType } from 'antd/lib/table/interface'
import { moveStatusMap, statusMap } from '../../constant'
import { SettingOutlined } from '@ant-design/icons'
import { memberStatusMap, moveStatusMap, statusMap } from '../../constant'
import { SettingOutlined, StopOutlined } from '@ant-design/icons'
import { validatorByte } from '@/utils/regExp'
import { PublicApi } from '@/services/api'
import { GetPayMemberAssetAccountGetMemberAssetAccountResponse } from '@/services/PayApi'
const { TextArea } = Input
......@@ -20,6 +22,25 @@ const AccountDetail: React.FC<{}> = () => {
const [moveRecord, setMoveRecord] = useState<any>()
const [isDisabled, setIsDisabled] = useState<boolean>(false)
const [visibleModal, setVisibleModal] = useState<boolean>(false)
const [ details, setDetails ] = useState<any>({ accountBalance: 0, lockBalance: 0})
useEffect(() => {
getAccountInfo()
// pay/memberAssetAccount/getMemberAssetAccount
}, [])
const getAccountInfo = async () => {
const { id } = history.location.query
let res = await PublicApi.getPayMemberAssetAccountGetMemberAssetAccount({id})
const { code, data } = res
setDetails(data)
if(code === 1000){
let tradeRecord = await PublicApi.getPayMemberAssetAccountGetAccountTradeRecord({memberAssetAccountId: data.id + ''})
let statusRecord = await PublicApi.getPayMemberAssetAccountGetAccountCheckRecord({memberAssetAccountId: data.id + ''})
setDealRecord(tradeRecord.data)
setMoveRecord(statusRecord.data)
}
}
const columns: ColumnType<any>[] = [
{
......@@ -102,18 +123,22 @@ const AccountDetail: React.FC<{}> = () => {
const handleRelieve = () => {
setVisibleModal(true)
console.log('解除')
}
const handleOK = () => {
console.log('OK')
}
const handleCancel = () => {
console.log('取消')
setVisibleModal(false)
}
const handleOK = () => {
checkForm.validateFields().then(values => {
setVisibleModal(false)
PublicApi.postPayMemberAssetAccountUpdateMemberAssetAccountEnable({ id: details.id, status: details.accountStatus === 1 ? 2 : 1, ...values }).then(res => {
if(res.code === 1000)
getAccountInfo()
})
})
}
return (
<PageHeaderWrapper
title="账户详情"
......@@ -124,10 +149,10 @@ const AccountDetail: React.FC<{}> = () => {
key="1"
onClick={handleRelieve}
type="primary"
icon={<SettingOutlined />}
icon={details?.accountStatus === 1 ? <SettingOutlined /> : <StopOutlined />}
disabled={isDisabled}
>
解冻
{details?.accountStatus === 1 ? '冻结' : '解冻'}
</Button>,
]}
>
......@@ -140,12 +165,12 @@ const AccountDetail: React.FC<{}> = () => {
<div className={styles.statistic}>
<div className={styles['statistic-title']}>可用余额(元):</div>
<div className={styles['statistic-amount']}>
{`100000`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
{`${details.accountBalance - details.lockBalance}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
</div>
</div>
<div className={styles['repayment-end']}>
<span className={styles['repayment-time']}>
温州市龙昌皮具有限公司
{details?.memberName}
</span>
</div>
</div>
......@@ -158,7 +183,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户归属:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>广州数商云网络科技有限公司</p>
<p className={styles.rightInfo}>{details?.parentMemberName}</p>
</Col>
</Row>
<Row>
......@@ -166,7 +191,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户余额(元):</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>10,000</p>
<p className={styles.rightInfo}>{details?.accountBalance}</p>
</Col>
</Row>
<Row>
......@@ -174,7 +199,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>锁定金额(元):</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>0.00</p>
<p className={styles.rightInfo}>{details?.lockBalance}</p>
</Col>
</Row>
<Row>
......@@ -182,7 +207,12 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户状态:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}><StatusTag type="success" title="正常" /></p>
<p className={styles.rightInfo}>
{
details?.accountStatus &&
<StatusTag title={memberStatusMap[details.accountStatus]['title']} type={memberStatusMap[details.accountStatus]['type']} />
}
</p>
</Col>
</Row>
</div>
......@@ -201,7 +231,7 @@ const AccountDetail: React.FC<{}> = () => {
</Card>
</Space>
<Modal
title="会员冻结"
title={details?.accountStatus === 1 ? '会员冻结' : '会员解冻'}
visible={visibleModal}
onOk={handleOK}
onCancel={handleCancel}
......@@ -211,8 +241,8 @@ const AccountDetail: React.FC<{}> = () => {
form={checkForm}
>
<Form.Item
name="checkRemark"
label={'会员冻结原因'}
name="remark"
label={details?.accountStatus === 1 ? '会员冻结原因' : '会员解冻原因'}
rules={[
{
required: true,
......
......@@ -11,14 +11,33 @@ import { ColumnType } from 'antd/lib/table/interface'
import ModalForm from '@/components/ModalForm'
import { createFormActions } from '@formily/antd'
import { rechargeSchema } from './schema'
import { moveStatusMap, statusMap } from '../../constant'
import { memberStatusMap, moveStatusMap, statusMap } from '../../constant'
import { PublicApi } from '@/services/api'
const schemaActions = createFormActions()
const AccountDetail: React.FC<{}> = () => {
const modalRef = useRef<any>()
const [dealRecord, setDealRecord] = useState<any>()
const [moveRecord, setMoveRecord] = useState<any>()
const [ details, setDetails ] = useState<any>({ accountBalance: 0, lockBalance: 0})
const [dealRecord, setDealRecord] = useState<any>([])
const [moveRecord, setMoveRecord] = useState<any>([])
useEffect(() => {
getAccountInfo()
} ,[])
const getAccountInfo = async () => {
const { id } = history.location.query
let res = await PublicApi.getPayAssetAccountGetAssetAccount({id})
const { code, data } = res
setDetails(data)
if(code === 1000){
let tradeRecord = await PublicApi.getPayAssetAccountGetAccountTradeRecord({memberAssetAccountId: data.id + ''})
let statusRecord = await PublicApi.getPayAssetAccountGetAccountStatusRecord({memberAssetAccountId: data.id + ''})
setDealRecord(tradeRecord.data)
setMoveRecord(statusRecord.data)
}
}
const columns: ColumnType<any>[] = [
{
......@@ -100,25 +119,21 @@ const AccountDetail: React.FC<{}> = () => {
];
const handleConfirm = () => {
schemaActions.submit()
}
const handleCannel = () => {
}
const handleSubmit = () => {
schemaActions.submit()
const handleSubmit = (value) => {
console.log(value)
}
const handleRecharge = () => {
console.log(modalRef)
modalRef.current.setVisible(true)
}
// 前缀币制符号
// const characters = '$'
return (
<PageHeaderWrapper
title="账户详情"
......@@ -134,12 +149,12 @@ const AccountDetail: React.FC<{}> = () => {
<div className={styles.statistic}>
<div className={styles['statistic-title']}>可用余额(元):</div>
<div className={styles['statistic-amount']}>
{`100000`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
{`${details.accountBalance - details.lockBalance}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
</div>
</div>
<div className={styles['repayment-end']}>
<span className={styles['repayment-time']}>
温州市龙昌皮具有限公司
{details?.memberName}
</span>
</div>
</div>
......@@ -152,7 +167,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户归属:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>广州数商云网络科技有限公司</p>
<p className={styles.rightInfo}>{details?.parentMemberName}</p>
</Col>
</Row>
<Row>
......@@ -160,7 +175,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户余额(元):</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>10,000</p>
<p className={styles.rightInfo}>{details?.accountBalance}</p>
</Col>
</Row>
<Row>
......@@ -168,7 +183,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>锁定金额(元):</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>0.00</p>
<p className={styles.rightInfo}>{details?.lockBalance}</p>
</Col>
</Row>
<Row>
......@@ -176,7 +191,12 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户状态:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}><StatusTag type="success" title="正常" /></p>
<p className={styles.rightInfo}>
{
details?.accountStatus &&
<StatusTag title={memberStatusMap[details.accountStatus]['title']} type={memberStatusMap[details.accountStatus]['type']} />
}
</p>
</Col>
</Row>
</div>
......@@ -184,7 +204,7 @@ const AccountDetail: React.FC<{}> = () => {
<Col span={6}>
<div className={styles.rightActions}>
<Button className={styles.rightAction} type="primary" onClick={handleRecharge}>充值</Button>
<Button className={styles.rightAction}>申请提现</Button>
<Button className={styles.rightAction} onClick={() => history.push(`/memberCenter/payandSettle/capitalAccounts/accountLists/applyWithdraw?id=${details?.id}`)}>申请提现</Button>
</div>
</Col>
</Row>
......@@ -208,7 +228,7 @@ const AccountDetail: React.FC<{}> = () => {
confirm={handleConfirm}
onSubmit={handleSubmit}
cancel={handleCannel}
effects={($, {setFieldState}) => {
// effects={($, {setFieldState}) => {
// $('onFieldInputChange', 'money').subscribe(parentState => {
// console.log(parentState.value)
// setFieldState('money', state => {
......@@ -216,7 +236,7 @@ const AccountDetail: React.FC<{}> = () => {
// })
// })
// useAsyncSelect('addresId', async () => (await PublicApi.getLogisticsSelectListShipperAddress()).data, ['fullAddress', 'id'])
}}
// }}
/>
</PageHeaderWrapper>
)
......
......@@ -8,13 +8,30 @@ import StatusTag from '@/components/StatusTag'
import cx from 'classnames'
import moment from 'moment'
import { ColumnType } from 'antd/lib/table/interface'
import { statusMap } from '../../constant'
import { memberStatusMap, statusMap } from '../../constant'
import { PublicApi } from '@/services/api'
const { Step } = Steps;
const AccountDetail: React.FC<{}> = () => {
const [ details, setDetails ] = useState<any>({ accountBalance: 0, lockBalance: 0})
const [dealRecord, setDealRecord] = useState<any>()
const [withdrawAmount, setWidthdrawAmount] = useState<number>(0)
useEffect(() => {
getAccountInfo()
}, [])
const getAccountInfo = async () => {
const { id } = history.location.query
let res = await PublicApi.getPayAssetAccountGetAssetAccount({id})
const { code, data } = res
setDetails(data)
if(code === 1000){
let tradeRecord = await PublicApi.getPayAssetAccountGetAccountTradeRecord({memberAssetAccountId: data.id + ''})
setDealRecord(tradeRecord.data)
}
}
const columns: ColumnType<any>[] = [
{
......@@ -56,6 +73,10 @@ const AccountDetail: React.FC<{}> = () => {
},
];
const handleAllCharge = () => {
setWidthdrawAmount(details.accountBalance - details.lockBalance)
}
return (
<PageHeaderWrapper
title="申请提现"
......@@ -82,19 +103,25 @@ const AccountDetail: React.FC<{}> = () => {
<div className={styles['statistic-title']}>提现金额(元):</div>
<div style={{display: 'flex',alignItems:'flex-end'}}>
<InputNumber
defaultValue={0}
defaultValue={withdrawAmount}
value={withdrawAmount}
formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
parser={value => value.replace(/\$\s?|(,*)/g, '')}
className={styles['statistic-input']}
/>
<Button type="text" size="small" style={{marginLeft:24, color:'#fff'}}>
<Button
type="text"
size="small"
style={{marginLeft:24, color:'#fff'}}
onClick={handleAllCharge}
>
全部提现
</Button>
</div>
</div>
<div className={styles['repayment-end']}>
<span className={styles['repayment-time']}>
最多可以提现:¥10,000.00
最多可以提现:¥ {details.accountBalance - details.lockBalance}
</span>
</div>
</div>
......@@ -110,7 +137,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户归属:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>广州数商云网络科技有限公司</p>
<p className={styles.rightInfo}>{details?.parentMemberName}</p>
</Col>
</Row>
<Row>
......@@ -143,12 +170,12 @@ const AccountDetail: React.FC<{}> = () => {
<div className={styles.statistic}>
<div className={styles['statistic-title']}>可用余额(元):</div>
<div className={styles['statistic-amount']}>
{`100000`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
{`${details.accountBalance - details.lockBalance}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
</div>
</div>
<div className={styles['repayment-end']}>
<span className={styles['repayment-time']}>
温州市龙昌皮具有限公司
{details?.memberName}
</span>
</div>
</div>
......@@ -161,7 +188,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户归属:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>广州数商云网络科技有限公司</p>
<p className={styles.rightInfo}>{details?.parentMemberName}</p>
</Col>
</Row>
<Row>
......@@ -169,7 +196,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户余额(元):</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>10,000</p>
<p className={styles.rightInfo}>{details?.accountBalance}</p>
</Col>
</Row>
<Row>
......@@ -177,7 +204,7 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>锁定金额(元):</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}>0.00</p>
<p className={styles.rightInfo}>{details?.lockBalance}</p>
</Col>
</Row>
<Row>
......@@ -185,7 +212,10 @@ const AccountDetail: React.FC<{}> = () => {
<p className={styles.rightTitle}>账户状态:</p>
</Col>
<Col span={20}>
<p className={styles.rightInfo}><StatusTag type="success" title="正常" /></p>
{
details?.accountStatus &&
<StatusTag title={memberStatusMap[details.accountStatus]['title']} type={memberStatusMap[details.accountStatus]['type']} />
}
</Col>
</Row>
</div>
......
......@@ -13,7 +13,8 @@ import { PlusOutlined } from '@ant-design/icons'
import EyePreview from '@/components/EyePreview'
import { DatePicker } from '@formily/antd-components'
import StatusTag from '@/components/StatusTag'
import { accountStatusMap, memberStatusMap } from '../../constant'
import { accountStatusMap, memberStatusMap, memberLevelTypeMap } from '../../constant'
import LevelBrand from '@/pages/member/components/LevelBrand'
const formActions = createFormActions();
......@@ -43,14 +44,16 @@ const AccountLists: React.FC<{}> = () => {
key: 'memberRoleName',
},
{
title: '会员等级',
dataIndex: 'memberLevelName',
key: 'memberLevelName',
title: '所属会员等级',
dataIndex: 'memberLevel',
key: 'memberLevel',
render: (t, r) => <LevelBrand level={r.memberLevel} />
},
{
title: '会员等级类型',
dataIndex: 'memberLevelType',
key: 'memberLevelType',
render: (t, r) => memberLevelTypeMap[t]
},
{
title: '会员状态',
......@@ -62,7 +65,7 @@ const AccountLists: React.FC<{}> = () => {
title: '账户状态',
dataIndex: 'accountStatus',
key: 'accountStatus',
render: (t, r) => (<span className={memberStatusMap[t]['className']}>{accountStatusMap[t]['title']}</span>)
render: (t, r) => (<><span className={accountStatusMap[t]['className']}></span>{accountStatusMap[t]['title']}</>)
},
{
title: '账户余额',
......@@ -80,7 +83,7 @@ const AccountLists: React.FC<{}> = () => {
title: '可用余额',
dataIndex: 'usableBalance',
key: 'usableBalance',
render: text => `¥${text}`
render: (t, r) => `¥${r.accountStatus - r.lockBalance}`
},
]
......
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import alipay from '@/assets/imgs/alipay_icon.png';
import wxpay from '@/assets/imgs/wechat_icon.png';
export const searchSchema: ISchema = {
type: 'object',
......@@ -107,27 +109,12 @@ export const rechargeSchema: ISchema = {
wrapperCol: 24
},
properties: {
// money: {
// type: 'number',
// title: '充值金额',
// "x-component-props": {
// style: {
// width: '100%'
// },
// },
// "x-rules": [
// {
// required: true,
// message: '请输入充值金额'
// },
// ]
// },
money: {
type: "string",
title: '充值金额',
'x-component-props': {
addonBefore: "¥"
addonBefore: "¥",
suffix: "RMB"
},
"x-rules": [
{
......@@ -141,7 +128,12 @@ export const rechargeSchema: ISchema = {
type: "array:number",
"x-component": 'CardCheckBox',
"x-component-props": {
dataSource: [],
dataSource: [
// {id: 1, name: '支付宝', logo: 'https://shushangyun01.oss-cn-shenzhen.aliyuncs.com/66bf577211624304947938a2afde771b1603682420367.png'},
// {id: 2, name: '微信', logo: 'https://shushangyun01.oss-cn-shenzhen.aliyuncs.com/733815c243ce4cec8a8cb10e0e92876f1603682449715.png'}
{id: 1, name: '支付宝', logoUrl: alipay},
{id: 2, name: '微信', logoUrl: wxpay}
],
type: 'radio' // CardCheckBox 单选模式
},
"title": "充值方式",
......@@ -152,7 +144,6 @@ export const rechargeSchema: ISchema = {
}
],
}
}
}
}
......
......@@ -84,4 +84,10 @@ export const memberStatusMap = {
export const accountStatusMap = {
'1': { title: '正常', className: 'commonStatusValid' },
'2': { title: '已冻结', className: 'commonStatusNoPass' },
}
export const memberLevelTypeMap = {
'1': '平台会员',
'2': '商户会员',
'3': '渠道会员',
}
\ No newline at end of file
......@@ -41,7 +41,7 @@ const QuotaMenage: React.FC = () => {
align: 'center',
render: (text, record) => (
<>
{/* 未申请过,并且授信状态为未申请 或者 申请中 */}
{/* 未申请过,并且授信状态为未申请 或者 申请中 则显示文本 */}
{(!record.isHasApply && (record.status === CREDIT_STATUS_NOT_APPLIED || record.status === CREDIT_STATUS_APPLYING)) ? (
text
) : (
......@@ -94,7 +94,7 @@ const QuotaMenage: React.FC = () => {
render: (text, record) => (
<Progress
type="circle"
percent={Math.floor(record.useQuota / record.quota)}
percent={Math.floor(record.useQuota / record.quota) * 100}
strokeColor="#41CC9E"
strokeWidth={12}
width={40}
......
......@@ -41,7 +41,7 @@ const TransactionRules: React.FC<{}> = () => {
key: 'name',
className: 'commonPickColor',
render: (text: any, record: any) => <EyePreview
url={`/memberCenter/tranactionAbility/transactionRules/addRule?id=${record.id}&preview=1`}
url={`/memberCenter/tranactionAbility/transactionRules/detail?id=${record.id}&preview=1`}
>
{text}
</EyePreview>
......@@ -96,7 +96,7 @@ const TransactionRules: React.FC<{}> = () => {
>
<Button type='link'>删除</Button>
</Popconfirm>
<Button type='link' onClick={()=>history.push(`/memberCenter/tranactionAbility/transactionRules/addRule?id=${record.id}`)}>修改</Button>
<Button type='link' onClick={()=>history.push(`/memberCenter/tranactionAbility/transactionRules/add?id=${record.id}`)}>修改</Button>
</> : ''
}
</>
......@@ -168,7 +168,7 @@ const TransactionRules: React.FC<{}> = () => {
},
children: (
<>
<Button type="primary" icon={<PlusOutlined />} onClick={() => history.push('/memberCenter/tranactionAbility/transactionRules/addRule')}>
<Button type="primary" icon={<PlusOutlined />} onClick={() => history.push('/memberCenter/tranactionAbility/transactionRules/add')}>
新建
</Button>
</>
......
......@@ -113,48 +113,58 @@ export function timeRange(val: number) {
return { st, et }
}
export const arrayGroupsByCount = (array, count) => {
let index = 0;
let newArray = [];
while (index < array.length) {
newArray.push(array.slice(index, index += count));
}
return newArray;
}
// 判断是否是素数
export function isPrimeNum(num){
if (!isNum(num)){
return false;
export function isPrimeNum(num) {
if (!isNum(num)) {
return false;
}
if (!isInteger(num)){
return false;
if (!isInteger(num)) {
return false;
}
if (num==2||num==3||num==5) {
return true;
if (num == 2 || num == 3 || num == 5) {
return true;
}
if (!isDual(num)){
return false;
if (!isDual(num)) {
return false;
}
if (!isThree(num)){
return false;
if (!isThree(num)) {
return false;
}
for (var i = 2; i < num/5+1; i++) {
if (num%i==0){
return false;
}
for (var i = 2; i < num / 5 + 1; i++) {
if (num % i == 0) {
return false;
}
};
return true;
}
function isInteger(num){
function isInteger(num) {
return num == ~~num ? true : false;
}
function isNum(num){
function isNum(num) {
return num == +num ? true : false;
}
function isDual(num){
function isDual(num) {
var num = num.toString();
var lastNum = num.substring(num.length-1,num.length);
return lastNum%2 == 0 || lastNum%5 == 0 ? false : true;
var lastNum = num.substring(num.length - 1, num.length);
return lastNum % 2 == 0 || lastNum % 5 == 0 ? false : true;
}
function isThree(num){
function isThree(num) {
var str = num.toString();
var sum = 0;
for (var i = 0; i < str.length; i++) {
sum += +str.substring(i,i+1);
sum += +str.substring(i, i + 1);
};
return sum%3 == 0 ? false : true;
return sum % 3 == 0 ? false : true;
}
export function omit(obj: any, arr: string[]) {
......@@ -173,7 +183,7 @@ export function omit(obj: any, arr: string[]) {
export const findItemAndDelete = (arr: any[], target: any, customKey?: string) => {
const newArr = [...arr]
if (newArr.length > 0 && isObject(newArr[0])) {
return newArr.filter(v => v[customKey||'id'] !== target)
return newArr.filter(v => v[customKey || 'id'] !== target)
}
const targetIndex = arr.indexOf(target)
if (targetIndex === -1) {
......@@ -247,7 +257,7 @@ export const getStepNumber = (target: number, step?: number) => {
export const findTreeKeys = (arr: any[], keyword?: ReactText) => {
const copyArr: any[] = deepClone(arr)
const results: any[] = []
while(copyArr.length > 0) {
while (copyArr.length > 0) {
const item = copyArr.shift()
results.push(Number(keyword ? item[keyword] : item.key))
if (item.children) {
......@@ -303,7 +313,7 @@ export const transFormSchema = (data: any[]): ISchema => {
}
}
}
}
}
......@@ -337,9 +347,9 @@ export const getFieldType = (field) => {
}
}),
maxLength: field.fieldLength,
"x-component-props": {
help: field.fieldRemark,
placeholder: `请输入${field.fieldCNName}`,
"x-component-props": {
help: field.fieldRemark,
placeholder: `请输入${field.fieldCNName}`,
size: 'large'
}
}
......@@ -409,14 +419,14 @@ export const padRequiredMessage = (originSchema: ISchema) => {
return type ? '请选择' : '请输入'
}
const todoFn = (targetSchema) => {
}
Object.entries(originSchema.properties).map(([key, value]) => {
if (value.required) {
const isSelect = value.enum
const message = messageSwich(isSelect) + (value.title || '')
value['x-rules'] = Array.isArray(value['x-rules']) ? value['x-rules'].concat([{ message, required: true }]) : [{message, required: true}]
value['x-rules'] = Array.isArray(value['x-rules']) ? value['x-rules'].concat([{ message, required: true }]) : [{ message, required: true }]
}
if (value.properties) {
padRequiredMessage(value)
......@@ -477,7 +487,7 @@ export const isJSONStr = str => {
try {
const complete = JSON.parse(str);
return complete;
} catch(e) {
} catch (e) {
return null;
}
}
......
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