first commit

This commit is contained in:
编码猿
2024-09-27 01:32:49 +08:00
commit 28ebe05a64
7399 changed files with 1174529 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab

19
滴滴淘/houtaiguanli/.gitignore vendored Normal file
View File

@@ -0,0 +1,19 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/npm-debug.log*
/yarn-error.log
/yarn.lock
/package-lock.json
# production
/dist
# misc
.DS_Store
# umi
/src/.umi/
/.env.local
.idea/

View File

@@ -0,0 +1,8 @@
**/*.md
**/*.svg
**/*.ejs
**/*.html
package.json
.umi
.umi-production
.umi-test

View File

@@ -0,0 +1,11 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}

View File

@@ -0,0 +1 @@
8c81ca36-90f1-4e55-8da8-d1a9563d8049

View File

@@ -0,0 +1,74 @@
import path from 'path';
import { defineConfig } from 'umi';
import routes from './src/routes/index';
export default defineConfig({
nodeModulesTransform: {
type: 'none',
},
// 开启分包
// dynamicImport: {
// loading: resolve('src/components/loading/loading.tsx'),
// },
publicPath: './',
history: { type: 'hash' },
// 启动自定义配置
runtimePublicPath: true,
// 开启dva模式
dva: {},
routes: routes,
// 目录别名方便引入
alias: {
'@service': resolve('src/core/service/imp'),
'@assets': resolve('src/assets'),
'@components': resolve('src/components'),
'@less': resolve('src/assets/less'),
'@annotation': resolve('src/core/annotation'),
'@Ioc': resolve('src/core/Ioc'),
},
// 额外的css
styles: [`.selectOption .ant-select-item-option-content { word-wrap: break-word; white-space: normal;}`],
// 需要兼容的最低版本
targets: { chrome: 49, firefox: 64, safari: 10, edge: 13, ios: 10 },
// proxy: {
// "/api": {
// "target": "https://pvp.qq.com",
// "changeOrigin": true,
// "pathRewrite": { "^/api": "" }
// }
// }
plugins: ['@alitajs/hd'],
// 开启rem配置参考https://github.com/alitajs/alita/tree/master/packages/hd#readme或者看声明文件中的参数
// hd: {
// rootValue: 75,
// propBlackList: [], //不需要转换的属性
// selectorBlackList: [], //以包含***的class不需要转换
// },
extraPostCSSPlugins: [],
// 提取公共依赖
// chainWebpack: function (config, { webpack }) {
// config.merge({
// optimization: {
// minimize: true,
// splitChunks: {
// chunks: 'all',
// minSize: 30000,
// minChunks: 3,
// automaticNameDelimiter: '.',
// cacheGroups: {
// vendor: {
// name: 'vendors',
// test({ resource }) {
// return /[\\/]node_modules[\\/]/.test(resource);
// },
// priority: 10,
// },
// },
// },
// }
// });
// },
});
function resolve(dir: string) {
return path.join(__dirname, dir);
}

View File

@@ -0,0 +1 @@
#houtaiguanli

View File

View File

@@ -0,0 +1 @@
7e88e718-ac00-4993-adc9-a2c860cbfaa5

View File

@@ -0,0 +1,9 @@
export default {
// 支持值为 Object 和 Array
'GET /api/getUser': { users: [1, 2] },
// GET 可忽略
'/api/users/1': { id: 1 },
// GET 可忽略
'GET /api/login': { token: 'asdadadasddddddddddasdad' },
};

View File

@@ -0,0 +1,37 @@
{
"private": true,
"scripts": {
"start": "umi dev",
"build": "umi build",
"postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test",
"test:coverage": "umi-test --coverage"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,less,md,json}": [
"prettier --write"
],
"*.ts?(x)": [
"prettier --parser=typescript --write"
]
},
"dependencies": {
"@alitajs/hd": "^2.3.9",
"@ant-design/pro-layout": "^6.4.19",
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.1.0",
"axios": "^0.19.2",
"copy-to-clipboard": "^3.3.1",
"lint-staged": "^10.0.7",
"prettier": "^1.19.1",
"react": "16.13.1",
"react-dom": "16.13.1",
"umi": "^3.1.0",
"wangeditor": "^3.1.1",
"yorkie": "^2.0.0"
}
}

View File

@@ -0,0 +1 @@
8f459caa-1d1c-445e-82a3-b9cabff3671a

View File

@@ -0,0 +1,8 @@
import { history } from 'umi';
import { Utils } from '@/core/utils/utils';
import 'antd/dist/antd.css';
// 没有登录
if (localStorage.getItem('token') == null) {
history.push('/login');
}

View File

@@ -0,0 +1 @@
da3e00f3-3d84-4c55-874c-7b1ad2876144

View File

@@ -0,0 +1 @@
d4d3be68-2d8d-479b-8375-270855746cb3

View File

@@ -0,0 +1,2 @@
@import './public/font.less';
@import './public/index.less';

View File

@@ -0,0 +1 @@
2754d97e-98a6-4612-a9a1-200a246f6e00

View File

@@ -0,0 +1,48 @@
// 主题颜色
// 产品品牌色,多用于主按钮。重要图标,重要入口
@c1: #1890ff;
@c2: #d9ecff;
@c3: #ecf5ff;
// 辅助色 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)
@success1: #67c23a;
@success2: #e1f3d8;
@success3: #f0f9eb;
@warning1: #e6a23c;
@warning2: #faecd8;
@warning3: #fdf6ec;
@danger1: #f56c6c;
@danger2: #fde2e2;
@danger3: #fef0f0;
@info1: #909399;
@info2: #e9e9eb;
@info3: #f4f4f5;
// 点缀色 主要用于提示作用,多用于标签,角标,小按钮等
@emb1: #67C23A;
@emb2: #F56C6C;
// 文字主题色
// 多用于标题文字,重要文字
@color1: #303133;
@color2: #606266;
@color3: #909399;
@color4: #c0c4cc;
// 常规颜色
@white: #fff;
@black: #000;
// 线条颜色
@BorderBase: #DCDFE6;
// 阴影颜色
@shadow: #8fa8bf59;
// 背景色
@BackgroundColor: #f2f2f2;
@NavbarColor: #273543;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,86 @@
@import './color.less';
html {
background-color: @BackgroundColor;
min-width: 1200px;
}
.center {
background-color: @white;
}
.ml10{
margin-left: 10px !important;
}
.ml130{
margin-left: 130px;
}
.mr10{
margin-right: 10px;
}
.mt20{
margin-top: 20px;
}
.mt24{
margin-top: 24px;
}
.mt30{
margin-top: 30px;
}
.mb5{
margin-bottom: 5px;
}
.mb10{
margin-bottom: 10px;
}
.mb20{
margin-bottom: 20px !important;
}
.mb25{
margin-bottom: 25px;
}
.mr5{
margin-right: 5px;
}
.pr10{
padding-right: 10px;
}
.pd7{
padding: 7.5px;
}
.pd20{
padding: 20px;
}
.lineHegith{
line-height: 32px;
}
.flex{
display: flex;
}
.flex1{
flex: 1;
}
.flex3{
flex: 3;
}
.align{
align-items: center;
}
.between{
justify-content: space-between;
}
.column{
flex-direction: column;
}
.flexWrap{
flex-wrap:wrap;
}
.dottedLine{
border: 1px dashed @BorderBase;
padding: 10px 0;
text-align: center;
cursor: pointer;
&:hover{
border-color: @c1;
color: @c1;
}
}

View File

@@ -0,0 +1,45 @@
@import './color.less';
.scroll() {
&::-webkit-scrollbar {
/*滚动条整体样式*/
height: 4px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #535353;
}
&::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 10px;
background: #ededed;
}
}
.shadow() {
box-shadow: 0 0px 20px @shadow;
}
.marginAuto(@w: 990px, @c: #ffffff, @p: 20px) {
width: @w;
margin: 0px auto;
padding: @p;
background-color: @c;
height: 100%;
// box-sizing: border-box;
}
.hiddenText(@a: 1) {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: @a;
-webkit-box-orient: vertical;
}
.title(){
color: @black;
font-size: 16px;
margin: 0 0 20px 0;
font-weight: bold;
}

View File

@@ -0,0 +1 @@
b7db3c47-9d9e-42eb-a5ed-e1bfab66c3bb

View File

@@ -0,0 +1 @@
85dc4b27-55c5-4acb-86ea-0306309f7863

View File

@@ -0,0 +1,20 @@
@themecolor:#ffc900;
.myprogress {
position: fixed;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.7);
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1001;
.progress{
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}

View File

@@ -0,0 +1,62 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import './index.less'
import { Spin } from 'antd';
import { SyncOutlined } from '@ant-design/icons';
class Progress extends Component {
state: {
show: boolean,
time: NodeJS.Timeout | null
} = {
show: false,
time: null
}
start() { // 开始显示
this.setState({
show: true
})
this.state.time = setTimeout(() => {
this.setState({
show: false
})
clearTimeout(this.state.time as NodeJS.Timeout)
}, 10000)
}
done() { // 结束隐藏
this.setState({
show: false
})
clearTimeout(this.state.time as NodeJS.Timeout)
}
render() {
return (
<div className="myprogress" style={this.state.show ? { display: 'block' } : { display: 'none' }}>
<div className="progress">
<div style={{ textAlign: 'center' }}>
<SyncOutlined spin style={{ fontSize: 28, color: '#409eff' }} />
<p style={{ fontSize: 18, color: '#409eff' }}></p>
</div>
</div>
</div>
)
}
}
// 创建元素追加到body
let div = document.createElement('div');
let props = {
};
document.body.appendChild(div);
let AxiosLoading = ReactDOM.render(React.createElement(
Progress,
props
), div);
export default AxiosLoading;

View File

@@ -0,0 +1 @@
8e0ba04f-de0e-409b-96ea-22ebdd8b6bff

View File

@@ -0,0 +1,9 @@
@import '../../assets/less/public/color.less';
@import '../../assets/less/public/mixins.less';
.header {
position: fixed;
height: 50px;
width: 100%;
background-color: #191a23;
}

View File

@@ -0,0 +1,151 @@
import React, { Component } from 'react';
import style from './index.less';
import { Menu, Dropdown } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { history } from 'umi';
import { BuyerService } from '@/core/service/buyerService';
import {
Select,
Input,
DatePicker,
Button,
Table,
Modal,
message,
Form,
Row,
Col,
} from 'antd';
const tailLayout = {
wrapperCol: { offset: 5, span: 16 },
};
const layout = {
labelCol: { span: 5 },
wrapperCol: { span: 16 },
};
class Head extends Component {
state = {
isShowEditPassword: false,
userInfo: {},
};
async componentDidMount() {
await this.userInfo();
}
async userInfo() {
let res = await BuyerService.userInfo({});
console.log('用户信息:', res);
this.setState({ userInfo: res });
}
menu() {
return (
<Menu>
<Menu.Item>
<a
onClick={() => {
this.setState({ isShowEditPassword: true });
}}
>
</a>
</Menu.Item>
<Menu.Item>
<a
onClick={() => {
if (confirm('确认退出登录吗?')) {
localStorage.removeItem('token');
setTimeout(() => history.push('/login'), 300);
}
}}
>
退
</a>
</Menu.Item>
</Menu>
);
}
async onFinish(values: any) {
let res = await BuyerService.setPassword(values);
this.setState({ isShowEditPassword: false });
}
onFinishFailed(errorInfo: any) {
console.log('Failed:', errorInfo);
}
render() {
return (
<div className={style.header}>
<Dropdown overlay={this.menu()}>
<a
style={{
float: 'right',
lineHeight: '50px',
marginRight: '50px',
color: '#fff',
}}
className="ant-dropdown-link"
onClick={e => e.preventDefault()}
>
{(this.state.userInfo as any).username} <DownOutlined />
</a>
</Dropdown>
<Modal
title="修改秘密"
footer=""
visible={this.state.isShowEditPassword}
onOk={() => {}}
onCancel={() => this.setState({ isShowEditPassword: false })}
>
<Form
{...layout}
name="basic"
style={{ width: '100%', margin: '0 auto' }}
initialValues={{ remember: true }}
onFinish={this.onFinish.bind(this)}
onFinishFailed={this.onFinishFailed}
>
<Form.Item
label="原始密码"
name="origin_password"
rules={[{ required: true, message: '请输入原始密码' }]}
>
<Input />
</Form.Item>
<Form.Item
label="新密码"
name="new_password"
rules={[{ required: true, message: '请输入新密码' }]}
>
<Input.Password />
</Form.Item>
<Form.Item
label="确认新密码"
name="repeat_password"
rules={[{ required: true, message: '请输入确认密码' }]}
>
<Input.Password />
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
</Button>
</Form.Item>
</Form>
</Modal>
</div>
);
}
}
export default Head;

View File

@@ -0,0 +1 @@
61eed9ff-7bd1-4a8a-8fb3-758ba5bbc9f1

View File

@@ -0,0 +1,28 @@
import React, { Component } from 'react';
import '@assets/less/index.less';
type IProps = {
icon: string;
fontSize?: number;
color?: string;
};
class Icon extends Component<IProps> {
private readonly IconConfig: IProps;
constructor(props: IProps) {
super(props);
this.IconConfig = props;
}
render() {
return (
<i
className={`buyer-font ${this.IconConfig.icon}`}
style={{ fontSize: this.props.fontSize, color: this.props.color }}
></i>
);
}
}
export default Icon;

