tiefen_space_op/src/pages/BlockUser/index.jsx

494 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useRef, useEffect } from "react";
import { Form, Input, Button, Space, Table, Menu, Image, Modal } from "antd";
import {
Routes,
Route,
Navigate,
useNavigate,
useLocation,
} from "react-router-dom";
import baseRequest from "../../utils/baseRequest";
const BlockUserContent = (props) => {
const current = props.current;
//表头
const columns = [
{
title: "用户信息",
dataIndex: "user",
key: "user",
onCell: (_, index) => ({
rowSpan: _.rowSpan,
}),
render: (data) => (
<div>
<Image
src={data.avatar}
width={50}
height={50}
className="rounded-full object-cover"
/>
<p>
昵称<span className="text-red-400">{data.name}</span>
</p>
<p>
ID<span className="text-red-400">{data.user_id}</span>
</p>
</div>
),
},
{
title: "封禁内容",
dataIndex: "type",
key: "type",
render: (data) => (
<div>
<p>{data === 0 && "限制广场发帖"}</p>
<p>{data === 1 && "限制空间内发布免费帖"}</p>
<p>{data === 2 && "限制空间内发布付费帖"}</p>
<p>{data === 3 && "限制空间内发帖"}</p>
<p>{data === 4 && "主播搜索隐藏"}</p>
<p>{data === 5 && "主播发现隐藏"}</p>
<p>{data === 6 && "主播广场隐藏"}</p>
<p>{data === 7 && "禁止付款"}</p>
<p>{data === 8 && "试运营限制广场发帖"}</p>
<p>{data === 9 && "试运营主播发现隐藏"}</p>
</div>
),
},
{
title: "起始时间",
dataIndex: "ct",
key: "ct",
},
{
title: "结束时间",
dataIndex: "end_time",
key: "end_time",
},
{
title: "状态",
dataIndex: "status",
key: "status",
render: (data, record) => (
<div>
<p className="text-green-400">{data === 0 && "处罚中"}</p>
<p className="text-green-400">{data === 1 && "正常结束"}</p>
<p className="text-red-400">
{data === 2 && `提前终止:${record.ut}`}
</p>
</div>
),
},
{
title: "操作",
dataIndex: "opeartion",
key: "opeartion",
render: (_, record) => (
<div>
<Space>
<Space.Compact direction="vertical">
{current === "blocking" && (
<Button type="primary" onClick={() => unblock(record)}>
{current === "blocking" && "解封"}
</Button>
)}
</Space.Compact>
</Space>
</div>
),
},
];
//给表单绑定ref
const formRef = useRef(null);
//点击修改状态按钮
const unblock = (record) => {
formRef.current.id = record.id;
formRef.current.btn = "unblock";
formRef.current.submit();
};
//提交表单
const handleSubmit = async (value) => {
//提交数据
try {
const base = baseRequest();
const _response = await fetch("/op/account_punishment/unblock", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: formRef.current.id,
...base,
}),
});
const _data = await _response.json();
if (_data.ret === -1) {
alert(_data.msg);
return;
}
} catch (error) {
console.error(error);
}
//刷新页面
window.location.reload();
};
//获取数据
const [data, setData] = useState([]);
const getData = async (user_id) => {
let querryUrl;
switch (current) {
case "blocking":
querryUrl = "/op/account_punishment/list";
break;
case "terminated":
querryUrl = "/op/account_punishment/list_terminated";
break;
default:
break;
}
try {
const base = baseRequest();
const _response = await fetch(querryUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
offset: 0,
limit: 100,
user_id: user_id ? parseInt(user_id, 10) : undefined,
...base,
}),
});
const _data = await _response.json();
if (_data.ret === -1) {
alert(_data.msg);
return;
}
//将每人的每种封禁拆分
const blockList = _data.data.list
.map((item1, index1) =>
item1.account_punishments.map((item2, index2) => ({
rowSpan: index2 === 0 ? item1.account_punishments.length : 0,
account: item1.account,
account_punishments: item2,
}))
)
.flat();
//匹配表格格式
const structedData = blockList.map((item, index) => {
return {
key: index,
id: item.account_punishments.id,
rowSpan: item.rowSpan,
user: {
avatar: item.account.avatar?.images[0].urls[0],
user_id: item.account.user_id,
name: item.account.name,
},
type: item.account_punishments.type,
ct: new Date(item.account_punishments.ct * 1000).toLocaleString(),
end_time: new Date(
item.account_punishments.end_time * 1000
).toLocaleString(),
status: item.account_punishments.status,
ut: new Date(item.account_punishments.ut * 1000).toLocaleString(),
};
});
setData([...structedData]);
} catch (error) {
console.error(error);
}
};
useEffect(() => {
getData();
}, [current]);
//展示的数据
const [showData, setShowData] = useState([]);
useEffect(() => {
setShowData(data);
}, [data]);
//搜索用户
const search = (value) => {
getData(value.id);
};
//打开添加封禁Modal
const [isModalVisible, setIsModalVisible] = useState(false);
//在modal中搜索用户
const [userInfo, setUserInfo] = useState();
const modalSearch = async (value) => {
try {
const base = baseRequest();
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();
console.log(_data);
if (_data.ret === -1) {
alert(_data.msg);
return;
}
setSelectedUser();
setUserInfo(_data.data.account);
} catch (error) {
console.error(error);
}
};
//选中用户
const [selectedUser, setSelectedUser] = useState();
const handleSelected = () => {
if (selectedUser) {
setSelectedUser();
return;
}
setSelectedUser(userInfo.mid);
};
//添加封禁
const [form] = Form.useForm();
const block = async (value) => {
if (!selectedUser) {
alert("还未选中用户");
return;
}
try {
const base = baseRequest();
const _response = await fetch("/op/account_punishment/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mid: selectedUser,
type: parseInt(value.type, 10),
duration: parseInt(value.duration, 10),
...base,
}),
});
const _data = await _response.json();
if (_data.ret === -1) {
alert(_data.msg);
return;
}
handleCancelModal();
//刷新页面
window.location.reload();
} catch (error) {
console.error(error);
}
};
//关闭弹窗
const handleCancelModal = () => {
form.resetFields();
setUserInfo();
setSelectedUser();
setIsModalVisible(false);
};
//表单提交失败
const onFinishFailed = (errorInfo) => {
console.log("Failed:", errorInfo);
};
return (
<div style={{ marginLeft: 20, marginRight: 20, marginTop: 20 }}>
<Form name="search" onFinish={search} onFinishFailed={onFinishFailed}>
<Space style={{ marginBottom: 20 }}>
<Form.Item label="网红ID" name="id" style={{ margin: 0 }}>
<Input />
</Form.Item>
<Button type="primary" htmlType="submit">
搜索
</Button>
</Space>
</Form>
<Button
className="mb-4"
type="primary"
onClick={() => setIsModalVisible(true)}
>
添加封禁
</Button>
<p className="text-sm text-red-400">仅显示最新100条</p>
<Form
ref={formRef}
name="remarks"
onFinish={handleSubmit}
onFinishFailed={onFinishFailed}
>
<Table
columns={columns}
dataSource={showData}
pagination={{ pageSize: 20 }}
scroll={{ y: window.innerHeight - 300 }}
/>
</Form>
{isModalVisible && (
<Modal footer={null} open={isModalVisible} onCancel={handleCancelModal}>
<p className="text-sm text-red-400 font-bold">
*请选中用户后再执行操作
</p>
<Form name="modal_search" onFinish={modalSearch}>
<Space style={{ marginBottom: 20 }}>
<Form.Item label="ID" name="userId" style={{ margin: 0 }}>
<Input type="number" />
</Form.Item>
<Button type="primary" htmlType="submit">
搜索
</Button>
</Space>
</Form>
{userInfo && (
<div
className={`flex flex-row items-center p-2 rounded-xl ${
selectedUser ? "bg-green-300" : "bg-gray-300"
}`}
>
<Image
src={userInfo?.avatar?.images[0].urls[0]}
width={80}
height={80}
/>
<div className="flex flex-col justify-center mx-4">
<p className="text-lg font-bold">ID{userInfo.user_id}</p>
<p className="text-lg font-bold">昵称{userInfo.name}</p>
</div>
<Button
type={selectedUser ? "default" : "primary"}
onClick={handleSelected}
>
{selectedUser ? "取消选中" : "选中用户"}
</Button>
</div>
)}
<Form className="mt-4 flex flex-col" form={form} onFinish={block}>
<Space>
<Form.Item
name="type"
label="封禁内容"
initialValue={0}
rules={[
{
required: true,
message: "请选择封禁内容",
},
]}
>
<select
style={{
height: 32,
padding: "4px 11px",
border: "1px solid #d9d9d9",
borderRadius: 4,
outline: "none",
}}
>
<option value={0}>限制广场发帖</option>
<option value={1}>限制空间内发布免费帖</option>
<option value={2}>限制空间内发布付费帖</option>
<option value={3}>限制空间内发帖</option>
<option value={4}>主播搜索隐藏</option>
<option value={5}>主播发现隐藏</option>
<option value={6}>主播广场隐藏</option>
<option value={7}>禁止付款</option>
<option value={8}>试运营限制广场发帖</option>
<option value={9}>试运营主播发现隐藏</option>
</select>
</Form.Item>
<Form.Item
name="duration"
label="封禁时长"
initialValue={86400}
rules={[
{
required: true,
message: "请选择封禁时长",
},
]}
>
<select
style={{
height: 32,
padding: "4px 11px",
border: "1px solid #d9d9d9",
borderRadius: 4,
outline: "none",
}}
>
<option value={86400}>1</option>
<option value={259200}>3</option>
<option value={604800}>7</option>
<option value={1296000}>15</option>
<option value={2592000}>30</option>
<option value={3155760000}>永久</option>
</select>
</Form.Item>
</Space>
<Button className="ml-8" type="primary" htmlType="submit">
确认
</Button>
</Form>
</Modal>
)}
</div>
);
};
export default function BlockUser() {
const navigate = useNavigate();
//当前tab
const location = useLocation();
const pathname = location.pathname.split("/")[2] || "blocking";
const [current, setCurrent] = useState(pathname);
//tab名称
const items = [
{
label: "封禁中",
key: "blocking",
},
{
label: "已结束",
key: "terminated",
},
];
const onClick = (e) => {
setCurrent(e.key);
navigate(e.key);
window.location.reload();
};
return (
<div>
<Menu
onClick={onClick}
selectedKeys={[current]}
mode="horizontal"
items={items}
/>
<Routes>
<Route path="/" element={<Navigate to="/blockUser/blocking" />} />
<Route
path="/blocking"
element={<BlockUserContent current="blocking" />}
/>
<Route
path="/terminated"
element={<BlockUserContent current="terminated" />}
/>
</Routes>
</div>
);
}