system-copyright-react/src/route/TrademarkMall/TrademarkMall.tsx
2025-06-27 15:47:46 +08:00

1002 lines
30 KiB
TypeScript
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 { useState, useEffect } from 'react'
import nothingImg from '../../static/appimgs/nothing.png'
import { useLocation, useNavigate } from 'react-router-dom';
import { trademarkList, getFileTypeByIds, supplementTrademarkData } from '../../request/api'
import { showImage, uploadFileUrl } from '../../request/request'
import { UploadOutlined } from '@ant-design/icons';
import { Modal } from 'antd';
import type { TableProps, } from 'antd';
import {
message, Spin,
Pagination,
Table, Image,
Input, Form, Upload, Button
} from 'antd';
const { TextArea } = Input;
import { buySupplementList, supplementDetail } from '../../request/api'
export default function TrademarkMall() {
// 获取上传过的文件类型
const getUpFileTypeByIdsArray = async (ids: string) => {
try {
const res: any = await getFileTypeByIds({
ids: ids
})
console.log(res);
const newUpFile = res.map((item: any) => {
return {
uid: item.fileId,
name: item.fileName,
status: 'done',
url: showImage(item.fileId, false)
}
})
// console.log(newUpFile, 'newUpFile');
setUpFileArray(newUpFile)
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
const [trademarkId, setTrademarkId] = useState('')
const getBuySupplementList = async (page: number, id: string) => {
try {
const res: any = await buySupplementList({
orderId: id,
page: page,
rows: 10
})
// setPage(res.page)
// setTotal(res.total)
// // console.log(res);
// setData(res.rows)
setCommunicationData(res.rows)
setCommunicationTotal(res.total)
setCommunicationPage(res.page)
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
const token = sessionStorage.getItem('token')
const [upFileArray, setUpFileArray] = useState<any>([]) // 上传的文件数组
const [form] = Form.useForm();
const [modal, setModal] = useState(false)
// 自定义验证函数
const validateContentOrFile = (_rule: any, _value: any, callback: (error?: string) => void, form: any) => {
const { upCorrectionRemark, upFile } = form.getFieldsValue();
if (upCorrectionRemark || (upFile && Array.isArray(upFile.fileList) && upFile.fileList.length > 0)) {
callback();
} else {
callback('内容和附件至少需要填写或上传一项');
}
};
// 点击上传资料确定
const [correctionId, setCorrectionId] = useState('') // 点击查看内容选中的id
// 是否需要回复信息
const [correctionReply, setCorrectionReply] = useState('') //0为仅通知 , 1为需要回复
const [orderId, setOrderId] = useState('')
const submitData = async (params: any) => {
if (correctionReply == '0') {
try {
await supplementTrademarkData({
correctionParentId: correctionId,
// correctionType: CorrectionType,
orderId: orderId,
correctionFiles: '',
correctionRemark: '已读',
})
getBuySupplementList(communicationPage, trademarkId)
getTrademarkList(page)
// if (props.user == 'sell') {
// getSellSupplementList()
// } else if (props.user == 'buy') {
// getBuySupplementList()
// }
// props.upData()
// messageApi.open({
// type: 'success',
// content: '已提交',
// })
setIsModalVisible(false)
// form.resetFields();
// console.log(res);
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
} else {
try {
await supplementTrademarkData({
correctionParentId: correctionId,
// correctionType: CorrectionType,
orderId: orderId,
correctionFiles: params.correctionFiles,
correctionRemark: params.correctionRemark,
})
// if (props.user == 'sell') {
// getSellSupplementList()
// } else if (props.user == 'buy') {
// getBuySupplementList()
// }
// props.upData()
messageApi.open({
type: 'success',
content: '已提交',
})
getTrademarkList(page)
getBuySupplementList(communicationPage, trademarkId)
setIsModalVisible(false)
// form.resetFields();
// console.log(res);
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
}
// 补充资料详情
const [detailData, setDetailData] = useState<any>({})
// 补充资料弹窗
const [isModalVisible, setIsModalVisible] = useState(false)
// 沟通弹窗
const [visible, setVisible] = useState(false);
const [fileList, setFileList] = useState<any>([]) // 上传文件列表
// 获取文件类型
const getFileTypeByIdsArray = async (ids: string) => {
try {
const res: any = await getFileTypeByIds({
ids: ids
})
setFileList(res)
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
// const [orderId, setOrderId] = useState('')
const [checkRemark, setCheckRemark] = useState('') //失败原因
const [messageApi, contextHolder] = message.useMessage();
const { state } = useLocation()
const nav = useNavigate();
const height = window.innerHeight - 180;
const columns: TableProps<any>['columns'] = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
align: 'center',
fixed: 'left',
width: 90,
render: (_text, _record, index) => (page - 1) * 10 + index + 1, // 显示序号从1开始
},
{
title: '服务类型',
dataIndex: 'trademarkModeName',
fixed: 'left',
align: 'center',
key: 'trademarkModeName',
width: 150,
ellipsis: {
showTitle: true,
},
},
{
title: '类型/名称',
fixed: 'left',
dataIndex: 'trademarkName',
key: 'trademarkName',
align: 'center',
ellipsis: {
showTitle: true,
},
width: 200,
render: (_text, record) => (
<span>
{record.trademarkType == 'text' ? '文字' : record.trademarkType == 'image' ? '图形' : record.trademarkType == 'text-image' ? '图文' : ''} <span style={{
display: record.trademarkType == 'image' ? 'none' : 'unset',
}}>
<span style={{
display: record.trademarkType == '' ? 'none' : 'unset',
}}>/</span>
{record.trademarkName}</span>
{/* {record} */}
</span>
)
},
{
title: '涉及类别',
dataIndex: 'trademarkTypeDTOS',
align: 'center',
key: 'trademarkTypeDTOS',
width: 150,
ellipsis: {
showTitle: true,
},
render: (trademarkTypeDTOS) => (
// trademarkTypeDTOS.map(
// <div>
// </div>
// )
trademarkTypeDTOS.length > 0 ? (
trademarkTypeDTOS.map((item: any) => {
return (
<div key={item.id} title={item.name}>
{item.code} : {item.name}
</div>
)
})
) : '暂无'
)
},
{
title: '商标图样',
dataIndex: 'trademarkPhoto',
align: 'center',
key: 'trademarkPhoto',
width: 200,
render: (text) => (
text ? (
<Image src={showImage(text, false)}
height={100}
style={{
maxWidth: 200,
}}
>
</Image>
) : '暂无'
)
},
{
title: '状态',
dataIndex: 'trademarkStatus',
align: 'center',
key: 'trademarkStatus',
width: 110,
render: (text, record) => (
<div>
{text == '-1' ?
<div style={{
color: 'red',
cursor: 'pointer',
}}
title='点击查看原因'
onClick={() => {
setCheckRemark(record.checkRemark)
setModal(true)
// console.log(record.checkRemark);
}}
>
<div></div>
<div>退</div>
<div style={{
fontSize: '12px',
}}>()</div>
</div>
: text == '0' ?
<span
style={{
color: 'skyblue',
}}
></span>
: text == '1' ?
<span
style={{
color: 'green',
}}
></span>
: text == '2' ?
<span
style={{
color: 'rgb(0, 127, 255)',
}}
></span>
: text == '3' ?
<span
style={{
color: 'rgb(136, 185, 233)',
}}
></span>
: text == '4' ?
<span
style={{
color: 'red',
}}
></span>
: text == '5' ?
<span
style={{
color: 'rgb(136, 185, 233)',
}}
></span>
: text == '6' ?
<span
style={{
color: 'rgb(136, 185, 233)',
}}
></span>
: text == '7' ?
<span
style={{
color: 'rgb(136, 185, 233)',
}}
></span>
: text == '8' ?
<span
style={{
color: 'rgb(136, 185, 233)',
}}
></span>
: text == '9' ?
<span
style={{
color: 'rgb(136, 185, 233)',
}}
></span> : '未知'
}
</div>
)
},
// {
// title: '申请人',
// // 使用数组形式访问嵌套对象属性
// dataIndex: ['trademarkUserDTO', 'name'],
// align: 'center',
// // 修改 key 保证唯一性
// key: 'trademarkUserDTOName',
// width: 150,
// render: (text) => (
// <span>
// {text || '-'}
// </span>
// )
// },
// // {
// // title: '申请人证件号',
// // dataIndex: ['trademarkUserDTO', 'name'],
// // align: 'center',
// // key: 'appOrderId',
// // width: 150,
// // render: (text) => (
// // <span>
// // {text ? text : '未完善'}
// // </span>
// // )
// // },
// {
// title: '联系人',
// // 使用数组形式访问嵌套对象属性
// dataIndex: ['trademarkUserDTO', 'contactName'],
// align: 'center',
// // 修改 key 保证唯一性
// key: 'trademarkUserDTOContactName',
// width: 150,
// render: (text) => (
// <span>
// {text || '-'}
// </span>
// )
// },
{
title: '操作',
// dataIndex: 'contractManagementId',
align: 'center',
// key: 'appOrderId',
width: 150,
// bordeLeft: true,
fixed: 'right',
render: (record) => (
<div style={{
}}>
<span style={{
cursor: 'pointer',
color: '#007FFF',
display: record.trademarkModeName === '智能申请注册' ? 'unset' : 'none',
}} onClick={() => {
nav(`/trademark-ai-edit/${record.trademarkId}`, {
// state: {
// trademarkMode: record.trademarkMode, //申请类型id
// trademarkModeName: record.trademarkModeName, //申请类型名称
// trademarkId: record.trademarkId, //商标id
// }
})
// console.log(record.checkStatus);
}}>{
record.trademarkStatus == '2' || record.trademarkStatus == '3' ? '查看' : '编辑'
}
</span>
<span style={{
cursor: 'pointer',
color: '#007FFF',
position: 'relative',
// display: record.waitCorrectionCount > 0 ? 'unset' : 'none',
display: Number(record.trademarkStatus) >= 4 ? 'unset' : 'none',
marginLeft: 10,
}}
onClick={async () => {
setTrademarkId(record.trademarkId)
setVisible(true)
getBuySupplementList(1, record.trademarkId)
}}
>
<div style={{
display: record.waitCorrectionCount > 0 ? 'unset' : 'none',
}}>
<div style={{
position: 'absolute',
top: '-10px',
right: '-10px',
// fontSize:'16px',
background: 'red',
color: '#fff',
fontWeight: '700',
width: '20px',
height: '20px',
borderRadius: '50%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}>
{record.waitCorrectionCount}
</div>
</div>
</span>
</div>
)
},
]
const [disabled, setDisabled] = useState(false)
const getSupplementDetail = async (id: string) => {
try {
const res: any = await supplementDetail(id)
console.log(res);
setDetailData(res)
if (res.correctionFiles) {
await getFileTypeByIdsArray(res.correctionFiles)
}
if (res.buyId) {
setDisabled(true)
const newData: any = await supplementDetail(res.buyId)
form.setFieldsValue({
upCorrectionRemark: newData.correctionRemark, // 内容
})
if (newData.correctionFiles) {
getUpFileTypeByIdsArray(newData.correctionFiles)
}
} else {
setDisabled(false)
}
} catch (error: any) {
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
}
}
const [data, setData] = useState<any>([])
// 沟通数组
const [communicationData, setCommunicationData] = useState<any>([])
// 沟通分页
const [communicationPage, setCommunicationPage] = useState(1)
// 沟通分页条数
const [communicationTotal, setCommunicationTotal] = useState(0)
const communicationColums: TableProps<any>['columns'] = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
align: 'center',
width: 90,
render: (_text, _record, index) => (communicationPage - 1) * 10 + index + 1, // 显示序号从1开始
},
{
title: '资料主题',
dataIndex: 'correctionTitle',
align: 'center',
width: 200,
render: (text) => (
<div style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={text}>{text}</div>
)
},
{
title: '资料内容',
dataIndex: 'correctionRemark',
align: 'center',
width: 300,
render: (text) => (
<div style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={text}>{text}</div>
)
},
{
title: '发起时间',
dataIndex: 'createTime',
align: 'center',
width: 200,
},
{
title: '当前进度',
dataIndex: 'correctionStatus',
align: 'center',
width: 100,
render: (text) => (
<>
<span> {text == '4' ? '不予受理' : text == '5' ? '已受理' : text == '6' ? '已发初审公告' : text == '7' ? '部分驳回' : text == '8' ? '全部驳回' : text == '9' ? '商标注册完成' : "未知"}</span>
</>
)
},
{
title: '状态',
dataIndex: 'buyId',
align: 'center',
width: 100,
render: (text) => (
<>
<span style={{ color: '#DD0000', fontSize: '16px', fontWeight: '700', display: text == '' ? 'unset' : 'none' }}></span>
<span style={{ color: 'green', fontSize: '16px', fontWeight: '700', display: text == '' ? 'none' : 'unset' }}></span>
{/* <span> {text == '4' ? '不予受理' : text == '5' ? '已受理' : text == '6' ? '已发初审公告' : text == '7' ? '部分驳回' : text == '8' ? '全部驳回' : text == '9' ? '商标注册完成' : "未知"}</span> */}
</>
)
},
{
title: '操作',
align: 'center',
width: 100,
render: (record: any) => (
<span className='transaction-order-table-btn' onClick={() => {
console.log(record);
setCorrectionReply(record.correctionReply)
// console.log(record.correctionId);
setCorrectionId(record.correctionId)
getSupplementDetail(record.correctionId)
setIsModalVisible(true)
setOrderId(record.orderId)
form.resetFields();
}}></span>
)
},
]
const [loading, setLoading] = useState(false)
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
const getTrademarkList = async (page: any) => {
try {
setLoading(true)
setData([])
const res: any = await trademarkList({
keywords: state && state.keywords ? state.keywords : '',
rows: 10,
page: page
})
console.log('结果', res);
setData(res.rows)
setTotal(res.total)
setLoading(false)
} catch (error: any) {
setLoading(false)
if (error.response) {
const data = error.response.data;
messageApi.open({
type: 'error',
content: data.msg ? data.msg : `${data.path}(${data.status})`,
});
} else {
console.error(error)
}
} finally {
setLoading(false)
}
}
// useEffect(() => {
// // console.log(state.keywords);
// getTrademarkList(1)
// // console.log(1);
// }, [])
useEffect(() => {
// console.log(state.keywords);
getTrademarkList(1)
}, [state])
return (
<Spin tip="正在处理,请稍后..." size="small" spinning={loading}>
<div className='appElectionBox' style={{ height: `${height}px`, overflow: 'auto' }}>
{contextHolder}
{data.length <= 0 ? (<div style={{ height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column' }}>
<img src={nothingImg} alt="" width={368} height={355} />
<div style={{
marginTop: 50,
fontSize: 16,
color: '#D0D0D0'
}}></div>
</div>) : (
<div className='' >
<div style={{
height: `${height - 80}px`,
// background: "pink" ,
paddingTop: 20
}}>
<Table
scroll={{ y: `${height - 150}px` }}
dataSource={data}
columns={columns}
bordered
// pagination={{
// defaultPageSize: 10, // 设置默认一页显示 5 条数据
// }}
pagination={false} // 不显示分页
style={{ textAlign: 'center' }} // 设置表格内容居中显示
rowKey="trademarkId" // 指定数据项的唯一标识符
locale={{ emptyText: '暂无数据' }}
></Table>
</div>
<div className='product-release-pagination'>
<Pagination
showSizeChanger={false}
current={page} total={total} defaultPageSize={10} onChange={(page) => {
setPage(page)
getTrademarkList(page)
}} />
</div>
</div>
)}
</div>
<Modal
title="失败原因"
centered
open={modal}
footer={null}
onCancel={() => { setModal(false) }}
>
:{checkRemark}
</Modal>
<Modal
title="进度沟通"
centered
open={visible}
footer={null}
onCancel={() => { setVisible(false) }}
width={1300}
>
<Table
scroll={{ y: `${height - 150}px` }}
dataSource={communicationData}
columns={communicationColums}
bordered
// pagination={{
// defaultPageSize: 10, // 设置默认一页显示 5 条数据
// }}
pagination={
{
pageSize: 10,
total: communicationTotal,
onChange: (currentPage) => {
setCommunicationPage(currentPage);
getBuySupplementList(currentPage, trademarkId)
},
showSizeChanger: false,
current: communicationPage
}
}
style={{ textAlign: 'center' }} // 设置表格内容居中显示
rowKey="trademarkId" // 指定数据项的唯一标识符
locale={{ emptyText: '暂无数据' }}
></Table>
</Modal>
<Modal title={'进度沟通'}
destroyOnClose={true}
open={isModalVisible}
footer={null} // footer 设置为 null 来隐藏自带按钮
width={1000}
onCancel={() => {
setIsModalVisible(false);
// 清空表单
form.resetFields();
}}
centered
>
<div>
{/* {correctionId}
{CorrectionType} */}
<div className='editModal-title'>
<div className='editModal-title-box'></div>
<div className='editModal-title-name'></div>
</div>
<div className='correctionTitleBox'>
<div className='correctionTitle'></div>
<Input value={detailData.correctionTitle} style={{
height: 40,
color: 'black'
}}
disabled
></Input>
</div>
<div className='correctionRemarkBox'>
<div className='correctionTitle'></div>
<TextArea value={detailData.correctionRemark} style={{
height: 100,
color: 'black',
resize: 'none'
}}
disabled
></TextArea>
</div>
<div className='upFileBox'>
<div className='correctionTitle'></div>
{fileList.length > 0 ? (
// <div>材料列表</div>
<div>
{
fileList.map((item: any) => {
return (
<div
key={item.fileId}
style={{
// background: 'pink',
marginBottom: 5,
maxWidth: 800,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
cursor: 'pointer',
color: '#1B8BD2',
//下划线
textDecoration: 'underline',
}}
title={item.fileName}
onClick={() => {
window.open(showImage(item.fileId, false))
}}
>
{item.fileName}
</div>
)
})
}
</div>
) : (
<div style={{ fontSize: 18, fontWeight: 700 }}>
</div>
)}
</div>
<div style={{
display: correctionReply == '0' && disabled ? 'none' : 'unset'
}}>
<div className='editModal-title' style={{ marginTop: 30 }}>
<div className='editModal-title-box'></div>
<div className='editModal-title-name'></div>
</div>
<Form
name="basic"
form={form}
layout="vertical"
onFinish={(value) => {
const uids = upFileArray.map((file: any) => file.response.data.fileId).join(',');
// console.log('提取的 uid 字符串:', uids);
submitData({
correctionFiles: uids,
correctionRemark: value.upCorrectionRemark,
})
}}
onFinishFailed={() => {
messageApi.open({
type: 'error',
content: '内容和附件至少需要填写或上传一项',
})
}}
autoComplete="off"
>
<div className='correctionRemarkBox'>
<div className='correctionTitle'></div>
<Form.Item
name="upCorrectionRemark"
// rules={[
// {
// validator: (rule, value, callback) => validateContentOrFile(rule, value, callback, form),
// },
// ]}
rules={correctionReply == '0' ? [] : [
{
validator: (rule, value, callback) => validateContentOrFile(rule, value, callback, form),
},
]}
>
<TextArea style={{
height: 100,
resize: 'none',
width: 900,
}}
placeholder='请输入需要补充内容'
disabled={correctionReply == '0'}
></TextArea>
</Form.Item>
</div>
<div className='correctionRemarkBox' style={{
marginTop: 0
}}>
<div className='correctionTitle'></div>
<div style={{
maxWidth: 800,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}>
<Form.Item
name="upFile"
// rules={[
// // { required: true, message: '请上传附件' },
// {
// validator: (rule, value, callback) => validateContentOrFile(rule, value, callback, form),
// },
// ]}
rules={correctionReply === '0' ? [] : [
{
validator: (rule, value, callback) => validateContentOrFile(rule, value, callback, form),
},
]}
>
<Upload
name="file"
action={uploadFileUrl()}
defaultFileList={upFileArray}
onChange={(info) => {
setUpFileArray(info.fileList)
// console.log(info.fileList);
}}
headers={{ 'Auth': `Bearer ${token}` }}
disabled={correctionReply == '0'}
>
<Button icon={<UploadOutlined />}></Button>
</Upload>
</Form.Item>
</div>
</div>
<Form.Item
>
<div style={{
display: 'flex',
justifyContent: 'flex-end',
gap: 10,
// marginTop: 20
}}>
<div style={{
display: disabled ? 'none' : 'flex'
}}>
<Button onClick={() => {
setIsModalVisible(false)
form.resetFields();
}}></Button>
<Button type="primary" htmlType="submit" style={{
marginLeft: 10
}} >{correctionReply == '0' ? '已读' : '提交'}</Button>
</div>
</div>
</Form.Item>
</Form>
</div>
</div>
</Modal>
</Spin>
)
}