View File

@@ -0,0 +1,11 @@
import MyIcon from './icon';
import Loading from './loading';
import Navbar from './navbar';
import Head from './header';
export {
MyIcon,
Loading,
Navbar,
Head
};

View File

@@ -0,0 +1 @@
675b0b4f-dee9-4db4-a7ff-5f1ed41aacf5

View File

@@ -0,0 +1,22 @@
import React, { Component } from 'react';
import { Spin } from 'antd';
const style = {
height: '100%',
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
};
class Loading extends Component {
render() {
return (
<div style={style}>
<Spin size="large" />
</div>
);
}
}
export default Loading;

View File

@@ -0,0 +1 @@
7b760731-e739-4966-a6f0-9d0b0f3345fe

View File

@@ -0,0 +1,24 @@
@import '../../assets/less/public/color.less';
@import '../../assets/less/public/mixins.less';
.navbar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
height: 100%;
width: 240px;
z-index: 999;
background-color: #191a23;
box-shadow: 2px 0 6px rgba(0,21,41,.35);
.logo{
color: @white;
height: 50px;
margin-bottom: 10px;
text-align: center;
line-height: 42px;
}
.menuColor{
background-color: #191a23;
}
}

View File

@@ -0,0 +1,308 @@
import React, { Component } from 'react';
import style from './index.less';
import { Menu } from 'antd';
import { history } from 'umi';
import {
AppstoreOutlined,
PieChartOutlined,
TransactionOutlined,
createFromIconfontCN,
} from '@ant-design/icons';
import route from '@/routes/index';
const { SubMenu } = Menu;
type children = {
path: string;
title: string;
};
interface routerConfig {
path: string;
title: string;
icon: JSX.Element;
children: children[];
}
const MyIcon = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_1629634_h3podjyxjv.js', // 在 iconfont.cn 上生成
});
class Navbar extends Component {
private route = route;
private rootSubmenuKeys = ['realName', 'buyerAccouet', 'realName2'];
state = {
collapsed: false,
routerConfig: [
{
path: '/realName',
title: '实名认证',
icon: <MyIcon type="buyer-icon-credentials_icon" />,
children: [
{
path: '/realName/realNameList',
title: '审核中列表',
},
{
path: '/realName/adoptList',
title: '已通过列表',
},
{
path: '/realName/failedList',
title: '未通过列表',
},
{
path: '/realName/rejectList',
title: '已拒绝列表',
},
],
},
{
path: '/task',
title: '任务管理',
icon: <MyIcon type="buyer-icon-credentials_icon" />,
children: [
{
path: '/task/tobeReviewed',
title: '任务管理',
},
],
},
{
path: '/buyerAccouet',
title: '买号管理',
icon: <MyIcon type="buyer-icon-mai" />,
children: [
{
path: '/buyerAccouet/examineList',
title: '审核中列表',
},
{
path: '/buyerAccouet/adoptList',
title: '已通过列表',
},
{
path: '/buyerAccouet/rejectList',
title: '已拒绝列表',
},
{
path: '/buyerAccouet/deviceList',
title: '设备列表',
},
],
},
{
path: '/userList',
title: '用户列表',
icon: <MyIcon type="buyer-icon-icon_signal" />,
children: [
{
path: '/userList/MerchantList',
title: '商家列表',
},
{
path: '/userList/BuyerList',
title: '买家列表',
},
{
path: '/userList/PromotionList',
title: '推广列表',
},
],
},
{
path: '/fundManagement',
title: '资金管理',
icon: <MyIcon type="buyer-icon-qian" />,
children: [
{
path: '/fundManagement/fundRecords',
title: '资金记录',
},
{
path: '/fundManagement/RechargeRecord',
title: '充值记录',
},
{
path: '/fundManagement/BuyerCash',
title: '买家提现记录',
},
{
path: '/fundManagement/extension',
title: '推广提现记录',
},
{
path: '/TransferOut/list',
title: '转出记录',
},
],
},
{
path: '/shop',
title: '店铺管理',
icon: <MyIcon type="buyer-icon-dianpu1" />,
children: [
{
path: '/shop/list',
title: '店铺列表',
},
{
path: '/shop/BuyerEvaluate',
title: '买家评价列表',
},
{
path: '/shop/BusinessEvaluate',
title: '商家评价列表',
},
{
path: '/shop/BabyManagement',
title: '宝贝管理',
},
],
},
{
path: '/VersionManagement',
title: 'App版本管理',
icon: <MyIcon type="buyer-icon-android" />,
children: [
{
path: '/VersionManagement/add',
title: '添加版本',
},
{
path: '/VersionManagement/list',
title: '添加列表',
},
],
},
{
path: '/other',
title: '其他功能',
icon: <MyIcon type="buyer-icon-qita" />,
children: [
{
path: '/other/Notice',
title: '公告管理',
},
{
path: '/other/HelpCenter',
title: '帮助中心',
},
{
path: '/other/ExceptionList',
title: '队列异常管理',
},
{
path: '/other/TaskExceptionList',
title: '任务异常管理',
},
],
},
{
path: '/cms',
title: '内容管理',
icon: <MyIcon type="buyer-icon-gonggao" />,
children: [
{
path: '/other/Notice',
title: '公告管理',
},
{
path: '/other/HelpCenter',
title: '帮助中心',
},
{
path: '/cms/ChangeLog',
title: '更新日志',
},
],
},
{
path: '/SmsManagement',
title: '短信管理',
icon: <MyIcon type="buyer-icon-pinglun" />,
children: [
{
path: '/SmsManagement/smsList',
title: '短信列表',
},
],
},
],
defaultSelectedKeys: '',
openKeys: [''],
};
componentWillMount() {
let arr = history.location.pathname.match(/\/[^\/]*/g) || [];
if (arr.length <= 0) return;
this.setState({
defaultSelectedKeys: history.location.pathname,
openKeys: [JSON.parse(JSON.stringify(arr[0]))],
});
}
Item(data: children[]) {
return data.map((v, i) => {
return (
<Menu.Item key={v.path} onClick={() => history.push(v.path)}>
{v.title}
</Menu.Item>
);
});
}
Menu(data: routerConfig[]) {
return data.map((v, i) => {
return v.children.length > 0 ? (
<SubMenu
key={v.path}
title={
<div>
{v.icon} {v.title}
</div>
}
>
{this.Item(v.children)}
</SubMenu>
) : (
<Menu.Item key={v.path} onClick={() => history.push(v.path)}>
{v.icon} {v.title}
</Menu.Item>
);
});
}
onOpenChange = (openKeys: any) => {
const latestOpenKey = openKeys.find(
(key: any) => this.state.openKeys.indexOf(key) === -1,
);
if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
this.setState({
openKeys: latestOpenKey ? [latestOpenKey] : [],
});
}
};
render() {
return (
<div className={style.navbar}>
<div className={style.logo}></div>
<Menu
defaultSelectedKeys={[this.state.defaultSelectedKeys]}
openKeys={this.state.openKeys}
mode="inline"
theme="dark"
className={style.menuColor}
inlineCollapsed={this.state.collapsed}
onOpenChange={this.onOpenChange}
>
{this.Menu(this.state.routerConfig)}
</Menu>
</div>
);
}
}
export default Navbar;

View File

@@ -0,0 +1 @@
b9bb48e3-c4b1-4073-8cf9-b3364c0092cb

View File

@@ -0,0 +1 @@
eca19925-9acb-4537-9248-98fbdc1cccc9

View File

@@ -0,0 +1,18 @@
import React, { Component } from 'react';
import { Utils } from '@/core/utils/utils'
interface utlisType {
[k: string]: Function;
}
export class IocComponent<P = {}, S = {}> extends Component<P, S> {
/**
* 挂载全局方法
*/
protected globalMethod: utlisType = {};
// 挂载工具类
protected Utils: typeof Utils = Utils
}
export default React;

View File

@@ -0,0 +1 @@
0fb81f0f-982d-4dd3-9999-c3dcf76a1af8

View File

@@ -0,0 +1,16 @@
import { PublicService } from '@/core/service/publicService'
// import UserModel from '@/models/user';
import { Utils } from '@/core/utils/utils'
const publicService: PublicService = new PublicService()
/**
* 如果页面刷新则重新发送ajax来获取路由配置
* 从路由配置中获取当前组件的等级
* @param params 组件名
*/
export function access(params: string) {
return function (target: any) {
// let lv: number = Utils.valueOnArror(UserModel.state.routerConfig, params)
// target.access = lv > 0 ? lv : 0
}
}

View File

@@ -0,0 +1,68 @@
import { Axios } from "@/core/dao/index";
const axios = new Axios()
interface requestOption {
url?: string
str?: string
loading?: boolean
}
/**
* 获取方法名作为请求url
* 获取入参作为请求参数
*/
export function get(option?: requestOption) {
return function (target: any, attr: string, descriptor: PropertyDescriptor) {
let url: string;
if (option && option.url) {
url = option.url
} else if (option && option.str) {
url = `${option.str}/${attr}`
}
descriptor.value = async function (data: any) {
let res = await axios.get({
url: url,
data: data,
loading: option?.loading
})
return res
}
}
}
export function post(option?: requestOption) {
return function (target: any, attr: string, descriptor: PropertyDescriptor) {
let url: string;
if (option && option.url) {
url = option.url
} else if (option && option.str) {
url = `${option.str}/${attr}`
}
descriptor.value = async function (data: any) {
let res = await axios.post({
url: !!url ? url : attr,
data: data,
loading: option?.loading
})
return res
}
}
}
export function put(option?: requestOption) {
return function (target: any, attr: string, descriptor: PropertyDescriptor) {
let url: string;
if (option && option.url) {
url = option.url
} else if (option && option.str) {
url = `${option.str}/${attr}`
}
descriptor.value = async function (data: any) {
return await axios.put({
url: !!url ? url : attr,
data: data
})
}
}
}

View File

@@ -0,0 +1,3 @@
export * from './operationalComponent';
export * from './ajaxType';
export * from './access';

View File

@@ -0,0 +1,69 @@
import { dynamic, history } from 'umi';
import { Component } from 'react';
// import UeroModel from '@/models/user';
function listen() {
return new Promise((resolve, reject) => {
history.listen(res => {
resolve(res)
})
})
}
/**
* 对外导出2种用法
* 函数用法和装饰器用法
*/
export class OperationalComponent {
/**
* 在正常对外高阶组件中必须调用此方法
* 并使用此方法返回的组件进行再处理
* 接收一个组件并返回处理后的组件
* @param model 组件
*/
private static componentHoc<T extends typeof Component>(model: T): T {
return model;
}
/**
* 页面权限控制
* @param model
*/
public static routerHoc<T extends typeof Component>(model: T): T {
let hoc: T = this.componentHoc(model);
// let router = JSON.stringify(UeroModel.state.routerConfig)
let hashname: string = window.location.hash.slice(1)
// if (router.indexOf(hashname) < 0) {
// // @ts-ignore
// let el: T = LimitedAuthority;
// return el;
// }
return hoc
}
/**
* 组件加载动画
* @param el
*/
public static LoadDemand<T>(el: T): React.ComponentClass<{}, T> | T {
return dynamic({
loader: async () => {
// 需要等待的时间
await new Promise(resolve => {
setTimeout(resolve, 500);
});
return el;
},
// 动画组件必须使用require动态加载模块
loading: require('../../components/loading/index.tsx').default,
});
}
}
export function routerHoc(target: any) {
return (target = OperationalComponent.routerHoc(target));
}
export function LoadDemand(target: any) {
return (target = OperationalComponent.LoadDemand(target));
}

View File

@@ -0,0 +1 @@
03ce7596-2a21-42aa-8308-c8f9749f1b1b

View File

