| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="info-card"> |
| | | <div class="card-header">变更记录</div> |
| | | <div class="card-content" v-loading="recordsLoading"> |
| | | <div v-if="changeRecords.length === 0" class="empty-tip">暂无变更记录</div> |
| | | <div v-else class="change-record" v-for="(item, index) in changeRecords" :key="index"> |
| | | <div class="record-header"> |
| | | <span class="record-time">{{ item.createTime }}</span> |
| | | <span class="record-status" :class="approvalClass(item.approvalStatus)">{{ approvalText(item.approvalStatus) }}</span> |
| | | </div> |
| | | <div class="record-line"> |
| | | <span class="record-status-change"> |
| | | {{ statusText(item.originalStatus) }} → {{ statusText(item.targetStatus) }} |
| | | </span> |
| | | <span class="record-user">申请人:{{ item.createUserName || '--' }}</span> |
| | | </div> |
| | | <div class="record-reason">变更原因:{{ item.reason || '--' }}</div> |
| | | <div v-if="item.approvalStatus === 'REJECTED' && item.rejectReason" class="record-reject">驳回原因:{{ item.rejectReason }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import { ref, reactive, onMounted, computed } from 'vue' |
| | | import { useRoute } from 'vue-router' |
| | | import { ElMessage } from 'element-plus' |
| | | import { |
| | | getDeviceInfo, |
| | | import { |
| | | getDeviceInfo, |
| | | } from '@/api/equipmentManagement/deviceInfo' |
| | | import { listStatusChangeRecord } from '@/api/device/statusChangeRecord' |
| | | |
| | | const route = useRoute() |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | const changeRecords = ref([]) |
| | | const recordsLoading = ref(false) |
| | | |
| | | const statusText = (s) => (s == 1 ? '启用' : '停用') |
| | | |
| | | const approvalText = (s) => { |
| | | const map = { PENDING: '审批中', APPROVED: '已通过', REJECTED: '已驳回' } |
| | | return map[s] || s || '--' |
| | | } |
| | | |
| | | const approvalClass = (s) => { |
| | | const map = { PENDING: 'status-pending', APPROVED: 'status-approved', REJECTED: 'status-rejected' } |
| | | return map[s] || '' |
| | | } |
| | | |
| | | const fetchChangeRecords = async (deviceId) => { |
| | | recordsLoading.value = true |
| | | try { |
| | | const res = await listStatusChangeRecord({ deviceId, pageNum: 1, pageSize: 20 }) |
| | | if (res.code === 200) { |
| | | changeRecords.value = res.data?.records || res.data || [] |
| | | } |
| | | } catch (error) { |
| | | console.error('获取变更记录失败:', error) |
| | | } finally { |
| | | recordsLoading.value = false |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | const deviceId = route.query.deviceId || route.params.deviceId || '' |
| | | fetchDeviceInfo(deviceId) |
| | | fetchChangeRecords(deviceId) |
| | | }) |
| | | </script> |
| | | |
| | |
| | | color: #52c41a; |
| | | } |
| | | |
| | | .empty-tip { |
| | | color: #999; |
| | | text-align: center; |
| | | padding: 20px 0; |
| | | } |
| | | |
| | | .change-record { |
| | | padding: 14px 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | .change-record:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .record-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .record-time { |
| | | color: #666; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .record-status { |
| | | font-size: 12px; |
| | | padding: 2px 10px; |
| | | border-radius: 12px; |
| | | background: #f5f5f5; |
| | | color: #666; |
| | | } |
| | | |
| | | .status-pending { |
| | | background: #fff7e6; |
| | | color: #fa8c16; |
| | | } |
| | | |
| | | .status-approved { |
| | | background: #f6ffed; |
| | | color: #52c41a; |
| | | } |
| | | |
| | | .status-rejected { |
| | | background: #fff1f0; |
| | | color: #f5222d; |
| | | } |
| | | |
| | | .record-line { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 6px; |
| | | } |
| | | |
| | | .record-status-change { |
| | | color: #2c3e50; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .record-user { |
| | | color: #999; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .record-reason { |
| | | color: #666; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .record-reject { |
| | | color: #f5222d; |
| | | font-size: 13px; |
| | | margin-top: 4px; |
| | | } |
| | | |
| | | |
| | | |
| | | @media (max-width: 768px) { |