信用卡账单数据分析

微信和WhatsApp聊天记录显示
feature/2.0-sales-trade
尹诚诚 3 years ago
parent 98f07422d9
commit 0cd869e056

@ -0,0 +1 @@
npm run build

@ -18,6 +18,9 @@ import ProtectedRoute from "./views/ProtectedRoute"
import Customer_care_inchina from "./charts/Customer_care_inchina"
import Customer_care_potential from "./charts/Customer_care_potential"
import Customer_care_regular from "./charts/Customer_care_regular"
import Wechat_session from "./charts/Wechat_session"
import WhatsApp_session from "./charts/WhatsApp_session"
import Credit_card_bill from "./views/Credit_card_bill"
import Logo from './logo.png'
import {stores_Context} from "./config";
import {observer} from "mobx-react";
@ -39,6 +42,8 @@ const App = () => {
{key: 31, label: <NavLink to="/customer_care_potential">潜力客户</NavLink>},
{key: 32, label: <NavLink to="/customer_care_regular">老客户</NavLink>},
{key: 33, label: <NavLink to="/customer_care_inchina">在华客户</NavLink>},
{key: 34, label: <NavLink to="/wechat_session">微信会话存档</NavLink>},
{key: 35, label: <NavLink to="/whatsapp_session">WhatsApp会话存档</NavLink>},
]
},
{
@ -46,8 +51,7 @@ const App = () => {
label: '财务',
icon: <TeamOutlined/>,
children: [
{key: 412, label: <NavLink to="/order">损益表</NavLink>},
{key: 41, label: <NavLink to="/order">信用卡账单</NavLink>},
{key: 41, label: <NavLink to="/credit_card_bill">信用卡账单</NavLink>},
]
},
@ -84,6 +88,11 @@ const App = () => {
<Route path="/customer_care_inchina" element={<Customer_care_inchina/>}/>
<Route path="/customer_care_regular" element={<Customer_care_regular/>}/>
<Route path="/customer_care_potential" element={<Customer_care_potential/>}/>
<Route path="/whatsapp_session" element={<WhatsApp_session/>}/>
<Route path="/wechat_session" element={<Wechat_session/>}/>
</Route>
<Route element={<ProtectedRoute auth={['admin', 'director_bu', 'financial']}/>}>
<Route path="/credit_card_bill" element={<Credit_card_bill/>}/>
</Route>
</Routes>
</Content>

@ -0,0 +1,33 @@
import React, {Component} from 'react';
import {Select} from 'antd';
import {observer} from 'mobx-react';
const BillTypeSelect = (props) => {
const {store} = props;
return (
<div>
<Select
mode={store.bill_type_mode}
style={{width: '100%'}}
placeholder="选择类型"
value={store.bill_types}
onChange={store.bt_handleChange}
>
{props.show_all ? <Select.Option key="-1" value="ALL">ALL 账单类型</Select.Option> : ''}
{Object.keys(store.data).length == 0 ? '' : store.data.map((item, index) => {
return (
<Select.Option key={index}
value={item.cb_billtype}>{item.cb_billtype}</Select.Option>
)
})
}
</Select>
</div>
);
}
export default observer(BillTypeSelect);

@ -0,0 +1,28 @@
import React, {Component} from 'react';
import {Select} from 'antd';
import {observer} from "mobx-react";
const Business_unit = (props) => {
const {store} = props;
return (
<div>
<Select
mode={store.bu_select_mode}
allowClear
style={{width: '100%',}}
placeholder="选择事业部"
value={store.business_units}
onChange={(value) => store.bu_handleChange(value)}
>
{props.show_all ? <Select.Option key="-1" value="ALL">ALL 事业部</Select.Option> : ''}
<Select.Option key="0" value="公共开支">公共开支</Select.Option>
<Select.Option key="1" value="GH事业部">GH事业部</Select.Option>
<Select.Option key="2" value="国际事业部">国际事业部</Select.Option>
<Select.Option key="4" value="孵化学院">孵化学院</Select.Option>
</Select>
</div>
);
}
export default observer(Business_unit);

@ -9,7 +9,7 @@ class GroupSelect extends Component {
}
render() {
const store=this.props.store;
const store = this.props.store;
return (
<div>
<Select
@ -18,8 +18,9 @@ class GroupSelect extends Component {
style={{width: '100%',}}
placeholder="选择小组"
value={store.groups}
onChange={(value)=>store.handleChange(value)}
onChange={(value) => store.group_handleChange(value)}
>
{this.props.show_all ? <Select.Option key="0" value="ALL">ALL 小组</Select.Option> : ''}
<Select.Option key="1" value="1">CH直销</Select.Option>
<Select.Option key="2" value="2">CH大客户</Select.Option>
<Select.Option key="28" value="28">AH</Select.Option>

@ -0,0 +1,66 @@
import React, {useContext, useEffect} from 'react';
import {Row, Col, List, Avatar, Table, Space, Radio, Tooltip} from 'antd';
import {
ContainerOutlined,
SearchOutlined,
} from '@ant-design/icons';
import {stores_Context} from '../config'
import {Line} from "@ant-design/charts";
import {observer} from 'mobx-react';
import DatePickerCharts from '../charts/DatePickerCharts'
import {NavLink, useParams} from "react-router-dom";
import * as comm from "../utils/commons";
import * as config from "../config";
import SiteSelect from "../charts/SiteSelect";
import GroupSelect from "../charts/GroupSelect";
import {utils, writeFileXLSX} from "xlsx";
const Wechat_session = () => {
const {orders_store, date_picker_store, customer_store} = useContext(stores_Context);
const inchina_data = customer_store.inchina_data;
useEffect(() => {
}, [])
const data = [
{
title: 'Ant Design Title 1',
},
{
title: 'Ant Design Title 2',
},
{
title: 'Ant Design Title 3',
},
{
title: 'Ant Design Title 4',
},
];
return (
<div>
<Row>
<Col span={8}>
<List
itemLayout="horizontal"
dataSource={data}
renderItem={(item) => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src="https://joeschmoe.io/api/v1/random" />}
title={<a href="https://ant.design">{item.title}</a>}
description=""
/>
</List.Item>
)}
/>
</Col>
</Row>
</div>
);
}
export default observer(Wechat_session);

@ -0,0 +1,40 @@
import React, {useContext, useEffect} from 'react';
import {Row, Col, Button, Divider, Table, Space, Radio, Tooltip} from 'antd';
import {
ContainerOutlined,
SearchOutlined,
} from '@ant-design/icons';
import {stores_Context} from '../config'
import {Line} from "@ant-design/charts";
import {observer} from 'mobx-react';
import DatePickerCharts from '../charts/DatePickerCharts'
import {NavLink, useParams} from "react-router-dom";
import * as comm from "../utils/commons";
import * as config from "../config";
import SiteSelect from "../charts/SiteSelect";
import GroupSelect from "../charts/GroupSelect";
import {utils, writeFileXLSX} from "xlsx";
const WhatsApp_session = () => {
const {orders_store, date_picker_store, customer_store} = useContext(stores_Context);
const inchina_data = customer_store.inchina_data;
useEffect(() => {
}, [])
return (
<div>
<Row>
<Col span={8}>
<h2>WhatsAPP会话</h2>
</Col>
</Row>
</div>
);
}
export default observer(WhatsApp_session);

@ -2,5 +2,5 @@ import React from "react";
export const stores_Context = React.createContext();
export const DATE_FORMAT = 'YYYY-MM-DD';
export const HT_HOST = 'https://p9axztuwd7x8a7.mycht.cn';
//export const HT_HOST = 'http://202.103.68.100:890';//889正式库
//export const HT_HOST = 'https://p9axztuwd7x8a7.mycht.cn';
export const HT_HOST = 'http://202.103.68.100:890';//889正式库

@ -9,11 +9,11 @@ class AuthStore {
constructor(rootStore) {
this.rootStore = rootStore;
makeAutoObservable(this);
this.get_auth();
//this.get_auth();
}
auth = [];
user = {};
auth = ['admin'];
user = {name:'ycc',userid:'12345678'};
has_permission(requireds) {
if (Object.keys(requireds).length == 0) {

@ -0,0 +1,52 @@
import {makeAutoObservable, runInAction} from "mobx";
import * as dd from 'dingtalk-jsapi';
import * as config from "../config";
//会话管理
class ChatSessionStore {
constructor(rootStore) {
this.rootStore = rootStore;
makeAutoObservable(this);
}
wechat_data = {
counselors: [],//顾问列表
customers: [],//客户列表
}
//请求权限
get_auth() {
let _this = this;
const CORPID = 'ding48bce8fd3957c96b';//企业的id
dd.runtime.permission.requestAuthCode({
corpId: CORPID,
onSuccess: function (res) {
console.log(res);
let code = res.code;
let url = '/dingtalk/dingtalkwork/Getusers_auth?code=' + code;
//请求获取HT接口获取用户权限和用户信息
fetch(config.HT_HOST + url)
.then((response) => response.json())
.then((json) => {
runInAction(() => {
_this.user = json.result;
_this.auth = json.result.authlist;
})
})
.catch((error) => {
console.log('fetch data failed', error);
});
},
onFail: function (err) {
console.log(err)
}
});
}
}
export default ChatSessionStore;

@ -71,7 +71,7 @@ class CustomerStore {
group_select_mode: 'multiple',//是否多选分组
groups: ['1', '2', '7'],
date_type: 'applyDate',
handleChange: this.handleChange_group_select.bind(this),
group_handleChange: this.handleChange_group_select.bind(this),
onChange_datetype: this.onChange_datetype.bind(this),
potential_customer_order: this.potential_customer_order.bind(this),
onChange_show_detail_table: this.onChange_show_detail_table.bind(this),
@ -141,7 +141,7 @@ class CustomerStore {
group_select_mode: 'multiple',//是否多选分组
groups: ['1', '2', '28', '7'],
date_type: 'applyDate',
handleChange: this.handleChange_group_select_regular.bind(this),
group_handleChange: this.handleChange_group_select_regular.bind(this),
onChange_datetype: this.onChange_datetype_regular.bind(this),
regular_customer_order: this.regular_customer_order.bind(this),
onChange_show_detail_table: this.onChange_show_detail_table_regular.bind(this),
@ -211,7 +211,7 @@ class CustomerStore {
group_select_mode: 'multiple',//是否多选分组
groups: ['1', '2', '28', '7'],
date_type: 'applyDate',
handleChange: this.handleChange_group_select_inchina.bind(this),
group_handleChange: this.handleChange_group_select_inchina.bind(this),
onChange_datetype: this.onChange_datetype_inchina.bind(this),
inchina_customer_order: this.inchina_customer_order.bind(this),
onChange_show_detail_table: this.onChange_show_detail_table_inchina.bind(this),

@ -182,7 +182,7 @@ class DashboardStore {
},
],
date_type: 'applyDate',
handleChange: this.handleChange_group_select.bind(this),
group_handleChange: this.handleChange_group_select.bind(this),
onChange_datetype: this.onChange_datetype.bind(this),
asyncFetch: this.get_CountYDOrder.bind(this),
}

@ -0,0 +1,84 @@
import {makeAutoObservable, runInAction} from "mobx";
import * as dd from 'dingtalk-jsapi';
import * as config from "../config";
//财务管理
class FinancialStore {
constructor(rootStore) {
this.rootStore = rootStore;
makeAutoObservable(this);
this.get_bill_types();
}
bill_type_data = {
data: [],
bill_type_mode: false,
bill_types: ['ALL'],
bt_handleChange: this.bt_handleChange.bind(this),
}
bt_handleChange(value) {
this.bill_type_data.bill_types = value;
};
get_bill_types() {
const date_picker_store = this.rootStore.date_picker_store;
let url = '/service-web/QueryData/GetCreditCardBillType';
fetch(config.HT_HOST + url)
.then((response) => response.json())
.then((json) => {
runInAction(() => {
this.bill_type_data.data = json.billtype;
})
})
.catch((error) => {
console.log('fetch data failed', error);
});
}
credit_card_data = {
data: [],
loading:false,
bu_select_mode: false,
business_units: ['ALL'],
group_select_mode: false,
groups: ['ALL'],
bu_handleChange: this.bu_handleChange.bind(this),
group_handleChange: this.group_handleChange.bind(this),
};
bu_handleChange(value) {
this.credit_card_data.business_units = value;
};
group_handleChange(value) {
this.credit_card_data.groups = value;
};
//请求信用卡账单
get_credit_card_bills() {
const date_picker_store = this.rootStore.date_picker_store;
let url = '/service-web/QueryData/GetCreditCardBills';
url += `?business_unit=${this.credit_card_data.business_units.toString()}&groups=${this.credit_card_data.groups.toString()}&billtype=${this.bill_type_data.bill_types.toString()}`;
url += '&billdate1=' + date_picker_store.start_date.format(config.DATE_FORMAT) + '&billdate2=' + date_picker_store.end_date.format(config.DATE_FORMAT) + '%2023:59:59';
if (date_picker_store.start_date_cp && date_picker_store.end_date_cp) {
url += '&billdateOld1=' + date_picker_store.start_date_cp.format(config.DATE_FORMAT) + '&billdateOld2=' + date_picker_store.end_date_cp.format(config.DATE_FORMAT) + '%2023:59:59';
}
fetch(config.HT_HOST + url)
.then((response) => response.json())
.then((json) => {
runInAction(() => {
this.credit_card_data.data = json;
})
})
.catch((error) => {
console.log('fetch data failed', error);
});
}
}
export default FinancialStore;

@ -4,6 +4,8 @@ import DashboardStore from "./DashboardStore";
import DatePickerStore from "./DatePickerStore";
import CustomerStore from "./CustomerStore";
import AuthStore from "./AuthStore";
import ChatSessionStore from "./ChatSessionStore";
import FinancialStore from "./FinancialStore";
class Index {
@ -13,6 +15,8 @@ class Index {
this.date_picker_store = new DatePickerStore(this);
this.customer_store = new CustomerStore(this);
this.auth_store = new AuthStore(this);
this.chat_session_store = new ChatSessionStore(this);
this.financial_store = new FinancialStore(this);
makeAutoObservable(this);
}

@ -0,0 +1,93 @@
import React, {Component, useContext} from 'react';
import {observer} from 'mobx-react';
import {Row, Col, Button, Tabs, Table} from 'antd';
import {stores_Context} from '../config'
import {useNavigate} from "react-router-dom";
import {
SlackOutlined,
SketchOutlined,
AntCloudOutlined,
SearchOutlined,
GithubOutlined
} from '@ant-design/icons';
import BillTypeSelect from '../charts/BillTypeSelect'
import GroupSelect from '../charts/GroupSelect'
import Business_unit from '../charts/Business_unit'
import DatePickerCharts from '../charts/DatePickerCharts'
import {Line} from "@ant-design/charts";
import * as com from '../utils/commons'
const Credit_card_bill = () => {
const {financial_store} = useContext(stores_Context);
const {bill_type_data, credit_card_data} = financial_store;
const data_source = !com.empty(credit_card_data.data) ? credit_card_data.data.billdate1 : [];
const line_config = {
data: data_source,
padding: 'auto',
xField: 'cb_datetime',
yField: 'cb_usd',
seriesField: 'groups',
xAxis: {
type: 'timeCat',
},
point: {
size: 4,
shape: 'cicle',
},
label: {},//显示标签
legend: {
itemValue: {
formatter: (text, item) => {
const items = data_source.filter((d) => d.groups === item.value);//按站点筛选
return items.length ? Math.round(items.reduce((a, b) => a + b.cb_usd, 0)) : '';//计算总数
},
},
},
// tooltip: {
// customContent: (title, items) => {
// const data = items[0]?.data || {};
// return `<div>${title}</div><div>${data.seriesField} ${data.yField}</div>`;
// }
// },
smooth: true,
};
return (
<div>
<Row>
<Col span={11}>
<h2>信用卡账单</h2>
</Col>
<Col span={10}>
<Row>
<Col span={24}><BillTypeSelect store={bill_type_data} show_all={true}/></Col>
<Col span={12}>
<Business_unit store={credit_card_data} show_all={true}/>
<GroupSelect store={credit_card_data} show_all={true}/>
</Col>
<Col span={12}>
<DatePickerCharts/>
</Col>
</Row>
</Col>
<Col span={1}></Col>
<Col span={2}>
<Button type="primary" icon={<SearchOutlined/>} size='large' loading={credit_card_data.loading}
onClick={() => {
financial_store.get_credit_card_bills();
}}>统计</Button>
</Col>
</Row>
<Row>
<Col span={24}>
<Line {...line_config} />
</Col>
</Row>
</div>
);
}
export default observer(Credit_card_bill);

@ -214,7 +214,7 @@ class Orders extends Component {
</Row>
<Row gutter={[16, {xs: 8, sm: 16, md: 24, lg: 32}]}>
<Col className="gutter-row" span={24}>
<Col span={24}>
<Line {...config} />
</Col>

Loading…
Cancel
Save