diff --git a/src/api/l2/sendJob.js b/src/api/l2/sendJob.js new file mode 100644 index 0000000..22ce6a7 --- /dev/null +++ b/src/api/l2/sendJob.js @@ -0,0 +1,36 @@ +import request from '@/utils/L2Request' + +// 创建发送任务 +export function createSendJob(data) { + return request({ + url: '/business/sendJob', + method: 'post', + data + }) +} + +// 执行发送任务 +export function executeSendJob(jobId) { + return request({ + url: `/business/sendJob/${jobId}/execute`, + method: 'post' + }) +} + +// 查询发送任务列表(分页) +export function listSendJob(query) { + // 若你后端是 GET /business/sendJob/list(现状),这里用 params + return request({ + url: '/business/sendJob/list', + method: 'get', + params: query + }) +} + +// 获取发送任务详情 +export function getSendJob(jobId) { + return request({ + url: `/business/sendJob/${jobId}`, + method: 'get' + }) +} diff --git a/src/api/l2/sendTemplate.js b/src/api/l2/sendTemplate.js new file mode 100644 index 0000000..b152e4d --- /dev/null +++ b/src/api/l2/sendTemplate.js @@ -0,0 +1,45 @@ +import request from '@/utils/L2Request' + +// 获取发送模板(含明细) +export function getSendTemplate(templateCode) { + return request({ + url: `/business/sendTemplate/${templateCode}`, + method: 'get' + }) +} + +// 获取最近一次成功发送(用于推荐值 + 上次发送时间显示) +export function getLastSuccess(groupType) { + return request({ + url: '/business/sendJob/lastSuccess', + method: 'get', + params: { groupType } + }) +} + +// 更新模板主表(deviceName 等) +export function updateSendTemplate(data) { + return request({ + url: '/business/sendTemplate', + method: 'put', + data + }) +} + +// 批量更新模板明细(address/defaultValueRaw/enabled 等) +export function updateSendTemplateItems(data) { + return request({ + url: '/business/sendTemplate/items', + method: 'put', + data + }) +} + +// 批量保存模板明细(新增/更新/删除)- 仅提交变更,避免请求体过大 +export function batchSaveSendTemplateItems(data) { + return request({ + url: '/business/sendTemplate/items/batchSave', + method: 'put', + data + }) +} diff --git a/src/api/l2/setupValue.js b/src/api/l2/setupValue.js new file mode 100644 index 0000000..82eabc3 --- /dev/null +++ b/src/api/l2/setupValue.js @@ -0,0 +1,20 @@ +import request from '@/utils/L2Request' + +// 获取 DRIVE 设定值(最新成功发送) +export function getDriveSetupValue() { + return request({ + url: '/business/sendJob/lastSuccess', + method: 'get', + params: { groupType: 'DRIVE' } + }) +} + +// 获取 FURNACE 设定值(最新成功发送) +export function getFurnaceSetupValue() { + return request({ + url: '/business/sendJob/lastSuccess', + method: 'get', + params: { groupType: 'FURNACE' } + }) +} + diff --git a/src/api/l2/template.js b/src/api/l2/template.js new file mode 100644 index 0000000..d1d319e --- /dev/null +++ b/src/api/l2/template.js @@ -0,0 +1,13 @@ +import request from '@/utils/l2-request' + +/** + * 按模板编码查询发送模板(含明细) + * @param {string} templateCode 模板编码,如 FURNACE_DEFAULT + */ +export function getSendTemplate(templateCode) { + return request({ + url: `/business/sendTemplate/${templateCode}`, + method: 'get' + }) +} + diff --git a/src/components/FloatingPanel.vue b/src/components/FloatingPanel.vue new file mode 100644 index 0000000..731b6e6 --- /dev/null +++ b/src/components/FloatingPanel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/l2/report/pdo.vue b/src/views/l2/report/pdo.vue index 2f0b786..350d8ec 100644 --- a/src/views/l2/report/pdo.vue +++ b/src/views/l2/report/pdo.vue @@ -6,8 +6,8 @@
Performance Report - Please select time range to view data - + Displaying data for the last month by default +
Performance @@ -70,14 +70,14 @@ {{ displayTimeRange }} - Reselect Time + Change Time Range - + + :summary="reportSummary" :dataset="reportDetail" :columns="columns" @@ -97,7 +97,7 @@ export default { data() { return { loading: false, - hasSelectedTime: false, + hasSelectedTime: true, // Directly show report content timeRange: { startTime: '', endTime: '' @@ -123,7 +123,31 @@ export default { } } }, + created() { + this.setDefaultTimeRangeAndFetch() + }, methods: { + setDefaultTimeRangeAndFetch() { + const end = new Date() + const start = new Date() + start.setMonth(start.getMonth() - 1) + + this.timeRange.endTime = this.formatDate(end) + this.timeRange.startTime = this.formatDate(start) + + this.fetchReportData() + }, + + formatDate(date) { + const year = date.getFullYear() + const month = (date.getMonth() + 1).toString().padStart(2, '0') + const day = date.getDate().toString().padStart(2, '0') + const hours = date.getHours().toString().padStart(2, '0') + const minutes = date.getMinutes().toString().padStart(2, '0') + const seconds = date.getSeconds().toString().padStart(2, '0') + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` + }, + handleTimeReset() { this.timeRange = { startTime: '', @@ -146,9 +170,7 @@ export default { }, handleReturn() { this.hasSelectedTime = false - this.handleTimeReset() - this.reportSummary = [] - this.reportDetail = [] + // Do not reset time, so user can see the previous selection }, async fetchReportData() { this.loading = true @@ -157,7 +179,7 @@ export default { startTime: this.timeRange.startTime, endTime: this.timeRange.endTime, pageNum: 1, - pageSize: 1000 + pageSize: 1000 // Assuming we fetch all data for the report } const res = await getReportSummary(queryParams) this.reportSummary = [ @@ -309,4 +331,4 @@ export default { } } } - \ No newline at end of file + diff --git a/src/views/l2/report/roller.vue b/src/views/l2/report/roller.vue index bc15eba..81bdd59 100644 --- a/src/views/l2/report/roller.vue +++ b/src/views/l2/report/roller.vue @@ -6,8 +6,8 @@
Roll Change Report - Please select time range to view data - + Displaying data for the last month by default +
Roll Change @@ -23,8 +23,6 @@
- - - - Query - Reset -
@@ -62,22 +56,17 @@
Report Type: - Roll Change Report - | Time Range: - {{ displayTimeRange }}
- Reselect Time - + Change Time Range
:summary="reportSummary" :dataset="reportDetail" :columns="columns" @@ -97,7 +86,7 @@ export default { data() { return { loading: false, - hasSelectedTime: false, + hasSelectedTime: true, timeRange: { startTime: '', endTime: '' @@ -114,16 +103,38 @@ export default { displayTimeRange() { if (!this.canQuery) return '-' return `${this.timeRange.startTime} to ${this.timeRange.endTime}` - // 至 }, overviewInfo() { return { - reportLabel: 'Roll Change Report', // 换辊报表 + reportLabel: 'Roll Change Report', rangeText: this.displayTimeRange } } }, + created() { + this.setDefaultTimeRangeAndFetch() + }, methods: { + setDefaultTimeRangeAndFetch() { + const end = new Date() + const start = new Date() + start.setMonth(start.getMonth() - 1) + + this.timeRange.endTime = this.formatDateTime(end) + this.timeRange.startTime = this.formatDateTime(start) + + this.fetchReportData() + }, + formatDateTime(date) { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + const hours = String(date.getHours()).padStart(2, '0') + const minutes = String(date.getMinutes()).padStart(2, '0') + const seconds = String(date.getSeconds()).padStart(2, '0') + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` + }, + handleTimeReset() { this.timeRange = { startTime: '', @@ -132,11 +143,11 @@ export default { }, async handleTimeConfirm() { if (!this.canQuery) { - this.$message.warning('Please select complete time range') // 请选择完整的时间范围 + this.$message.warning('Please select complete time range') return } if (new Date(this.timeRange.startTime) > new Date(this.timeRange.endTime)) { - this.$message.warning('Start time cannot be later than end time') // 开始时间不能晚于结束时间 + this.$message.warning('Start time cannot be later than end time') return } this.hasSelectedTime = true @@ -144,9 +155,6 @@ export default { }, handleReturn() { this.hasSelectedTime = false - this.handleTimeReset() - this.reportSummary = [] - this.reportDetail = [] }, async fetchReportData() { this.loading = true @@ -162,26 +170,26 @@ export default { ...item })) this.columns = [ - { label: 'Change ID', prop: 'changeid' }, // 换辊号 - { label: 'Roll ID', prop: 'rollid' }, // 轧辊号 - { label: 'Type', prop: 'type' }, // 类型 - { label: 'Position', prop: 'position' }, // 位置 - { label: 'Diameter', prop: 'diameter' }, // 直径 - { label: 'Roughness', prop: 'rough' }, // 粗糙度 - { label: 'Crown', prop: 'crown' }, // 凸度 - { label: 'Rolled Length', prop: 'rolledLength' }, // 轧制长度 - { label: 'Rolled Weight', prop: 'rolledWeight' }, // 轧制重量 - { label: 'Rolled Count', prop: 'rolledCount' }, // 轧制次数 - { label: 'Install Time', prop: 'instalTime' }, // 上线时间 - { label: 'Uninstall Time', prop: 'deinstalTime' } // 下线时间 + { label: 'Change ID', prop: 'changeid' }, + { label: 'Roll ID', prop: 'rollid' }, + { label: 'Type', prop: 'type' }, + { label: 'Position', prop: 'position' }, + { label: 'Diameter', prop: 'diameter' }, + { label: 'Roughness', prop: 'rough' }, + { label: 'Crown', prop: 'crown' }, + { label: 'Rolled Length', prop: 'rolledLength' }, + { label: 'Rolled Weight', prop: 'rolledWeight' }, + { label: 'Rolled Count', prop: 'rolledCount' }, + { label: 'Install Time', prop: 'instalTime' }, + { label: 'Uninstall Time', prop: 'deinstalTime' } ] this.reportSummary = [ - { label: 'Data Count', value: this.reportDetail.length }, // 数据条数 - { label: 'Time Range', value: this.displayTimeRange } // 时间范围 + { label: 'Data Count', value: this.reportDetail.length }, + { label: 'Time Range', value: this.displayTimeRange } ] } catch (error) { console.error(error) - this.$message.error('Failed to fetch report data') // 获取报表数据失败 + this.$message.error('Failed to fetch report data') } finally { this.loading = false } @@ -300,4 +308,4 @@ export default { } } } - \ No newline at end of file + diff --git a/src/views/l2/report/stop.vue b/src/views/l2/report/stop.vue index 62a1932..8355abf 100644 --- a/src/views/l2/report/stop.vue +++ b/src/views/l2/report/stop.vue @@ -6,8 +6,8 @@
Stoppage Report - Please select time range to view data - + Displaying data for the last month by default +
Stoppage @@ -18,13 +18,10 @@
Please select query date range -
- - - - Query - Reset -
@@ -62,22 +55,17 @@
Report Type: - Stoppage Report - | Time Range: - {{ displayTimeRange }}
- Reselect Time - + Change Date Range
:summary="reportSummary" :dataset="reportDetail" :columns="columns" @@ -97,7 +85,7 @@ export default { data() { return { loading: false, - hasSelectedTime: false, + hasSelectedTime: true, timeRange: { startTime: '', endTime: '' @@ -105,14 +93,14 @@ export default { reportSummary: [], reportDetail: [], columns: [ - { label: 'Coil ID', prop: 'coilid' }, // 钢卷号 - { label: 'Shift', prop: 'shift' }, // 班次号 - { label: 'Group', prop: 'area' }, // 组 - { label: 'Start Time', prop: 'startDate' }, // 开始时间 - { label: 'End Time', prop: 'endDate' }, // 结束时间 - { label: 'Duration [min]', prop: 'duration' }, // 持续时间[分钟] - { label: 'Stoppage Type', prop: 'unit' }, // 停机类型 - { label: 'Remark', prop: 'remark' } // 备注 + { label: 'Coil ID', prop: 'coilid' }, + { label: 'Shift', prop: 'shift' }, + { label: 'Group', prop: 'area' }, + { label: 'Start Time', prop: 'startDate' }, + { label: 'End Time', prop: 'endDate' }, + { label: 'Duration [min]', prop: 'duration' }, + { label: 'Stoppage Type', prop: 'unit' }, + { label: 'Remark', prop: 'remark' } ] } }, @@ -123,16 +111,35 @@ export default { displayTimeRange() { if (!this.canQuery) return '-' return `${this.timeRange.startTime} to ${this.timeRange.endTime}` - // 至 }, overviewInfo() { return { - reportLabel: 'Stoppage Report', // 停机报表 + reportLabel: 'Stoppage Report', rangeText: this.displayTimeRange } } }, + created() { + this.setDefaultDateRangeAndFetch() + }, methods: { + setDefaultDateRangeAndFetch() { + const end = new Date() + const start = new Date() + start.setMonth(start.getMonth() - 1) + + this.timeRange.endTime = this.formatDate(end) + this.timeRange.startTime = this.formatDate(start) + + this.fetchReportData() + }, + formatDate(date) { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + return `${year}-${month}-${day}` + }, + handleTimeReset() { this.timeRange = { startTime: '', @@ -141,11 +148,11 @@ export default { }, async handleTimeConfirm() { if (!this.canQuery) { - this.$message.warning('Please select complete date range') // 请选择完整的日期范围 + this.$message.warning('Please select complete date range') return } if (new Date(this.timeRange.startTime) > new Date(this.timeRange.endTime)) { - this.$message.warning('Start date cannot be later than end date') // 开始日期不能晚于结束日期 + this.$message.warning('Start date cannot be later than end date') return } this.hasSelectedTime = true @@ -153,9 +160,6 @@ export default { }, handleReturn() { this.hasSelectedTime = false - this.handleTimeReset() - this.reportSummary = [] - this.reportDetail = [] }, async fetchReportData() { this.loading = true @@ -171,14 +175,14 @@ export default { const res2 = await getStoppageSummary(queryParams) this.reportSummary = [ - { label: 'Statistics Range', value: this.displayTimeRange }, // 统计区间 - { label: 'Stoppage Count', value: res2.data?.[0] || 0 }, // 停机次数 - { label: 'Stoppage Duration [hours]', value: res2.data?.[1] || 0 }, // 停机时长[小时] - { label: 'Operation Rate', value: (res2.data?.[2] || 0) + ' %' } // 作业率 + { label: 'Statistics Range', value: this.displayTimeRange }, + { label: 'Stoppage Count', value: res2.data?.[0] || 0 }, + { label: 'Stoppage Duration [hours]', value: res2.data?.[1] || 0 }, + { label: 'Operation Rate', value: (res2.data?.[2] || 0) + ' %' } ] } catch (error) { console.error(error) - this.$message.error('Failed to fetch report data') // 获取报表数据失败 + this.$message.error('Failed to fetch report data') } finally { this.loading = false } @@ -257,7 +261,7 @@ export default { .selector-content { width: 100%; - max-width: 600px; + max-width: 640px; padding: 0 20px; } } @@ -297,4 +301,4 @@ export default { } } } - \ No newline at end of file + diff --git a/src/views/l2/send/components/FurnaceHistoryPanel.vue b/src/views/l2/send/components/FurnaceHistoryPanel.vue new file mode 100644 index 0000000..0ca3075 --- /dev/null +++ b/src/views/l2/send/components/FurnaceHistoryPanel.vue @@ -0,0 +1,138 @@ + + + + + + diff --git a/src/views/l2/send/drive.vue b/src/views/l2/send/drive.vue new file mode 100644 index 0000000..0c0dd4e --- /dev/null +++ b/src/views/l2/send/drive.vue @@ -0,0 +1,316 @@ + + + + + diff --git a/src/views/l2/send/furnace.vue b/src/views/l2/send/furnace.vue new file mode 100644 index 0000000..1060242 --- /dev/null +++ b/src/views/l2/send/furnace.vue @@ -0,0 +1,543 @@ + + + + + diff --git a/src/views/l2/send/history.vue b/src/views/l2/send/history.vue new file mode 100644 index 0000000..100779b --- /dev/null +++ b/src/views/l2/send/history.vue @@ -0,0 +1,141 @@ + + + + + + diff --git a/src/views/l2/setup/index.vue b/src/views/l2/setup/index.vue index b845441..8f15781 100644 --- a/src/views/l2/setup/index.vue +++ b/src/views/l2/setup/index.vue @@ -45,7 +45,7 @@ - +
@@ -124,7 +124,7 @@ export default { padding: 15px; background: #e8e8e8; border-bottom: 1px solid #d4d4d4; - + h3 { margin: 0; font-size: 16px; @@ -137,23 +137,23 @@ export default { border-right: none; flex: 1; overflow: hidden; - + ::v-deep .el-menu-item { height: 48px; line-height: 48px; font-size: 13px; color: #666; - + &.is-active { background-color: #f0f0f0; color: #333; border-right: 2px solid #999; } - + &:hover { background-color: #f5f5f5; } - + i { margin-right: 8px; font-size: 14px; @@ -177,4 +177,4 @@ export default { display: flex; flex-direction: column; } - \ No newline at end of file + diff --git a/src/views/l2/track/components/LatestSetValues.vue b/src/views/l2/track/components/LatestSetValues.vue new file mode 100644 index 0000000..5b3702b --- /dev/null +++ b/src/views/l2/track/components/LatestSetValues.vue @@ -0,0 +1,114 @@ + + + + + + diff --git a/src/views/l2/track/rect.vue b/src/views/l2/track/rect.vue index 585a109..442da82 100644 --- a/src/views/l2/track/rect.vue +++ b/src/views/l2/track/rect.vue @@ -1,2510 +1,2566 @@ - - - - + .ws-status-right .el-button { + min-width: 140px; + height: 34px; + font-weight: 600; + } + + .ws-status-bar i { + font-size: 18px; + color: #606266; + cursor: pointer; + } + + /* 分区头部增强 */ + .section-header { + display: flex; + justify-content: space-between; + align-items: center; + } + + .section-info { + font-size: 13px; + color: #67c23a; + font-weight: 500; + } + + /* 信号信息面板 */ + .signal-info { + padding: 10px 0; + } + + .signal-info.signal-warning { + background: #fef0f0; + padding: 15px; + border-radius: 4px; + border: 1px solid #fde2e2; + } + + .signal-info.signal-success { + background: #f0f9ff; + padding: 15px; + border-radius: 4px; + border: 1px solid #c6e2ff; + } + + .signal-info.signal-complete { + background: #f0f9ff; + padding: 15px; + border-radius: 4px; + border: 1px solid #b3e19d; + } + + .signal-detail { + margin-top: 10px; + font-size: 13px; + line-height: 2; + } + + .signal-detail div { + padding: 4px 0; + } + + .text-warning { + color: #e6a23c; + font-weight: 600; + font-size: 14px; + } + + .text-success { + color: #67c23a; + font-weight: 600; + font-size: 14px; + } + + /* 计算结果头部 */ + .calc-result-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; + padding-bottom: 10px; + border-bottom: 1px solid #ebeef5; + font-size: 14px; + } + + /* 生产计划详情 */ + .plan-detail-content { + overflow-y: auto; + } + + /* 位置信息提示卡片 */ + .position-alert { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 15px; + margin-bottom: 15px; + background: #f0f9ff; + border: 1px solid #b3d8ff; + border-left: 4px solid #409eff; + border-radius: 4px; + } + + .position-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + background: #409eff; + border-radius: 50%; + color: #fff; + font-size: 20px; + flex-shrink: 0; + } + + .position-info { + flex: 1; + } + + .position-label { + font-size: 12px; + color: #909399; + margin-bottom: 4px; + } + + .position-name { + font-size: 16px; + font-weight: 600; + color: #303133; + margin-bottom: 2px; + } + + .position-code { + font-size: 12px; + color: #606266; + font-family: 'Courier New', monospace; + } + + .plan-time-info { + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid #ebeef5; + } + + .info-subtitle { + font-size: 13px; + font-weight: 600; + color: #606266; + margin-bottom: 10px; + } + + .panel-title { + display: flex; + justify-content: space-between; + align-items: center; + } + + .panel-title i { + margin-right: 5px; + } + + \ No newline at end of file