Merge remote-tracking branch 'origin/shiy-login' into PingChuan
This commit is contained in:
@@ -62,7 +62,7 @@ export function DocumentListModal({
|
||||
try {
|
||||
// 更新文档状态,传递JWT
|
||||
const updatedFile = await updateDocumentAuditStatus(fileId, 2, frontendJWT);
|
||||
console.log('更新后的文档状态:', updatedFile);
|
||||
// console.log('更新后的文档状态:', updatedFile);
|
||||
} catch (error) {
|
||||
console.error('更新文件审核状态时出错:', error);
|
||||
toastService.error(`更新文件审核状态时出错:${error instanceof Error ? error.message : '未知错误'}`);
|
||||
|
||||
@@ -182,7 +182,7 @@ interface ReviewPointsListProps {
|
||||
reviewPoints: ReviewPoint[];
|
||||
statistics: Statistics;
|
||||
activeReviewPointResultId: string | null;
|
||||
onReviewPointSelect: (id: string, page?: number, charPositions?: CharPosition[]) => void;
|
||||
onReviewPointSelect: (id: string, page?: number, charPositions?: CharPosition[], value?: string) => void;
|
||||
onStatusChange?: (id: string, editAuditStatusId: string | number, status: string, message: string) => void;
|
||||
scoringProposals?: ScoringProposal[];
|
||||
jwtToken?: string; // 添加JWT token参数
|
||||
@@ -779,16 +779,17 @@ export function ReviewPointsList({
|
||||
}
|
||||
// 打印最终请求体
|
||||
// console.log('最终请求体:', data);
|
||||
// console.log('jwtToken:', jwtToken);
|
||||
// 用 axios + application/json 提交
|
||||
try {
|
||||
const response = await axios.post(`${API_BASE_URL.replace(/\/$/, '')}/admin/cross_review/proposals`, data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${userInfo.frontend_jwt}`,
|
||||
'Authorization': `Bearer ${jwtToken}`,
|
||||
}
|
||||
});
|
||||
const result = response.data;
|
||||
if (response.status === 200) {
|
||||
if (result.code === 200 || result.code === 0) {
|
||||
toastService.success('意见提交成功');
|
||||
|
||||
// 创建新的提案对象
|
||||
@@ -814,11 +815,24 @@ export function ReviewPointsList({
|
||||
|
||||
handleCloseOpinionModal();
|
||||
} else {
|
||||
toastService.error(result.detail || '提交意见失败');
|
||||
throw new Error(result.msg || '提交意见失败')
|
||||
// toastService.error(result.msg || '提交意见失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交意见失败:', error);
|
||||
toastService.error('提交意见失败,请稍后重试');
|
||||
|
||||
// 正确处理 axios 错误响应
|
||||
let errorMessage = '提交意见失败,请稍后重试';
|
||||
|
||||
if (axios.isAxiosError(error) && error.response?.data) {
|
||||
// 从 axios 错误响应中提取 msg 字段
|
||||
errorMessage = error.response.data.msg || errorMessage;
|
||||
} else if (error instanceof Error) {
|
||||
// 处理普通 Error 对象
|
||||
errorMessage = error.message || errorMessage;
|
||||
}
|
||||
|
||||
toastService.error(errorMessage);
|
||||
}
|
||||
setIsSubmittingOpinion(false);
|
||||
};
|
||||
@@ -1407,7 +1421,7 @@ export function ReviewPointsList({
|
||||
for (const item of chain) {
|
||||
if (item.data.page && typeof onReviewPointSelect === 'function') {
|
||||
hasPage = true;
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions);
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions, item.data.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1421,7 +1435,7 @@ export function ReviewPointsList({
|
||||
// 遍历chain找到第一个有效的page
|
||||
for (const item of chain) {
|
||||
if (item.data.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions);
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions, item.data.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1461,11 +1475,11 @@ export function ReviewPointsList({
|
||||
// 假设onReviewPointSelect在作用域内可用
|
||||
const reviewPointId = reviewPoint.id as string;
|
||||
if (reviewPointId && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPointId, Number(item.data.page), item.data.char_positions);
|
||||
onReviewPointSelect(reviewPointId, Number(item.data.page), item.data.char_positions, item.data.value);
|
||||
}
|
||||
}
|
||||
else if(reviewPoint.contentPage && reviewPoint.contentPage[item.field]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[item.field]));
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[item.field]), item.data.char_positions, item.data.value);
|
||||
}
|
||||
else{
|
||||
toastService.error(`没有找到${item.field}对应的索引内容`);
|
||||
@@ -1544,11 +1558,11 @@ export function ReviewPointsList({
|
||||
if (chain[0].data.page) {
|
||||
const reviewPointId = reviewPoint.id as string;
|
||||
if (reviewPointId && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPointId, chain[0].data.page, chain[0].data.char_positions);
|
||||
onReviewPointSelect(reviewPointId, chain[0].data.page, chain[0].data.char_positions, chain[0].data.value);
|
||||
}
|
||||
}
|
||||
else if(reviewPoint.contentPage && reviewPoint.contentPage[chain[0].field]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[0].field]));
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[0].field]), chain[0].data.char_positions, chain[0].data.value);
|
||||
}
|
||||
else{
|
||||
toastService.error(`没有找到${chain[0].field}对应的索引内容`);
|
||||
@@ -1570,11 +1584,11 @@ export function ReviewPointsList({
|
||||
if (chain[1].data.page) {
|
||||
const reviewPointId = reviewPoint.id as string;
|
||||
if (reviewPointId && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPointId, chain[1].data.page, chain[1].data.char_positions);
|
||||
onReviewPointSelect(reviewPointId, chain[1].data.page, chain[1].data.char_positions, chain[1].data.value);
|
||||
}
|
||||
}
|
||||
else if(reviewPoint.contentPage && reviewPoint.contentPage[chain[1].field]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[1].field]));
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[1].field]), chain[1].data.char_positions, chain[1].data.value);
|
||||
}
|
||||
else{
|
||||
toastService.error(`没有找到${chain[1].field}对应的索引内容`);
|
||||
@@ -1710,9 +1724,9 @@ export function ReviewPointsList({
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (mainTypeValue.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions);
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[fieldKey]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]));
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${fieldKey}对应的索引内容`);
|
||||
}
|
||||
@@ -1721,7 +1735,9 @@ export function ReviewPointsList({
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
if (mainTypeValue.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions);
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[fieldKey]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${fieldKey}对应的索引内容`);
|
||||
}
|
||||
@@ -1832,9 +1848,9 @@ export function ReviewPointsList({
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (value.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions);
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions, value.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[key]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]));
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]), value.char_positions, value.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${key}对应的索引内容`);
|
||||
}
|
||||
@@ -1844,9 +1860,9 @@ export function ReviewPointsList({
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
if (value.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions);
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions, value.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[key]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]));
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]), value.char_positions, value.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${key}对应的索引内容`);
|
||||
}
|
||||
@@ -2404,29 +2420,26 @@ export function ReviewPointsList({
|
||||
<>
|
||||
<div className="relative">
|
||||
{/* 悬浮的意见数量显示 - 固定在左侧 */}
|
||||
<button
|
||||
className="absolute left-[-35px] top-16 z-10 group cursor-pointer"
|
||||
<button
|
||||
className="absolute left-[-35px] top-16 z-10 cursor-pointer"
|
||||
onClick={() => handleOpenOpinionListModal(reviewPoints[0])}
|
||||
type="button"
|
||||
aria-label="查看意见列表"
|
||||
>
|
||||
{/* 默认状态:竖向排列,窄宽度 */}
|
||||
<div className="flex flex-col items-center bg-blue-50 px-2 py-2 rounded-lg border border-blue-200 shadow-md transition-all duration-300 group-hover:scale-0 group-hover:opacity-0 origin-top-right">
|
||||
<i className="ri-chat-1-line text-blue-600 text-base"></i>
|
||||
<span className="text-base text-blue-600 font-bold leading-tight whitespace-nowrap">{scoringProposals.length}</span>
|
||||
<span className="text-xs text-blue-500 leading-tight whitespace-wrap">条</span>
|
||||
<span className="text-xs text-blue-500 leading-tight whitespace-wrap">意</span>
|
||||
<span className="text-xs text-blue-500 leading-tight whitespace-wrap">见</span>
|
||||
</div>
|
||||
|
||||
{/* 悬浮状态:横向排列,显示图标,数字放大 */}
|
||||
<div className="absolute top-0 right-0 opacity-0 scale-0 group-hover:opacity-100 group-hover:scale-100 flex items-center bg-blue-50 px-3 py-2 rounded-lg border border-blue-200 shadow-lg transition-all duration-300 origin-top-right">
|
||||
<div className="flex flex-col">
|
||||
<i className="ri-chat-1-line text-blue-600 text-base"></i>
|
||||
<span className="text-xl text-blue-600 font-bold">{scoringProposals.length}</span>
|
||||
<span className="text-xs text-blue-500 leading-tight whitespace-wrap">条</span>
|
||||
<span className="text-xs text-blue-500 leading-tight whitespace-wrap">意</span>
|
||||
<span className="text-xs text-blue-500 leading-tight whitespace-wrap">见</span>
|
||||
<div className={`relative flex flex-col items-center bg-gradient-to-br from-blue-50 to-blue-100 px-2 py-2 rounded-lg border border-blue-300 shadow-md transition-all duration-200 ease-out hover:scale-110 hover:shadow-xl active:scale-95 ${scoringProposals.length === 0 ? 'opacity-50' : 'opacity-100'}`}>
|
||||
{/* 脉动提示点 - 仅当有意见时显示 */}
|
||||
{scoringProposals.length > 0 && (
|
||||
<span className="absolute -top-1 -right-1 flex h-3 w-3">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||
</span>
|
||||
)}
|
||||
<i className="ri-chat-1-line text-blue-600 text-lg mb-0.5"></i>
|
||||
<span className="text-lg text-blue-700 font-bold leading-tight">{scoringProposals.length}</span>
|
||||
<div className="flex flex-col items-center text-[10px] text-blue-600 leading-tight mt-0.5">
|
||||
<span>条</span>
|
||||
<span>意</span>
|
||||
<span>见</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
@@ -2656,14 +2669,16 @@ export function ReviewPointsList({
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<Table
|
||||
columns={[
|
||||
<div style={{ minHeight: '500px', display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={{ flex: 1, minHeight: '450px' }}>
|
||||
<Table
|
||||
columns={[
|
||||
{
|
||||
title: "评查点名称",
|
||||
key: "evaluation_point_name",
|
||||
width: "15%",
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => (
|
||||
<div className="text-sm">{record.evaluation_point_name}</div>
|
||||
<div className="text-sm text-left py-1">{record.evaluation_point_name}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
@@ -2671,7 +2686,7 @@ export function ReviewPointsList({
|
||||
key: "problem_message",
|
||||
width: "18%",
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => (
|
||||
<div className="text-sm text-left">{record.problem_message}</div>
|
||||
<div className="text-sm text-left py-1">{record.problem_message}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
@@ -2682,14 +2697,14 @@ export function ReviewPointsList({
|
||||
const reason = record.reason || '';
|
||||
const display = reason.length > 20 ? reason.slice(0, 20) + '...' : reason;
|
||||
return (
|
||||
<span title={reason}>{display}</span>
|
||||
<div className="text-sm text-left py-1" title={reason}>{display}</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "调整分数",
|
||||
key: "proposed_score",
|
||||
width: "5%",
|
||||
width: "8%",
|
||||
align: "center" as const,
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => (
|
||||
<span className={`text-sm font-medium ${record.proposed_score >= 0 ? 'text-green-600' : 'text-red-600'}`}>
|
||||
@@ -2700,8 +2715,7 @@ export function ReviewPointsList({
|
||||
{
|
||||
title: "投票人",
|
||||
key: "votes",
|
||||
width: "22%",
|
||||
align: "center" as const,
|
||||
width: "24%",
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => {
|
||||
// 投票类型配置
|
||||
const voterGroups = [
|
||||
@@ -2728,19 +2742,20 @@ export function ReviewPointsList({
|
||||
}
|
||||
];
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5 py-1 min-w-[120px]">
|
||||
<div className="flex flex-col items-start gap-1.5 py-1 w-full">
|
||||
{voterGroups.map((group) => (
|
||||
Array.isArray(group.voters) && group.voters.length > 0 && (
|
||||
<div key={group.type} className="flex flex-wrap gap-1">
|
||||
<div key={group.type} className="flex items-start gap-1 w-full">
|
||||
{group.voters.map((name, idx) => (
|
||||
<span
|
||||
key={`${group.type}-${name}-${idx}`}
|
||||
className={`
|
||||
px-1.5 py-0.5 rounded text-xs font-medium
|
||||
${group.color} ${group.bg} ${group.border}
|
||||
whitespace-nowrap overflow-hidden text-ellipsis max-w-[80px]
|
||||
whitespace-nowrap
|
||||
transition-all hover:scale-[1.03] hover:shadow-sm
|
||||
`}
|
||||
title={name}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
@@ -2757,9 +2772,10 @@ export function ReviewPointsList({
|
||||
key: "proposer",
|
||||
width: "8%",
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => (
|
||||
<div className="flex items-center justify-center text-left">
|
||||
<div className="flex items-center justify-center py-1">
|
||||
<span
|
||||
className="px-1.5 py-0.5 rounded text-xs font-medium text-yellow-700 bg-yellow-100 border border-yellow-200 whitespace-nowrap overflow-hidden text-ellipsis max-w-[80px] transition-all hover:scale-[1.03] hover:shadow-sm"
|
||||
className="px-1.5 py-0.5 rounded text-xs font-medium text-yellow-700 bg-yellow-100 border border-yellow-200 whitespace-nowrap transition-all hover:scale-[1.03] hover:shadow-sm"
|
||||
title={record.proposer}
|
||||
>
|
||||
{record.proposer}
|
||||
</span>
|
||||
@@ -2769,15 +2785,16 @@ export function ReviewPointsList({
|
||||
{
|
||||
title: "发起时间",
|
||||
key: "created_at",
|
||||
width: "12%",
|
||||
width: "8%",
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => (
|
||||
<div className="text-sm text-left">{record.created_at}</div>
|
||||
<div className="text-sm text-left py-1">{record.created_at}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: "投票状态",
|
||||
key: "opinion_status",
|
||||
width: "12%",
|
||||
align: "center" as const,
|
||||
render: (_: unknown, record: CrossCheckingOpinion) => {
|
||||
let label = '';
|
||||
let color = '';
|
||||
@@ -2796,7 +2813,7 @@ export function ReviewPointsList({
|
||||
color = 'text-yellow-600';
|
||||
break;
|
||||
}
|
||||
return <span className={`font-bold ${color}`}>{label}</span>;
|
||||
return <span className={`text-sm font-bold ${color}`}>{label}</span>;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -2812,25 +2829,27 @@ export function ReviewPointsList({
|
||||
}
|
||||
}
|
||||
]}
|
||||
dataSource={opinionListData}
|
||||
rowKey="proposal_id"
|
||||
emptyText="暂无意见数据"
|
||||
className="opinion-list-table"
|
||||
/>
|
||||
dataSource={opinionListData}
|
||||
rowKey="proposal_id"
|
||||
emptyText="暂无意见数据"
|
||||
className="opinion-list-table"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 分页组件 */}
|
||||
{opinionListTotal > 0 && (
|
||||
<Pagination
|
||||
{/* 分页组件 */}
|
||||
{opinionListTotal > 0 && (
|
||||
<Pagination
|
||||
currentPage={opinionListCurrentPage}
|
||||
total={opinionListTotal}
|
||||
pageSize={opinionListPageSize}
|
||||
onChange={handleOpinionListPageChange}
|
||||
onPageSizeChange={handleOpinionListPageSizeChange}
|
||||
showTotal={true}
|
||||
showPageSizeChanger={true}
|
||||
pageSizeOptions={[5,10, 20, 30, 50]}
|
||||
/>
|
||||
)}
|
||||
onChange={handleOpinionListPageChange}
|
||||
onPageSizeChange={handleOpinionListPageSizeChange}
|
||||
showTotal={true}
|
||||
showPageSizeChanger={true}
|
||||
pageSizeOptions={[5,10, 20, 30, 50]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,13 @@ import '../../styles/components/chat-with-llm/index.css';
|
||||
|
||||
const { Content } = Layout;
|
||||
|
||||
// 扩展 Window 接口以支持自定义属性
|
||||
declare global {
|
||||
interface Window {
|
||||
hasSetInitialSidebarState?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主聊天组件
|
||||
* 实现单页面应用模式,参考webapp-conversation的初始化逻辑
|
||||
@@ -348,6 +355,11 @@ export default function Chat() {
|
||||
if (conversationId !== currConversationId) {
|
||||
setCurrConversationId(conversationId, CHAT_CONFIG.APP_ID);
|
||||
}
|
||||
|
||||
// 移动端选中对话后自动隐藏侧边栏
|
||||
if (isMobile && !sidebarCollapsed) {
|
||||
setSidebarCollapsed(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -485,7 +497,15 @@ export default function Chat() {
|
||||
// 检查屏幕尺寸
|
||||
useEffect(() => {
|
||||
const checkScreenSize = () => {
|
||||
setIsMobile(window.innerWidth < 992);
|
||||
const isMobileDevice = window.innerWidth < 992;
|
||||
setIsMobile(isMobileDevice);
|
||||
|
||||
// 移动端默认隐藏侧边栏,桌面端默认显示
|
||||
// 只在初次加载时设置,避免影响用户的手动切换
|
||||
if (!window.hasSetInitialSidebarState) {
|
||||
setSidebarCollapsed(isMobileDevice);
|
||||
window.hasSetInitialSidebarState = true;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始检查
|
||||
@@ -537,7 +557,7 @@ export default function Chat() {
|
||||
const conversationIntroduction = currConversationInfo?.introduction || '';
|
||||
|
||||
return (
|
||||
<Layout style={{ height: '100%', display: 'flex', flexDirection: 'row' }}>
|
||||
<Layout style={{ height: '100%', display: 'flex', flexDirection: 'row', position: 'relative' }}>
|
||||
{/* 移动端遮罩层 */}
|
||||
{!sidebarCollapsed && isMobile && (
|
||||
<div
|
||||
@@ -546,6 +566,24 @@ export default function Chat() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* ChatSidebar 隐藏时显示的展开按钮 */}
|
||||
{sidebarCollapsed && (
|
||||
<button
|
||||
onClick={handleSidebarToggle}
|
||||
className="fixed left-0 top-1/2 -translate-y-1/2 z-[998] bg-white hover:bg-gray-100 shadow-lg rounded-r-lg px-2 py-4 transition-all duration-200 border border-l-0 border-gray-200"
|
||||
style={{
|
||||
width: '32px',
|
||||
height: '48px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
aria-label="展开对话列表"
|
||||
>
|
||||
<i className="ri-menu-unfold-line text-lg text-gray-600"></i>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* 侧边栏 */}
|
||||
<ChatSidebar
|
||||
ref={sidebarRef}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
|
||||
import { Link, useLocation, useNavigate } from '@remix-run/react';
|
||||
import type { UserRole } from '~/root';
|
||||
import { getUserRoutesByRole, mapUserRoleToRoleKey, type MenuItem } from '~/api/auth/user-routes';
|
||||
import { DOCUMENT_URL } from '~/config/api-config';
|
||||
|
||||
interface SidebarProps {
|
||||
onToggle: () => void;
|
||||
@@ -320,7 +321,7 @@ export function Sidebar({ onToggle, collapsed, userRole, frontendJWT = '' }: Sid
|
||||
<div className={`flex items-center ${collapsed ? 'justify-center' : ''}`}>
|
||||
{selectedModulePicPath && (
|
||||
<img
|
||||
src={selectedModulePicPath}
|
||||
src={selectedModuleName === '智慧法务大模型' || selectedModuleName === '交叉评查' ? selectedModulePicPath : `${DOCUMENT_URL}${selectedModulePicPath}`}
|
||||
alt={selectedModuleName}
|
||||
className={`${collapsed ? 'w-8 h-8' : 'w-6 h-6 mr-3'}`}
|
||||
/>
|
||||
|
||||
@@ -211,6 +211,7 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage
|
||||
// console.log('[FilePreview] 渲染PDF预览', { real_path, targetPage, charPositions });
|
||||
// console.log('[FilePreview] 渲染PDF预览', { fileContent });
|
||||
const pageOffset = fileContent.ocrResult?.__meta?.page_offset || fileContent.ocr_result?.__meta?.page_offset || 0;
|
||||
// console.log('pageOffset', pageOffset)
|
||||
return (
|
||||
<PdfPreview
|
||||
filePath={real_path}
|
||||
|
||||
Reference in New Issue
Block a user