添加合伙人

This commit is contained in:
al 2025-02-26 15:16:09 +08:00
parent faafbcb819
commit c687dab446
2 changed files with 538 additions and 4 deletions

View File

@ -0,0 +1,445 @@
import React, {
useContext,
useEffect,
useRef,
useState,
useCallback,
useMemo,
} from "react";
import { Button, Form, Input, Popconfirm, Table, Select, message } from "antd";
import baseRequest from "../../../../utils/baseRequest";
const EditableContext = React.createContext(null);
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
const handleCheck = () => {
return true;
};
return (
<Form form={form} component={false} onFinish={handleCheck}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
zone_third_partner_sharing_ratio,
handleSave,
handleSetEditable,
handleDelete,
handleSubmit,
currentSharingRatioTotal,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
setEditing(record?.editable || !record?.id);
if (record?.editable || !record?.id) {
form.setFieldsValue({
collaborator_user_id: record?.["collaborator_user_id"],
sharing_ratio: record?.["sharing_ratio"],
});
}
}, [record, form]);
const save = async () => {
try {
const values = await form.validateFields();
// toggleEdit();
handleSave({
...record,
...values,
});
} catch (errInfo) {
console.log("Save failed:", errInfo);
}
};
let childNode = children;
childNode =
dataIndex === "operation" ? (
<>
<>
{record?.id ? (
<>
{!editing ? (
<Button
type="text"
onClick={() => handleSetEditable(record.key)}
>
<span className="text-blue-400">编辑</span>
</Button>
) : (
<Button
type="primary"
onClick={() => handleSubmit(record, "update")}
>
确定
</Button>
)}
</>
) : (
<Button
type="primary"
onClick={async () => {
form
.validateFields()
.then((values) => {
handleSubmit({ ...values, key: record.key }, "create");
})
.catch((errorInfo) => {
console.log("Failed:", errorInfo);
});
// debugger;
}}
>
<span>创建</span>
</Button>
)}
</>
{record?.id && (
<Popconfirm
title="确定要删除吗?"
okText="确定"
cancelText="取消"
onConfirm={() => handleDelete(record.id)}
>
<Button type="text">
<span className="text-red-400">删除</span>
</Button>
</Popconfirm>
)}
</>
) : editing && record?.key !== undefined ? (
<Form.Item
style={{ margin: 0 }}
name={dataIndex}
rules={[{ required: true, message: `${title} 是必填的.` }]}
>
{dataIndex === "collaborator_user_id" ? (
<Input
ref={inputRef}
// onPressEnter={save}
onBlur={save}
placeholder="请输入ID"
allowClear
disabled={record?.id}
/>
) : (
<Select
ref={inputRef}
// onPressEnter={save}
onBlur={save}
placeholder="请选择分成比例"
>
{
// 分成比例
Array.from(
{
length:
zone_third_partner_sharing_ratio * 100 -
currentSharingRatioTotal * 100,
},
(_, index) => (
<Select.Option
key={index}
value={parseFloat(((index + 1) / 100).toFixed(2))}
>
{`${index + 1} %`}
</Select.Option>
)
)
}
</Select>
)}
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{ paddingInlineEnd: 24 }}
// onClick={toggleEdit}
>
{dataIndex === "sharing_ratio"
? `${
record[dataIndex] &&
parseFloat((record[dataIndex] * 100)?.toPrecision(2))
}%`
: children}
</div>
);
return <td {...restProps}>{childNode}</td>;
};
const PartnerComponent = ({
getDataSource,
zid,
visitor_role,
zone_third_partner_sharing_ratio,
}) => {
const [dataSource, setDataSource] = useState([]);
const [count, setCount] = useState(0);
useEffect(() => {
getDataSource(dataSource);
}, [dataSource]);
useEffect(() => {
getData();
}, []);
const getData = async (changedId, type, changeKey) => {
try {
const base = baseRequest();
const detailResponse = await fetch(`/op/zone_collaborator/list`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
zid,
visitor_role,
...base,
}),
});
const detailData = await detailResponse.json();
if (detailData.ret === -1) {
alert(detailData.msg);
return;
}
setCount(detailData.data.offset);
setDataSource((prev) => {
if (!prev.length) {
return detailData.data.list.map(
({ collaborator_account, sharing_ratio, id }, index) => {
return {
collaborator_user_id: collaborator_account.user_id,
sharing_ratio,
id,
editable: false,
key: index,
};
}
);
}
const changedItem = detailData.data.list.find((item) => {
if (type === "create") {
return item.collaborator_account.user_id === changedId;
}
return item.id === changedId;
});
// debugger;
if (type === "create") {
return prev.map((item, index) => {
return item.key === changeKey
? {
collaborator_user_id:
changedItem?.collaborator_account.user_id,
sharing_ratio: changedItem?.sharing_ratio,
id: changedItem?.id,
editable: false,
key: index,
}
: item;
});
}
if (!changedItem && changedId) {
return prev.filter((item) => item.id !== changedId);
}
return prev.map((item, index) => {
return item.id === changedId && changedItem
? {
collaborator_user_id: changedItem?.collaborator_account.user_id,
sharing_ratio: changedItem?.sharing_ratio,
id: changedItem?.id,
editable: false,
key: index,
}
: item;
});
});
} catch (error) {
console.error(error);
}
};
const handleDelete = useCallback(async (id) => {
try {
const base = baseRequest();
const detailResponse = await fetch(`/op/zone_collaborator/delete`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id,
...base,
}),
});
const detailData = await detailResponse.json();
if (detailData.ret === -1) {
alert(detailData.msg);
return;
}
message.success("删除成功");
getData(id);
} catch (error) {
console.error(error);
}
}, []);
const handleSetEditable = (key) => {
const newData = dataSource.map((item) => {
return { ...item, editable: item.key === key ? true : item.editable };
});
setDataSource(newData);
};
const handleSubmit = async (data, type) => {
// 创建接口要改,不能上传数组,因为更新是单条
try {
const base = baseRequest();
const baseBody =
type === "create"
? {
collaborator_user_id: parseInt(data.collaborator_user_id),
}
: { id: data.id };
const detailResponse = await fetch(
`/op/zone_collaborator/${type === "create" ? "create" : "update"}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...baseBody,
zid,
sharing_ratio: data.sharing_ratio,
...base,
}),
}
);
const detailData = await detailResponse.json();
if (detailData.ret === -1) {
alert(detailData.msg);
return;
}
message.success("提交成功");
await getData(
type === "create" ? parseInt(data.collaborator_user_id) : data.id,
type,
data.key
);
} catch (error) {
console.error(error);
}
};
const [defaultColumns] = useState([
{
title: "ID",
dataIndex: "collaborator_user_id",
editable: false,
},
{
title: "合伙人分成比例",
dataIndex: "sharing_ratio",
editable: false,
width: 160,
},
{
title: "操作",
dataIndex: "operation",
width: 160,
editable: false,
},
]);
const handleAdd = (newKey) => {
const newData = {
key: newKey,
collaborator_user_id: "",
sharing_ratio: "",
editable: false,
};
// debugger;
setDataSource((pre) => [...pre, newData]);
setCount(newKey + 1);
};
const handleSave = useCallback(
(row) => {
const newData = [...dataSource];
const index = newData.findIndex((item) => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
setDataSource(newData);
},
[dataSource]
);
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const columns = useMemo(() => {
const newColumns = defaultColumns.map((col) => {
// if (!col.editable) {
// return col;
// }
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
with: col.width,
currentSharingRatioTotal: dataSource.reduce(
(total, item) =>
total + (item.key === record.key ? 0 : item.sharing_ratio),
0
),
zone_third_partner_sharing_ratio,
handleSave,
handleSetEditable,
handleDelete,
handleSubmit,
}),
};
});
return newColumns;
}, [
defaultColumns,
handleSave,
handleDelete,
handleSetEditable,
handleSubmit,
]);
return (
<div>
<Button
onClick={() => handleAdd(count)}
type="primary"
style={{
marginBottom: 16,
}}
>
添加合伙人
</Button>
<Table
components={components}
rowClassName={() => "editable-row"}
bordered
dataSource={dataSource}
columns={columns}
pagination={{
pageSize: 5,
total: count,
}}
/>
</div>
);
};
export default PartnerComponent;

View File

@ -13,12 +13,14 @@ import {
} from "antd";
import baseRequest from "../../utils/baseRequest";
import { useNavigate } from "react-router-dom";
import PartnerComponent from "./components/PartnerComponent";
//tab
const StreamerSpaceContent = () => {
const navigate = useNavigate();
const { TextArea } = Input;
const [superSingles, setSuperSingles] = useState([]);
//
const [partners, setPartners] = useState([]);
//
const [showColumns, setShowColumns] = useState([
"baseInfo",
@ -226,6 +228,14 @@ const StreamerSpaceContent = () => {
添加代运营
</Button>
)}
{record.ratio.zone_third_partner?.third_partner_account?.mid && (
<Button
type="primary"
onClick={() => handlePartnersModal(record)}
>
编辑合伙人
</Button>
)}
<Button
onClick={() =>
navigate(`/editSpacePost?user_id=${record.baseInfo.id}`)
@ -689,6 +699,12 @@ const StreamerSpaceContent = () => {
// setShowData([]);
setDefaultValues({});
setIsAddAgencyModalOpen(false);
const searchValue = searchForm.getFieldsValue();
if (searchValue.id) {
search(searchValue);
} else {
getAllSpace();
}
};
//Modal
const handleAddAgencyModalCancel = () => {
@ -721,8 +737,11 @@ const StreamerSpaceContent = () => {
console.error(error);
}
};
//
const [selectedUser, setSelectedUser] = useState();
//
const [selectedPartners, setSelectedPartners] = useState([]);
const handleSelected = () => {
if (selectedUser) {
setSelectedUser();
@ -742,6 +761,8 @@ const StreamerSpaceContent = () => {
//Modal
const [isAgencyModalOpen, setIsAgencyModalOpen] = useState(false);
//Modal
const [isPartnerModalOpen, setPartnersModalOpen] = useState(false);
//
const handleAgencyModal = (record) => {
setDefaultValues(record);
@ -749,6 +770,11 @@ const StreamerSpaceContent = () => {
setSelectedUser();
setUserInfo();
};
//
const handlePartnersModal = (record) => {
setDefaultValues(record);
setPartnersModalOpen(true);
};
//
const handleSubmitAgencySetting = async (value) => {
if (!value.sharing_ratio?.toString() || !value.is_hided?.toString()) {
@ -798,6 +824,25 @@ const StreamerSpaceContent = () => {
alert(_data.msg);
return;
}
const _response2 = await fetch(`/op/zone_collaborator/create_batch`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
list: partners.map((item) => ({
zid: defaultValues.key,
collaborator_user_id: parseInt(item.collaborator_mid),
sharing_ratio: parseInt(item.sharing_ratio, 10) / 100,
})),
...base,
}),
});
const _data2 = await _response2.json();
if (_data2.ret === -1) {
alert(_data2.msg);
return;
}
} catch (error) {
console.error(error);
}
@ -805,6 +850,12 @@ const StreamerSpaceContent = () => {
// setShowData([]);
setDefaultValues({});
setIsAgencyModalOpen(false);
const searchValue = searchForm.getFieldsValue();
if (searchValue.id) {
search(searchValue);
} else {
getAllSpace();
}
};
//
@ -831,6 +882,12 @@ const StreamerSpaceContent = () => {
// setShowData([]);
setDefaultValues({});
setIsAgencyModalOpen(false);
const searchValue = searchForm.getFieldsValue();
if (searchValue.id) {
search(searchValue);
} else {
getAllSpace();
}
} catch (error) {
console.error(error);
}
@ -887,7 +944,7 @@ const StreamerSpaceContent = () => {
onFinishFailed={onModalFormFinishFailed}
autoComplete="off"
>
<div className="flex flex-col overflow-y-scroll">
<div className="flex flex-col">
<div className="flex flex-row mb-4">
<Image
width={80}
@ -1091,7 +1148,7 @@ const StreamerSpaceContent = () => {
open={isAddAgencyModalOpen}
onCancel={handleAddAgencyModalCancel}
>
<div className="flex flex-col overflow-y-scroll">
<div className="flex flex-col">
<div className="flex flex-row mb-4">
<Image
width={80}
@ -1222,8 +1279,10 @@ const StreamerSpaceContent = () => {
footer={null}
open={isAgencyModalOpen}
onCancel={handleAgencyModalCancel}
onClose={handleAgencyModalCancel}
style={{ minWidth: 600 }}
>
<div className="flex flex-col overflow-y-scroll">
<div className="flex flex-col">
<div className="flex flex-row mb-4">
<Image
width={80}
@ -1359,6 +1418,7 @@ const StreamerSpaceContent = () => {
<option value={0}></option>
</select>
</Form.Item>
<Button type="primary" htmlType="submit">
确认
</Button>
@ -1367,6 +1427,35 @@ const StreamerSpaceContent = () => {
</div>
</Modal>
)}
{/* 编辑合伙人Modal是否可见 */}
{isPartnerModalOpen && (
<Modal
footer={null}
open={isPartnerModalOpen}
onCancel={() => {
setPartnersModalOpen(false);
setDefaultValues({});
const searchValue = searchForm.getFieldsValue();
if (searchValue.id) {
search(searchValue);
} else {
getAllSpace();
}
}}
style={{ minWidth: 600 }}
>
<div className="flex flex-col">
<p className="mb-4">合伙人设置</p>
<PartnerComponent
getDataSource={setPartners}
zid={defaultValues?.key}
zone_third_partner_sharing_ratio={
defaultValues?.ratio?.zone_third_partner?.sharing_ratio
}
/>
</div>
</Modal>
)}
</div>
);
};