@@ -0,0 +1,82 @@
export class Config {
/**
* ajax 基础配置信息
*/
public static AjaxConfig = {
// 开发环境api基地址
devBaseUrl: 'http://ddt.api.fanmigou.com/',
// 正式环境api基地址
proBaseUrl: 'http://www.yzt.test/',
bankList:
'https://s-static-1255741738.cos.ap-shanghai.myqcloud.com/json/bank.json',
ApiList: {
verifyList: 'account/verifyList', // 买号审核列表
verify: 'account/verify',
detail: 'account/detail', // 买号详情
sellerList: 'user/sellerList', // 商家列表
buyerList: 'user/buyerList', // 买家列表
buyerDetail: 'user/buyerDetail', // 买家用户详情
referList: 'user/referList', // 推广列表
referDetail: 'user/referDetail', // 推广用户详情
realnameVerifyList: 'realname/verifyList', // 实名审核列表
realnameVerify: 'realname/verify', // 实名认证审核
realnameDetail: 'realname/detail', // 买家实名详情数据
recordList: 'finance/recordList', // 资金记录列表
recordManage: 'finance/recordManage', // 资金管理(增减)
chargeList: 'finance/chargeList', // 充值记录
verifyCharge: 'finance/verifyCharge', // 充值审核
buyerCashList: 'finance/buyerCashList', // 买家提现记录
verifyBuyerCash: 'finance/verifyBuyerCash', // 买家提现审核
buyerCashDetail: 'finance/buyerCashDetail', // 买家端提现详情
getShopList: 'shop/shopList', //店铺列表
verifyShop: 'shop/verifyShop', //店铺审核
shopDetail: 'shop/shopDetail', //店铺详情
reg: 'reg', // 用户注册
login: 'login', // 用户注册
setPassword: 'setPassword', // 修改密码
userInfo: 'userInfo', // 获取用户信息
referCashList: 'finance/referCashList', // 推广提现记录
referCashDetail: 'finance/referCashDetail', // 推广端详情
buyerCommentList: 'shop/buyerCommentList', // 买家预评价列表
commentDetail: 'shop/commentDetail', // 买家/商家评价详情
verifyComment: 'shop/verifyComment', // 买家/商家评价审核
sellerCommentList: 'shop/sellerCommentList', // 商家添加评价列表
spuList: 'shop/spuList', // 宝贝管理
spuDetail: 'shop/spuDetail', // 宝贝详情
spuManage: 'shop/spuManage', // 禁止宝贝发布任务
announceList: 'announce/list', // 系统公告列表
add: 'announce/add', // 添加系统公告
modify: 'announce/modify', // 编辑系统公告
announceDetail: 'announce/detail', // 公告详情
sellerDetail: 'user/sellerDetail', // 商家详情
announceNav: 'announce/nav', // 公告类型
announceDelete: 'announce/delete', // 删除公告
guideNav: 'guide/nav', // 帮助类型
guideList: 'guide/list', //帮助列表
guideDelete: 'guide/delete', // 帮助删除
guideAdd: 'guide/add', // 帮助添加
guideDetail: 'guide/detail', // 帮助详情
guideModify: 'guide/modify', // 帮助编辑
deviceList: 'device/getList', // 设备列表
getDetail: 'device/getDetail', // 获取设备详情
noteList: 'note/getList', // 短信列表
verifyReferCash: 'finance/verifyReferCash', // 推广端提现审核
buyerTransferList: 'finance/buyerTransferList', // 买家端推广转出列表
verifyTransfer: 'finance/verifyTransfer', // 推广转出审核
setAppVersion: 'version/setAppVersion', // 添加新版本
getVersionList: 'version/getVersionList', // 获取版本列表
modifyAppVersion: 'version/modifyAppVersion', // 修改版本
getFailedList: 'queueFailed/getFailedList', // 获取异常列表
getFailedDetail: 'queueFailed/getFailedDetail', // 获取异常队列详情
deleteFailedRecord: 'queueFailed/deleteFailedRecord', // 删除异常数据(真删除)
taskFailedGetFailedList: 'taskFailed/getFailedList', // 任务异常列表
taskFailedGetFailedDetail: 'taskFailed/getFailedDetail', // 任务异常详情
taskFailedSolveFailed: 'taskFailed/solveFailed', // 解决异常
DataStat: 'dataStat', // 首页数据统计
changeLogList: 'changeLog/getList', //更新日志
setChangeLog: 'changeLog/setLog', //设置日志
},
};
public static prefix: string = '';
}

View File

@@ -0,0 +1 @@
852157c4-0e8b-447c-82cc-1aea4ec3ff94

View File

@@ -0,0 +1,199 @@
import { Utils } from '../utils/utils';
import axios, { AxiosInstance } from 'axios';
import { Modal } from 'antd';
import Loading from '@/components/axiosLoading';
/**
* 将提示变为Promise可以操作点击确定后再进行下一步
* @param msg
*/
function awaitSuccess(msg: string) {
return new Promise((resolve, reject) => {
Modal.success({
title: '提示',
content: msg,
onOk: () => {
resolve();
},
});
});
}
export class Axios {
private instance: AxiosInstance;
constructor() {
this.instance = axios.create({
baseURL: Utils.CheckAjaxUrl(),
timeout: 1000000,
});
this.ResponseInterceptor();
this.RequestInterceptor();
}
/**
* Get 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async get(params: {
url: string;
data: Object;
header?: Object;
loading?: boolean;
}): Promise<Object> {
let data: any = '';
params.url == 'login' || params.url == 'reg'
? (data = params.data)
: (data = Object.assign(params.data, {
authorization: localStorage.getItem('token'),
}));
try {
if (params.loading) {
Loading.start();
}
return await this.instance.get(params.url, {
params: data,
headers: Object.assign({}, params.header),
});
} catch (e) {
return e.message;
}
}
/**
* Post 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async post(params: {
url: string;
data: Object;
header?: Object;
loading?: boolean;
}): Promise<Object> {
let data: any = '';
params.url == 'login' || params.url == 'reg'
? (data = params.data)
: (data = Object.assign(params.data, {
authorization: localStorage.getItem('token'),
}));
try {
if (params.loading) {
Loading.start();
}
return await this.instance.post(params.url, data, {
headers: Object.assign({}, params.header),
});
} catch (e) {
return e.message;
}
}
/**
* Put 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async put(params: { url: string; data: Object }): Promise<Object> {
try {
return await this.instance.put(params.url, params.data);
} catch (e) {
return e.message;
}
}
/**
* delete 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async delete(params: { url: string; data: Object }): Promise<Object> {
try {
return await this.instance.delete(params.url, { params: params.data });
} catch (e) {
return e.message;
}
}
/**
* 添加响应拦截器
* @constructor
*/
public async ResponseInterceptor(): Promise<any> {
this.instance.interceptors.response.use(
async (response: any) => {
this.CloseLoadingData();
switch (response.data.code) {
case 0:
switch (response.data.status) {
case 61003:
Modal.error({
title: '61003 错误提示',
content: response.data.msg,
});
break;
case 1:
if (response.data.msg == null) return response.data.data;
await awaitSuccess(response.data.msg);
return response.data.data;
default:
Modal.error({
title: `[${response.data.status}]${response.data.msg}`,
});
break;
}
break;
case 1001:
Modal.error({
title: '温馨提示',
content: '登录失效,请重新登录',
okText: '确定',
onOk: () => {
location.replace('#/login');
},
});
return false;
break;
default:
// 处理code错误
return null;
}
},
function(error: any) {
return Promise.reject(error);
},
);
}
/**
* 添加请求拦截器
* @constructor
*/
public async RequestInterceptor(): Promise<any> {
this.OpenLoadingData();
this.instance.interceptors.request.use(
config => {
return config;
},
function(error) {
return Promise.reject(error);
},
);
}
/**
* 显示加载进度
* @constructor
*/
private OpenLoadingData(): void {}
/**
* 清除加载进度条
*/
private CloseLoadingData(): void {
Loading.done();
}
}

View File

@@ -0,0 +1 @@
34ecdd37-7942-4726-bc9b-0f113444875b

View File

@@ -0,0 +1,184 @@
import { get, post } from '@/core/annotation/ajaxType';
import { Config } from '@/core/config/config';
export class BuyerService {
@get({ url: Config.AjaxConfig.ApiList.verifyList })
public static async verifyList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.detail })
public static async detail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.sellerList })
public static async sellerList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.buyerList })
public static async buyerList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.buyerDetail })
public static async buyerDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.referList })
public static async referList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.referDetail })
public static async referDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.realnameVerifyList })
public static async realnameVerifyList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.deviceList })
public static async deviceList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.getDetail })
public static async getDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.realnameDetail })
public static async realnameDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.noteList })
public static async noteList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.recordList })
public static async recordList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.chargeList })
public static async chargeList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.buyerCashList })
public static async buyerCashList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.userInfo })
public static async userInfo(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.buyerCashDetail })
public static async buyerCashDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.sellerDetail })
public static async sellerDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.getVersionList })
public static async getVersionList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.commentDetail })
public static async commentDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.referCashDetail })
public static async referCashDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.buyerCommentList })
public static async buyerCommentList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.referCashList })
public static async referCashList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.sellerCommentList })
public static async sellerCommentList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.spuList })
public static async spuList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.spuDetail })
public static async spuDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.announceList })
public static async announceList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.announceDetail })
public static async announceDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.announceNav })
public static async announceNav(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.guideNav })
public static async guideNav(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.guideList })
public static async guideList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.guideDetail })
public static async guideDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.buyerTransferList })
public static async buyerTransferList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.getFailedList })
public static async getFailedList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.getFailedDetail })
public static async getFailedDetail(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.DataStat })
public static async DataStat(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.taskFailedGetFailedList })
public static async taskFailedGetFailedList(params: object): Promise<any> {}
@get({ url: Config.AjaxConfig.ApiList.taskFailedGetFailedDetail })
public static async taskFailedGetFailedDetail(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.verify })
public static async verify(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.modifyAppVersion })
public static async modifyAppVersion(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.verifyTransfer })
public static async verifyTransfer(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.taskFailedSolveFailed })
public static async taskFailedSolveFailed(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.deleteFailedRecord })
public static async deleteFailedRecord(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.guideModify })
public static async guideModify(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.guideDelete })
public static async guideDelete(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.guideAdd })
public static async guideAdd(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.announceDelete })
public static async announceDelete(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.verifyReferCash })
public static async verifyReferCash(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.add })
public static async add(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.modify })
public static async modify(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.verifyComment })
public static async verifyComment(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.recordManage })
public static async recordManage(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.realnameVerify })
public static async realnameVerify(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.reg })
public static async reg(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.login })
public static async login(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.spuManage })
public static async spuManage(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.verifyCharge })
public static async verifyCharge(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.verifyBuyerCash })
public static async verifyBuyerCash(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.setPassword })
public static async setPassword(params: object): Promise<any> {}
@post({ url: Config.AjaxConfig.ApiList.setAppVersion })
public static async setAppVersion(params: object): Promise<any> {}
}

View File

@@ -0,0 +1,20 @@
import { get, post } from '@/core/annotation/ajaxType';
import { Config } from '@/core/config/config';
export class PublicService {
// @get()
// public static async getRoutesConfig(): Promise<any> { }
// @post({ url: Config.AjaxConfig.ApiList.uploadFile })
// public static async uploadFile(params: object): Promise<any> { }
// @post({ url: Config.AjaxConfig.ApiList.reg })
// public static async reg(params: object): Promise<any> { }
// @post({ url: Config.AjaxConfig.ApiList.login })
// public static async login(params: object): Promise<any> { }
// @post({ url: Config.AjaxConfig.ApiList.forget })
// public static async forget(params: object): Promise<any> { }
}

View File

@@ -0,0 +1,14 @@
import { get, post } from '@/core/annotation/ajaxType';
import { Config } from '@/core/config/config';
export class ShopService {
@get({ url: Config.AjaxConfig.ApiList.getShopList })
public static async getShopList(params: object): Promise<any> { }
@post({ url: Config.AjaxConfig.ApiList.verifyShop })
public static async verifyShop(params: object): Promise<any> { }
@get({ url: Config.AjaxConfig.ApiList.shopDetail })
public static async shopDetail(params: object): Promise<any> { }
}

View File

@@ -0,0 +1 @@
c0ffe075-2368-49ef-8dc9-df9a95d33f7b

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,198 @@
import React from 'react';
import { Utils } from './utils';
import { notification } from 'antd';
interface wxConfig {
// 链接的通道的地址
url: string;
// 心跳时间间隔
heartTime: number;
// 心跳信息,默认为'ping'
heartMsg: any;
// 是否自动重连
isReconnect: boolean;
// 重连时间间隔
reconnectTime: number;
// 重连次数 -1 则不限制
reconnectCount: number;
}
export class Socket {
private ws!: WebSocket;
private wxConfig: wxConfig = {
url: 'ws://211.159.227.186:9999',
heartTime: 40000,
heartMsg: { path: "ping" },
isReconnect: true,
reconnectTime: 5000,
reconnectCount: 5,
};
// 重连定时器
private restartTime!: NodeJS.Timeout;
// 销毁定时器
private closeTime!: NodeJS.Timeout;
// 消息回调,服务端返回消息时调用
private onMsg!: (res: any) => void
constructor(option?: any, onMsg?: (res: any) => void) {
Object.assign(this.wxConfig, option);
onMsg && (this.onMsg = onMsg)
this.create();
}
// 创建链接
private create() {
if (!('WebSocket' in window)) {
new Error('当前浏览器不支持,无法使用');
return;
}
if (!this.wxConfig.url) {
new Error('地址不存在,无法建立通道');
return;
}
this.ws = new WebSocket(this.wxConfig.url);
this.start();
this.onopen();
this.onmessage();
this.onerror();
}
// 启动心跳
private start() {
// 开启定时器
this.restartTime = setTimeout(() => {
this.send(this.wxConfig.heartMsg);
// 如果发送消息返回失败则触发关闭
this.closeTime = setTimeout(() => {
console.error('服务器长时间无响应,尝试重启服务');
this.destroy();
this.create();
}, this.wxConfig.heartTime);
}, this.wxConfig.heartTime);
}
// 重启心跳
private restart() {
clearTimeout(this.restartTime); // 清除重连定时器
clearTimeout(this.closeTime); // 清除销毁定时器
this.start();
}
/**
* 自定义连接成功事件
*/
onopen() {
this.ws.onopen = event => {
let login = {
path: 'login',
// token: Utils.getToken(),
auth: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJsaXVxaWFuLmRldiIsInVpZCI6MSwiaWF0IjoxNTk3MjkwMjk5LCJleHAiOjE1OTczMTkwOTl9.hHfXbJwfUv-nEsGgjANFHghKAIgxrXM8XVewDmSNiig'
};
this.send(login);
};
}
/**
* 自定义关闭事件
*/
onclose() {
this.ws.onclose = event => {
console.log(event);
};
}
/**
* 自定义错误事件
*/
onerror() {
this.ws.onerror = event => {
console.log(event);
};
}
/**
* 自定义消息监听事件
*/
onmessage() {
this.ws.onmessage = async event => {
this.restart();
console.log('event.data: ', event.data);
let data = JSON.parse(event.data);
// if (data.status == -1) {
// this.destroy()
// this.create()
// return
// }
if (data.path == 'login' || data.path == 'welcome' || data.path == 'pong') return;
// 弹出层消息
notification.open({
message: data.msg,
onClick: () => { },
});
// 如果返回的数据中有data存在则保存 消息数量
if (data.audio == 1) {
this.playAudio('https://static.fanmigou.com/audio/msg.mp3')
}
if (data.audio == 2) {
this.playAudio('https://static.fanmigou.com/audio/income.mp3')
}
if (data.audio == 3) {
this.playAudio('https://static.fanmigou.com/audio/new_account_check.mp3')
}
this.onMsg(data)
};
}
/**
* 自定义发送消息事件
* @param {any} msg 发送的文本
*/
send(msg: any) {
if (this.ws.readyState !== this.ws.OPEN) {
new Error('没有连接到服务器,无法推送');
return;
}
let str: string = JSON.stringify(msg);
this.ws.send(str);
}
/**
* 销毁
*/
destroy() {
this.restart();
clearTimeout(this.restartTime); // 清除重连定时器
this.ws.close();
}
/**
* 播放音频文件
*/
playAudio(url: string) {
let audio = document.createElement("audio")
audio.src = url
audio.controls = true;
audio.autoplay = true;
document.body.appendChild(audio);
var play = document.querySelector('video');
let promise = play?.play()
audio.onended = function () {
document.body.removeChild(audio);
}
if (play !== undefined) {
promise?.then(_ => {
}).catch(error => {
console.error("当前浏览器不支持语音播放")
});
}
}
}

