From fbb2c7eb5ac25ddc7d67604e07b0fa333bb60b91 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 15 八月 2025 13:38:13 +0800
Subject: [PATCH] 采购台账扫码采集、韦德实业的设备监控

---
 src/views/procurementManagement/procurementLedger/index.vue |  349 +++++++++++++++++++++++++++++
 src/views/equipmentManagement/iotMonitor/indexWD.vue        |  317 ++++++++++++++++++++++++++
 2 files changed, 666 insertions(+), 0 deletions(-)

diff --git a/src/views/equipmentManagement/iotMonitor/indexWD.vue b/src/views/equipmentManagement/iotMonitor/indexWD.vue
new file mode 100644
index 0000000..40a2eb0
--- /dev/null
+++ b/src/views/equipmentManagement/iotMonitor/indexWD.vue
@@ -0,0 +1,317 @@
+<template>
+  <div class="app-container iot-monitor">
+    <div class="header">
+      <div class="title">瀹炴椂宸ュ喌鐩戞帶锛圛oT锛�</div>
+      <div class="actions">
+        <el-button type="primary" @click="toggleCollecting">{{ collecting ? '鏆傚仠閲囬泦' : '鍚姩閲囬泦' }}</el-button>
+        <el-button @click="resetAll">閲嶇疆</el-button>
+        <span class="ts">涓婃鏇存柊鏃堕棿锛歿{ lastUpdatedDisplay }}</span>
+      </div>
+    </div>
+
+<!--    <el-alert-->
+<!--      title="杈圭紭棰勮瑙勫垯锛氳酱鎵跨(鎹�-鎸姩鍊煎亸绂诲熀绾柯�5%瑙﹀彂鍛婅锛涙俯搴�/鍘嬪姏瓒婄晫瑙﹀彂鎻愰啋"-->
+<!--      type="info"-->
+<!--      :closable="false"-->
+<!--      show-icon-->
+<!--      class="rule-alert"-->
+<!--    />-->
+
+    <el-row :gutter="16">
+      <el-col v-for="dev in devices" :key="dev.id" :span="12">
+        <el-card :class="['device-card', dev.hasAlert ? 'is-alert' : '']">
+          <template #header>
+            <div class="card-header">
+              <div class="card-title">
+                <span class="device-name">{{ dev.name }}</span>
+                <el-tag :type="dev.hasAlert ? 'danger' : 'success'" size="small">{{ dev.hasAlert ? '鍛婅' : '姝e父' }}</el-tag>
+              </div>
+              <div class="meta">绫诲瀷锛歿{ dev.type }}锝滃熀绾挎尟鍔細{{ dev.baseline.vibration.toFixed(2) }} mm/s</div>
+            </div>
+          </template>
+
+          <div class="metrics">
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.vibration }">
+              <div class="metric-head">
+                <span>鎸姩(mm/s)</span>
+                <el-tag :type="dev.alerts.vibration ? 'danger' : 'info'" size="small">{{ dev.alerts.vibration ? '卤5%瓒婄晫' : '鍩虹嚎卤5%' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.vibration).toFixed(2) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: 'mm/s' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.vibration }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#409EFF']"
+              />
+            </div>
+
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.temperature }">
+              <div class="metric-head">
+                <span>娓╁害(掳C)</span>
+                <el-tag :type="dev.alerts.temperature ? 'warning' : 'info'" size="small">{{ dev.alerts.temperature ? '瓒婄晫' : '20~80' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.temperature).toFixed(1) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: '掳C' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.temperature }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#E6A23C']"
+              />
+            </div>
+
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.pressure }">
+              <div class="metric-head">
+                <span>鍘嬪姏(MPa)</span>
+                <el-tag :type="dev.alerts.pressure ? 'warning' : 'info'" size="small">{{ dev.alerts.pressure ? '瓒婄晫' : '0.2~1.5' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.pressure).toFixed(2) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: 'MPa' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.pressure }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#67C23A']"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+  
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue'
+import { ElNotification } from 'element-plus'
+import Echarts from '@/components/Echarts/echarts.vue'
+
+defineOptions({ name: 'IoTMonitor' })
+
+const windowSize = 30
+const collecting = ref(true)
+const lastUpdated = ref(Date.now())
+const lastUpdatedDisplay = computed(() => new Date(lastUpdated.value).toLocaleTimeString())
+
+const xAxisLabels = ref(Array.from({ length: windowSize }, (_, i) => i - (windowSize - 1)).map(n => `${n}s`))
+
+function makeSeries(fill, decimals = 2) {
+  return Array.from({ length: windowSize }, () => Number(fill.toFixed(decimals)))
+}
+
+const devices = reactive([
+  {
+    id: 'hydrocyclone-desander',
+    name: '鏃嬫祦闄ょ爞鍣�',
+    type: '鍒嗙璁惧',
+    baseline: { vibration: 8 },
+    initial: { temperature: 35, pressure: 0.85 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(8),
+      temperature: makeSeries(35, 1),
+      pressure: makeSeries(0.85, 2),
+    },
+  },
+  {
+    id: 'high-pressure-separator',
+    name: '楂樺帇鍒嗙鍣ㄦ挰',
+    type: '鍒嗙璁惧',
+    baseline: { vibration: 6 },
+    initial: { temperature: 45, pressure: 1.20 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(6),
+      temperature: makeSeries(45, 1),
+      pressure: makeSeries(1.2, 2),
+    },
+  },
+  {
+    id: 'heating-throttle-pressure',
+    name: '缁勫悎寮忓姞鐑妭娴佽皟鍘�',
+    type: '璋冨帇璁惧',
+    baseline: { vibration: 10 },
+    initial: { temperature: 75, pressure: 1.80 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(10),
+      temperature: makeSeries(75, 1),
+      pressure: makeSeries(1.8, 2),
+    },
+  },
+  {
+    id: 'three-phase-separator',
+    name: '涓夌浉鍒嗙鍣�',
+    type: '鍒嗙璁惧',
+    baseline: { vibration: 7 },
+    initial: { temperature: 38, pressure: 0.95 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(7),
+      temperature: makeSeries(38, 1),
+      pressure: makeSeries(0.95, 2),
+    },
+  },
+])
+
+function currentValue(arr) {
+  return arr[arr.length - 1] ?? 0
+}
+
+function pushWindow(arr, val) {
+  if (arr.length >= windowSize) arr.shift()
+  arr.push(val)
+}
+
+function clamp(val, min, max) { return Math.max(min, Math.min(max, val)) }
+
+function tickDevice(dev) {
+  const vibBase = dev.baseline.vibration
+  // 鎸姩锛氬熀绾柯�2%闅忔満娉㈠姩锛�5%姒傜巼瑙﹀彂8%~12%灏栧嘲妯℃嫙鍛婅
+  const spike = Math.random() < 0.05
+  const vibNoise = vibBase * (spike ? (1 + (Math.random() * 0.08 + 0.04) * (Math.random() < 0.5 ? -1 : 1)) : (1 + (Math.random() - 0.5) * 0.04))
+  const vibVal = Number(vibNoise.toFixed(2))
+  pushWindow(dev.series.vibration, vibVal)
+
+  // 娓╁害锛氱紦鎱㈤殢鏈烘父璧帮紝骞舵坊鍔犲伓鍙戦珮娓╁亸绉�
+  const tPrev = currentValue(dev.series.temperature)
+  const tDrift = tPrev + (Math.random() - 0.5) * 0.8 + (Math.random() < 0.02 ? 6 : 0)
+  const tVal = Number(clamp(tDrift, 15, 95).toFixed(1))
+  pushWindow(dev.series.temperature, tVal)
+
+  // 鍘嬪姏锛氬皬骞呮尝鍔紝鍋跺彂浣庡帇/楂樺帇
+  const pPrev = currentValue(dev.series.pressure)
+  const pDrift = pPrev + (Math.random() - 0.5) * 0.05 + (Math.random() < 0.02 ? (Math.random() < 0.5 ? -0.3 : 0.3) : 0)
+  const pVal = Number(clamp(pDrift, 0.05, 2.0).toFixed(2))
+  pushWindow(dev.series.pressure, pVal)
+
+  // 杈圭紭璁$畻闃堝�煎垽鏂�
+  const vibDelta = Math.abs(vibVal - vibBase) / vibBase
+  const vibAlert = vibDelta > 0.05
+  const tAlert = tVal < 20 || tVal > 80
+  const pAlert = pVal < 0.2 || pVal > 1.5
+
+  const prevHasAlert = dev.hasAlert
+  dev.alerts.vibration = vibAlert
+  dev.alerts.temperature = tAlert
+  dev.alerts.pressure = pAlert
+  dev.hasAlert = vibAlert || tAlert || pAlert
+
+  if (dev.hasAlert && !prevHasAlert) {
+    const reasons = []
+    if (vibAlert) reasons.push(`鎸姩鍋忕卤5% (褰撳墠 ${vibVal} / 鍩虹嚎 ${vibBase})`)
+    if (tAlert) reasons.push(`娓╁害瓒婄晫 (褰撳墠 ${tVal}掳C, 鏈熸湜 20~80掳C) `)
+    if (pAlert) reasons.push(`鍘嬪姏瓒婄晫 (褰撳墠 ${pVal}MPa, 鏈熸湜 0.2~1.5MPa) `)
+    ElNotification({
+      title: `${dev.name} 鍛婅`,
+      message: reasons.join('锛�'),
+      type: vibAlert ? 'error' : 'warning',
+      duration: 5000,
+    })
+  }
+}
+
+let timer = null
+function start() {
+  if (timer) return
+  timer = setInterval(() => {
+    if (!collecting.value) return
+    devices.forEach(tickDevice)
+    lastUpdated.value = Date.now()
+  }, 10000)
+}
+
+function stop() {
+  if (timer) {
+    clearInterval(timer)
+    timer = null
+  }
+}
+
+function toggleCollecting() { collecting.value = !collecting.value }
+
+function resetAll() {
+  devices.forEach(dev => {
+    dev.series.vibration = makeSeries(dev.baseline.vibration)
+    const t0 = dev.initial?.temperature ?? 45
+    const p0 = dev.initial?.pressure ?? 0.8
+    dev.series.temperature = makeSeries(t0, 1)
+    dev.series.pressure = makeSeries(p0, 2)
+    dev.alerts.vibration = false
+    dev.alerts.temperature = false
+    dev.alerts.pressure = false
+    dev.hasAlert = false
+  })
+  lastUpdated.value = Date.now()
+}
+
+onMounted(() => {
+  start()
+})
+
+onBeforeUnmount(() => {
+  stop()
+})
+</script>
+
+<style lang="scss" scoped>
+.iot-monitor {
+  .header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 12px;
+    .title { font-size: 18px; font-weight: 600; }
+    .actions { display: flex; align-items: center; gap: 8px; }
+    .ts { color: #909399; font-size: 12px; }
+  }
+  .rule-alert { margin-bottom: 12px; }
+}
+
+.device-card {
+  margin-bottom: 16px;
+  transition: border-color 0.2s ease, box-shadow 0.2s ease;
+  &.is-alert { border-color: #F56C6C; box-shadow: 0 0 0 2px rgba(245,108,108,0.2) inset; }
+  .card-header {
+    display: flex; flex-direction: column; gap: 4px;
+    .card-title { display: flex; align-items: center; gap: 8px; font-weight: 600; }
+    .meta { color: #909399; font-size: 12px; }
+  }
+  .metrics {
+    display: grid;
+    grid-template-columns: 1fr;
+    gap: 12px;
+  }
+}
+
+.metric {
+  border: 1px solid #ebeef5;
+  border-radius: 6px;
+  padding: 8px 8px 0 8px;
+  &-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; font-size: 13px; color: #606266; }
+  &-value { font-size: 20px; font-weight: 600; margin: 2px 0 6px 0; }
+}
+
+.metric-alert {
+  border-color: #F56C6C;
+  background: #FFF6F6;
+}
+
+@media (min-width: 1200px) {
+  .device-card .metrics { grid-template-columns: 1fr 1fr 1fr; }
+}
+</style>
+
+
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 82f31df..2877efd 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -39,6 +39,7 @@
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
         <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="success" @click="openScanAddDialog">鎵爜鏂板</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
@@ -164,6 +165,7 @@
               @click="showQRCode(scope.row)"
               >鐢熸垚浜岀淮鐮�</el-button
             >
+
           </template>
         </el-table-column>
       </el-table>
@@ -560,6 +562,206 @@
           <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
         </div>
       </div>
+    </el-dialog>
+
+    <!-- 鎵爜鏂板瀵硅瘽妗� -->
+    <el-dialog
+      v-model="scanAddDialogVisible"
+      title="鎵爜鏂板閲囪喘鍙拌处"
+      width="70%"
+      @close="closeScanAddDialog"
+    >
+      <el-form
+        :model="scanAddForm"
+        label-width="140px"
+        label-position="top"
+        :rules="scanAddRules"
+        ref="scanAddFormRef"
+      >
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜鍐呭锛�">
+              <el-input
+                v-model="scanAddForm.scanContent"
+                type="textarea"
+                :rows="3"
+                placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
+                @input="parseScanContent"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
+              <el-input
+                v-model="scanAddForm.purchaseContractNumber"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
+              <el-input
+                v-model="scanAddForm.supplierName"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
+              <el-input
+                v-model="scanAddForm.projectName"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓閲戦(鍏�)锛�" prop="contractAmount">
+              <el-input-number
+                v-model="scanAddForm.contractAmount"
+                :precision="2"
+                :step="0.1"
+                clearable
+                style="width: 100%"
+                placeholder="璇疯緭鍏�"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠樻鏂瑰紡锛�">
+              <el-input
+                v-model="scanAddForm.paymentMethod"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="褰曞叆浜猴細">
+              <el-input v-model="scanAddForm.recorderName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="澶囨敞锛�">
+              <el-input
+                v-model="scanAddForm.remark"
+                type="textarea"
+                :rows="2"
+                placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitScanAdd">纭鏂板</el-button>
+          <el-button @click="closeScanAddDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鎵爜鐧昏瀵硅瘽妗� -->
+    <el-dialog
+      v-model="scanDialogVisible"
+      title="鎵爜鐧昏"
+      width="60%"
+      @close="closeScanDialog"
+    >
+      <el-form
+        :model="scanForm"
+        label-width="120px"
+        label-position="left"
+        :rules="scanRules"
+        ref="scanFormRef"
+      >
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+              <el-input v-model="scanForm.purchaseContractNumber" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+              <el-input v-model="scanForm.supplierName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�">
+              <el-input v-model="scanForm.projectName" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵爜鏃堕棿锛�">
+              <el-input v-model="scanForm.scanTime" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鎵爜浜猴細">
+              <el-input v-model="scanForm.scannerName" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵爜鐘舵�侊細">
+              <el-tag :type="scanForm.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+                {{ scanForm.scanStatus }}
+              </el-tag>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜澶囨敞锛�">
+              <el-input
+                v-model="scanForm.scanRemark"
+                type="textarea"
+                :rows="3"
+                placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜璁板綍锛�">
+              <el-table :data="scanRecords" border style="width: 100%">
+                <el-table-column label="搴忓彿" type="index" width="60" align="center" />
+                <el-table-column label="鎵爜鏃堕棿" prop="scanTime" width="180" />
+                <el-table-column label="鎵爜浜�" prop="scannerName" width="120" />
+                <el-table-column label="鎵爜鐘舵��" prop="scanStatus" width="100">
+                  <template #default="scope">
+                    <el-tag :type="scope.row.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+                      {{ scope.row.scanStatus }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column label="澶囨敞" prop="scanRemark" />
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitScan">纭鎵爜</el-button>
+          <el-button @click="closeScanDialog">鍙栨秷</el-button>
+        </div>
+      </template>
     </el-dialog>
   </div>
 </template>
@@ -1220,6 +1422,153 @@
   proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
 };
 
+// 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
+const scanAddDialogVisible = ref(false);
+const scanAddForm = reactive({
+  scanContent: "",
+  purchaseContractNumber: "",
+  supplierName: "",
+  projectName: "",
+  contractAmount: "",
+  paymentMethod: "",
+  recorderName: "",
+  scanRemark: "",
+});
+const scanAddRules = {
+  purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
+  supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }],
+  projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+};
+
+// 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
+const scanDialogVisible = ref(false);
+const scanForm = reactive({
+  purchaseContractNumber: "",
+  supplierName: "",
+  projectName: "",
+  scanTime: "",
+  scannerName: "",
+  scanStatus: "鏈壂鐮�",
+  scanRemark: "",
+});
+const scanRules = {
+  scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
+};
+const scanRecords = ref([]);
+
+// 鎵撳紑鎵爜鏂板瀵硅瘽妗�
+const openScanAddDialog = () => {
+  scanAddForm.scanContent = "";
+  scanAddForm.purchaseContractNumber = "";
+  scanAddForm.supplierName = "";
+  scanAddForm.projectName = "";
+  scanAddForm.contractAmount = "";
+  scanAddForm.paymentMethod = "";
+  scanAddForm.recorderName = userStore.nickName;
+  scanAddForm.scanRemark = "";
+  scanAddDialogVisible.value = true;
+};
+
+// 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
+const parseScanContent = (content) => {
+  if (!content) return;
+  
+  // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
+  // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡椤圭洰|閲戦|浠樻鏂瑰紡
+  const parts = content.split('|');
+  if (parts.length >= 3) {
+    scanAddForm.purchaseContractNumber = parts[0] || "";
+    scanAddForm.supplierName = parts[1] || "";
+    scanAddForm.projectName = parts[2] || "";
+    scanAddForm.contractAmount = parts[3] || "";
+    scanAddForm.paymentMethod = parts[4] || "";
+  }
+};
+
+// 鍏抽棴鎵爜鏂板瀵硅瘽妗�
+const closeScanAddDialog = () => {
+  scanAddDialogVisible.value = false;
+  proxy.resetForm("scanAddFormRef");
+};
+
+// 鎻愪氦鎵爜鏂板
+const submitScanAdd = () => {
+  proxy.$refs["scanAddFormRef"].validate((valid) => {
+    if (valid) {
+      // 鏋勫缓鏂板鏁版嵁
+      const newData = {
+        purchaseContractNumber: scanAddForm.purchaseContractNumber,
+        supplierName: scanAddForm.supplierName,
+        projectName: scanAddForm.projectName,
+        contractAmount: scanAddForm.contractAmount,
+        paymentMethod: scanAddForm.paymentMethod,
+        recorderName: scanAddForm.recorderName,
+        entryDate: getCurrentDate(),
+        remark: scanAddForm.scanRemark,
+        type: 2
+      };
+      
+      // 妯℃嫙鏂板鎴愬姛
+      proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
+      closeScanAddDialog();
+      
+      // 鍙互閫夋嫨鏄惁鍒锋柊鍒楄〃
+      // getList();
+    }
+  });
+};
+
+// 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
+const openScanDialog = (row) => {
+  scanForm.purchaseContractNumber = row.purchaseContractNumber;
+  scanForm.supplierName = row.supplierName;
+  scanForm.projectName = row.projectName;
+  scanForm.scanTime = getCurrentDateTime();
+  scanForm.scannerName = userStore.nickName;
+  scanForm.scanStatus = "鏈壂鐮�";
+  scanForm.scanRemark = "";
+  scanRecords.value = [];
+  scanDialogVisible.value = true;
+};
+
+// 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
+const closeScanDialog = () => {
+  scanDialogVisible.value = false;
+  proxy.resetForm("scanFormRef");
+};
+
+// 鎻愪氦鎵爜鐧昏
+const submitScan = () => {
+  proxy.$refs["scanFormRef"].validate((valid) => {
+    if (valid) {
+      // 娣诲姞鎵爜璁板綍
+      scanRecords.value.push({
+        ...scanForm,
+        id: Date.now(), // 妯℃嫙ID
+        scanTime: getCurrentDateTime(),
+      });
+      scanForm.scanStatus = "宸叉壂鐮�";
+      scanForm.scanRemark = scanForm.scanRemark || "鏃�";
+      proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
+      closeScanDialog();
+    }
+  });
+};
+
+// 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
+function getCurrentDateTime() {
+  const now = new Date();
+  const year = now.getFullYear();
+  const month = String(now.getMonth() + 1).padStart(2, "0");
+  const day = String(now.getDate()).padStart(2, "0");
+  const hours = String(now.getHours()).padStart(2, "0");
+  const minutes = String(now.getMinutes()).padStart(2, "0");
+  const seconds = String(now.getSeconds()).padStart(2, "0");
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+
+
 onMounted(() => {
   getList();
 });

--
Gitblit v1.9.3