Commit 34c207b5 authored by 前端-许佳敏's avatar 前端-许佳敏
parents 9576018f 11254eb0
......@@ -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',
},
]
},
// 会员信息查询
......
......@@ -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
......@@ -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}
......
......@@ -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