View File

@@ -0,0 +1,354 @@
import { Config } from '../config/config';
import DefaultCity from './defaultCity';
import { Modal } from 'antd';
import React from '@/core/Ioc';
// import Login from '@/pages/login';
export class Utils {
/**
* 判断当前环境返回api地址
*/
public CheckAjaxUrl(): string {
return process.env.NODE_ENV == 'production'
? Config.AjaxConfig.proBaseUrl
: Config.AjaxConfig.devBaseUrl;
}
public static CheckAjaxUrl(): string {
return process.env.NODE_ENV == 'production'
? Config.AjaxConfig.proBaseUrl
: Config.AjaxConfig.devBaseUrl;
}
/**
* 获取银行卡列表
*/
public static async getBankList(id: number) {
return new Promise((resolve, reject) => {
fetch(`${Config.AjaxConfig.bankList}?time=${new Date().valueOf()}`)
.then(function(response) {
return response.json();
})
.then(body => {
resolve(body.filter((val: any, index: number) => val.id == id)[0]);
});
});
}
/**
* 判断路由中是否有传入value相对的obj[key]
* @param obj
* @param value
*/
public static valueOnObj(obj: any, value: string): number {
if (obj.hasOwnProperty('name') && obj['name'] == value) {
return obj['access'];
}
if (obj.hasOwnProperty('routes')) {
return this.valueOnArror(obj['routes'], value);
}
return -1;
}
public static ReturnToHome() {}
/**
* 时间戳转正常时间
* @param data
* @returns {string}
*/
public static formatDate(data: any) {
let now = new Date(data * 1000);
let year = now.getFullYear();
let month = now.getMonth() + 1;
let date = now.getDate();
let hour = now.getHours();
let minute = now.getMinutes();
let second = now.getSeconds();
return (
year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second
);
}
public static TipsMessage(res: any) {
let textString = '';
if (res !== undefined) {
if (res.success.length != 0) {
res.success.forEach((val: any, index: number) => {
textString += `任务:${val.id}${val.msg}\n`;
});
}
if (res.failed.length != 0) {
res.failed.forEach((val: any, index: number) => {
textString += `任务:${val.id}${val.msg}\n`;
});
}
Modal.info({
title: '提示',
content: textString,
});
}
}
/**
* 判断数组中是否存在某值
* @param arr
* @param value
*/
public static valueOnArror(arr: any[], value: string): number {
for (let i = 0; i < arr.length; i++) {
if (this.valueOnObj(arr[i], value)) {
return this.valueOnObj(arr[i], value);
}
}
return -1;
}
/**
* 获取本地Storage中存放的数据
* @param name
*/
public static getStorage(name: string): string {
try {
let data: string | null = localStorage.getItem(
`${Config.prefix}_${name}`,
);
if (!!data) {
return JSON.parse(data);
}
return 'no';
} catch (error) {
throw `获取storage时出错:${error}`;
}
}
/**
* 存储数据到本地
* @param name
* @param data
*/
public static setStorage(name: string, data: any): boolean {
try {
localStorage.setItem(`${Config.prefix}_${name}`, JSON.stringify(data));
return true;
} catch (error) {
throw `插入storage时出错:${error}`;
}
}
/**
* 去除数组中的空值并返回新数组
* @param data
*/
public emptyArray(data: any[]): any[] {
let newArr: any[] = [];
data.forEach((v, i) => {
if (!this.isEmpty(v)) {
newArr.push(v);
}
});
return newArr;
}
/**
* 判断当前传入的值是否是空值, 下方是测试用例
* isEmpty() //true
* isEmpty([]) //true
* isEmpty({}) //true
* isEmpty(0) //true
* isEmpty(Number("abc")) //true
* isEmpty("") //true
* isEmpty(" ") //true
* isEmpty(false) //true
* isEmpty(null) //true
* isEmpty(undefined) //true
* @param v
*/
public isEmpty(v: any): boolean {
switch (typeof v) {
case 'undefined':
return true;
case 'string':
if (v.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0)
return true;
break;
case 'boolean':
if (!v) return true;
break;
case 'number':
if (0 === v || isNaN(v)) return true;
break;
case 'object':
if (null === v || v.length === 0) return true;
for (var i in v) {
return false;
}
return true;
}
return false;
}
/**
* 用于把 单位为分 转换成 单位为元
* @param m 后端返回被处理成 单位为分 的钱
*/
public static conversionMoney(m: number): number {
return Number((m / 10 / 10).toFixed(2));
}
/**
* 将数值四舍五入(保留2位小数)后格式化成金额形式
*
* @param num 数值(Number或者String)
* @return 金额格式的字符串,如'1,234,567.45'
* @type String
*/
public static formatCurrency(num: any) {
num = this.conversionMoney(num);
num = num.toString().replace(/\$|\,/g, '');
if (isNaN(num)) num = '0';
let sign = num == (num = Math.abs(num));
num = Math.floor(num * 100 + 0.50000000001);
let cents: any = num % 100;
num = Math.floor(num / 100).toString();
if (cents < 10) cents = '0' + cents;
for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
num =
num.substring(0, num.length - (4 * i + 3)) +
',' +
num.substring(num.length - (4 * i + 3));
return (sign ? '' : '-') + num + '.' + cents;
}
public static FullCityName(areasCode: string) {
// 34 01 02
console.log('areasCode: ', areasCode);
let provinces = areasCode.slice(0, 2) + '0000';
let cities = areasCode.slice(2, 4);
let areas = areasCode.slice(4, 6);
// console.log("provinces: ", provinces);
let provincesData: any = DefaultCity.filter((val: any, index: number) => {
return val.id == provinces;
});
if (provincesData[0]['sub'][cities]['sub'].hasOwnProperty(`${areas}`)) {
return [
provincesData[0].full_name,
provincesData[0]['sub'][cities].full_name,
provincesData[0]['sub'][cities]['sub'][areas].full_name,
];
} else {
return [
provincesData[0].full_name,
provincesData[0]['sub'][cities].full_name,
];
}
}
/**
* 判断是否是对象
* @param obj
*/
public static isObj(obj: any): boolean {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/**
* 判断是否是对象
* @param obj
*/
public static isArr(arr: any): boolean {
return Object.prototype.toString.call(arr) === '[object Array]';
}
/**
* 获取YYYY-MM-DD HH:MM:SS 时间
*/
public static getTimes() {
var thisDay = new Date();
var year = thisDay.getFullYear(); //年
var month = thisDay.getMonth() + 1; //月
var day = thisDay.getDate(); //日
var hh = thisDay.getHours(); //时
var mm = thisDay.getMinutes(); //分
var ss = thisDay.getSeconds(); //秒
var timer = year + '-';
if (month < 10) timer += '0';
timer += month + '-';
if (day < 10) timer += '0';
timer += day + ' ';
if (hh < 10) timer += '0';
timer += hh + ':';
if (mm < 10) timer += '0';
timer += mm + ':';
if (ss < 10) timer += '0';
timer += ss;
return timer;
}
/**
* 获取当前用户IP地址
* @param onNewIP 回调函数
*/
public static getUserIP(onNewIP: Function) {
// @ts-ignore
var myPeerConnection =
window.RTCPeerConnection ||
window.mozRTCPeerConnection ||
window.webkitRTCPeerConnection;
var pc = new myPeerConnection({
iceServers: [],
}),
noop: Function = function() {},
localIPs: any = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key;
function iterateIP(ip: any) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
//create a bogus data channel
pc.createDataChannel('');
// create offer and set local description
pc.createOffer()
.then(function(sdp: any) {
sdp.sdp.split('\n').forEach(function(line: any) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(iterateIP);
});
// @ts-ignore
pc.setLocalDescription(sdp, noop, noop);
})
.catch(function(reason) {
// An error occurred, so handle the failure to connect
});
//sten for candidate events
pc.onicecandidate = function(ice: any) {
if (
!ice ||
!ice.candidate ||
!ice.candidate.candidate ||
!ice.candidate.candidate.match(ipRegex)
)
return;
ice.candidate.candidate.match(ipRegex).forEach(iterateIP);
};
}
}

View File

@@ -0,0 +1,6 @@
// @import './assets/less/Buyer.less';
#root {
height: 100%;
width: 100%;
}

View File

@@ -0,0 +1 @@
13123c64-cfbf-4a66-881a-bad7761737a8

View File

@@ -0,0 +1,55 @@
import React, { IocComponent } from '@Ioc/index';
import { LoadDemand } from '@annotation/index';
import { Navbar, Head } from '@/components/index';
import { Affix, ConfigProvider } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import { Socket } from '@/core/utils/socket';
@LoadDemand
class Index extends IocComponent {
state = {
currentRoute: '/home'
}
componentDidMount() {
new Socket()
}
componentWillReceiveProps() {
this.setState({
currentRoute: window.location.hash.slice(1)
})
}
render() {
return (
<ConfigProvider locale={zhCN}>
<div style={{ height: '100%' }}>
{/* 左侧菜单栏 */}
<Navbar />
<div style={{ height: '100%' }}>
{/* 头部导航 固定到顶部 */}
<Affix offsetTop={0}>
<div>
<Head />
</div>
</Affix>
{/* 子页面 */}
<div style={{
paddingLeft: 240,
paddingTop: 50,
height: '100%',
backgroundColor: '#f5f7f9'
}}>
<div style={{padding: 20, height: '100%'}}>{this.props.children}</div>
</div>
</div>
</div>
</ConfigProvider>
);
}
}
export default Index;

View File

@@ -0,0 +1 @@
16742d52-e74d-4f6c-8e93-97e10b341417

View File

@@ -0,0 +1,2 @@
# 国际化
- 如果需要国际化则在此定义国际化文字描述

View File

@@ -0,0 +1 @@
a678840b-de46-4e88-919c-ea715823aec0

View File

@@ -0,0 +1 @@
c8fb8ed7-4225-4997-9b12-9b4d5c112419

View File

