wanshenmean
2026-03-19 c493779a8504fe1eb548c865ff268a7f7436ec01
Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/EditView.vue
@@ -1,5 +1,5 @@
<template>
  <div>
<template>
  <div class="admin-page">
    <div v-if="loading" class="loading-container">
      <el-icon class="loading-icon" :size="40"><Loading /></el-icon>
      <p>加载中...</p>
@@ -40,7 +40,7 @@
      <el-row justify="center">
        <el-col :lg="24">
          <el-card shadow="never">
          <el-card shadow="never" class="panel-card">
            <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
              <!-- 基本信息 -->
              <el-divider content-position="left">
@@ -98,6 +98,21 @@
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="协议模板" prop="protocolTemplateId">
                    <el-select v-model="form.protocolTemplateId" style="width: 100%">
                      <el-option
                        v-for="tpl in protocolTemplates"
                        :key="tpl.id"
                        :label="`${tpl.name} (${tpl.id})`"
                        :value="tpl.id"
                      />
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <!-- 内存配置 -->
              <el-divider content-position="left">
                <h3>内存配置</h3>
@@ -105,7 +120,7 @@
              <el-row :gutter="20">
                <el-col :span="8">
                  <el-form-item label="M区域大小">
                  <el-form-item label="M区大小">
                    <el-input-number
                      v-model="form.mRegionSize"
                      :min="0"
@@ -114,7 +129,7 @@
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="I区域大小">
                  <el-form-item label="I区大小">
                    <el-input-number
                      v-model="form.iRegionSize"
                      :min="0"
@@ -123,7 +138,7 @@
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="Q区域大小">
                  <el-form-item label="Q区大小">
                    <el-input-number
                      v-model="form.qRegionSize"
                      :min="0"
@@ -135,11 +150,16 @@
              <el-row :gutter="20">
                <el-col :span="8">
                  <el-form-item label="DB块数量">
                    <el-input-number
                      v-model="form.dbBlockCount"
                      :min="0"
                  <el-form-item label="DB块列表">
                    <el-select
                      v-model="form.dbBlockNumbers"
                      multiple
                      filterable
                      allow-create
                      default-first-option
                      :reserve-keyword="false"
                      style="width: 100%"
                      placeholder="输入块号后回车,例如 50、900、901"
                    />
                  </el-form-item>
                </el-col>
@@ -194,7 +214,7 @@
import type { FormInstance, FormRules } from 'element-plus'
import { Edit, Back, Loading } from '@element-plus/icons-vue'
import * as api from '../api'
import type { InstanceConfig, MemoryRegionConfig, SiemensPLCType } from '../types'
import type { InstanceConfig, MemoryRegionConfig, ProtocolTemplate, SiemensPLCType } from '../types'
const router = useRouter()
const route = useRoute()
@@ -207,9 +227,11 @@
  port: 102,
  activationKey: '',
  autoStart: false,
  protocolTemplateId: '',
  mRegionSize: 1024,
  dbBlockCount: 100,
  dbBlockSize: 1024,
  dbBlockCount: 0,
  dbBlockNumbers: [] as Array<number | string>,
  dbBlockSize: 65536,
  iRegionSize: 256,
  qRegionSize: 256,
  tRegionCount: 64,
@@ -220,6 +242,7 @@
const errorMsg = ref('')
const submitting = ref(false)
const isRunning = ref(false)
const protocolTemplates = ref<ProtocolTemplate[]>([])
const id = route.params.id as string
@@ -232,12 +255,17 @@
  ],
  port: [
    { required: true, message: '请输入监听端口', trigger: 'blur' },
    { type: 'number', min: 1, max: 65535, message: '端口必须在1-65535之间', trigger: 'blur' }
    { type: 'number', min: 1, max: 65535, message: '端口必须在 1-65535 之间', trigger: 'blur' }
  ],
  protocolTemplateId: [
    { required: true, message: '请选择协议模板', trigger: 'change' }
  ]
}
onMounted(async () => {
  try {
    protocolTemplates.value = await api.getProtocolTemplates()
    // 获取实例状态
    const state = await api.getInstance(id)
    if (!state) {
@@ -263,8 +291,10 @@
      port: config.port,
      activationKey: config.activationKey,
      autoStart: config.autoStart,
      protocolTemplateId: config.protocolTemplateId || '',
      mRegionSize: config.memoryConfig.mRegionSize,
      dbBlockCount: config.memoryConfig.dbBlockCount,
      dbBlockCount: 0,
      dbBlockNumbers: toDbBlockNumbers(config.memoryConfig.dbBlockNumbers, config.memoryConfig.dbBlockCount),
      dbBlockSize: config.memoryConfig.dbBlockSize,
      iRegionSize: config.memoryConfig.iRegionSize,
      qRegionSize: config.memoryConfig.qRegionSize,
@@ -288,9 +318,16 @@
    submitting.value = true
    try {
      const dbBlockNumbers = normalizeDbBlockNumbers(form.value.dbBlockNumbers)
      if (dbBlockNumbers.length === 0) {
        ElMessage.error('请至少配置一个DB块号,例如 50,900,901')
        return
      }
      const memoryConfig: MemoryRegionConfig = {
        mRegionSize: form.value.mRegionSize > 0 ? form.value.mRegionSize : 1024,
        dbBlockCount: form.value.dbBlockCount > 0 ? form.value.dbBlockCount : 100,
        dbBlockCount: 0,
        dbBlockNumbers,
        dbBlockSize: form.value.dbBlockSize > 0 ? form.value.dbBlockSize : 1024,
        iRegionSize: form.value.iRegionSize > 0 ? form.value.iRegionSize : 256,
        qRegionSize: form.value.qRegionSize > 0 ? form.value.qRegionSize : 256,
@@ -305,6 +342,7 @@
        port: form.value.port,
        activationKey: form.value.activationKey,
        autoStart: form.value.autoStart,
        protocolTemplateId: form.value.protocolTemplateId,
        memoryConfig
      }
@@ -324,49 +362,29 @@
    }
  })
}
function normalizeDbBlockNumbers(input: Array<number | string>): number[] {
  return Array.from(new Set(
    input
      .map(x => Number(String(x).trim()))
      .filter(x => Number.isInteger(x) && x > 0)
  )).sort((a, b) => a - b)
}
function toDbBlockNumbers(dbBlockNumbers: number[] | undefined, dbBlockCount: number): Array<number | string> {
  if (dbBlockNumbers && dbBlockNumbers.length > 0) {
    return dbBlockNumbers
  }
  if (dbBlockCount > 0) {
    return Array.from({ length: dbBlockCount }, (_, idx) => idx + 1)
  }
  return []
}
</script>
<style scoped>
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 16px;
}
.header-left h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px 0;
}
.text-muted {
  color: #909399;
  margin: 0;
}
.loading-container {
  text-align: center;
  padding: 60px 0;
  color: #909399;
}
.loading-icon {
  animation: spin 1s linear infinite;
}
@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
.form-tip {
  font-size: 12px;
  color: #909399;