代码合并
This commit is contained in:
1 parent
1938c80061
commit
230fab013a
14 files changed
+273
-56
No files matched your search
@@ -119,7 +119,8 @@
|
|||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-color: rgba(43, 143, 254, 0.6);
|
border-color: rgba(43, 143, 254, 0.6);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(20px);
|
||||||
|
-webkit-backdrop-filter: blur(20px);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 108px;
|
left: 108px;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
@@ -211,6 +211,13 @@ export const HighFidelityReport: React.FC<HighFidelityReportProps> = ({
|
|||||||
[artifactsBySeat],
|
[artifactsBySeat],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 只保留「有产出文件」的席位;加载中 / 出错的席位仍保留以展示其状态。
|
||||||
|
// 全部席位都没有文件(且都已加载完成、无错误)时,整块「生成的报告文件」隐藏。
|
||||||
|
const seatsWithFiles = useMemo(
|
||||||
|
() => artifactsBySeat.filter((s) => s.loading || s.error || s.files.length > 0),
|
||||||
|
[artifactsBySeat],
|
||||||
|
);
|
||||||
|
|
||||||
const toggleSeat = useCallback((key: string) => {
|
const toggleSeat = useCallback((key: string) => {
|
||||||
setExpandedSeats((prev) => {
|
setExpandedSeats((prev) => {
|
||||||
const next = new Set(prev);
|
const next = new Set(prev);
|
||||||
@@ -424,21 +431,20 @@ export const HighFidelityReport: React.FC<HighFidelityReportProps> = ({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Section 3: Generated files per seat —— 点击「查看」进入沙箱分栏预览 */}
|
{/* Section 3: Generated files per seat —— 点击「查看」进入沙箱分栏预览。
|
||||||
<section className="bg-white border border-slate-200 rounded-2xl p-5 shadow-[0_2px_8px_rgba(0,0,0,0.02)]">
|
仅当存在「有产出文件 / 加载中 / 出错」的席位时才渲染;全部席位无文件则整块隐藏。 */}
|
||||||
<h4 className="text-xs font-black text-slate-900 uppercase tracking-widest mb-3 flex items-center gap-2">
|
{seatsWithFiles.length > 0 && (
|
||||||
<Download className="w-4 h-4 text-primary" />
|
<section className="bg-white border border-slate-200 rounded-2xl p-5 shadow-[0_2px_8px_rgba(0,0,0,0.02)]">
|
||||||
生成的报告文件
|
<h4 className="text-xs font-black text-slate-900 uppercase tracking-widest mb-3 flex items-center gap-2">
|
||||||
<span className="text-[10px] font-mono font-semibold text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded">
|
<Download className="w-4 h-4 text-primary" />
|
||||||
{totalFileCount}
|
生成的报告文件
|
||||||
</span>
|
<span className="text-[10px] font-mono font-semibold text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded">
|
||||||
</h4>
|
{totalFileCount}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
|
||||||
{artifactsBySeat.length === 0 ? (
|
|
||||||
<p className="text-[11px] text-slate-400 italic">尚未初始化席位线程,无法列出文件。</p>
|
|
||||||
) : (
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{artifactsBySeat.map((seat) => (
|
{seatsWithFiles.map((seat) => (
|
||||||
<div key={seat.agentName} className="border border-slate-150 rounded-xl">
|
<div key={seat.agentName} className="border border-slate-150 rounded-xl">
|
||||||
<div className="flex items-center justify-between gap-2 px-3 py-2 bg-slate-50 border-b border-slate-150 rounded-t-xl">
|
<div className="flex items-center justify-between gap-2 px-3 py-2 bg-slate-50 border-b border-slate-150 rounded-t-xl">
|
||||||
<span className="text-[11.5px] font-bold text-slate-800 truncate">{seat.displayName}</span>
|
<span className="text-[11.5px] font-bold text-slate-800 truncate">{seat.displayName}</span>
|
||||||
@@ -501,8 +507,8 @@ export const HighFidelityReport: React.FC<HighFidelityReportProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
</section>
|
||||||
</section>
|
)}
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="pt-2 border-t border-slate-100 flex items-center justify-between flex-wrap gap-4">
|
<div className="pt-2 border-t border-slate-100 flex items-center justify-between flex-wrap gap-4">
|
||||||
|
|||||||
+53
-26
@@ -4,9 +4,11 @@ import { Bot, ChevronRight, Download, Edit, Eye, FileText, Layers, MoreHorizonta
|
|||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Col, Empty, Loading, Pagination, Progress, Row } from 'tdesign-react';
|
import { Col, Loading, Pagination, Progress, Row } from 'tdesign-react';
|
||||||
import { requestCrudService } from '@/service/request-axios-service';
|
import { requestCrudService } from '@/service/request-axios-service';
|
||||||
import { ActionColumn } from './ActionColumn';
|
import { ActionColumn } from './ActionColumn';
|
||||||
|
import { resolveStatusIcon } from './icons';
|
||||||
|
import { mockActionColumns, mockTaskList } from './actionMock';
|
||||||
|
|
||||||
interface ActionAnalyzesProps {
|
interface ActionAnalyzesProps {
|
||||||
TaskType?: string;
|
TaskType?: string;
|
||||||
@@ -68,6 +70,14 @@ export const ActionAnalyzes: React.FC<ActionAnalyzesProps> = ({ title, category,
|
|||||||
await taskListSearch();
|
await taskListSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 接口不可用 / 返回为空时回落到本地预览数据,方便联调看效果。
|
||||||
|
const fallbackToMock = () => {
|
||||||
|
setTaskList(mockTaskList);
|
||||||
|
setTotal(mockTaskList.length);
|
||||||
|
setActionColumnList(mockActionColumns);
|
||||||
|
if (mockTaskList[0]) setTaskId(mockTaskList[0].id);
|
||||||
|
};
|
||||||
|
|
||||||
// 任务查询
|
// 任务查询
|
||||||
const taskListSearch = async () => {
|
const taskListSearch = async () => {
|
||||||
const param = {
|
const param = {
|
||||||
@@ -76,21 +86,27 @@ export const ActionAnalyzes: React.FC<ActionAnalyzesProps> = ({ title, category,
|
|||||||
pageSize: state.current.pageSize
|
pageSize: state.current.pageSize
|
||||||
}
|
}
|
||||||
setTaskLoading(true);
|
setTaskLoading(true);
|
||||||
const res = await service.post(`${zncmUrl}/action/cop-action-tasks`, param);
|
try {
|
||||||
setTaskLoading(false);
|
const res = await service.post(`${zncmUrl}/action/cop-action-tasks`, param);
|
||||||
console.log('任务搜索', res);
|
const result: TaskListItem[] = Array.isArray(res?.data) ? res.data : [];
|
||||||
const result = res.data;
|
if (result.length === 0) {
|
||||||
result.forEach((item: TaskListItem) => {
|
fallbackToMock();
|
||||||
item.progress = item.endCount / item.sumAll || 0; // 获取已完成和未完成的占比
|
return;
|
||||||
item.taskStatusData = taskStatusList[item.taskStatus] // 根据任务状态码获取相关信息
|
}
|
||||||
})
|
result.forEach((item: TaskListItem) => {
|
||||||
setTaskList(result || []); // 设置任务列表页
|
item.progress = item.endCount / item.sumAll || 0; // 获取已完成和未完成的占比
|
||||||
const totalRes = await service.post(`${zncmUrl}/action/cop-action-tasks-count`, param); // 查询任务总数
|
item.taskStatusData = taskStatusList[item.taskStatus] // 根据任务状态码获取相关信息
|
||||||
console.log('totalRes', totalRes)
|
})
|
||||||
setTotal(totalRes.data || 0); // 设置总数
|
setTaskList(result); // 设置任务列表页
|
||||||
if (result.length > 0) {
|
const totalRes = await service.post(`${zncmUrl}/action/cop-action-tasks-count`, param); // 查询任务总数
|
||||||
|
setTotal(totalRes?.data || result.length); // 设置总数
|
||||||
setTaskId(result[0].id);
|
setTaskId(result[0].id);
|
||||||
await actionListSearch(result[0].id);
|
await actionListSearch(result[0].id);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('任务搜索失败,使用本地预览数据', err);
|
||||||
|
fallbackToMock();
|
||||||
|
} finally {
|
||||||
|
setTaskLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,16 +116,23 @@ export const ActionAnalyzes: React.FC<ActionAnalyzesProps> = ({ title, category,
|
|||||||
taskId: taskId,
|
taskId: taskId,
|
||||||
}
|
}
|
||||||
setActionLoading(true);
|
setActionLoading(true);
|
||||||
const res = await service.get(`${zncmUrl}/action/cop-task-actions`, param);
|
try {
|
||||||
console.log('行动查询', res);
|
const res = await service.get(`${zncmUrl}/action/cop-task-actions`, param);
|
||||||
setActionLoading(false);
|
const result = res?.data ?? {};
|
||||||
const result = res.data;
|
const columns = [
|
||||||
setActionColumnList([
|
{ columnName: '待分析', icon: '待CEH.svg', actionList: result.collect || [] },
|
||||||
{ columnName: '待分析', icon: '待CEH.svg', actionList: result.collect || [] },
|
{ columnName: 'CEH中', icon: '进行中.svg', actionList: result.collect1 || [] },
|
||||||
{ columnName: 'CEH中', icon: '进行中.svg', actionList: result.collect1 || [] },
|
{ columnName: 'CEH完成', icon: '完成.svg', actionList: result.collect2 || [] },
|
||||||
{ columnName: 'CEH完成', icon: '完成.svg', actionList: result.collect2 || [] },
|
{ columnName: '已终止', icon: '已终止.svg', actionList: result.endDate || [] },
|
||||||
{ columnName: '已终止', icon: '已终止.svg', actionList: result.endDate || [] },
|
];
|
||||||
]);
|
const hasAny = columns.some((c) => c.actionList.length > 0);
|
||||||
|
setActionColumnList(hasAny ? columns : mockActionColumns);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('行动查询失败,使用本地预览数据', err);
|
||||||
|
setActionColumnList(mockActionColumns);
|
||||||
|
} finally {
|
||||||
|
setActionLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const taskDataChange = async (taskId: number) => {
|
const taskDataChange = async (taskId: number) => {
|
||||||
@@ -151,7 +174,7 @@ export const ActionAnalyzes: React.FC<ActionAnalyzesProps> = ({ title, category,
|
|||||||
<div className="text-[var(--text-color)] text-[17px] mb-[5px] font-[500]">{item.taskName}</div>
|
<div className="text-[var(--text-color)] text-[17px] mb-[5px] font-[500]">{item.taskName}</div>
|
||||||
<div className="text-[#7f7f7f] mb-[5px]">{format(new Date(item.taskStartDate), 'yyyy-MM-dd HH:mm:ss')}</div>
|
<div className="text-[#7f7f7f] mb-[5px]">{format(new Date(item.taskStartDate), 'yyyy-MM-dd HH:mm:ss')}</div>
|
||||||
<div className="flex items-center mb-[8px]">
|
<div className="flex items-center mb-[8px]">
|
||||||
<img src={`/icon/${item?.taskStatusData?.icon}`} alt="" />
|
<img src={resolveStatusIcon(item?.taskStatusData?.icon)} className="w-[20px]" alt="" />
|
||||||
<span className="ml-[5px] leading-[16px]">{item?.taskStatusData?.label}</span>
|
<span className="ml-[5px] leading-[16px]">{item?.taskStatusData?.label}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="pb-[10px] pt-[10px]">
|
<div className="pb-[10px] pt-[10px]">
|
||||||
@@ -195,7 +218,11 @@ export const ActionAnalyzes: React.FC<ActionAnalyzesProps> = ({ title, category,
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
actionColumnList.length === 0 && <Empty/>
|
actionColumnList.length === 0 && (
|
||||||
|
<div className={`col-span-4 flex items-center justify-center py-[60px] text-sm ${isDark ? 'text-slate-500' : 'text-[#bfbfbf]'}`}>
|
||||||
|
暂无数据
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</Loading>
|
</Loading>
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import { Bot, ChevronRight, Download, Edit, Eye, FileText, Layers, MoreHorizonta
|
|||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Col, Empty, Pagination, Progress, Row } from 'tdesign-react';
|
import { Col, Pagination, Progress, Row } from 'tdesign-react';
|
||||||
import { requestCrudService } from '@/service/request-axios-service';
|
import { requestCrudService } from '@/service/request-axios-service';
|
||||||
|
import { resolveStatusIcon } from './icons';
|
||||||
|
|
||||||
interface ActionColumnProps {
|
interface ActionColumnProps {
|
||||||
TaskType?: string;
|
TaskType?: string;
|
||||||
@@ -66,7 +67,7 @@ export const ActionColumn: React.FC<ActionColumnProps> = ({ title, category, sub
|
|||||||
<div className={`h-[calc(100vh-100px)] p-[10px] flex-1 ${isDark? 'dark-action-bg' : `bg-white action-bg${columnIndex} shadow-[2px_0px_6px_rgba(0,0,0,0.12)]`} rounded-[4px]`}>
|
<div className={`h-[calc(100vh-100px)] p-[10px] flex-1 ${isDark? 'dark-action-bg' : `bg-white action-bg${columnIndex} shadow-[2px_0px_6px_rgba(0,0,0,0.12)]`} rounded-[4px]`}>
|
||||||
<div className="mb-[10px]">
|
<div className="mb-[10px]">
|
||||||
<div className="flex items-center mb-[20px]">
|
<div className="flex items-center mb-[20px]">
|
||||||
<img src={`/icon/${icon}`} className="w-[24px] mr-[10px]" alt="" />
|
<img src={resolveStatusIcon(icon)} className="w-[24px] mr-[10px]" alt="" />
|
||||||
<span className="text-[#222222] text-[18px] font-bold mr-[20px]">{columnName}</span>
|
<span className="text-[#222222] text-[18px] font-bold mr-[20px]">{columnName}</span>
|
||||||
<span className="text-[#222222] text-[18px] font-bold mr-[20px]">{actionCount}</span>
|
<span className="text-[#222222] text-[18px] font-bold mr-[20px]">{actionCount}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,13 +100,11 @@ export const ActionColumn: React.FC<ActionColumnProps> = ({ title, category, sub
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
actionList.length === 0 && <Empty image={
|
actionList.length === 0 && (
|
||||||
<img
|
<div className={`flex items-center justify-center py-[48px] text-sm ${isDark ? 'text-slate-500' : 'text-[#bfbfbf]'}`}>
|
||||||
src="/icon/empty-list.png"
|
暂无数据
|
||||||
alt="empty"
|
</div>
|
||||||
className="w-[135px]"
|
)
|
||||||
/>
|
|
||||||
} />
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -236,9 +236,6 @@ const TaskAnalyzes: React.FC<TaskListPageProps> = ({ title, category, subCategor
|
|||||||
<div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
|
<div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="flex h-11 w-11 items-center justify-center rounded-2xl border border-[rgba(96,165,250,0.28)] bg-[linear-gradient(180deg,rgba(22,119,255,0.28),rgba(14,63,135,0.18))] shadow-[0_10px_30px_rgba(14,63,135,0.24)]">
|
|
||||||
<Bot className="h-5 w-5 text-[#7CC9FF]" />
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<h1 className={`text-[26px] font-semibold tracking-[0.02em] ${isDark ? 'text-slate-50' : 'text-[#222222]'}`}>
|
<h1 className={`text-[26px] font-semibold tracking-[0.02em] ${isDark ? 'text-slate-50' : 'text-[#222222]'}`}>
|
||||||
{title}
|
{title}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* 行动 CE 看板的本地预览数据。
|
||||||
|
*
|
||||||
|
* 仅在接口不可用 / 返回为空时回落使用(见 ActionAnalyzes 的 catch 分支),
|
||||||
|
* 后端正常返回数据时不会用到。纯前端联调 / 演示效果用。
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
actionColumnItem,
|
||||||
|
ActionListItem,
|
||||||
|
TaskListItem,
|
||||||
|
taskStatusList,
|
||||||
|
} from "./TaskManagement";
|
||||||
|
|
||||||
|
const statusMap = taskStatusList as Record<string, TaskListItem["taskStatusData"]>;
|
||||||
|
|
||||||
|
/** 左侧任务列表 —— 覆盖「待分析 / 分析中 / 审核通过(完成) / 审核未通过」四种状态图标。 */
|
||||||
|
export const mockTaskList: TaskListItem[] = (
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: 9001,
|
||||||
|
taskName: "京津冀区域舆情联动处置专项",
|
||||||
|
taskStartDate: "2026-06-08 09:12:00",
|
||||||
|
taskStatus: 20,
|
||||||
|
endCount: 3,
|
||||||
|
sumAll: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9002,
|
||||||
|
taskName: "重点人群引导策略分析",
|
||||||
|
taskStartDate: "2026-06-07 14:30:00",
|
||||||
|
taskStatus: 10,
|
||||||
|
endCount: 0,
|
||||||
|
sumAll: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9003,
|
||||||
|
taskName: "阶段性成效复盘与归档",
|
||||||
|
taskStartDate: "2026-06-05 16:45:00",
|
||||||
|
taskStatus: 110,
|
||||||
|
endCount: 6,
|
||||||
|
sumAll: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9004,
|
||||||
|
taskName: "审核未通过任务回溯",
|
||||||
|
taskStartDate: "2026-06-04 11:10:00",
|
||||||
|
taskStatus: 50,
|
||||||
|
endCount: 2,
|
||||||
|
sumAll: 7,
|
||||||
|
},
|
||||||
|
] as Array<Partial<TaskListItem>>
|
||||||
|
).map((t) => ({
|
||||||
|
...t,
|
||||||
|
progress: t.sumAll ? (t.endCount as number) / (t.sumAll as number) : 0,
|
||||||
|
taskStatusData: statusMap[String(t.taskStatus)],
|
||||||
|
})) as unknown as TaskListItem[];
|
||||||
|
|
||||||
|
function action(partial: Partial<ActionListItem>): ActionListItem {
|
||||||
|
return partial as unknown as ActionListItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 右侧四栏行动 —— 列与 ActionAnalyzes 里真实构建的四栏一一对应。 */
|
||||||
|
export const mockActionColumns: actionColumnItem[] = [
|
||||||
|
{
|
||||||
|
columnName: "待分析",
|
||||||
|
icon: "待CEH.svg",
|
||||||
|
actionList: [
|
||||||
|
action({
|
||||||
|
id: 1101,
|
||||||
|
actionName: "梳理重点平台舆情数据,输出待分析清单",
|
||||||
|
level: 1,
|
||||||
|
deptName: "情报研判处",
|
||||||
|
actionStatus: 0,
|
||||||
|
}),
|
||||||
|
action({
|
||||||
|
id: 1102,
|
||||||
|
actionName: "采集竞品动向与受众反馈样本",
|
||||||
|
level: 2,
|
||||||
|
deptName: "数据采集组",
|
||||||
|
actionStatus: 0,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
columnName: "CEH中",
|
||||||
|
icon: "进行中.svg",
|
||||||
|
actionList: [
|
||||||
|
action({
|
||||||
|
id: 1201,
|
||||||
|
actionName: "开展多智能体会商,形成初步处置共识",
|
||||||
|
level: 1,
|
||||||
|
deptName: "策略策划处",
|
||||||
|
actionStatus: 1,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
columnName: "CEH完成",
|
||||||
|
icon: "完成.svg",
|
||||||
|
actionList: [
|
||||||
|
action({
|
||||||
|
id: 1301,
|
||||||
|
actionName: "完成作战方案撰写并通过审核",
|
||||||
|
level: 1,
|
||||||
|
deptName: "指挥协调中心",
|
||||||
|
actionStatus: 1,
|
||||||
|
}),
|
||||||
|
action({
|
||||||
|
id: 1302,
|
||||||
|
actionName: "归档阶段性成效报告并同步相关单位",
|
||||||
|
level: 2,
|
||||||
|
deptName: "综合保障组",
|
||||||
|
actionStatus: 1,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
columnName: "已终止",
|
||||||
|
icon: "已终止.svg",
|
||||||
|
actionList: [
|
||||||
|
action({
|
||||||
|
id: 1401,
|
||||||
|
actionName: "因优先级调整终止的预备行动",
|
||||||
|
level: 2,
|
||||||
|
deptName: "综合保障组",
|
||||||
|
actionStatus: 1,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 行动 / 任务状态图标。
|
||||||
|
*
|
||||||
|
* 用 `import` 引入 SVG,让 Vite 把它们打进产物并生成带 hash 的最终 URL,
|
||||||
|
* 这样无论部署到子路径(base)还是带指纹的静态资源服务都能正确访问 ——
|
||||||
|
* 不能再用 `/icon/xxx.svg` 这种运行时绝对路径(部署后会 404)。
|
||||||
|
*
|
||||||
|
* key 沿用后端 / taskStatusList 里给的中文文件名,方便按名取用。
|
||||||
|
*/
|
||||||
|
import daiQianShou from "./待签收.svg";
|
||||||
|
import daiCEH from "./待CEH.svg";
|
||||||
|
import jinXingZhong from "./进行中.svg";
|
||||||
|
import wanCheng from "./完成.svg";
|
||||||
|
import weiTongGuo from "./未通过.svg";
|
||||||
|
import yiZhongZhi from "./已终止.svg";
|
||||||
|
|
||||||
|
export const statusIconMap: Record<string, string> = {
|
||||||
|
"待签收.svg": daiQianShou,
|
||||||
|
"待CEH.svg": daiCEH,
|
||||||
|
"进行中.svg": jinXingZhong,
|
||||||
|
"完成.svg": wanCheng,
|
||||||
|
"未通过.svg": weiTongGuo,
|
||||||
|
"已终止.svg": yiZhongZhi,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 按文件名取打包后的图标 URL;取不到返回 undefined(<img> 不渲染 broken icon)。 */
|
||||||
|
export function resolveStatusIcon(name?: string | null): string | undefined {
|
||||||
|
if (!name) return undefined;
|
||||||
|
return statusIconMap[name];
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="11" fill="#1eb07f"/>
|
||||||
|
<path d="M7.5 12.3 10.5 15.3 16.5 9" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 284 B |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="11" fill="#8c8c8c"/>
|
||||||
|
<rect x="8.7" y="8.7" width="6.6" height="6.6" rx="1.4" fill="#fff"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 225 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="11" fill="#2f9acc"/>
|
||||||
|
<circle cx="11" cy="11" r="3.2" stroke="#fff" stroke-width="1.8" fill="none"/>
|
||||||
|
<path d="M13.4 13.4 16.2 16.2" stroke="#fff" stroke-width="1.8" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 325 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="11" fill="#0062d9"/>
|
||||||
|
<rect x="7.6" y="7.8" width="8.8" height="9.6" rx="1.6" stroke="#fff" stroke-width="1.5" fill="none"/>
|
||||||
|
<path d="M9.8 7.8v-.5a1 1 0 0 1 1-1h2.4a1 1 0 0 1 1 1v.5" stroke="#fff" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M9.8 11h4.4M9.8 13.6h2.8" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 507 B |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="11" fill="#cf1322"/>
|
||||||
|
<path d="M8.8 8.8 15.2 15.2M15.2 8.8 8.8 15.2" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 258 B |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="11" fill="#d97b00"/>
|
||||||
|
<path d="M10.2 8.4 15.4 12l-5.2 3.6z" fill="#fff" stroke="#fff" stroke-width="1.2" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 264 B |
@@ -14,7 +14,7 @@ models:
|
|||||||
display_name: DeepSeek Chat
|
display_name: DeepSeek Chat
|
||||||
use: langchain_openai:ChatOpenAI
|
use: langchain_openai:ChatOpenAI
|
||||||
model: deepseek-chat
|
model: deepseek-chat
|
||||||
api_key: sk-e1c22b7931dc446f8b67e57878edd105
|
api_key: sk-3fee562f834a4c08bb0d471ef44cb445
|
||||||
base_url: https://api.deepseek.com
|
base_url: https://api.deepseek.com
|
||||||
request_timeout: 600.0
|
request_timeout: 600.0
|
||||||
max_retries: 2
|
max_retries: 2
|
||||||
@@ -27,7 +27,7 @@ models:
|
|||||||
display_name: DeepSeek V4 Flash
|
display_name: DeepSeek V4 Flash
|
||||||
use: langchain_openai:ChatOpenAI
|
use: langchain_openai:ChatOpenAI
|
||||||
model: deepseek-v4-flash
|
model: deepseek-v4-flash
|
||||||
api_key: sk-e1c22b7931dc446f8b67e57878edd105
|
api_key: sk-3fee562f834a4c08bb0d471ef44cb445
|
||||||
base_url: https://api.deepseek.com
|
base_url: https://api.deepseek.com
|
||||||
request_timeout: 600.0
|
request_timeout: 600.0
|
||||||
max_retries: 2
|
max_retries: 2
|
||||||
|
|||||||
Reference in new issue
Block a user