feat(ft546): add WCS operations console
This commit is contained in:
5
ruoyi-ui/src/api/wcs/device.js
Normal file
5
ruoyi-ui/src/api/wcs/device.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listDevices(query) {
|
||||
return request({ url: '/wcs/devices', method: 'get', params: query })
|
||||
}
|
||||
21
ruoyi-ui/src/api/wcs/order.js
Normal file
21
ruoyi-ui/src/api/wcs/order.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listOrders(query) {
|
||||
return request({ url: '/wcs/orders', method: 'get', params: query })
|
||||
}
|
||||
|
||||
export function suspendOrder(orderId, reason) {
|
||||
return request({
|
||||
url: `/wcs/orders/${orderId}/suspend`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
})
|
||||
}
|
||||
|
||||
export function resumeOrder(orderId) {
|
||||
return request({ url: `/wcs/orders/${orderId}/resume`, method: 'post' })
|
||||
}
|
||||
|
||||
export function cancelOrder(orderId) {
|
||||
return request({ url: `/wcs/orders/${orderId}/cancel`, method: 'post' })
|
||||
}
|
||||
21
ruoyi-ui/src/api/wcs/recovery.js
Normal file
21
ruoyi-ui/src/api/wcs/recovery.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listRecoveryCases(query) {
|
||||
return request({ url: '/wcs/recovery/cases', method: 'get', params: query })
|
||||
}
|
||||
|
||||
export function confirmRecovery(caseId, data) {
|
||||
return request({
|
||||
url: `/wcs/recovery/cases/${caseId}/confirm`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function abortRecovery(caseId, reason) {
|
||||
return request({
|
||||
url: `/wcs/recovery/cases/${caseId}/abort`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
})
|
||||
}
|
||||
9
ruoyi-ui/src/api/wcs/traffic.js
Normal file
9
ruoyi-ui/src/api/wcs/traffic.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listResources(query) {
|
||||
return request({
|
||||
url: '/wcs/traffic/resources',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
61
ruoyi-ui/src/views/wcs/device/index.vue
Normal file
61
ruoyi-ui/src/views/wcs/device/index.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div class="app-container wcs-page">
|
||||
<div class="wcs-page__bar"><h2>WCS 设备</h2><el-switch v-model="autoRefresh" active-text="自动刷新" /></div>
|
||||
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
|
||||
<el-form-item label="命令状态" prop="state"><el-select v-model="queryParams.state" clearable placeholder="全部状态"><el-option v-for="state in commandStates" :key="state" :label="state" :value="state" /></el-select></el-form-item>
|
||||
<el-form-item><el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button><el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="rows" stripe @row-click="openDetail">
|
||||
<el-table-column label="设备 ID" prop="deviceId" min-width="130" show-overflow-tooltip />
|
||||
<el-table-column label="类型" prop="deviceType" width="120" />
|
||||
<el-table-column label="连接" prop="connected" width="90" align="center"><template slot-scope="scope"><el-tag size="mini" :type="scope.row.connected ? 'success' : 'danger'">{{ scope.row.connected ? '在线' : '离线' }}</el-tag></template></el-table-column>
|
||||
<el-table-column label="当前位置" prop="currentSite" min-width="130" />
|
||||
<el-table-column label="命令状态" prop="commandState" width="130" align="center" />
|
||||
<el-table-column label="当前命令" prop="currentCommandKey" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="活动告警" prop="activeAlarmCode" min-width="140"><template slot-scope="scope"><span :class="{ 'alarm-text': scope.row.activeAlarmCode }">{{ scope.row.activeAlarmCode || '-' }}</span></template></el-table-column>
|
||||
<el-table-column label="更新时间" prop="updatedAt" width="180"><template slot-scope="scope">{{ parseTime(scope.row.updatedAt) }}</template></el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
<el-drawer title="设备详情" :visible.sync="detailOpen" size="420px"><dl v-if="current" class="wcs-detail"><template v-for="item in details"><dt :key="item.key + '-label'">{{ item.label }}</dt><dd :key="item.key">{{ current[item.key] === null || current[item.key] === undefined ? '-' : current[item.key] }}</dd></template></dl></el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listDevices } from '@/api/wcs/device'
|
||||
|
||||
export default {
|
||||
name: 'WcsDevice',
|
||||
data() {
|
||||
return {
|
||||
loading: false, autoRefresh: true, timer: null, rows: [], total: 0, current: null, detailOpen: false,
|
||||
queryParams: { pageNum: 1, pageSize: 20, state: null },
|
||||
commandStates: ['CREATED', 'SENT', 'ACKNOWLEDGED', 'RUNNING', 'COMPLETED', 'FAILED', 'UNKNOWN'],
|
||||
details: [
|
||||
{ key: 'deviceId', label: '设备 ID' }, { key: 'deviceType', label: '类型' },
|
||||
{ key: 'connected', label: '连接' }, { key: 'currentSite', label: '当前位置' },
|
||||
{ key: 'currentCommandKey', label: '当前命令' }, { key: 'commandState', label: '命令状态' },
|
||||
{ key: 'activeAlarmCode', label: '活动告警' }, { key: 'recoveryCaseId', label: '恢复案例' },
|
||||
{ key: 'updatedAt', label: '更新时间' }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() { this.getList() },
|
||||
mounted() { this.timer = window.setInterval(() => { if (this.autoRefresh) this.getList(true) }, 5000) },
|
||||
beforeDestroy() { window.clearInterval(this.timer) },
|
||||
methods: {
|
||||
getList(silent) { if (!silent) this.loading = true; return listDevices(this.queryParams).then(r => { this.rows = r.rows || []; this.total = r.total || 0 }).finally(() => { this.loading = false }) },
|
||||
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
|
||||
resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
|
||||
openDetail(row) { this.current = row; this.detailOpen = true }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wcs-page__bar { display:flex; align-items:center; justify-content:space-between; min-height:58px; margin-bottom:16px; padding-bottom:12px; border-bottom:1px solid #dcdfe6; }
|
||||
.wcs-page__bar h2 { margin:0; color:#17202a; font-size:20px; font-weight:600; letter-spacing:0; }
|
||||
.alarm-text { color:#c0362c; font-weight:600; }
|
||||
.wcs-detail { display:grid; grid-template-columns:110px minmax(0, 1fr); gap:0; margin:0 24px; border-top:1px solid #ebeef5; }
|
||||
.wcs-detail dt,.wcs-detail dd { margin:0; padding:12px 8px; border-bottom:1px solid #ebeef5; overflow-wrap:anywhere; }
|
||||
.wcs-detail dt { color:#667085; background:#f7f8fa; }.wcs-detail dd { color:#17202a; }
|
||||
</style>
|
||||
141
ruoyi-ui/src/views/wcs/order/index.vue
Normal file
141
ruoyi-ui/src/views/wcs/order/index.vue
Normal file
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div class="app-container wcs-page">
|
||||
<div class="wcs-page__bar">
|
||||
<div>
|
||||
<h2>WCS 订单</h2>
|
||||
<span class="wcs-page__stamp">{{ refreshStamp || '-' }}</span>
|
||||
</div>
|
||||
<el-switch v-model="autoRefresh" active-text="自动刷新" />
|
||||
</div>
|
||||
|
||||
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
|
||||
<el-form-item label="订单状态" prop="state">
|
||||
<el-select v-model="queryParams.state" clearable placeholder="全部状态">
|
||||
<el-option v-for="state in orderStates" :key="state" :label="state" :value="state" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="rows" stripe @row-click="openDetail">
|
||||
<el-table-column label="WMS 任务号" prop="externalRequestId" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="订单 ID" prop="orderId" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="订单状态" prop="orderState" width="140" align="center">
|
||||
<template slot-scope="scope"><el-tag size="mini" :type="stateType(scope.row.orderState)">{{ scope.row.orderState || '-' }}</el-tag></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="步骤" prop="stepId" min-width="130" show-overflow-tooltip />
|
||||
<el-table-column label="设备" prop="deviceId" width="110" />
|
||||
<el-table-column label="命令状态" prop="commandState" width="130" align="center" />
|
||||
<el-table-column label="更新时间" prop="updatedAt" width="180">
|
||||
<template slot-scope="scope">{{ parseTime(scope.row.updatedAt) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="230" fixed="right" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="canSuspend(scope.row)" type="text" icon="el-icon-video-pause" v-hasPermi="['wcs:order:control']" @click.stop="openSuspend(scope.row)">暂停</el-button>
|
||||
<el-button v-if="scope.row.orderState === 'SUSPENDED'" type="text" icon="el-icon-video-play" v-hasPermi="['wcs:order:control']" @click.stop="resume(scope.row)">恢复</el-button>
|
||||
<el-button v-if="canCancel(scope.row)" type="text" class="danger-action" icon="el-icon-circle-close" v-hasPermi="['wcs:order:control']" @click.stop="cancel(scope.row)">取消</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<el-dialog title="暂停订单" :visible.sync="suspendOpen" width="460px" append-to-body>
|
||||
<el-form ref="suspendForm" :model="suspendForm" :rules="suspendRules" label-width="80px">
|
||||
<el-form-item label="原因" prop="reason"><el-input v-model="suspendForm.reason" type="textarea" :rows="3" maxlength="200" show-word-limit /></el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer"><el-button @click="suspendOpen = false">取消</el-button><el-button type="primary" @click="submitSuspend">确认暂停</el-button></div>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer title="订单详情" :visible.sync="detailOpen" size="420px">
|
||||
<dl v-if="current" class="wcs-detail">
|
||||
<template v-for="item in orderDetails"><dt :key="item.key + '-label'">{{ item.label }}</dt><dd :key="item.key">{{ current[item.key] || '-' }}</dd></template>
|
||||
</dl>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOrders, suspendOrder, resumeOrder, cancelOrder } from '@/api/wcs/order'
|
||||
|
||||
export default {
|
||||
name: 'WcsOrder',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
autoRefresh: true,
|
||||
timer: null,
|
||||
refreshStamp: '',
|
||||
rows: [],
|
||||
total: 0,
|
||||
current: null,
|
||||
detailOpen: false,
|
||||
suspendOpen: false,
|
||||
suspendForm: { orderId: null, reason: '' },
|
||||
suspendRules: { reason: [{ required: true, message: '请输入暂停原因', trigger: 'blur' }] },
|
||||
queryParams: { pageNum: 1, pageSize: 20, state: null },
|
||||
orderStates: ['ACCEPTED', 'PLANNED', 'EXECUTING', 'SUSPENDED', 'CANCEL_REQUESTED', 'COMPLETED', 'FAILED', 'CANCELLED'],
|
||||
orderDetails: [
|
||||
{ key: 'externalRequestId', label: 'WMS 任务号' }, { key: 'orderId', label: '订单 ID' },
|
||||
{ key: 'orderState', label: '订单状态' }, { key: 'workflowId', label: '工作流' },
|
||||
{ key: 'stepId', label: '当前步骤' }, { key: 'deviceId', label: '设备' },
|
||||
{ key: 'currentCommandKey', label: '命令键' }, { key: 'commandState', label: '命令状态' },
|
||||
{ key: 'recoveryCaseId', label: '恢复案例' }, { key: 'updatedAt', label: '更新时间' }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() { this.getList() },
|
||||
mounted() { this.timer = window.setInterval(() => { if (this.autoRefresh) this.getList(true) }, 5000) },
|
||||
beforeDestroy() { window.clearInterval(this.timer) },
|
||||
methods: {
|
||||
getList(silent) {
|
||||
if (!silent) this.loading = true
|
||||
return listOrders(this.queryParams).then(response => {
|
||||
this.rows = response.rows || []
|
||||
this.total = response.total || 0
|
||||
this.refreshStamp = this.parseTime(new Date())
|
||||
}).finally(() => { this.loading = false })
|
||||
},
|
||||
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
|
||||
resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
|
||||
openDetail(row) { this.current = row; this.detailOpen = true },
|
||||
stateType(state) {
|
||||
if (state === 'COMPLETED') return 'success'
|
||||
if (state === 'FAILED' || state === 'CANCELLED') return 'danger'
|
||||
if (state === 'SUSPENDED' || state === 'CANCEL_REQUESTED') return 'warning'
|
||||
return ''
|
||||
},
|
||||
canSuspend(row) { return ['ACCEPTED', 'PLANNED', 'EXECUTING'].includes(row.orderState) },
|
||||
canCancel(row) { return ['ACCEPTED', 'PLANNED', 'CANCEL_REQUESTED'].includes(row.orderState) },
|
||||
openSuspend(row) { this.suspendForm = { orderId: row.orderId, reason: '' }; this.suspendOpen = true },
|
||||
submitSuspend() {
|
||||
this.$refs.suspendForm.validate(valid => {
|
||||
if (!valid) return
|
||||
suspendOrder(this.suspendForm.orderId, this.suspendForm.reason).then(() => {
|
||||
this.suspendOpen = false; this.$modal.msgSuccess('订单已暂停'); this.getList()
|
||||
})
|
||||
})
|
||||
},
|
||||
resume(row) { resumeOrder(row.orderId).then(() => { this.$modal.msgSuccess('订单已恢复'); this.getList() }) },
|
||||
cancel(row) {
|
||||
this.$modal.confirm(`确认取消 WMS 任务 ${row.externalRequestId || row.orderId}?`).then(() => cancelOrder(row.orderId)).then(() => {
|
||||
this.$modal.msgSuccess('订单已取消'); this.getList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wcs-page__bar { display:flex; align-items:center; justify-content:space-between; min-height:58px; margin-bottom:16px; padding-bottom:12px; border-bottom:1px solid #dcdfe6; }
|
||||
.wcs-page__bar h2 { margin:0 0 5px; color:#17202a; font-size:20px; font-weight:600; letter-spacing:0; }
|
||||
.wcs-page__stamp { color:#7b8794; font-size:12px; }
|
||||
.danger-action { color:#d14343; }
|
||||
.wcs-detail { display:grid; grid-template-columns:110px minmax(0, 1fr); gap:0; margin:0 24px; border-top:1px solid #ebeef5; }
|
||||
.wcs-detail dt,.wcs-detail dd { margin:0; padding:12px 8px; border-bottom:1px solid #ebeef5; overflow-wrap:anywhere; }
|
||||
.wcs-detail dt { color:#667085; background:#f7f8fa; }
|
||||
.wcs-detail dd { color:#17202a; }
|
||||
</style>
|
||||
102
ruoyi-ui/src/views/wcs/recovery/index.vue
Normal file
102
ruoyi-ui/src/views/wcs/recovery/index.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="app-container wcs-page">
|
||||
<div class="wcs-page__bar"><h2>恢复处置</h2><el-switch v-model="autoRefresh" active-text="自动刷新" /></div>
|
||||
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
|
||||
<el-form-item label="案例状态" prop="state"><el-select v-model="queryParams.state" placeholder="案例状态"><el-option v-for="state in recoveryStates" :key="state" :label="state" :value="state" /></el-select></el-form-item>
|
||||
<el-form-item><el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button><el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="rows" stripe @row-click="openDetail">
|
||||
<el-table-column label="案例 ID" prop="caseId" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="设备" prop="deviceId" width="110" />
|
||||
<el-table-column label="命令键" prop="commandKey" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="状态" prop="state" width="120" align="center"><template slot-scope="scope"><el-tag size="mini" :type="recoveryType(scope.row.state)">{{ scope.row.state }}</el-tag></template></el-table-column>
|
||||
<el-table-column label="原因" prop="reason" min-width="210" show-overflow-tooltip />
|
||||
<el-table-column label="创建时间" prop="createdAt" width="180"><template slot-scope="scope">{{ parseTime(scope.row.createdAt) }}</template></el-table-column>
|
||||
<el-table-column label="操作" width="170" fixed="right" align="center"><template slot-scope="scope"><template v-if="scope.row.state === 'OPEN'"><el-button type="text" icon="el-icon-circle-check" v-hasPermi="['wcs:recovery:confirm']" @click.stop="openConfirm(scope.row)">确认事实</el-button><el-button type="text" class="danger-action" icon="el-icon-circle-close" v-hasPermi="['wcs:recovery:confirm']" @click.stop="openAbort(scope.row)">中止</el-button></template></template></el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<el-dialog title="确认现场事实" :visible.sync="confirmOpen" width="520px" append-to-body>
|
||||
<el-form ref="confirmForm" :model="confirmForm" :rules="confirmRules" label-width="90px">
|
||||
<el-form-item label="当前位置" prop="currentSite"><el-input v-model="confirmForm.currentSite" /></el-form-item>
|
||||
<el-form-item label="任务号" prop="taskNumber"><el-input v-model="confirmForm.taskNumber" /></el-form-item>
|
||||
<el-form-item label="设备模式" prop="deviceMode"><el-select v-model="confirmForm.deviceMode"><el-option label="AUTO" value="AUTO" /><el-option label="MANUAL" value="MANUAL" /></el-select></el-form-item>
|
||||
<el-form-item label="载货状态" prop="loaded"><el-switch v-model="confirmForm.loaded" active-text="有货" inactive-text="空载" /></el-form-item>
|
||||
<el-form-item label="确认原因" prop="reason"><el-input v-model="confirmForm.reason" type="textarea" :rows="3" maxlength="200" show-word-limit /></el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer"><el-button @click="confirmOpen = false">取消</el-button><el-button type="primary" @click="submitConfirm">提交事实</el-button></div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="中止恢复案例" :visible.sync="abortOpen" width="460px" append-to-body>
|
||||
<el-form ref="abortForm" :model="abortForm" :rules="abortRules" label-width="80px"><el-form-item label="原因" prop="reason"><el-input v-model="abortForm.reason" type="textarea" :rows="3" maxlength="200" show-word-limit /></el-form-item></el-form>
|
||||
<div slot="footer"><el-button @click="abortOpen = false">取消</el-button><el-button type="danger" @click="submitAbort">确认中止</el-button></div>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer title="恢复案例详情" :visible.sync="detailOpen" size="420px"><dl v-if="current" class="wcs-detail"><template v-for="item in details"><dt :key="item.key + '-label'">{{ item.label }}</dt><dd :key="item.key">{{ current[item.key] || '-' }}</dd></template></dl></el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listRecoveryCases, confirmRecovery, abortRecovery } from '@/api/wcs/recovery'
|
||||
|
||||
export default {
|
||||
name: 'WcsRecovery',
|
||||
data() {
|
||||
return {
|
||||
loading: false, autoRefresh: true, timer: null, rows: [], total: 0, current: null, detailOpen: false,
|
||||
confirmOpen: false, abortOpen: false,
|
||||
queryParams: { pageNum: 1, pageSize: 20, state: 'OPEN' },
|
||||
recoveryStates: ['OPEN', 'CONFIRMED', 'ABORTED'],
|
||||
confirmForm: { caseId: null, currentSite: '', taskNumber: '', deviceMode: 'AUTO', loaded: false, reason: '' },
|
||||
abortForm: { caseId: null, reason: '' },
|
||||
confirmRules: {
|
||||
currentSite: [{ required: true, message: '请输入当前位置', trigger: 'blur' }],
|
||||
taskNumber: [{ required: true, message: '请输入任务号', trigger: 'blur' }],
|
||||
deviceMode: [{ required: true, message: '请选择设备模式', trigger: 'change' }],
|
||||
reason: [{ required: true, message: '请输入确认原因', trigger: 'blur' }]
|
||||
},
|
||||
abortRules: { reason: [{ required: true, message: '请输入中止原因', trigger: 'blur' }] },
|
||||
details: [
|
||||
{ key: 'caseId', label: '案例 ID' }, { key: 'deviceId', label: '设备' },
|
||||
{ key: 'commandKey', label: '命令键' }, { key: 'state', label: '状态' },
|
||||
{ key: 'reason', label: '原因' }, { key: 'createdAt', label: '创建时间' },
|
||||
{ key: 'resolvedBy', label: '处置人' }, { key: 'resolvedAt', label: '处置时间' }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() { this.getList() },
|
||||
mounted() { this.timer = window.setInterval(() => { if (this.autoRefresh) this.getList(true) }, 5000) },
|
||||
beforeDestroy() { window.clearInterval(this.timer) },
|
||||
methods: {
|
||||
getList(silent) { if (!silent) this.loading = true; return listRecoveryCases(this.queryParams).then(r => { this.rows = r.rows || []; this.total = r.total || 0 }).finally(() => { this.loading = false }) },
|
||||
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
|
||||
resetQuery() { this.resetForm('queryForm'); this.queryParams.state = 'OPEN'; this.handleQuery() },
|
||||
openDetail(row) { this.current = row; this.detailOpen = true },
|
||||
recoveryType(state) { if (state === 'CONFIRMED') return 'success'; if (state === 'ABORTED') return 'danger'; return 'warning' },
|
||||
openConfirm(row) { this.confirmForm = { caseId: row.caseId, currentSite: '', taskNumber: '', deviceMode: 'AUTO', loaded: false, reason: '' }; this.confirmOpen = true },
|
||||
submitConfirm() {
|
||||
this.$refs.confirmForm.validate(valid => {
|
||||
if (!valid) return
|
||||
const data = { ...this.confirmForm }; delete data.caseId
|
||||
confirmRecovery(this.confirmForm.caseId, data).then(() => { this.confirmOpen = false; this.$modal.msgSuccess('现场事实已确认'); this.getList() })
|
||||
})
|
||||
},
|
||||
openAbort(row) { this.abortForm = { caseId: row.caseId, reason: '' }; this.abortOpen = true },
|
||||
submitAbort() {
|
||||
this.$refs.abortForm.validate(valid => {
|
||||
if (!valid) return
|
||||
abortRecovery(this.abortForm.caseId, this.abortForm.reason).then(() => { this.abortOpen = false; this.$modal.msgSuccess('恢复案例已中止'); this.getList() })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wcs-page__bar { display:flex; align-items:center; justify-content:space-between; min-height:58px; margin-bottom:16px; padding-bottom:12px; border-bottom:1px solid #dcdfe6; }
|
||||
.wcs-page__bar h2 { margin:0; color:#17202a; font-size:20px; font-weight:600; letter-spacing:0; }
|
||||
.danger-action { color:#d14343; }
|
||||
.wcs-detail { display:grid; grid-template-columns:110px minmax(0, 1fr); gap:0; margin:0 24px; border-top:1px solid #ebeef5; }
|
||||
.wcs-detail dt,.wcs-detail dd { margin:0; padding:12px 8px; border-bottom:1px solid #ebeef5; overflow-wrap:anywhere; }
|
||||
.wcs-detail dt { color:#667085; background:#f7f8fa; }.wcs-detail dd { color:#17202a; }
|
||||
</style>
|
||||
63
ruoyi-ui/src/views/wcs/traffic/index.vue
Normal file
63
ruoyi-ui/src/views/wcs/traffic/index.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="app-container wcs-page">
|
||||
<div class="wcs-page__bar"><h2>交通资源</h2><el-switch v-model="autoRefresh" active-text="自动刷新" /></div>
|
||||
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
|
||||
<el-form-item label="占用状态" prop="state"><el-select v-model="queryParams.state" clearable placeholder="全部状态"><el-option v-for="state in resourceStates" :key="state" :label="state" :value="state" /></el-select></el-form-item>
|
||||
<el-form-item><el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button><el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="rows" stripe @row-click="openDetail">
|
||||
<el-table-column label="资源键" prop="resourceKey" min-width="210" show-overflow-tooltip />
|
||||
<el-table-column label="类型" prop="resourceType" width="100" />
|
||||
<el-table-column label="容量" prop="capacity" width="80" align="right" />
|
||||
<el-table-column label="保护数" prop="protectedCount" width="90" align="right" />
|
||||
<el-table-column label="持有者" prop="holder" width="110" show-overflow-tooltip />
|
||||
<el-table-column label="状态" prop="reservationState" width="130" align="center"><template slot-scope="scope"><el-tag size="mini" :type="resourceType(scope.row.reservationState)">{{ scope.row.reservationState }}</el-tag></template></el-table-column>
|
||||
<el-table-column label="释放证据" prop="releaseEvidenceId" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="更新时间" prop="updatedAt" width="180"><template slot-scope="scope">{{ parseTime(scope.row.updatedAt) }}</template></el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
<el-drawer title="资源详情" :visible.sync="detailOpen" size="420px"><dl v-if="current" class="wcs-detail"><template v-for="item in details"><dt :key="item.key + '-label'">{{ item.label }}</dt><dd :key="item.key">{{ detailValue(current[item.key]) }}</dd></template></dl></el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listResources } from '@/api/wcs/traffic'
|
||||
|
||||
export default {
|
||||
name: 'WcsTraffic',
|
||||
data() {
|
||||
return {
|
||||
loading: false, autoRefresh: true, timer: null, rows: [], total: 0, current: null, detailOpen: false,
|
||||
queryParams: { pageNum: 1, pageSize: 20, state: null },
|
||||
resourceStates: ['FREE', 'RESERVED', 'OCCUPIED', 'RELEASING', 'UNKNOWN'],
|
||||
details: [
|
||||
{ key: 'resourceKey', label: '资源键' }, { key: 'resourceType', label: '类型' },
|
||||
{ key: 'capacity', label: '容量' }, { key: 'protectedCount', label: '保护数' },
|
||||
{ key: 'holder', label: '持有者' }, { key: 'reservationState', label: '状态' },
|
||||
{ key: 'orderId', label: '订单' }, { key: 'stepId', label: '步骤' },
|
||||
{ key: 'vehicleId', label: '车辆' }, { key: 'fencingToken', label: '围栏令牌' },
|
||||
{ key: 'releaseEvidenceId', label: '释放证据' }, { key: 'updatedAt', label: '更新时间' }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() { this.getList() },
|
||||
mounted() { this.timer = window.setInterval(() => { if (this.autoRefresh) this.getList(true) }, 5000) },
|
||||
beforeDestroy() { window.clearInterval(this.timer) },
|
||||
methods: {
|
||||
getList(silent) { if (!silent) this.loading = true; return listResources(this.queryParams).then(r => { this.rows = r.rows || []; this.total = r.total || 0 }).finally(() => { this.loading = false }) },
|
||||
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
|
||||
resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
|
||||
openDetail(row) { this.current = row; this.detailOpen = true },
|
||||
detailValue(value) { return value === null || value === undefined || value === '' ? '-' : value },
|
||||
resourceType(state) { if (state === 'FREE') return 'success'; if (state === 'UNKNOWN') return 'danger'; if (state === 'RESERVED' || state === 'RELEASING') return 'warning'; return '' }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wcs-page__bar { display:flex; align-items:center; justify-content:space-between; min-height:58px; margin-bottom:16px; padding-bottom:12px; border-bottom:1px solid #dcdfe6; }
|
||||
.wcs-page__bar h2 { margin:0; color:#17202a; font-size:20px; font-weight:600; letter-spacing:0; }
|
||||
.wcs-detail { display:grid; grid-template-columns:110px minmax(0, 1fr); gap:0; margin:0 24px; border-top:1px solid #ebeef5; }
|
||||
.wcs-detail dt,.wcs-detail dd { margin:0; padding:12px 8px; border-bottom:1px solid #ebeef5; overflow-wrap:anywhere; }
|
||||
.wcs-detail dt { color:#667085; background:#f7f8fa; }.wcs-detail dd { color:#17202a; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user