yeg
2026-08-26 9f48020dfd3e29d1c0049a3da9df3203c40bc264
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script setup lang="ts">
import { reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { dataRevisionRecords } from '@/stores/dataRevisions'
import { getConsoleDataRow } from '@/stores/consoleTestData'
import { getCurrentUser } from '@/utils/auth'
 
const route = useRoute()
const router = useRouter()
const testId = Number(route.params.id)
const recordId = Number(route.params.recordId)
const testName = String(route.query.testName || `测试任务 #${testId}`)
const testCompleted = route.query.completed === '1'
const row = getConsoleDataRow(testId, recordId)
 
const form = reactive({
  voltage: row?.voltage || '',
  current: row?.current || '',
  capacity: row?.capacity || '',
  energy: row?.energy || '',
  temperature: row?.temperature || '',
  positivePotential: row?.positivePotential || '',
  negativePotential: row?.negativePotential || '',
  remark: '',
})
 
const fields = [
  { key: 'voltage', label: '电压', unit: 'V' },
  { key: 'current', label: '电流', unit: 'mA' },
  { key: 'capacity', label: '容量', unit: 'mAh' },
  { key: 'energy', label: '能量', unit: 'mWh' },
  { key: 'temperature', label: '温度(采集器)', unit: '℃' },
  { key: 'positivePotential', label: '正电位(采集器)', unit: 'V' },
  { key: 'negativePotential', label: '负电位(采集器)', unit: 'V' },
] as const
 
function backToDataList() {
  router.push({ path: `/test-list/${testId}/console`, query: { tab: 'data-list', state: testCompleted ? 'ended' : 'running' } })
}
 
function revisionValues(source: NonNullable<typeof row>) {
  return {
    voltage: source.voltage,
    current: source.current,
    capacity: source.capacity,
    energy: source.energy,
    temperature: source.temperature,
    positivePotential: source.positivePotential,
    negativePotential: source.negativePotential,
  }
}
 
function submitEdit() {
  if (!row) return
  const hasInvalidValue = fields.some(field => !form[field.key].trim() || !Number.isFinite(Number(form[field.key])))
  if (hasInvalidValue) {
    ElMessage.warning('请填写完整、有效的采集数据')
    return
  }
  if (!form.remark.trim()) {
    ElMessage.warning('请填写修改原因')
    return
  }
 
  const originalData = revisionValues(row)
  fields.forEach(field => { row[field.key] = form[field.key].trim() })
  const now = new Date()
  const pad = (value: number) => String(value).padStart(2, '0')
  const modifiedAt = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
  dataRevisionRecords.unshift({
    id: `DR-${Date.now()}-${row.id}`,
    testId,
    testName,
    testedAt: row.recordedAt,
    generatedAt: row.recordedAt,
    modifiedAt,
    modifier: getCurrentUser()?.displayName || '管理员',
    remark: form.remark.trim(),
    operation: '修改',
    stepName: row.stepName,
    cycleNo: row.cycleNo,
    stepNo: row.stepNo,
    stepDuration: row.stepDuration,
    absoluteTime: row.recordedAt,
    originalData,
    revisedData: revisionValues(row),
  })
  ElMessage.success('数据修改已提交,修订记录已生成')
  backToDataList()
}
</script>
 
<template>
  <div class="data-edit-page">
    <div class="page-tools"><button class="back-button" type="button" @click="backToDataList"><el-icon><ArrowLeft /></el-icon>返回数据列表</button><span>DATA REVISION · {{ row?.recordNo || recordId }}</span></div>
 
    <section v-if="row" class="edit-panel">
      <header class="section-heading"><div><i></i><strong>数据详情</strong><span>DATA DETAILS</span></div><small>{{ testName }}</small></header>
      <dl class="step-summary">
        <div><dt>工步名称</dt><dd>{{ row.stepName }}</dd></div>
        <div><dt>循环编号</dt><dd>{{ row.cycleNo }}</dd></div>
        <div><dt>工步序号</dt><dd>{{ row.stepNo }}</dd></div>
        <div><dt>工步时间</dt><dd>{{ row.stepDuration }}</dd></div>
        <div><dt>绝对时间</dt><dd>{{ row.recordedAt }}</dd></div>
      </dl>
 
      <div class="form-grid">
        <label v-for="field in fields" :key="field.key">
          <span>{{ field.label }}({{ field.unit }})</span>
          <el-input v-model="form[field.key]" inputmode="decimal" />
        </label>
        <label class="remark-field"><span>修改原因</span><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="120" show-word-limit placeholder="请输入数据修改原因,提交后将写入修订记录" /></label>
      </div>
 
      <footer class="form-actions"><button class="primary-button" type="button" @click="submitEdit"><el-icon><Check /></el-icon>提交修改</button><button class="secondary-button" type="button" @click="backToDataList"><el-icon><ArrowLeft /></el-icon>返回</button></footer>
    </section>
 
    <section v-else class="empty-panel"><el-icon><Warning /></el-icon><strong>未找到需要修改的数据</strong><p>该数据可能已删除,或者修改页面不是从当前测试的数据列表进入。</p><button class="secondary-button" type="button" @click="backToDataList">返回数据列表</button></section>
  </div>
</template>
 
<style scoped>
.data-edit-page{width:100%;padding-bottom:24px}.page-tools{height:42px;display:flex;align-items:center;justify-content:space-between}.page-tools>span{color:#7f8d99;font-size:10px;font-weight:600}.back-button{display:inline-flex;align-items:center;gap:6px;border:0;color:#52606d;background:transparent;font-size:13px;cursor:pointer}.back-button:hover{color:var(--blue)}.edit-panel,.empty-panel{min-height:620px;border:1px solid #d8e1e9;background:#fff}.section-heading{height:50px;display:flex;align-items:center;justify-content:space-between;padding:0 20px;border-bottom:1px solid var(--line);background:var(--surface-soft)}.section-heading>div{display:flex;align-items:center;gap:8px}.section-heading i{width:3px;height:16px;background:#2b78a3}.section-heading strong{color:var(--ink);font-size:15px}.section-heading span{color:#81909d;font-size:10px}.section-heading small{color:#71808d;font-size:11px}.step-summary{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:20px;padding:22px 28px;border-bottom:1px solid #d8e1e9}.step-summary>div{display:flex;align-items:center;gap:14px;min-width:0}.step-summary dt{color:#71808d;font-size:12px;white-space:nowrap}.step-summary dd{min-width:0;color:#52606d;font-size:12px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:22px 40px;padding:30px 32px 22px}.form-grid label{display:grid;gap:8px;min-width:0}.form-grid label>span{color:#52606d;font-size:12px;font-weight:500}.form-grid :deep(.el-input__wrapper),.form-grid :deep(.el-textarea__inner){border-radius:2px;background:#f6f8fa;box-shadow:0 0 0 1px #e0e7ed inset}.form-grid :deep(.el-input__wrapper){min-height:36px}.remark-field{grid-column:1/-1;max-width:760px}.form-actions{display:flex;align-items:center;gap:12px;padding:0 32px 32px}.primary-button,.secondary-button{height:34px;min-width:92px;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:0 14px;border:1px solid transparent;border-radius:3px;font-size:13px;font-weight:500;cursor:pointer}.primary-button{color:#fff;background:var(--blue);border-color:var(--blue)}.primary-button:hover{background:#176fcb}.secondary-button{color:#52606d;background:#fff;border-color:var(--line-strong)}.secondary-button:hover{color:var(--blue);border-color:#9dc8f5}.empty-panel{display:flex;align-items:center;justify-content:center;flex-direction:column;gap:10px;color:#71808d}.empty-panel>.el-icon{font-size:28px;color:#d39a36}.empty-panel strong{color:#405261}.empty-panel p{font-size:12px}.empty-panel button{margin-top:8px}@media(max-width:1100px){.step-summary{grid-template-columns:repeat(3,minmax(0,1fr))}.form-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:760px){.step-summary{grid-template-columns:1fr;gap:12px;padding:18px}.form-grid{grid-template-columns:1fr;gap:16px;padding:22px 18px}.remark-field{grid-column:auto}.form-actions{padding:0 18px 24px}.section-heading{padding:0 16px}.section-heading span{display:none}}
</style>