初步完成人工充值页面;完成数据统计页面
This commit is contained in:
parent
fce15a60d7
commit
99c6f600a8
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
|
@ -1,7 +1,6 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Form, Input, Table, Image, Space, Button, Modal, Radio } from "antd";
|
||||
import baseRequest from "../../utils/baseRequest";
|
||||
import { generateSignature } from "../../utils/crypto";
|
||||
|
||||
const ManualRechargeAndWithdrawalContent = (props) => {
|
||||
const { TextArea } = Input;
|
||||
|
@ -134,20 +133,16 @@ const ManualRechargeAndWithdrawalContent = (props) => {
|
|||
const modalSearch = async (value) => {
|
||||
try {
|
||||
const base = baseRequest();
|
||||
const signature = generateSignature();
|
||||
const response = await fetch(
|
||||
`/op/account/list_by_user_id?signature=${signature}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
user_id: parseInt(value.userId, 10),
|
||||
...base,
|
||||
}),
|
||||
}
|
||||
);
|
||||
const response = await fetch(`/op/account/list_by_user_id`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
user_id: parseInt(value.userId, 10),
|
||||
...base,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.ret === -1) {
|
||||
alert(data.msg);
|
||||
|
@ -177,34 +172,23 @@ const ManualRechargeAndWithdrawalContent = (props) => {
|
|||
|
||||
try {
|
||||
const base = baseRequest();
|
||||
const signature = generateSignature({
|
||||
mid: selectedUser,
|
||||
coins: parseInt(value.num, 10),
|
||||
operator: base.b_mid.toString(),
|
||||
...base,
|
||||
const response = await fetch(`/op/vas/create_order`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mid: selectedUser,
|
||||
coins: parseInt(value.num, 10),
|
||||
operator: value.password,
|
||||
...base,
|
||||
}),
|
||||
});
|
||||
const response = await fetch(
|
||||
`/op/vas/create_order?signature=${signature}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mid: selectedUser,
|
||||
coins: parseInt(value.num, 10),
|
||||
operator: base.b_mid.toString(),
|
||||
...base,
|
||||
}),
|
||||
}
|
||||
);
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
if (data.ret === -1) {
|
||||
alert(data.msg);
|
||||
return;
|
||||
}
|
||||
setUserInfo(data.data.account);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
@ -342,6 +326,19 @@ const ManualRechargeAndWithdrawalContent = (props) => {
|
|||
>
|
||||
<Input className="w-32" type="number" min={0} max={10000} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="支付密码"
|
||||
name="password"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: "未填写",
|
||||
},
|
||||
]}
|
||||
style={{ margin: 0 }}
|
||||
>
|
||||
<Input className="w-32" type="password" min={0} max={10000} />
|
||||
</Form.Item>
|
||||
<Button className="ml-8" type="primary" htmlType="submit">
|
||||
确认
|
||||
</Button>
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import baseRequest from "../../utils/baseRequest";
|
||||
import { DatePicker, Table } from "antd";
|
||||
|
||||
export default function Data() {
|
||||
const { RangePicker } = DatePicker;
|
||||
const [data, setData] = useState();
|
||||
|
||||
// 获取当前时间戳
|
||||
const currentTimestamp = Date.now();
|
||||
// 获取前2个小时的时间戳
|
||||
const oneHourAgoTimestamp = currentTimestamp - 7200000; // 1小时 = 60分钟 * 60秒 * 1000毫秒
|
||||
const [selectTime, setSelectTime] = useState({
|
||||
ct_lower_bound: oneHourAgoTimestamp,
|
||||
ct_upper_bound: currentTimestamp,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const getData = async () => {
|
||||
try {
|
||||
const base = baseRequest();
|
||||
const response = await fetch(`/op/daily_statement/list`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
ct_lower_bound: Math.floor(selectTime.ct_lower_bound / 1000),
|
||||
ct_upper_bound: Math.floor(selectTime.ct_upper_bound / 1000),
|
||||
offset: 0,
|
||||
limit: 100,
|
||||
...base,
|
||||
}),
|
||||
});
|
||||
const _data = await response.json();
|
||||
const structedData = _data.data.list.map((item, index) => {
|
||||
return {
|
||||
key: index,
|
||||
time: {
|
||||
start: new Date(item.start_time * 1000).toLocaleString(),
|
||||
end: new Date(item.end_time * 1000).toLocaleString(),
|
||||
},
|
||||
h5_call_count: item.h5_call_count,
|
||||
registered_user_count: item.registered_user_count,
|
||||
order_created_count: item.order_created_count,
|
||||
order_finished_count: item.order_finished_count,
|
||||
};
|
||||
});
|
||||
setData(structedData);
|
||||
if (_data.ret === -1) {
|
||||
alert(_data.msg);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
getData();
|
||||
}, [selectTime]);
|
||||
|
||||
const onOk = (value) => {
|
||||
const startTimeStamp = value[0] && value[0].valueOf() - 60000; // 起始时间的时间戳
|
||||
const endTimeStamp = value[1] && value[1].valueOf() + 60000; // 结束时间的时间戳
|
||||
setSelectTime({
|
||||
ct_lower_bound: startTimeStamp,
|
||||
ct_upper_bound: endTimeStamp,
|
||||
});
|
||||
};
|
||||
|
||||
//表头
|
||||
const columns = [
|
||||
{
|
||||
title: "时段",
|
||||
dataIndex: "time",
|
||||
key: "time",
|
||||
render: (data) => {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<span className="text-green-400">开始时间:</span>
|
||||
{data.start}
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-red-400">结束时间:</span>
|
||||
{data.end}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "当日页面访问",
|
||||
dataIndex: "h5_call_count",
|
||||
key: "h5_call_count",
|
||||
},
|
||||
{
|
||||
title: "总注册",
|
||||
dataIndex: "registered_user_count",
|
||||
key: "registered_user_count",
|
||||
},
|
||||
{
|
||||
title: "总订单创建",
|
||||
dataIndex: "order_created_count",
|
||||
key: "order_created_count",
|
||||
},
|
||||
{
|
||||
title: "总订单完成",
|
||||
dataIndex: "order_finished_count",
|
||||
key: "order_finished_count",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="px-4">
|
||||
<h1>数据统计</h1>
|
||||
<p>请选择时段</p>
|
||||
<RangePicker
|
||||
showTime={{
|
||||
format: "HH:mm",
|
||||
}}
|
||||
showNow
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
onOk={onOk}
|
||||
/>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
pagination={{ pageSize: 20 }}
|
||||
scroll={{ y: window.innerHeight - 300 }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -16,6 +16,7 @@ import {
|
|||
import { Menu, Layout } from "antd";
|
||||
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
||||
import { checkAuth, signOut } from "../../utils/auth";
|
||||
import Data from "./data";
|
||||
|
||||
export default function Op() {
|
||||
const { Content, Sider } = Layout;
|
||||
|
@ -92,11 +93,8 @@ export default function Op() {
|
|||
zIndex: 999,
|
||||
}}
|
||||
>
|
||||
<div className="op-logo">
|
||||
<img
|
||||
src="https://s2.loli.net/2023/08/03/mu51haYNUOPXkqR.png"
|
||||
alt=""
|
||||
/>
|
||||
<div onClick={() => navigate("/")} className="op-logo">
|
||||
<img src="/images/icon_border.png" alt="" />
|
||||
<h2>铁粉空间运营</h2>
|
||||
</div>
|
||||
<Menu
|
||||
|
@ -118,7 +116,7 @@ export default function Op() {
|
|||
overflow: "initial",
|
||||
}}
|
||||
>
|
||||
{location.pathname === "/" && <h1>好兄弟,辛苦了!加油!奥利给!</h1>}
|
||||
{location.pathname === "/" && <Data />}
|
||||
<Outlet />
|
||||
</Content>
|
||||
</Layout>
|
||||
|
|
Loading…
Reference in New Issue