589 lines
25 KiB
TypeScript
589 lines
25 KiB
TypeScript
// 商家评价管理
|
|
import { connect } from "umi";
|
|
import type { CurrentUser } from "umi";
|
|
import type { ConnectState } from "@/models/connect";
|
|
import React, { useRef, useState } from "react";
|
|
import type { FormInstance } from "antd";
|
|
import { Button, Col, message, Modal, Row, Space, Spin, Tree, Image } from "antd";
|
|
import useRequest from "@ahooksjs/use-request";
|
|
import type { ActionType } from "@ant-design/pro-table";
|
|
import ProTable from "@ant-design/pro-table";
|
|
import LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
|
|
import PageTitleBox from "@/components/PageTitleBox";
|
|
import { handeDeleteCOMMENT, handeDeleteREPLY, handeGetCOMMENTDetail, handeGetCOMMENTList, handeGetREPLYDetail, handeSynchroCOMMENT, handeSynchroREPLY, handeSynchroReplyList } from "../service";
|
|
import moment from 'moment'
|
|
import session from "@/utils/session";
|
|
import { handleSetlogSave } from "@/utils/format";
|
|
import Draggable from "react-draggable";
|
|
import ProForm, { ProFormList, ProFormText, ProFormTextArea, ProFormUploadButton } from "@ant-design/pro-form";
|
|
import { getBase64 } from "@/utils/utils";
|
|
import './MerchantEvaluationManage.less'
|
|
|
|
|
|
|
|
const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent?: boolean, parentDetail?: any }> = (props) => {
|
|
const draggleRef = React.createRef<any>()
|
|
const { currentUser, isComponent, parentDetail } = props
|
|
const actionRef = useRef<ActionType>();
|
|
const formRef = useRef<FormInstance>();
|
|
const modalFormRef = useRef<FormInstance>();
|
|
const [collapsible, setCollapsible] = useState<boolean>(false)
|
|
// 弹出框拖动效果
|
|
const [bounds, setBounds] = useState<{ left: number, right: number, top: number, bottom: number }>() // 移动的位置
|
|
const [disabled, setDraggleDisabled] = useState<boolean>() // 是否拖动
|
|
// 显示回复抽屉
|
|
const [showDetailDrawer, setShowDetailDrawer] = useState<boolean>(false)
|
|
// 点击的当前数据
|
|
const [currentRow, setCurrentRow] = useState<any>()
|
|
// 评论的附件
|
|
const [fileList, setFileList] = useState<any>()
|
|
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false) // 预览图片
|
|
const [priviewImage, setPriviewImage] = useState<string>(); // 预览的图片地址
|
|
// 删除回复的加载效果
|
|
const [deleteREPLYLoading, setDeleteREPLYLoading] = useState<boolean>(false)
|
|
|
|
|
|
const MEMBERSHIPLEVELYNObj = session.get('MEMBERSHIPLEVELYNObj')
|
|
// 树相关的属性和方法
|
|
const [selectedId, setSelectedId] = useState<string>()
|
|
|
|
const onDraggaleStart = (event, uiData) => {
|
|
const { clientWidth, clientHeight } = window.document.documentElement;
|
|
const targetRect = draggleRef.current?.getBoundingClientRect();
|
|
if (!targetRect) {
|
|
return;
|
|
}
|
|
setBounds({
|
|
left: -targetRect.left + uiData.x,
|
|
right: clientWidth - (targetRect.right - uiData.x),
|
|
top: -targetRect.top + uiData.y,
|
|
bottom: clientHeight - (targetRect.bottom - uiData.y),
|
|
});
|
|
};
|
|
|
|
|
|
const columns: any = [
|
|
{
|
|
dataIndex: 'searchText',
|
|
title: '查询内容',
|
|
hideInTable: true,
|
|
fieldProp: {
|
|
placeholder: "请输入评价人员/商家名称"
|
|
}
|
|
},
|
|
{
|
|
title: '评价时间',
|
|
dataIndex: 'search_date',
|
|
valueType: 'dateRange',
|
|
hideInTable: true,
|
|
hideInDescriptions: true,
|
|
search: {
|
|
transform: (value) => {
|
|
return {
|
|
CREATE_DATE_Start: value[0],
|
|
CREATE_DATE_End: value[1],
|
|
};
|
|
},
|
|
},
|
|
fieldProps: {
|
|
ranges: {
|
|
"本月": [moment().startOf('M'), moment()],
|
|
"上月": [moment().subtract(1, 'M').startOf('M'), moment().subtract(1, 'M').endOf('M')],
|
|
"近三月": [moment().subtract(3, 'M').startOf('M'), moment().endOf('M')],
|
|
"近半年": [moment().subtract(6, 'M').startOf('M'), moment().endOf('M')],
|
|
}
|
|
},
|
|
// initialValue: [moment().add(-1, 'M').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
|
|
initialValue: [moment().startOf('M'), moment()],
|
|
},
|
|
{
|
|
title: "序号",
|
|
dataIndex: "index",
|
|
valueType: "index",
|
|
hideInSearch: true,
|
|
align: "center",
|
|
width: 60,
|
|
},
|
|
{
|
|
title: "商家名称",
|
|
dataIndex: "SELLER_NAME",
|
|
width: 270,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
},
|
|
{
|
|
title: "评价时间",
|
|
dataIndex: "CREATE_DATE",
|
|
width: 170,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
render: (_, record) => {
|
|
return record?.CREATE_DATE ? moment(record?.CREATE_DATE).format('YYYY-MM-DD HH:mm:ss') : "-"
|
|
}
|
|
},
|
|
{
|
|
title: "评价人员",
|
|
dataIndex: "MEMBERSHIP_NAME",
|
|
width: 150,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
},
|
|
{
|
|
title: "会员类型",
|
|
dataIndex: "MEMBERSHIP_TYPE",
|
|
width: 150,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
valueType: "select",
|
|
valueEnum: MEMBERSHIPLEVELYNObj
|
|
},
|
|
{
|
|
title: "消费评价",
|
|
dataIndex: "SALEBILL_ID",
|
|
width: 120,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
render: (_, record) => {
|
|
return record?.SALEBILL_ID ? '是' : '否'
|
|
}
|
|
},
|
|
{
|
|
title: "评分",
|
|
dataIndex: "COMMENT_SCORE",
|
|
width: 120,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
sorter: (a, b) => a.COMMENT_SCORE - b.COMMENT_SCORE,
|
|
},
|
|
{
|
|
title: "评价内容",
|
|
dataIndex: "COMMENT_CONTENT",
|
|
width: 250,
|
|
hideInSearch: true,
|
|
ellipsis: true,
|
|
align: "center",
|
|
render: (_, record) => {
|
|
return record?.COMMENT_CONTENT ? <a onClick={() => {
|
|
console.log('recordrecord', record);
|
|
|
|
if (record?.ImageList && record?.ImageList.length > 0) {
|
|
let list: any = []
|
|
record?.ImageList.forEach((item: any) => {
|
|
list.push({
|
|
name: "",
|
|
url: item?.ImageUrl
|
|
})
|
|
})
|
|
setFileList(list)
|
|
}
|
|
|
|
setCurrentRow({
|
|
...record,
|
|
ReplyList: record?.ReplyList || []
|
|
})
|
|
setShowDetailDrawer(true)
|
|
}}>{record?.COMMENT_CONTENT}</a> : "-"
|
|
}
|
|
},
|
|
// {
|
|
// title: "回复内容",
|
|
// dataIndex: "回复内容",
|
|
// width: 250,
|
|
// hideInSearch: true,
|
|
// ellipsis: true,
|
|
// align: "center",
|
|
// },
|
|
]
|
|
|
|
// 删除评论
|
|
const handleDeleteEvaluation = async () => {
|
|
const req: any = {
|
|
COMMENTId: currentRow?.COMMENT_ID
|
|
}
|
|
const data = await handeDeleteCOMMENT(req)
|
|
if (data.Result_Code === 100) {
|
|
message.success(data.Result_Desc)
|
|
setShowDetailDrawer(false)
|
|
setCurrentRow(undefined);
|
|
setFileList([])
|
|
actionRef.current?.reload()
|
|
} else {
|
|
message.error(data.Result_Desc)
|
|
}
|
|
}
|
|
|
|
|
|
// 删除回复
|
|
const handleDeleteEvaluationREPLY = async (REPLY_ID: string) => {
|
|
const req: any = {
|
|
REPLYId: REPLY_ID
|
|
}
|
|
setDeleteREPLYLoading(true)
|
|
const data = await handeDeleteREPLY(req)
|
|
setDeleteREPLYLoading(false)
|
|
if (data.Result_Code === 100) {
|
|
message.success(data.Result_Desc)
|
|
actionRef?.current?.reload()
|
|
return true
|
|
} else {
|
|
message.error(data.Result_Desc)
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
// 预览上传后的图片
|
|
const handlePreview = async () => {
|
|
setFileList(fileList)
|
|
setImagePreviewVisible(true)
|
|
};
|
|
const handleChangePreview = (val: any) => {
|
|
setImagePreviewVisible(val)
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
|
{
|
|
isComponent ? '' :
|
|
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
|
|
|
|
}
|
|
<div style={{
|
|
width: isComponent ? '100%' : !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
|
paddingTop: 0,
|
|
paddingBottom: 0,
|
|
paddingRight: 0
|
|
}}>
|
|
<ProTable
|
|
actionRef={actionRef}
|
|
formRef={formRef}
|
|
columns={columns}
|
|
bordered
|
|
expandable={{
|
|
expandRowByClick: true
|
|
}}
|
|
options={false}
|
|
scroll={{ x: "100%", y: isComponent ? '300px' : "calc(100vh - 410px)" }}
|
|
headerTitle={<PageTitleBox props={props} />} // 列表表头
|
|
search={isComponent ? false : { span: 6 }}
|
|
request={async (params) => {
|
|
if (!selectedId && !isComponent) {
|
|
return
|
|
}
|
|
const req: any = isComponent ? {
|
|
SearchParameter: {
|
|
OWNERUNIT_ID: currentUser?.OwnerUnitId,
|
|
// PROVINCE_CODE: currentUser?.ProvinceCode,
|
|
COMMENT_ISVALID: 1,
|
|
CREATE_DATE_Start: params?.CREATE_DATE_Start || "",
|
|
CREATE_DATE_End: params?.CREATE_DATE_End || "",
|
|
MEMBERSHIP_IDS: parentDetail?.MEMBERSHIP_ID,
|
|
},
|
|
PageIndex: 1,
|
|
PageSize: 999999,
|
|
keyWord: {
|
|
Key: "SELLER_NAME,MEMBERSHIP_NAME",
|
|
Value: params?.searchText || ""
|
|
},
|
|
SortStr: "CREATE_DATE desc"
|
|
} : {
|
|
SearchParameter: {
|
|
OWNERUNIT_ID: currentUser?.OwnerUnitId,
|
|
// PROVINCE_CODE: currentUser?.ProvinceCode,
|
|
COMMENT_ISVALID: 1,
|
|
CREATE_DATE_Start: params?.CREATE_DATE_Start || "",
|
|
CREATE_DATE_End: params?.CREATE_DATE_End || "",
|
|
},
|
|
PageIndex: 1,
|
|
PageSize: 999999,
|
|
keyWord: {
|
|
Key: "SELLER_NAME,MEMBERSHIP_NAME",
|
|
Value: params?.searchText || ""
|
|
},
|
|
SortStr: "CREATE_DATE desc"
|
|
}
|
|
const data = await handeGetCOMMENTList(req)
|
|
console.log('datadatadatadatadata222', data);
|
|
|
|
handleSetlogSave(`点击查询按钮`)
|
|
|
|
if (data.List && data.List.length > 0) {
|
|
return { data: data.List, success: true, total: data.TotalCount }
|
|
}
|
|
return { data: [], success: true }
|
|
}}
|
|
toolbar={{
|
|
actions: [
|
|
]
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
{/* 图片预览组件 */}
|
|
{fileList && fileList.length > 0 && <div style={{ display: 'none' }}>
|
|
<Image.PreviewGroup
|
|
preview={{
|
|
visible: imagePreviewVisible,
|
|
onVisibleChange: vis => {
|
|
handleChangePreview(vis)
|
|
}
|
|
}}>
|
|
{
|
|
fileList.map((n) => <Image src={n.url} key={n.url} />)
|
|
}
|
|
</Image.PreviewGroup>
|
|
</div>}
|
|
|
|
|
|
<Modal
|
|
title={
|
|
<div
|
|
className="MerchantEvaluationManage"
|
|
>
|
|
评价回复
|
|
</div>
|
|
}
|
|
destroyOnClose={true}
|
|
width={900}
|
|
visible={showDetailDrawer}
|
|
afterClose={() => {
|
|
}}
|
|
bodyStyle={{
|
|
height: '700px', // 你可以根据需要调整高度
|
|
overflowY: 'auto',
|
|
}}
|
|
onCancel={() => {
|
|
setShowDetailDrawer(false)
|
|
setCurrentRow(undefined);
|
|
setFileList([])
|
|
}}
|
|
footer={<div style={{ width: '100%', boxSizing: 'border-box', padding: '0 8px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
|
<div>
|
|
<Button danger onClick={() => {
|
|
handleDeleteEvaluation()
|
|
}}>删除评论</Button>
|
|
</div>
|
|
<div>
|
|
<Button style={{ marginRight: '8px' }} onClick={() => {
|
|
setShowDetailDrawer(false)
|
|
setCurrentRow(undefined);
|
|
setFileList([])
|
|
}}>
|
|
取消
|
|
</Button>
|
|
|
|
<Button type={"primary"} onClick={() => {
|
|
modalFormRef?.current?.validateFields().then(() => {
|
|
modalFormRef?.current?.submit()
|
|
})
|
|
}}>确认</Button>
|
|
</div>
|
|
</div>}
|
|
modalRender={(modal) => {
|
|
return <Draggable
|
|
disabled={disabled}
|
|
bounds={bounds}
|
|
onStart={(event, uiData) => onDraggaleStart(event, uiData)}
|
|
handle=".MerchantEvaluationManage"
|
|
>
|
|
<div ref={draggleRef}>{modal}</div>
|
|
</Draggable>
|
|
}}
|
|
>
|
|
|
|
<ProForm
|
|
formRef={modalFormRef}
|
|
submitter={false}
|
|
labelCol={{ style: { width: 80 } }}
|
|
initialValues={currentRow}
|
|
onFinish={async (res: any) => {
|
|
console.log('currentRowcurrentRowcurrentRow', currentRow);
|
|
console.log('resresresresres', res);
|
|
|
|
if (res.ReplyList && res.ReplyList.length > 0) {
|
|
let list: any = []
|
|
res.ReplyList.forEach((item: any) => {
|
|
list.push({
|
|
COMMENT_ID: currentRow?.COMMENT_ID || "",
|
|
COMMENT_CONTENT: currentRow?.COMMENT_CONTENT || "",
|
|
// COMMENT_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
|
|
STAFF_ID: currentUser?.ID,
|
|
STAFF_NAME: currentUser?.Name,
|
|
REPLY_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
|
|
REPLY_CONTENT: item.REPLY_CONTENT,
|
|
REPLY_STATE: 1
|
|
})
|
|
})
|
|
console.log('list', list);
|
|
|
|
const data = await handeSynchroReplyList({
|
|
list: list
|
|
})
|
|
console.log('datadatadatadata', data);
|
|
if (data.Result_Code === 100) {
|
|
message.success(data.Result_Desc)
|
|
setFileList([])
|
|
setShowDetailDrawer(false)
|
|
setCurrentRow(undefined);
|
|
actionRef.current?.reload()
|
|
} else {
|
|
message.error(data.Result_Desc)
|
|
}
|
|
} else {
|
|
setFileList([])
|
|
setShowDetailDrawer(false)
|
|
setCurrentRow(undefined);
|
|
actionRef.current?.reload()
|
|
}
|
|
}}
|
|
// request={async () => {
|
|
// if (currentRow?.ReplyList && currentRow?.ReplyList.length > 0) {
|
|
// const req: any = {
|
|
// REPLYId: currentRow?.ReplyList[0].REPLY_ID
|
|
// }
|
|
// const data = await handeGetREPLYDetail(req)
|
|
// console.log('datadatadata', data);
|
|
// return {
|
|
// ...data,
|
|
// ReplyToEvaluation: data.REPLY_CONTENT
|
|
// }
|
|
// } else {
|
|
// return {}
|
|
// }
|
|
|
|
// }}
|
|
>
|
|
<Row>
|
|
<Col span={24}>
|
|
<ProFormTextArea
|
|
label={"评论内容"}
|
|
name={"COMMENT_CONTENT"}
|
|
readonly
|
|
/>
|
|
</Col>
|
|
|
|
<Col span={24}>
|
|
<ProFormUploadButton
|
|
label={""}
|
|
name={"ImageList"}
|
|
disabled
|
|
readonly
|
|
max={0}
|
|
fileList={fileList || []}
|
|
listType="picture-card"
|
|
accept="image/*"
|
|
fieldProps={{
|
|
onPreview: handlePreview
|
|
}}
|
|
/>
|
|
</Col>
|
|
|
|
|
|
<Col span={24} className="proformList">
|
|
<ProFormList
|
|
name="ReplyList"
|
|
label="回复评价"
|
|
copyIconProps={false}
|
|
deleteIconProps={false}
|
|
creatorButtonProps={{
|
|
position: 'bottom',
|
|
creatorButtonText: '新增一条回复',
|
|
}}
|
|
style={{ width: '100%' }}
|
|
itemContainerStyle={{ width: '100%' }}
|
|
>
|
|
{(field, index, action) => {
|
|
const isInitialItem = index < (currentRow?.ReplyList?.length || 0);
|
|
return (
|
|
<div
|
|
key={field.key}
|
|
style={{
|
|
width: '100%',
|
|
display: 'flex',
|
|
alignItems: 'flex-start',
|
|
marginBottom: '10px',
|
|
padding: '12px',
|
|
borderRadius: '4px'
|
|
}}
|
|
>
|
|
<div style={{ flex: 1 }}>
|
|
<ProFormTextArea
|
|
name={"REPLY_CONTENT"} // 确保使用 field.name
|
|
placeholder="请输入回复内容"
|
|
readonly={isInitialItem} // 直接使用 isInitialItem
|
|
fieldProps={{
|
|
style: { width: '100%' },
|
|
autoSize: { minRows: 3, maxRows: 6 },
|
|
}}
|
|
rules={[{ required: true, message: '请输入回复内容' }]}
|
|
/>
|
|
</div>
|
|
<div style={{
|
|
width: '50px',
|
|
marginLeft: '8px',
|
|
gap: '8px'
|
|
}}>
|
|
{isInitialItem ? (
|
|
<Button
|
|
danger
|
|
loading={deleteREPLYLoading}
|
|
onClick={async () => {
|
|
const replyId = currentRow?.ReplyList?.[index]?.REPLY_ID;
|
|
if (replyId) {
|
|
const success = await handleDeleteEvaluationREPLY(replyId);
|
|
if (success) {
|
|
action?.remove(index);
|
|
}
|
|
} else {
|
|
action?.remove(index);
|
|
}
|
|
}}
|
|
>
|
|
删除
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
danger
|
|
onClick={() => action?.remove(index)}
|
|
>
|
|
删除
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}}
|
|
</ProFormList>
|
|
</Col>
|
|
|
|
{/* <Col span={24}>
|
|
<ProFormTextArea
|
|
label={"回复评价"}
|
|
name={"ReplyToEvaluation"}
|
|
rules={[{
|
|
required: true,
|
|
message: '请输入回复内容'
|
|
}]}
|
|
readonly={currentRow?.ReplyList && currentRow?.ReplyList.length > 0 ? true : false}
|
|
/>
|
|
</Col> */}
|
|
</Row>
|
|
|
|
</ProForm>
|
|
|
|
</Modal >
|
|
</div >
|
|
)
|
|
}
|
|
|
|
export default connect(({ user }: ConnectState) => ({
|
|
currentUser: user.currentUser
|
|
}))(MerchantEvaluationManage);
|