@@ -0,0 +1 @@
6a539a53-0a1e-40de-8757-59c5295ec8c5

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,251 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import {
Input,
Select,
Button,
DatePicker,
Table,
message,
Popconfirm,
Modal,
Row,
Col,
Switch,
} from 'antd';
// @ts-ignore
import E from 'wangeditor';
import publicCss from '@less/public/index.less';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class ExceptionList extends IocComponent {
state: { [index: string]: any } = {
columns: [
{
title: 'id',
dataIndex: 'id',
key: 'id',
},
{
title: '任务名称',
dataIndex: 'job_title',
key: 'job_title',
},
{
title: '异常',
dataIndex: 'msg_title',
key: 'msg_title',
},
{
title: '队列名称',
dataIndex: 'queue_name',
key: 'queue_name',
},
{
title: '时间',
dataIndex: 'create_time',
key: 'create_time',
render: (text: any, record: any) => {
return <span>{Utils.formatDate(record.create_time)}</span>;
},
},
{
title: '操作',
dataIndex: 'x',
key: 'x',
render: (text: any, record: any) => {
return (
<>
<Button
style={{ marginRight: 10 }}
onClick={async () => {
await this.getFailedDetail(record.id);
}}
>
</Button>
<Button
danger
onClick={async () => {
await this.deleteFailedRecord();
}}
>
</Button>
</>
);
},
},
],
params: {
limit: 10,
page: 1,
},
PageCount: '',
FailedList: [],
loading: false,
isShowAddModal: false,
FailedDetail: {},
selectedRowKeys: [],
};
async componentDidMount() {
await this.getFailedLists();
}
/**
* 异常列表
*/
async getFailedLists() {
this.setState({ loading: true });
let res = await BuyerService.getFailedList(this.state.params);
if (res.hasOwnProperty('list')) {
this.state.PageCount = res.count;
this.setState({ FailedList: res.list });
}
this.setState({ loading: false });
}
/**
* 获取异常详情
*/
async getFailedDetail(id: string) {
let res = await BuyerService.getFailedDetail({ id: id });
let params = [],
msg = [];
if (res.param) {
for (const stateKey in res.param) {
params.push({
title: stateKey,
id: res.param[stateKey],
});
}
}
if (res.msg) {
for (const stateKey in res.msg) {
msg.push({
title: stateKey,
id: res.msg[stateKey],
});
}
}
res.param = params;
res.msg = msg;
this.setState({ FailedDetail: res, isShowAddModal: true });
}
/**
* 删除异常
*/
async deleteFailedRecord() {
let res = await BuyerService.deleteFailedRecord({
ids: this.state.selectedRowKeys,
});
await this.getFailedLists();
console.log('删除:', res);
}
onSelectChange = (selectedRowKeys: any, selectedRows: any) => {
this.state.selectedRowKeys = selectedRowKeys;
this.setState({});
};
render() {
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
};
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex} style={{ marginBottom: 20 }}>
<Table
loading={this.state.loading}
rowKey="id"
rowSelection={rowSelection}
columns={this.state.columns}
dataSource={this.state.FailedList}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.getFailedLists();
},
onChange: async current => {
this.state.params.page = current;
await this.getFailedLists();
},
}}
/>
<Modal
width="60%"
title="详情"
destroyOnClose={true}
visible={this.state.isShowAddModal}
onCancel={() => this.setState({ isShowAddModal: false })}
onOk={async () => {}}
>
<Row style={{ marginBottom: 15 }}>
<Col span={3}>id</Col>
<Col span={21}>{this.state.FailedDetail.id}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>{this.state.FailedDetail.queue_name}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>{this.state.FailedDetail.job_title}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
{this.state.FailedDetail.param &&
this.state.FailedDetail.param.map(
(val: any, index: number) => {
return (
<p style={{ marginBottom: 4 }} key={index}>
{val.title}{val.id}
</p>
);
},
)}
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
{this.state.FailedDetail.msg &&
this.state.FailedDetail.msg.map((val: any, index: number) => {
return (
<p style={{ marginBottom: 4 }} key={index}>
{val.title}{val.id}
</p>
);
})}
</Col>
</Row>
</Modal>
</div>
</div>
);
}
}

View File

@@ -0,0 +1 @@
4375fe55-0f3f-43ae-9d2d-652cee754b35

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,404 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import {
Input,
Select,
Button,
DatePicker,
Table,
message,
Popconfirm,
Modal,
Row,
Col,
Switch,
} from 'antd';
// @ts-ignore
import E from 'wangeditor';
import publicCss from '@less/public/index.less';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class HelpCenter extends IocComponent {
state: { [index: string]: any } = {
columns: [
{
title: 'id',
dataIndex: 'id',
key: 'id',
},
{
title: '标题',
dataIndex: 'title',
key: 'title',
},
{
title: '类型',
dataIndex: 'type',
render: (text: any, record: any) => {
return <span>{record.nav.name}</span>;
},
},
{
title: '发布时间',
dataIndex: 'create_time',
key: 'create_time',
render: (text: any, record: any) => {
return <span>{Utils.formatDate(record.create_time)}</span>;
},
},
{
title: '操作',
dataIndex: 'x',
render: (text: any, record: any) => {
return (
<>
<a
onClick={async () => {
await this.guideDetail(record.id);
}}
>
{' '}
{' '}
</a>
<Popconfirm
title="确定删除吗?"
onConfirm={async () => {
await this.guideDelete(record.id);
}}
onCancel={() => {}}
okText="确认"
cancelText="取消"
>
<a onClick={async () => {}}></a>
</Popconfirm>
</>
);
},
},
],
params: {
title: '',
type: '',
limit: 20,
page: 1,
},
PageCount: 0,
guideNavData: [],
guideListData: [],
guideDetailData: {},
guideAddParams: {
title: '',
content: '',
type: '',
},
isShowAddModal: false,
isShowEditModal: false,
addHelpContent: '',
editHelpContent: '',
editInfo: {},
loading: false,
};
async componentDidMount() {
await this.guideList();
await this.guideNav();
}
/**
* 初始化 添加 富文本编辑器
*/
initAddEditor() {
this.state.addHelpContent = new E(this.refs.addHelpContent);
this.state.addHelpContent.customConfig.zIndex = 100;
this.state.addHelpContent.create();
}
/**
* 初始化 编辑 富文本编辑器
*/
initEditEditor() {
this.state.editHelpContent = new E(this.refs.editHelpContent);
this.state.editHelpContent.customConfig.zIndex = 100;
this.state.editHelpContent.create();
}
/**
* 公告类型
*/
async guideNav() {
let res = await BuyerService.guideNav({});
this.setState({ guideNavData: res });
}
/**
* 列表
*/
async guideList() {
this.setState({ loading: true });
let res = await BuyerService.guideList(this.state.params);
if (res.hasOwnProperty('list')) {
this.state.PageCount = res.count;
this.setState({ guideListData: res.list });
console.log('guideList: ', this.state.guideListData);
}
this.setState({ loading: false });
}
/**
* 删除
* @param id
*/
async guideDelete(id: any) {
let res = await BuyerService.guideDelete({ guide_id: id });
await this.guideList();
}
/**
* 添加
*/
async guideAdd() {
let res = await BuyerService.guideAdd(this.state.guideAddParams);
await this.guideList();
this.setState({ isShowAddModal: false });
}
/**
* 帮助详情
* @param id
*/
async guideDetail(id: string) {
let res = await BuyerService.guideDetail({ guide_id: id });
this.setState({ guideDetailData: res });
// 保存编辑接口需要的id参数
this.state.guideAddParams.guide_id = res.id;
this.setState({ isShowEditModal: true });
setTimeout(() => {
this.initEditEditor();
// 赋值富文本编辑框
this.state.editHelpContent.txt.html(res.content);
}, 300);
}
async guideModify() {
console.log('编辑参数:', this.state.guideAddParams);
let res = await BuyerService.guideModify(this.state.guideAddParams);
await this.guideList();
this.setState({ isShowEditModal: false });
}
/**
* 添加新帮助的弹窗
* @constructor
*/
AddHelp() {
return (
<Modal
width="60%"
title="添加帮助"
destroyOnClose={true}
visible={this.state.isShowAddModal}
onCancel={() => this.setState({ isShowAddModal: false })}
onOk={async () => {
this.state.guideAddParams.content = this.state.addHelpContent.txt.html();
await this.guideAdd();
}}
>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Input
style={{ width: '100%' }}
placeholder="请输入帮助标题"
onChange={e => {
this.state.guideAddParams.title = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<div ref="addHelpContent" style={{ textAlign: 'left' }} />
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Select
defaultValue="帮助类型"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.guideAddParams.type = value;
this.setState({});
}}
>
{this.state.guideNavData.map((val: any, index: number) => {
return (
<Option key={index} value={val.id}>
{val.name}
</Option>
);
})}
</Select>
</Col>
</Row>
</Modal>
);
}
/**
* 编辑帮助的弹窗
* @constructor
*/
EditHelp() {
return (
<Modal
width="60%"
title="编辑帮助"
destroyOnClose={true}
visible={this.state.isShowEditModal}
onCancel={() => this.setState({ isShowEditModal: false })}
onOk={async () => {
this.state.guideAddParams.content = this.state.editHelpContent.txt.html();
await this.guideModify();
}}
>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Input
style={{ width: '100%' }}
placeholder="请输入帮助标题"
value={this.state.guideDetailData.title}
onChange={e => {
this.state.guideDetailData.title = e.target.value;
this.state.guideAddParams.title = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<div ref="editHelpContent" style={{ textAlign: 'left' }} />
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Select
defaultValue={this.state.guideDetailData.nav_id}
style={{ width: 160 }}
onChange={(value: any) => {
this.state.guideAddParams.type = value;
this.setState({});
}}
>
{this.state.guideNavData.map((val: any, index: number) => {
return (
<Option key={index} value={val.id}>
{val.name}
</Option>
);
})}
</Select>
</Col>
</Row>
</Modal>
);
}
render() {
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex} style={{ marginBottom: 20 }}>
<Input
className={publicCss.ml10}
style={{ width: 240, marginRight: 10 }}
placeholder="请输入标题"
onChange={e => {
this.state.params.title = e.target.value;
this.setState({});
}}
/>
<Select
defaultValue="帮助类型"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.type = value;
this.setState({});
}}
>
{this.state.guideNavData.map((val: any, index: number) => {
return (
<Option key={index} value={val.id}>
{val.name}
</Option>
);
})}
</Select>
<Button
className={publicCss.ml10}
type="primary"
onClick={async () => {
await this.guideList();
}}
>
</Button>
</div>
<div className={publicCss.flex} style={{ marginBottom: 20 }}>
<Button
type="primary"
onClick={() => {
this.setState({ isShowAddModal: true });
setTimeout(() => this.initAddEditor(), 300);
}}
>
</Button>
</div>
{this.AddHelp()}
{this.EditHelp()}
<Table
loading={this.state.loading}
rowKey="id"
columns={this.state.columns}
dataSource={this.state.guideListData}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.guideList();
},
onChange: async current => {
this.state.params.page = current;
await this.guideList();
},
}}
/>
</div>
);
}
}

View File

@@ -0,0 +1 @@
44cc251c-7273-4dec-a86b-b16e1ba74232

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,371 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import {
Input,
Select,
Button,
DatePicker,
Table,
message,
Modal,
Row,
Col,
Switch,
} from 'antd';
import publicCss from '@less/public/index.less';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
// @ts-ignore
import E from 'wangeditor';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
/**
* 买家提现记录
*/
export default class Notice extends IocComponent {
state: { [index: string]: any } = {
columns: [
{
title: 'id',
dataIndex: 'id',
key: 'id',
},
{
title: '标题',
dataIndex: 'title',
key: 'title',
},
{
title: '类型',
dataIndex: 'type',
render: (text: any, record: any) => {
return <span>{record.nav.name}</span>;
},
},
{
title: '发布时间',
dataIndex: 'create_time',
key: 'create_time',
},
{
title: '操作',
dataIndex: 'x',
render: (text: any, record: any) => {
return (
<>
<a onClick={async () => await this.announceDetail(record.id)}>
{' '}
{' '}
</a>
<a onClick={async () => await this.announceDelete(record.id)}>
</a>
</>
);
},
},
],
params: {
title: '',
type: '',
limit: 10,
page: 1,
},
PageCount: '', // 共有多少条
NoticeData: [],
isShowModal: false,
isShowEditModal: false,
addParams: {
title: '',
content: '',
type: '',
// status: false,
// sort: '',
},
announceDetailData: {},
announceNavList: [],
loading: false,
};
private editorAdd: any;
private editorModify: any;
async componentDidMount() {
await this.announceList();
await this.announceNav();
}
/**
* 公告类型
*/
async announceNav() {
let res = await BuyerService.announceNav({});
this.setState({ announceNavList: res });
console.log('公告类型:', res);
}
/**
* 删除公告
*/
async announceDelete(id: any) {
let res = await BuyerService.announceDelete({ announce_id: id });
await this.announceList();
}
initAddEditor() {
this.editorAdd = new E(this.refs.editorAddElem);
this.editorAdd.customConfig.zIndex = 100;
this.editorAdd.create();
}
initeditorModify() {
console.log(this.refs.editorModifyElem);
this.editorModify = new E(this.refs.editorModifyElem);
this.editorModify.customConfig.zIndex = 100;
this.editorModify.create();
}
async announceList() {
this.setState({ loading: true });
let res = await BuyerService.announceList(this.state.params);
this.state.NoticeData = res.data.data;
this.state.PageCount = res.count;
this.state.NoticeData.forEach((val: any, index: number) => {
val.key = index;
val.create_time = Utils.formatDate(val.create_time);
val.status = val.status == 1 ? '启用' : '不启用';
});
this.setState({ loading: false });
this.setState({});
}
async add() {
let res = await BuyerService.add(this.state.addParams);
await this.announceList();
}
/**
* 公告详情
* @param id
*/
async announceDetail(id: string) {
let res = await BuyerService.announceDetail({ announce_id: id });
await this.setState({ announceDetailData: res, isShowEditModal: true });
console.log(this.state.announceDetailData);
this.initeditorModify();
this.editorModify.txt.html((this.state.announceDetailData as any).content);
}
/**
* 更新
*/
async modify() {
// @ts-ignore
this.state.announceDetailData.announce_id = this.state.announceDetailData.id;
let res = await BuyerService.modify(this.state.announceDetailData);
await this.announceList();
}
render() {
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex} style={{ marginBottom: 20 }}>
<Input
className={publicCss.ml10}
style={{ width: 240, marginRight: 10 }}
placeholder="请输入标题"
onChange={e => {
this.state.params.title = e.target.value;
this.setState({});
}}
/>
<Select
defaultValue="公告类型"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.type = value;
console.log('公告类型: ', this.state.params.type);
this.setState({});
}}
>
{this.state.announceNavList.map((val: any, index: number) => {
return (
<Option key={index} value={val.id}>
{val.name}
</Option>
);
})}
</Select>
<Button
className={publicCss.ml10}
type="primary"
onClick={async () => {
await this.announceList();
}}
>
</Button>
</div>
<div className={publicCss.flex} style={{ marginBottom: 20 }}>
<Button
type="primary"
style={{ marginRight: 15 }}
onClick={async () => {
await this.setState({ isShowModal: true });
this.initAddEditor();
}}
>
</Button>
</div>
<div style={{ marginTop: '20px', marginBottom: '10px' }}>
<Table
loading={this.state.loading}
columns={this.state.columns}
dataSource={this.state.NoticeData}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.announceList();
},
onChange: async current => {
this.state.params.page = current;
await this.announceList();
},
}}
/>
</div>
<Modal
width="60%"
title="添加新公告"
destroyOnClose={true}
visible={this.state.isShowModal}
onCancel={() => {
this.state.addParams = {
title: '',
content: '',
type: '',
status: false,
sort: '',
};
this.setState({});
this.setState({ isShowModal: false });
}}
onOk={async () => {
this.state.addParams.content = this.editorAdd.txt.html();
await this.add();
}}
>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Input
style={{ width: '100%' }}
placeholder="请输入公告标题"
onChange={e => {
this.state.addParams.title = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<div ref="editorAddElem" style={{ textAlign: 'left' }} />
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Select
defaultValue="公告类型"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.addParams.type = value;
this.setState({});
}}
>
{this.state.announceNavList.map((val: any, index: number) => {
return (
<Option key={index} value={val.id}>
{val.name}
</Option>
);
})}
</Select>
</Col>
</Row>
</Modal>
<Modal
width="60%"
title="编辑公告"
destroyOnClose={true}
visible={this.state.isShowEditModal}
onCancel={() => {
this.setState({ isShowEditModal: false });
}}
onOk={async () => {
this.state.announceDetailData.content = this.editorModify.txt.html();
await this.modify();
}}
>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Input
style={{ width: '100%' }}
value={this.state.announceDetailData.title}
placeholder="请输入公告标题"
onChange={e => {
this.state.announceDetailData.title = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<div ref="editorModifyElem" style={{ textAlign: 'left' }} />
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
<Select
defaultValue={this.state.announceDetailData.nav_id}
style={{ width: 160 }}
onChange={(value: any) => {
this.state.announceDetailData.type = value;
this.setState({});
}}
>
{this.state.announceNavList.map((val: any, index: number) => {
return (
<Option key={index} value={val.id}>
{val.name}
</Option>
);
})}
</Select>
</Col>
</Row>
</Modal>
</div>
);
}
}

