diff --git a/src/api/workOrder.ts b/src/api/workOrder.ts
index 416a4f5..9a2fa0f 100644
--- a/src/api/workOrder.ts
+++ b/src/api/workOrder.ts
@@ -37,7 +37,7 @@ export function updateWorkOrder(data) {
export function dispatchWorkOrder(data) {
return request({
- url: `/iot/ioTworkOrder/dispat`,
+ url: `/iot/ioTworkOrder/dispatch`,
method: 'post',
data
});
@@ -45,10 +45,11 @@ export function dispatchWorkOrder(data) {
//开始执行工单
-export function startWorkOrder(id) {
+export function startWorkOrder(data) {
return request({
- url: `/iot/ioTworkOrder/start/${id}`,
- method: 'put',
+ url: `/iot/ioTworkOrder/start`,
+ method: 'post',
+ data
});
}
diff --git a/src/components/SystemSetting/AlarmSettingsManagement.tsx b/src/components/SystemSetting/AlarmSettingsManagement.tsx
index f9e7940..3784a8f 100644
--- a/src/components/SystemSetting/AlarmSettingsManagement.tsx
+++ b/src/components/SystemSetting/AlarmSettingsManagement.tsx
@@ -30,7 +30,7 @@ import {
} from '../../api/systemSetting';
import { useSelector } from 'react-redux';
import { RootState } from '@/src/store';
-import utils, { workOrderTypeOptions, getWorkOrderTypeText, errorLevelOptions, LEVEL_TAG_COLOR } from '@/lib/utils';
+import utils, { errorSourceOptions, getErrorSourceText } from '@/lib/utils';
const { Option } = Select;
@@ -121,6 +121,7 @@ const AlarmModelManagement: React.FC = () => {
form.setFieldsValue({
errorCode: record.errorCode,
modelId: record.modelId,
+ sourceType: record.sourceType,
autoGenerateOrder: record.autoGenerateOrder
});
setModalVisible(true);
@@ -183,7 +184,8 @@ const AlarmModelManagement: React.FC = () => {
// 后端要求字段
errorCode: values.errorCode,
modelId: values.modelId,
- autoGenerateOrder: values.autoGenerateOrder ?? false
+ autoGenerateOrder: values.autoGenerateOrder ?? false,
+ sourceType: values.sourceType ?? 1
};
const res = await saveAlarmOrderConfigApi(submitParams);
if (res.code === 200 && res.data === true) {
@@ -200,6 +202,12 @@ const AlarmModelManagement: React.FC = () => {
// 表格列配置
const columns = [
{ title: '错误编码', dataIndex: 'errorCode', key: 'errorCode' },
+ {
+ title: '错误来源',
+ dataIndex: 'sourceType',
+ key: 'sourceType',
+ render: (val: string) => getErrorSourceText(val)
+ },
{
title: '关联工单模型',
dataIndex: 'modelId',
@@ -284,6 +292,15 @@ const AlarmModelManagement: React.FC = () => {
+
+
+
+
+
{/* 是否自动生成工单 */}
{
map[key] = alarmLevelConfig[key].color;
return map;
@@ -42,6 +41,70 @@ const levelText = Object.keys(alarmLevelConfig).reduce((map, key) => {
return map;
}, {});
+// 级别颜色配置
+const levelColorMap = {
+ ERROR: '#FF4D4F', // 错误 红
+ WARNING: '#FA8C16', // 警告 橙
+ INFO: '#1890FF', // 信息 蓝
+};
+
+
+// 快速根据 value 获取 label
+const getLevelLabel = (val) => {
+ const item = errorLevelOptions.find(opt => opt.value === val);
+ return item?.label || '未知';
+};
+
+/**
+ * 通用告警级别标签组件
+ * @param level 接口返回字符串 INFO / WARNING / ERROR
+ * @param size small表格 | large详情弹窗
+ */
+const AlarmLevelTag = ({ level, size = 'small' }) => {
+ const color = levelColorMap[level] || '#86909C';
+ const text = getLevelLabel(level);
+
+ // 详情大标签
+ if (size === 'large') {
+ return (
+
+ {text}
+
+ );
+ }
+
+ // 表格小标签
+ return (
+
+ {text}
+
+ );
+};
+
export default function AlarmCenterPage() {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
@@ -55,6 +118,8 @@ export default function AlarmCenterPage() {
const [messageApi, contextHolder] = message.useMessage();
const [todayData, setTodayData] = useState({});
const [yesterdayData, setYesterdayData] = useState({});
+ const { stationId } = useSelector((state: RootState) => state.station);
+ const { userInfo } = useSelector((state: RootState) => state.user);
const [editModalVisible, setEditModalVisible] = useState(false);
const [editForm] = Form.useForm();
@@ -86,8 +151,8 @@ export default function AlarmCenterPage() {
const fetchList = async () => {
setLoading(true);
try {
- const res = await getAlarmList({ pageNum, pageSize, ...queryParams });
- if (res.code === 0) {
+ const res = await getAlarmList({ pageNum, pageSize, ...queryParams, siteId: stationId });
+ if (res.code === 200) {
setAlarmList(res.rows || []);
setTotal(res.total || 0);
}
@@ -189,7 +254,7 @@ export default function AlarmCenterPage() {
fetchList();
- }, [pageNum]);
+ }, [pageNum, stationId]);
useEffect(() => {
fetchTodayAndYesterdayStat();
fetchStat();
@@ -201,7 +266,6 @@ export default function AlarmCenterPage() {
{
title: '告警编号',
dataIndex: 'alarmNo',
- width: 180,
render: (text) => {text}
},
{
@@ -218,7 +282,7 @@ export default function AlarmCenterPage() {
{
title: '设备名称',
dataIndex: 'deviceName',
- width: 160
+ width: 280
},
{
title: '告警类型',
@@ -230,11 +294,8 @@ export default function AlarmCenterPage() {
title: '告警级别',
dataIndex: 'alarmLevel',
width: 100,
- render: (l) => (
-
- {levelText[l]}
-
- )
+ render: (l) =>
+
},
{
title: '告警时间',
@@ -379,10 +440,9 @@ export default function AlarmCenterPage() {
priorityLevel: currentAlarm.alarmLevel === 1 ? 1 : 2, // 严重=高,其他=中
deviceId: currentAlarm.deviceId || '',
deviceName: currentAlarm.deviceName || '',
- deviceType: '', // 没有就传空
- siteId: '',
- siteName: '',
- orgId: '',
+ deviceType: currentAlarm.deviceType, // 没有就传空
+ siteId: stationId,
+ orgId: userInfo?.orgId || '',
assigneeId: '',
assigneeName: '',
collaboratorIds: '',
@@ -752,7 +812,7 @@ export default function AlarmCenterPage() {
title="告警详情"
open={drawerVisible}
onClose={() => setDrawerVisible(false)}
- width={420}
+ width={480}
destroyOnClose
>
@@ -767,9 +827,7 @@ export default function AlarmCenterPage() {
{currentAlarm.alarmTitle}
-
- {levelText[currentAlarm.alarmLevel]}
-
+
告警编号:{currentAlarm.alarmNo}
@@ -795,7 +853,6 @@ export default function AlarmCenterPage() {
return {handleStatusMap[status] || '-'};
})()}
- {currentAlarm.handleUserName || '-'}
{/* 告警描述 */}
@@ -902,11 +959,8 @@ export default function AlarmCenterPage() {
name="alarmLevel"
rules={[{ required: true, message: '请选择告警级别' }]}
>
-
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index 1a7159a..f91ae8a 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -237,12 +237,28 @@ export function dataUrlToFile(dataUrl, fileName) {
// 错误来源
-export const errorSourceOptions = [
- { label: '无人机', value: 'UAV' },
- { label: '割草机', value: 'MOWER' },
- { label: '其他', value: 'OTHERS' },
+export const ERROR_SOURCE = {
+ UAV: 'UAV',
+ MOWER: 'MOWER',
+ OTHERS: 'OTHERS'
+} as const;
-];
+export type ErrorSourceType = typeof ERROR_SOURCE[keyof typeof ERROR_SOURCE];
+
+export const errorSourceOptions: Array<{
+ value: ErrorSourceType;
+ label: string;
+}> = [
+ { label: '无人机', value: ERROR_SOURCE.UAV },
+ { label: '割草机', value: ERROR_SOURCE.MOWER },
+ { label: '其他', value: ERROR_SOURCE.OTHERS },
+ ];
+
+export const getErrorSourceText = (source?: ErrorSourceType | string): string => {
+ if (!source) return "";
+ const target = errorSourceOptions.find((item) => item.value === source);
+ return target?.label ?? String(source);
+};
// 错误等级
export const errorLevelOptions = [
@@ -296,9 +312,9 @@ export const workOrderTypeOptions: Array<{
{ value: WORK_ORDER_TYPE.UAV_ERROR, label: "无人机故障" },
{ value: WORK_ORDER_TYPE.INSPECTION_TASK, label: "巡检" },
{ value: WORK_ORDER_TYPE.COMPONENT_DEFECT, label: "光伏组件故障" },
- { value: WORK_ORDER_TYPE.CLEAN_TASK, label: "清洗任务" },
- { value: WORK_ORDER_TYPE.MAINTAIN_TASK, label: "维护任务" },
- { value: WORK_ORDER_TYPE.REPAIR_TASK, label: "维修任务" },
+ { value: WORK_ORDER_TYPE.CLEAN_TASK, label: "清洗" },
+ { value: WORK_ORDER_TYPE.MAINTAIN_TASK, label: "维护" },
+ { value: WORK_ORDER_TYPE.REPAIR_TASK, label: "维修" },
{ value: WORK_ORDER_TYPE.OTHER, label: "其他" },
];
diff --git a/src/pages/WorkOrder.tsx b/src/pages/WorkOrder.tsx
index 905005b..6185410 100644
--- a/src/pages/WorkOrder.tsx
+++ b/src/pages/WorkOrder.tsx
@@ -33,18 +33,19 @@ import {
getWorkOrderApi,
getWorkOrderDetailApi,
updateWorkOrder,
- dispatchWorkOrder,
+ startWorkOrder,
completeWorkOrder,
suspendWorkOrder,
deleteWorkOrder
} from '../api/workOrder';
+import { getSiteDevice } from '../api/device';
import { UniversalLineChart } from '../components/recharts';
import { orderTypeConfig, sourceTypeMap } from '../constants';
import { useSelector } from 'react-redux';
import { RootState } from '../store';
import { getUser } from '../api/user';
-import utils from '../lib/utils';
+import utils, { getWorkOrderTypeText, workOrderTypeOptions } from '../lib/utils';
const { Option } = Select;
const { Search } = Input;
@@ -78,6 +79,7 @@ const WorkOrderPage = () => {
const [workOrderTotal, setWorkOrderTotal] = useState(0);
const [currentDetail, setCurrentDetail] = useState(null);
const [userList, setUserList] = useState([]);
+ const [deviceList, setDeviceList] = useState([]);
// 从 redux 获取用户信息
const { userInfo } = useSelector((state: RootState) => state.user);
@@ -108,6 +110,23 @@ const WorkOrderPage = () => {
}
};
+ // 获取设备列表
+ const fetchDeviceList = async () => {
+ try {
+ const res: any = await getSiteDevice({
+ siteId: userInfo?.siteId,
+ pageNum: 1,
+ pageSize: 10000,
+ orgId: userInfo?.orgId
+ });
+ if (res.code == 200) {
+ setDeviceList(res.rows || []);
+ }
+ } catch (error) {
+ console.error('获取设备列表失败', error);
+ }
+ };
+
// 统计数据
const stats = [
{ title: '今日新增工单', value: 18, subValue: '+3', subText: '较昨日', icon: , bg: '#e6f7ff' },
@@ -241,20 +260,24 @@ const WorkOrderPage = () => {
setEditModalVisible(true);
};
- // 打开派发工单弹窗
- const openDispatchModal = () => {
- if (!selectedRowKey) return messageApi.warning('请先选择一条工单');
- if (!isAdmin) return messageApi.error('只有管理员才可以派发工单');
+ // 打开执行工单弹窗
+ const openExecuteModal = () => {
+ if (selectedRowKeys.length > 0) {
+ // 批量执行
+ form.setFieldsValue({
+ orderIds: selectedRowKeys
+ });
+ } else if (selectedRowKey) {
+ // 单个执行
+ form.setFieldsValue({
+ orderIds: [selectedRowKey]
+ });
+ } else {
+ return messageApi.warning('请先选择一条工单');
+ }
- fetchUserList();
- form.setFieldsValue({
- orderId: selectedRowKey,
- assigneeId: currentDetail?.assigneeId ?? '',
- assigneeName: currentDetail?.assigneeName || '',
- planStartTime: currentDetail?.planStartTime ? dayjs(currentDetail.planStartTime) : null,
- planEndTime: currentDetail?.planEndTime ? dayjs(currentDetail.planEndTime) : null,
- deadlineTime: currentDetail?.deadlineTime ? dayjs(currentDetail.deadlineTime) : null,
- });
+
+ fetchDeviceList();
setDispatchModalVisible(true);
};
@@ -280,25 +303,21 @@ const WorkOrderPage = () => {
}
};
- // 提交派发工单
- const submitDispatch = async (values) => {
+ // 提交执行工单
+ const submitExecute = async (values) => {
try {
+ // 调用 startWorkOrder 接口,传递 ids 和 选择的设备 id
const params = {
- orderId: values.orderId,
- assigneeId: values.assigneeId ?? '',
- assigneeName: values.assigneeName,
- collaboratorIds: '',
- collaboratorNames: values.collaboratorNames?.join(',') || '',
- planStartTime: values.planStartTime?.format('YYYY-MM-DDTHH:mm:ss') || '',
- planEndTime: values.planEndTime?.format('YYYY-MM-DDTHH:mm:ss') || '',
- deadlineTime: values.deadlineTime?.format('YYYY-MM-DDTHH:mm:ss') || '',
+ ids: values.orderIds,
+ deviceId: values.deviceId
};
- await dispatchWorkOrder(params);
- messageApi.success('工单派发成功');
+ await startWorkOrder(params);
+ messageApi.success('工单执行成功');
setDispatchModalVisible(false);
+ setSelectedRowKeys([]); // 清空选中
getWorkOrderList();
} catch (error) {
- messageApi.error('工单派发失败');
+ messageApi.error('工单执行失败');
console.error(error);
}
};
@@ -517,20 +536,32 @@ const WorkOrderPage = () => {
工单列表
(共 {workOrderTotal} 条)
{selectedRowKeys.length > 0 && (
-
- }>
- 批量删除
+ <>
+
+ }>
+ 批量删除
+
+
+ }
+ onClick={openExecuteModal}
+ >
+ 批量执行 ({selectedRowKeys.length})
-
+ >
+
)}
}
bodyStyle={{ padding: 0 }}
style={{ ...cardStyle, marginBottom: 8 }}
>
+
{
legend={{ position: 'right', layout: 'vertical' }}
height={260}
/>
-
+
@@ -623,14 +654,14 @@ const WorkOrderPage = () => {
{currentDetail?.orderTitle || '暂无标题'}
{currentDetail?.priorityLevel && (
- {priorityConfig[currentDetail.priorityLevel].label}优先级
+ {currentDetail.priorityLevel}
)}
来源:{sourceTypeMap[currentDetail?.sourceType] || '--'}
- 工单类型:{orderTypeConfig[currentDetail?.orderType] || '--'}
+ 工单类型:{getWorkOrderTypeText(currentDetail?.orderType)}
负责人:{currentDetail?.assigneeName || '--'}
协同人员:{currentDetail?.collaboratorNames || '无'}
计划时间:
@@ -672,7 +703,7 @@ const WorkOrderPage = () => {
}}>
{item.active ? : item.step}
- {item.label}
+ {item?.label}
))}
@@ -683,12 +714,11 @@ const WorkOrderPage = () => {
}
>
- 派发工单
+ 执行工单
} block onClick={openEditModal} style={{ borderRadius: 8, height: 36, fontWeight: 600 }}>修改
@@ -781,9 +811,8 @@ const WorkOrderPage = () => {
-
-
-
+
+
@@ -800,30 +829,49 @@ const WorkOrderPage = () => {
- {/* 派发工单弹窗 */}
- setDispatchModalVisible(false)} footer={null} width={550}>
-