View File

@@ -0,0 +1 @@
f7ccd47b-b63f-449f-a525-23314f09970b

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,223 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import {
Input,
Select,
Button,
DatePicker,
Table,
message,
Popconfirm,
Modal,
Row,
Col,
Switch,
} from 'antd';
// @ts-ignore
import E from 'wangeditor';
import publicCss from '@less/public/index.less';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class TaskExceptionList extends IocComponent {
state: { [index: string]: any } = {
columns: [
{
title: '任务编号',
dataIndex: 'task_id',
key: 'task_id',
},
{
title: '异常次数',
dataIndex: 'times',
key: 'times',
},
{
title: '异常',
dataIndex: 'msg_title',
key: 'msg_title',
},
{
title: '状态',
dataIndex: 'status_text',
key: 'status_text',
},
{
title: '时间',
dataIndex: 'create_time',
key: 'create_time',
render: (text: any, record: any) => {
return <span>{Utils.formatDate(record.create_time)}</span>;
},
},
{
title: '操作',
dataIndex: 'x',
key: 'x',
render: (text: any, record: any) => {
return (
<>
<Button
style={{ marginRight: 10 }}
onClick={async () => {
await this.taskFailedGetFailedDetail(record.id);
}}
>
</Button>
<Button
danger
onClick={async () => {
await this.taskFailedSolveFailed(record.id);
}}
>
</Button>
</>
);
},
},
],
params: {
limit: 10,
page: 1,
},
PageCount: '',
FailedList: [],
loading: false,
isShowAddModal: false,
FailedDetail: {},
};
async componentDidMount() {
await this.getFailedLists();
}
/**
* 异常列表
*/
async getFailedLists() {
this.setState({ loading: true });
let res = await BuyerService.taskFailedGetFailedList(this.state.params);
if (res.hasOwnProperty('list')) {
this.state.PageCount = res.count;
this.setState({ FailedList: res.list });
}
this.setState({ loading: false });
}
/**
* 获取异常详情
*/
async taskFailedGetFailedDetail(id: string) {
let res = await BuyerService.taskFailedGetFailedDetail({ id: id });
let msg = [];
if (res.msg) {
for (const stateKey in res.msg) {
msg.push({
title: stateKey,
id: res.msg[stateKey],
});
}
}
res.msg = msg;
this.setState({ FailedDetail: res, isShowAddModal: true });
}
/**
* 解决异常
*/
async taskFailedSolveFailed(id: string) {
let res = await BuyerService.taskFailedSolveFailed({ id: id });
await this.getFailedLists();
}
render() {
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex} style={{ marginBottom: 20 }}>
<Table
loading={this.state.loading}
rowKey="id"
columns={this.state.columns}
dataSource={this.state.FailedList}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.getFailedLists();
},
onChange: async current => {
this.state.params.page = current;
await this.getFailedLists();
},
}}
/>
<Modal
width="60%"
title="详情"
destroyOnClose={true}
visible={this.state.isShowAddModal}
onCancel={() => this.setState({ isShowAddModal: false })}
onOk={async () => {}}
>
<Row style={{ marginBottom: 15 }}>
<Col span={3}>id</Col>
<Col span={21}>{this.state.FailedDetail.task_id}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}>id</Col>
<Col span={21}>{this.state.FailedDetail.exception_id}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>{this.state.FailedDetail.times}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
{Utils.formatDate(this.state.FailedDetail.create_time)}
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
{Utils.formatDate(this.state.FailedDetail.solve_time)}
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>{this.state.FailedDetail.status_text}</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={3}></Col>
<Col span={21}>
{this.state.FailedDetail.msg &&
this.state.FailedDetail.msg.map((val: any, index: number) => {
return (
<p style={{ marginBottom: 4 }} key={index}>
{val.title}{val.id}
</p>
);
})}
</Col>
</Row>
</Modal>
</div>
</div>
);
}
}

View File

@@ -0,0 +1 @@
206004da-50c1-4642-9ef8-a8cac4770296

View File

@@ -0,0 +1 @@
8c55b637-d88f-4cb8-afa6-528d979cf583

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,166 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import {
Input,
Select,
Button,
DatePicker,
Table,
message,
Modal,
Row,
Col,
} from 'antd';
import publicCss from '@less/public/index.less';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class SmsList extends IocComponent {
state = {
columns: [
{
title: '编号',
dataIndex: 'id',
key: 'id',
},
{
title: '手机号',
dataIndex: 'cellphone',
key: 'cellphone',
},
{
title: '内容',
dataIndex: 'param',
key: 'param',
render: (res: any, record: any) => {
return <div>{res.content.length == 0 ? '暂无' : res.content}</div>;
},
},
{
title: '时间',
dataIndex: 'create_time',
key: 'create_time',
render: (res: any, record: any) => {
return <div>{Utils.formatDate(record.create_time)}</div>;
},
},
{
title: '状态',
dataIndex: 'status_text',
key: 'status_text',
},
],
params: {
text_field: '',
text_value: '',
status: '',
date_field: 'create_time',
date_range: '',
limit: 20,
page: 1,
},
PageCount: 0,
SmsData: [],
loading: false,
};
async componentDidMount() {
await this.noteList();
}
async noteList() {
this.setState({ loading: true });
let res = await BuyerService.noteList(this.state.params);
if (res.hasOwnProperty('list')) {
this.state.PageCount = res.count;
this.setState({ SmsData: res.list });
}
this.setState({ loading: false });
}
render() {
return (
<div className={style.index}>
<div className={style.title}></div>
<div style={{ marginBottom: 20 }} className={publicCss.flex}>
<Select
defaultValue="请选择"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.text_field = value;
this.setState({});
}}
>
<Option value="phone"></Option>
</Select>
<Input
className={publicCss.ml10}
style={{ width: 240, marginRight: 10 }}
placeholder=""
onChange={e => {
this.state.params.text_value = e.target.value;
this.setState({});
}}
/>
<Select
defaultValue="状态"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.text_field = value;
this.setState({});
}}
>
<Option value="9"></Option>
<Option value="-8"></Option>
</Select>
<RangePicker
// @ts-ignore
onChange={(date: Date, dateString: Array<any>) => {
this.state.params.date_range = dateString.join(' - ');
}}
/>
<Button
className={publicCss.ml10}
type="primary"
onClick={async () => {
await this.noteList();
}}
>
</Button>
</div>
<Table
loading={this.state.loading}
columns={this.state.columns}
dataSource={this.state.SmsData}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.noteList();
},
onChange: async current => {
this.state.params.page = current;
await this.noteList();
},
}}
/>
</div>
);
}
}

View File

@@ -0,0 +1 @@
eebceb12-d3d9-4041-8efe-819f28e889bd

View File

@@ -0,0 +1,17 @@
@import '../../assets/less/public/color.less';
@import '../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
.modalTitle {
display: flex;
height: 50px;
align-items: center;
justify-content: space-around;
}
}

View File

@@ -0,0 +1,348 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import {
Input,
Select,
Button,
DatePicker,
Table,
message,
Modal,
Row,
Col,
Radio,
} from 'antd';
import publicCss from '@less/public/index.less';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
/**
* 推广端提现记录
*/
export default class extension extends IocComponent {
state = {
columns: [
{
title: '流水号',
dataIndex: 'id',
key: 'id',
},
{
title: '受理人',
dataIndex: 'admin_user',
render: (res: any, record: any) => {
return (
<div>{record.admin_user == null ? '暂无' : record.admin_user}</div>
);
},
},
{
title: '备注',
dataIndex: 'remark',
render: (res: any, record: any) => {
return <div>{record.remark == null ? '暂无' : record.remark}</div>;
},
},
{
title: '转出金额',
dataIndex: 'amount',
key: 'amount',
render: (res: any, record: any) => {
return <div>{Utils.conversionMoney(record.amount)}</div>;
},
},
{
title: '手机号',
dataIndex: 'cellphone',
key: 'cellphone',
},
{
title: '受理时间',
dataIndex: 'admin_time',
key: 'admin_time',
},
{
title: '申请时间',
dataIndex: 'create_time',
key: 'create_time',
},
{
title: '状态',
dataIndex: 'status_text',
key: 'status_text',
},
],
params: {
text_field: '',
text_value: '',
date_field: '',
date_range: '',
limit: 10,
page: 1,
},
status: 0,
listData: [],
PageCount: 0,
isShowDetailModal: false,
buyerCashDetail: {},
loading: false,
selectedRowKeys: [],
isShowModal: false,
remark: '',
};
async componentDidMount() {
await this.buyerTransferList();
}
async buyerTransferList() {
this.setState({ loading: true });
let res = await BuyerService.buyerTransferList(this.state.params);
console.log('buyerTransferList: ', res);
if (res.hasOwnProperty('list')) {
res.list.forEach((val: any, index: any) => {
val.admin_time = Utils.formatDate(val.admin_time);
val.create_time = Utils.formatDate(val.create_time);
val.amount = Utils.conversionMoney(val.amount);
});
this.state.PageCount = res.count;
this.setState({ listData: res.list });
}
this.setState({ loading: false });
}
onSelectChange = (selectedRowKeys: any, selectedRows: any) => {
this.state.selectedRowKeys = selectedRowKeys;
console.log('selectedRowKeys: ', selectedRowKeys);
this.setState({});
};
/**
* 推广端提现审核
*/
async verifyTransfer() {
let res = await BuyerService.verifyTransfer({
ids: this.state.selectedRowKeys,
status: this.state.status,
remark: this.state.remark,
});
if (res !== undefined) {
Utils.TipsMessage(res);
}
}
render() {
const detail: any = this.state.buyerCashDetail;
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
};
return (
<div className={style.index}>
<div className={style.title}>广</div>
<div style={{ marginBottom: 15 }} className={publicCss.flex}>
<Select
defaultValue="请选择"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.text_field = value;
this.setState({});
}}
>
<Option value="phone"></Option>
<Option value="amount"></Option>
</Select>
<Input
className={publicCss.ml10}
style={{ width: 240 }}
placeholder="请输入"
onChange={e => {
this.state.params.text_value = e.target.value;
this.setState({});
}}
/>
<Select
defaultValue="请选择"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.date_field = value;
this.setState({});
}}
>
<Option value="create_time"></Option>
<Option value="admin_time"></Option>
</Select>
<RangePicker
// @ts-ignore
onChange={(date: Date, dateString: Array<any>) => {
this.state.params.date_range = dateString.join(' - ');
}}
/>
<Button
className={publicCss.ml10}
type="primary"
onClick={async () => {
await this.buyerTransferList();
}}
>
</Button>
</div>
<div className={publicCss.flex} style={{ marginBottom: 15 }}>
<Button
type="primary"
style={{ marginRight: 15 }}
onClick={async () => {
if (this.state.selectedRowKeys.length == 0) {
message.error('请先选择');
} else {
this.state.status = 9;
await this.verifyTransfer();
}
}}
>
</Button>
<Button
type="primary"
danger
onClick={() => {
if (this.state.selectedRowKeys.length == 0) {
message.error('请先选择');
} else {
this.state.status = -8;
this.setState({ isShowModal: true });
}
}}
>
</Button>
</div>
<div style={{ marginTop: '20px', marginBottom: '10px' }}>
<Table
rowKey={'id'}
rowSelection={rowSelection}
loading={this.state.loading}
columns={this.state.columns}
dataSource={this.state.listData}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.buyerTransferList();
},
onChange: async current => {
this.state.params.page = current;
await this.buyerTransferList();
},
}}
/>
</div>
<Modal
title="请填写备注"
destroyOnClose={true}
visible={this.state.isShowModal}
onCancel={() => {
this.setState({ isShowModal: false });
}}
onOk={async () => {
await this.verifyTransfer();
}}
>
<Row>
<Col span={4}></Col>
<Col span={20}>
<TextArea
rows={4}
onChange={e => {
this.state.remark = e.target.value;
}}
/>
</Col>
</Row>
</Modal>
<Modal
width="70%"
title="详情"
visible={this.state.isShowDetailModal}
footer={null}
onCancel={() => {
this.setState({ isShowDetailModal: false });
}}
>
<div
style={{
display: 'flex',
height: 50,
alignItems: 'center',
justifyContent: 'space-around',
}}
>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
<div style={{ width: '6.6%', textAlign: 'center' }}></div>
</div>
<div
style={{
display: 'flex',
height: 50,
alignItems: 'center',
justifyContent: 'space-around',
}}
>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.amount}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.userinfo == null ? '暂无' : detail.userinfo.cellphone}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.status_text}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{Utils.formatDate(detail.create_time)}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.remark || '暂无'}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.user_bank == null ? '暂无' : detail.user_bank.bank_id}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.user_bank == null ? '暂无' : detail.user_bank.bank_owner}
</div>
<div style={{ width: '6.6%', textAlign: 'center' }}>
{detail.user_bank == null ? '暂无' : detail.user_bank.bank_num}
</div>
</div>
</Modal>
</div>
);
}
}

View File

@@ -0,0 +1 @@
3683ba01-446e-4c89-a5a6-6fccbd9c00bf

View File

@@ -0,0 +1 @@
1573cf29-4d4b-4cd1-87fd-a119696087c7

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.VersionManagement {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,153 @@
import React, { IocComponent } from '@/core/Ioc';
import style from './index.less';
import publicCss from '@less/public/index.less';
import {
Select,
DatePicker,
Table,
Modal,
message,
Row,
Col,
Switch,
Form,
Input,
Button,
Checkbox,
} from 'antd';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class VersionManagement extends IocComponent {
state: { [key: string]: any } = {
params: {
app_version: '',
app_content: [],
status: 0,
app_url: '',
},
SwitchCheck: false,
};
async componentDidMount() {}
async addAppVersion() {
if (this.state.params.app_version.length <= 0) {
message.error('App版本号必填');
return false;
}
if (this.state.params.app_content.length <= 0) {
message.error('App升级内容必填');
return false;
}
if (this.state.params.app_url.length <= 0) {
message.error('App下载地址不能为空');
return false;
}
let res = await BuyerService.setAppVersion(this.state.params);
console.log(res);
}
render() {
return (
<div className={style.VersionManagement}>
<div className={style.title}></div>
<div>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
App版本
</Col>
<Col span={8}>
<Input
placeholder="如: 1.1"
onChange={e => {
this.state.params.app_version = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
App下载地址
</Col>
<Col span={8}>
<Input
placeholder="http://xxx.com/xxx/xxx.apk"
onChange={e => {
this.state.params.app_url = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
App更新内容
</Col>
<Col span={8}>
<TextArea
rows={4}
placeholder="优化界面布局和排版&#10;完善接口错误状态&#10;新增更多页面"
onChange={e => {
this.state.params.app_content = e.target.value.split('\n');
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
</Col>
<Col span={8}>
<Switch
checked={this.state.SwitchCheck}
onChange={e => {
e
? (this.state.params.status = 1)
: (this.state.params.status = 0);
console.log(this.state.params.status);
this.setState({
SwitchCheck: e,
});
console.log(e);
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 20 }}>
<Col
span={8}
style={{ display: 'flex', alignItems: 'center' }}
></Col>
<Col
span={2}
style={{ display: 'flex', justifyContent: 'flex-end' }}
>
<Button
type="primary"
onClick={async () => {
await this.addAppVersion();
}}
>
</Button>
</Col>
</Row>
</div>
</div>
);
}
}

View File

@@ -0,0 +1 @@
127f077e-2549-44f3-ba58-6585397d3067

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.VersionManagement {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,273 @@
import React, { IocComponent } from '@/core/Ioc';
import style from './index.less';
import publicCss from '@less/public/index.less';
import {
Select,
DatePicker,
Table,
Modal,
message,
Row,
Col,
Switch,
Form,
Input,
Button,
Checkbox,
} from 'antd';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class VersionList extends IocComponent {
state: { [key: string]: any } = {
columns: [
{
title: 'id',
dataIndex: 'id',
key: 'id',
},
{
title: 'App版本',
dataIndex: 'app_version',
key: 'app_version',
},
{
title: 'App更新内容',
dataIndex: 'app_content',
key: 'app_content',
width: 120,
render: (text: any, record: any) => {
return <span>{record.app_content.join(',')}</span>;
},
},
{
title: 'App下载地址',
dataIndex: 'app_url',
key: 'app_url',
width: 140,
},
{
title: '是否强制更新',
dataIndex: 'status',
key: 'status',
render: (text: any, record: any) => {
return <span>{record.status == 0 ? '否' : '是'}</span>;
},
},
{
title: '发布时间',
dataIndex: 'create_time',
key: 'create_time',
render: (text: any, record: any) => {
return <span>{Utils.formatDate(record.create_time)}</span>;
},
},
{
title: '更新时间',
dataIndex: 'update_time',
key: 'update_time',
render: (text: any, record: any) => {
return <span>{Utils.formatDate(record.update_time)}</span>;
},
},
{
title: '操作',
dataIndex: 'x',
render: (text: any, record: any) => {
return (
<a
onClick={() => {
this.state.updateParams.id = record.id;
this.state.updateParams.app_version = record.app_version;
this.state.updateParams.status = record.status;
this.state.updateParams.app_url = record.app_url;
this.state.updateParams.app_content = record.app_content;
this.setState({ isShowDetailModal: true });
}}
>
</a>
);
},
},
],
loading: false,
versionList: [],
PageCount: '', // 共有多少条
params: {
page: 1,
limit: 10,
},
updateParams: {
id: '',
app_version: '',
app_url: '',
app_content: '',
status: 0,
},
SwitchCheck: false,
};
async componentDidMount() {
await this.getVersionList();
}
async getVersionList() {
let res = await BuyerService.getVersionList(this.state.params);
if (res.hasOwnProperty('list')) {
this.setState({ versionList: res.list, PageCount: res.count });
this.setState({});
}
console.log(res);
}
async modifyAppVersion() {
let res = await BuyerService.modifyAppVersion(this.state.updateParams);
await this.getVersionList();
this.setState({ isShowDetailModal: false });
}
render() {
return (
<div className={style.VersionManagement}>
<div className={style.title}></div>
<div>
<Table
rowKey={'id'}
loading={this.state.loading}
style={{ marginTop: 20 }}
columns={this.state.columns}
dataSource={this.state.versionList}
pagination={{
showSizeChanger: true,
showQuickJumper: false,
current: this.state.params.page,
showTotal: () => `${this.state.PageCount}`,
// @ts-ignore
total: this.state.PageCount,
pageSize: this.state.params.limit,
onShowSizeChange: async (current, size) => {
this.state.params.page = current;
this.state.params.limit = size;
await this.getVersionList();
},
onChange: async current => {
this.state.params.page = current;
await this.getVersionList();
},
}}
/>
</div>
<Modal
destroyOnClose={true}
width="50%"
title="编辑"
visible={this.state.isShowDetailModal}
footer={null}
onCancel={() => this.setState({ isShowDetailModal: false })}
>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
App版本
</Col>
<Col span={8}>
<Input
placeholder="如: 1.1"
defaultValue={this.state.updateParams.app_version}
onChange={e => {
this.state.updateParams.app_version = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
App下载地址
</Col>
<Col span={8}>
<Input
defaultValue={this.state.updateParams.app_url}
placeholder="http://xxx.com/xxx/xxx.apk"
onChange={e => {
this.state.updateParams.app_url = e.target.value;
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
App更新内容
</Col>
<Col span={8}>
<TextArea
rows={4}
defaultValue={this.state.updateParams.app_content}
placeholder="优化界面布局和排版&#10;完善接口错误状态&#10;新增更多页面"
onChange={e => {
if (e.target.value.includes(',')) {
this.state.updateParams.app_content = e.target.value.split(
',',
);
} else {
this.state.updateParams.app_content = e.target.value.split(
'\n',
);
}
console.log(this.state.updateParams.app_content);
this.setState({});
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 15 }}>
<Col span={2} style={{ display: 'flex', alignItems: 'center' }}>
</Col>
<Col span={8}>
<Switch
checked={this.state.updateParams.status == 0 ? false : true}
onChange={e => {
e
? (this.state.updateParams.status = 1)
: (this.state.updateParams.status = 0);
this.setState({ SwitchCheck: e });
console.log(e);
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: 20 }}>
<Col
span={8}
style={{ display: 'flex', alignItems: 'center' }}
></Col>
<Col
span={2}
style={{ display: 'flex', justifyContent: 'flex-end' }}
>
<Button
type="primary"
onClick={async () => {
await this.modifyAppVersion();
}}
>
</Button>
</Col>
</Row>
</Modal>
</div>
);
}
}

View File

@@ -0,0 +1 @@
ae5c654c-63c4-44bb-b7c3-7428f96b0e30

View File

@@ -0,0 +1 @@
5ae8c69e-5ebf-4521-9857-1a1036a9df13

View File

@@ -0,0 +1,11 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
}

View File

@@ -0,0 +1,126 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import publicCss from '@less/public/index.less';
import { Select, Input, DatePicker, Button, Table } from 'antd';
import { BuyerService } from '@/core/service/buyerService';
export default class Index extends IocComponent {
state = {
columns: [
{
title: '买号id',
dataIndex: 'id',
key: 'id',
},
{
title: '账号',
dataIndex: 'account',
key: 'account',
},
{
title: '姓名',
dataIndex: 'true_name',
key: 'true_name',
},
{
title: '电话',
dataIndex: 'cellphone',
key: 'cellphone',
},
{
title: '申请时间',
dataIndex: 'create_time',
key: 'create_time',
},
{
title: '足迹数量',
dataIndex: 'trace_count',
key: 'trace_count',
},
{
title: '信用分',
dataIndex: 'credit_total',
render: (res: any, record: any) => {
return (
<div>
{record.credit == null ? '暂无' : record.credit.credit_total}
</div>
);
},
},
{
title: '好评率',
dataIndex: 'good_rate',
render: (res: any, record: any) => {
return (
<div>
{record.credit == null ? '暂无' : record.credit.good_rate / 100}
</div>
);
},
},
{
title: '备注',
dataIndex: 'remark',
key: 'remark',
},
{
title: '审核人',
dataIndex: 'admin_user',
key: 'admin_user',
},
{
title: '审核状态',
dataIndex: 'status_text',
key: 'status_text',
},
{
title: '审核时间',
dataIndex: 'admin_time',
key: 'admin_time',
},
],
params: {
text_field: '', // 精确搜索的select买家手机(phone)、账号id(account_id)、账号(account)
text_value: '', // 精确搜索的input值
status: '9', // 0待审核-8未通过-9已拒绝9已通过
date_field: 'create_time', // 时间字段创建时间create_time
date_range: '', // 时间段2020-06-01 - 2020-06-10
limit: 100, // 每页显示数量
page: 1, // 页码
},
totalCount: 0,
loading: false,
verifyData: [], // 存放 买号审核列表 的数据
};
async componentDidMount() {
this.verifyList().then();
}
async verifyList() {
this.setState({ loading: true });
let res = await BuyerService.verifyList(this.state.params);
if (res.hasOwnProperty('list')) {
this.setState({ verifyData: res.list });
console.log(this.state.verifyData);
}
this.setState({ loading: false });
}
render() {
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex}></div>
<Table
rowKey={'id'}
loading={this.state.loading}
className={publicCss.mt20}
columns={this.state.columns}
dataSource={this.state.verifyData}
/>
</div>
);
}
}

View File

@@ -0,0 +1 @@
fd613047-fc44-4546-8d3c-b848b30aad22

View File

@@ -0,0 +1,17 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
.modalTitle {
display: flex;
height: 50px;
align-items: center;
justify-content: space-around;
}
}

View File

@@ -0,0 +1,271 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import publicCss from '@less/public/index.less';
import {
Select,
Input,
DatePicker,
Button,
Table,
Modal,
message,
Row,
Col,
} from 'antd';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class deviceList extends IocComponent {
state: { [key: string]: any } = {
columns: [
{
title: '手机号',
dataIndex: 'phone_number',
key: 'phone_number',
},
{
title: 'app级别',
dataIndex: 'app_level',
key: 'app_level',
},
{
title: 'app版本',
dataIndex: 'app_version',
key: 'app_version',
},
{
title: '品牌',
dataIndex: 'device_brand',
key: 'device_brand',
},
{
title: '唯一id',
dataIndex: 'device_unique_id',
key: 'device_unique_id',
},
{
title: '第一次安装时间',
dataIndex: 'first_install_time',
key: 'first_install_time',
render: (res: any, record: any) => {
return <span>{Utils.formatDate(record.first_install_time)}</span>;
},
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
render: (res: any, record: any) => {
return <span>{Utils.formatDate(record.create_time)}</span>;
},
},
{
title: '操作',
dataIndex: 'x',
render: (text: any, record: any) => {
return (
<a
onClick={async () => {
await this.getDetail(record.id);
}}
>
</a>
);
},
},
],
params: {
text_field: '',
text_value: '',
date_field: '',
date_range: '',
limit: 20,
page: 1,
},
totalCount: 0,
deviceData: [],
isShowInfo: false,
DetailInfo: {},
loading: false,
};
async componentDidMount() {
await this.deviceList();
}
async deviceList() {
this.setState({ loading: true });
let res = await BuyerService.deviceList(this.state.params);
console.log('deviceList: ', res);
if (res !== null && res.hasOwnProperty('list')) {
this.state.totalCount = res.count;
this.setState({ deviceData: res.list });
}
this.setState({ loading: false });
}
/**
* 设备详情
* @param id
*/
async getDetail(id: string) {
let res = await BuyerService.getDetail({ device_id: id });
this.setState({ DetailInfo: res, isShowInfo: true });
console.log('设备详情:', this.state.DetailInfo);
}
render() {
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex}>
<Select
defaultValue="请选择"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.text_field = value;
this.setState({});
}}
>
<Option value="phone_number"></Option>
<Option value="device_brand"></Option>
</Select>
<Input
className={publicCss.ml10}
style={{ width: 240 }}
placeholder="请输入手机号/品牌"
onChange={e => {
this.state.params.text_value = e.target.value;
this.setState({});
}}
/>
<Select
defaultValue="请选择"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.date_field = value;
this.setState({});
}}
>
<Option value="first_install_time"></Option>
<Option value="create_time"></Option>
</Select>
<RangePicker
// @ts-ignore
onChange={(date: Date, dateString: Array<any>) => {
this.state.params.date_range = dateString.join(' - ');
}}
/>
<Button
className={publicCss.ml10}
type="primary"
onClick={async () => {
await this.deviceList();
}}
>
</Button>
</div>
<Modal
width="60%"
title="设备详情"
visible={this.state.isShowInfo}
onCancel={() => {
this.setState({ isShowInfo: false });
}}
onOk={async () => {}}
>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>id</Col>
<Col span={20}>{this.state.DetailInfo.id || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>id</Col>
<Col span={20}>{this.state.DetailInfo.user_id || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>mac地址</Col>
<Col span={20}>{this.state.DetailInfo.mac || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{this.state.DetailInfo.serial_number || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{Utils.formatDate(this.state.DetailInfo.first_install_time) ||
'暂无'}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{this.state.DetailInfo.phone_number || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>app级别</Col>
<Col span={20}>{this.state.DetailInfo.app_level || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{this.state.DetailInfo.user_agent || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>app版本</Col>
<Col span={20}>{this.state.DetailInfo.app_version || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{this.state.DetailInfo.system_version || '暂无'}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{this.state.DetailInfo.system_name || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>id</Col>
<Col span={20}>{this.state.DetailInfo.device_id || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{this.state.DetailInfo.device_brand || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{this.state.DetailInfo.device_model || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{this.state.DetailInfo.device_manufacturer || '暂无'}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>id</Col>
<Col span={20}>
{this.state.DetailInfo.device_unique_id || '暂无'}
</Col>
</Row>
</Modal>
<Table
rowKey="id"
loading={this.state.loading}
style={{ marginTop: '20px' }}
columns={this.state.columns}
dataSource={this.state.deviceData}
/>
</div>
);
}
}

View File

@@ -0,0 +1 @@
4a994308-e0d5-44a2-96bc-569776857338

View File

@@ -0,0 +1,17 @@
@import '../../../assets/less/public/color.less';
@import '../../../assets/less/public/mixins.less';
.index {
padding: 20px;
height: 100%;
background-color: #ffffff;
.title {
.title();
}
.modalTitle {
display: flex;
height: 50px;
align-items: center;
justify-content: space-around;
}
}

View File

@@ -0,0 +1,448 @@
import React, { IocComponent } from '@Ioc/index';
import style from './index.less';
import publicCss from '@less/public/index.less';
import {
Select,
Input,
DatePicker,
Button,
Table,
Modal,
message,
Row,
Col,
} from 'antd';
import { BuyerService } from '@/core/service/buyerService';
import { Utils } from '@/core/utils/utils';
import { history } from '@@/core/history';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { TextArea } = Input;
export default class Index extends IocComponent {
state = {
columns: [
{
title: '买号id',
dataIndex: 'id',
key: 'id',
},
{
title: '账号',
dataIndex: 'account',
key: 'account',
},
{
title: '姓名',
dataIndex: 'true_name',
render: (res: any, record: any) => {
return (
<div>{record.true_name == null ? '暂无' : record.true_name}</div>
);
},
},
{
title: '电话',
dataIndex: 'cellphone',
key: 'cellphone',
},
{
title: '申请时间',
dataIndex: 'create_time',
key: 'create_time',
render: (res: any, record: any) => {
return <span>{Utils.formatDate(record.create_time)}</span>;
},
},
{
title: '足迹数量',
dataIndex: 'trace_count',
key: 'trace_count',
},
{
title: '信用分',
dataIndex: 'credit_total',
render: (res: any, record: any) => {
return (
<div>
{record.credit == null || record.credit.length == 0
? '暂无'
: record.credit.credit_total}
</div>
);
},
},
{
title: '好评率',
dataIndex: 'good_rate',
render: (res: any, record: any) => {
return (
<div>
{record.credit == null || record.credit.length == 0
? '暂无'
: record.credit.good_rate / 100}
</div>
);
},
},
{
title: '备注',
dataIndex: 'remark',
render: (res: any, record: any) => {
return <div>{record.remark == null ? '暂无' : record.remark}</div>;
},
},
// {
// title: '审核人',
// dataIndex: 'admin_user',
// key: 'admin_user',
// },
{
title: '审核状态',
dataIndex: 'status_text',
key: 'status_text',
},
// {
// title: '审核时间',
// dataIndex: 'admin_time',
// key: 'admin_time',
// },
{
title: '操作',
dataIndex: 'x',
render: (text: any, record: any) => {
return (
<a
onClick={async () => {
history.push({
pathname: '/buyerAccouet/info',
query: { id: record.id },
});
// await this.detail(record.id);
}}
>
</a>
);
},
},
],
params: {
text_field: '', // 精确搜索的select买家手机(phone)、账号id(account_id)、账号(account)
text_value: '', // 精确搜索的input值
status: '', // 0待审核-8未通过-9已拒绝9已通过
date_field: 'create_time', // 时间字段创建时间create_time
date_range: '', // 时间段2020-06-01 - 2020-06-10
limit: 100, // 每页显示数量
page: 1, // 页码
},
totalCount: 0,
verifyData: [], // 存放 买号审核列表 的数据
selectedRowKeys: [],
detail: {},
selectId: [],
status: 0,
remark: '',
isShowDetailModal: false, // 控制是否显示详情的弹窗
isShowRemarks: false, // 控制备注弹窗是否显示
loading: false,
};
async componentDidMount() {
this.verifyList().then();
}
async verifyList() {
this.setState({ loading: true });
let res = await BuyerService.verifyList(this.state.params);
if (res.hasOwnProperty('list')) {
res.list.forEach((val: any, index: any) => (val.key = index));
this.setState({ verifyData: res.list });
}
this.setState({ loading: false });
}
/**
* 获取详情
* @param id
*/
async detail(id: string) {
let res = await BuyerService.detail({ account_id: id });
this.setState({ detail: res });
this.setState({ isShowDetailModal: true });
}
onSelectChange = (selectedRowKeys: any, selectedRows: any) => {
this.state.selectId = selectedRows;
this.state.selectedRowKeys = selectedRowKeys;
this.setState({});
};
async verify() {
let ids: Array<any> = [];
this.state.selectId.forEach((val: any, index) => ids.push(val.id));
let params = {
ids: ids,
status: this.state.status,
remark: this.state.remark,
};
let res = await BuyerService.verify(params);
await this.verifyList();
this.setState({ selectedRowKeys: [], isShowRemarks: false });
Utils.TipsMessage(res);
console.log(res);
}
render() {
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
};
const detail: any = this.state.detail;
return (
<div className={style.index}>
<div className={style.title}></div>
<div className={publicCss.flex}>
<Select
defaultValue="请选择"
style={{ width: 160 }}
onChange={(value: any) => {
this.state.params.text_field = value;
this.setState({});
}}
>
<Option value="phone"></Option>
<Option value="account_id">id</Option>
<Option value="account"></Option>
</Select>
<Input
className={publicCss.ml10}
style={{ width: 240 }}
placeholder="请输入买家手机/账号id/账号"
onChange={e => {
this.state.params.text_value = e.target.value;
this.setState({});
}}
/>
<Select
className={publicCss.ml10}
defaultValue="请选择状态"
style={{ width: 160 }}
onChange={e => {
console.log(e);
this.state.params.status = e;
this.setState({});
}}
>
<Option value="0"></Option>
<Option value="-8"></Option>
<Option value="-9"></Option>
<Option value="9"></Option>
</Select>
<RangePicker
// @ts-ignore
onChange={(date: Date, dateString: Array<any>) => {
this.state.params.date_range = dateString.join(' - ');
}}
/>
<Button
className={publicCss.ml10}
type="primary"
onClick={async () => {
await this.verifyList();
}}
>
</Button>
</div>
<div
className={publicCss.flex}
style={{ marginTop: '20px', marginBottom: '10px' }}
>
<Button
style={{ marginRight: '10px' }}
onClick={() => {
if (this.state.selectedRowKeys.length == 0) {
message.error('请先选中买号');
} else {
this.state.status = -8;
this.setState({ isShowRemarks: true });
}
// 1
}}
>
</Button>
<Button
style={{ marginRight: '10px' }}
type="primary"
danger
onClick={() => {
if (this.state.selectedRowKeys.length == 0) {
message.error('请先选中买号');
} else {
this.state.status = -9;
this.setState({ isShowRemarks: true });
}
// 2
}}
>
</Button>
<Button
style={{ marginRight: '10px' }}
type="primary"
onClick={async () => {
if (this.state.selectedRowKeys.length == 0) {
message.error('请先选中买号');
} else {
this.state.status = 9;
await this.verify();
}
}}
>
</Button>
</div>
<Table
loading={this.state.loading}
rowSelection={rowSelection}
columns={this.state.columns}
dataSource={this.state.verifyData}
/>
<Modal
title="请填写备注"
destroyOnClose={true}
visible={this.state.isShowRemarks}
onCancel={() => {
this.setState({ isShowRemarks: false });
}}
onOk={async () => {
await this.verify();
}}
>
<Row>
<Col span={4}></Col>
<Col span={20}>
<TextArea
rows={4}
onChange={e => {
console.log(e.target.value);
this.state.remark = e.target.value;
}}
/>
</Col>
</Row>
</Modal>
<Modal
width="50%"
title="详情"
destroyOnClose={true}
visible={this.state.isShowDetailModal}
footer={null}
onCancel={() => {
this.setState({ isShowDetailModal: false });
}}
>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>id</Col>
<Col span={20}>{detail.id || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{detail.account || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{detail.status_text || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.admin_user == null ? '暂无' : detail.admin_user}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{Utils.formatDate(detail.admin_time)}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.remark == null ? '暂无' : detail.remark}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{detail.trace_count}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.true_name == null ? '暂无' : detail.true_name}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.trade_count == null ? '暂无' : detail.trade_count}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}>退</Col>
<Col span={20}>
{detail.trade_return == null ? '暂无' : detail.trade_return}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{detail.cellphone || '暂无'}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.credit == null ? '暂无' : detail.credit.credit_total}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.credit == null ? '暂无' : detail.credit.good_rate}
</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>{Utils.formatDate(detail.create_time)}</Col>
</Row>
<Row style={{ marginBottom: 10 }}>
<Col span={4}></Col>
<Col span={20}>
{detail.hasOwnProperty('account_tags') &&
detail.account_tags != null
? detail.account_tags.map((val: any, index: any) => {
return (
<span
key={index}
style={{ textAlign: 'center', marginRight: 10 }}
>
{val.tag_config.tag_title}
</span>
);
})
: '暂无'}
</Col>
</Row>
</Modal>
</div>
);
}
}

Some files were not shown because too many files have changed in this diff Show More