Quellcode durchsuchen

优化问题库管理页面

yawuga vor 2 Wochen
Ursprung
Commit
b4f62457b6

+ 212 - 98
src/views/base/faq/index.vue

@@ -1,24 +1,31 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="问题分类字典值,字典类型:robot_faq_category" prop="categoryType">
-        <el-select v-model="queryParams.categoryType" placeholder="请选择问题分类字典值,字典类型:robot_faq_category" clearable>
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="90px">
+      <el-form-item label="问题分类" prop="categoryType">
+        <el-select v-model="queryParams.categoryType" placeholder="请选择问题分类" clearable style="width: 180px">
           <el-option
             v-for="dict in robot_faq_category"
             :key="dict.value"
             :label="dict.label"
-            :value="dict.value"
+            :value="String(dict.value)"
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="排序号,数字越小越靠前" prop="sortNo">
+      <el-form-item label="标准问题" prop="question">
         <el-input
-          v-model="queryParams.sortNo"
-          placeholder="请输入排序号,数字越小越靠前"
+          v-model="queryParams.question"
+          placeholder="请输入标准问题关键字"
           clearable
+          style="width: 220px"
           @keyup.enter="handleQuery"
         />
       </el-form-item>
+      <el-form-item label="启用状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择启用状态" clearable style="width: 160px">
+          <el-option label="启用" value="1" />
+          <el-option label="停用" value="0" />
+        </el-select>
+      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
         <el-button icon="Refresh" @click="resetQuery">重置</el-button>
@@ -69,19 +76,52 @@
 
     <el-table v-loading="loading" :data="faqList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="主键ID" align="center" prop="id" />
-      <el-table-column label="问题分类字典值,字典类型:robot_faq_category" align="center" prop="categoryType">
+      <el-table-column label="问题分类" align="center" prop="categoryType" width="120">
+        <template #default="scope">
+          <dict-tag :options="robot_faq_category" :value="scope.row.categoryType != null ? String(scope.row.categoryType) : ''" />
+        </template>
+      </el-table-column>
+      <el-table-column label="标准问题" align="left" prop="question" min-width="220" show-overflow-tooltip />
+      <el-table-column label="相似问" align="center" width="90">
+        <template #default="scope">
+          <el-tag type="info">{{ getSimilarCount(scope.row) }} 条</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="答案摘要" align="left" prop="answer" min-width="260" show-overflow-tooltip>
+        <template #default="scope">
+          <span>{{ formatAnswerSummary(scope.row.answer) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="启用状态" align="center" prop="status" width="100">
         <template #default="scope">
-          <dict-tag :options="robot_faq_category" :value="scope.row.categoryType"/>
+          <el-tag v-if="String(scope.row.status) === '1'" type="success">启用</el-tag>
+          <el-tag v-else-if="String(scope.row.status) === '0'" type="info">停用</el-tag>
+          <el-tag v-else type="info">-</el-tag>
         </template>
       </el-table-column>
-      <el-table-column label="标准问题" align="center" prop="question" />
-      <el-table-column label="答案内容" align="center" prop="answer" />
-      <el-table-column label="排序号,数字越小越靠前" align="center" prop="sortNo" />
-      <el-table-column label="启用状态:0停用,1启用" align="center" prop="status" />
-      <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="更新时间" align="center" prop="updateTime" width="160">
         <template #default="scope">
+          <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') || '-' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="240" fixed="right" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button
+            v-if="String(scope.row.status) !== '1'"
+            link
+            type="primary"
+            icon="CircleCheck"
+            @click="handleStatusChange(scope.row, '1')"
+            v-hasPermi="['base:faq:edit']"
+          >启用</el-button>
+          <el-button
+            v-if="String(scope.row.status) === '1'"
+            link
+            type="warning"
+            icon="CircleClose"
+            @click="handleStatusChange(scope.row, '0')"
+            v-hasPermi="['base:faq:edit']"
+          >停用</el-button>
           <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['base:faq:edit']">修改</el-button>
           <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['base:faq:remove']">删除</el-button>
         </template>
@@ -96,71 +136,78 @@
       @pagination="getList"
     />
 
-    <!-- 添加或修改问答库管理对话框 -->
-    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
-      <el-form ref="faqRef" :model="form" :rules="rules" label-width="100px">
+    <!-- 添加或修改问答对话框 -->
+    <el-dialog :title="title" v-model="open" width="760px" append-to-body>
+      <el-form ref="faqRef" :model="form" :rules="rules" label-width="110px">
         <el-row>
           <el-col :span="24">
-            <el-form-item label="问题分类字典值,字典类型:robot_faq_category" prop="categoryType">
-              <el-select v-model="form.categoryType" placeholder="请选择问题分类字典值,字典类型:robot_faq_category">
+            <el-form-item label="问题分类" prop="categoryType">
+              <el-select v-model="form.categoryType" placeholder="请选择问题分类" style="width: 100%">
                 <el-option
                   v-for="dict in robot_faq_category"
                   :key="dict.value"
                   :label="dict.label"
-                  :value="dict.value"
+                  :value="String(dict.value)"
                 ></el-option>
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="24">
             <el-form-item label="标准问题" prop="question">
-              <el-input v-model="form.question" type="textarea" placeholder="请输入内容" />
+              <el-input
+                v-model="form.question"
+                maxlength="500"
+                show-word-limit
+                placeholder="请输入标准问题"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="相似问" prop="similarQuestionsText">
+              <el-input
+                v-model="similarQuestionsText"
+                type="textarea"
+                :rows="5"
+                maxlength="2000"
+                show-word-limit
+                placeholder="请输入相似问,一行一个。例如:&#10;你是谁?&#10;你能做什么?&#10;介绍一下你自己"
+              />
+              <div class="form-tip">一行一个相似问,保存时会自动转换为相似问列表。</div>
             </el-form-item>
           </el-col>
           <el-col :span="24">
             <el-form-item label="答案内容" prop="answer">
-              <el-input v-model="form.answer" type="textarea" placeholder="请输入内容" />
+              <el-input
+                v-model="form.answer"
+                type="textarea"
+                :rows="6"
+                maxlength="2000"
+                show-word-limit
+                placeholder="请输入答案内容"
+              />
             </el-form-item>
           </el-col>
           <el-col :span="24">
-            <el-form-item label="排序号,数字越小越靠前" prop="sortNo">
-              <el-input v-model="form.sortNo" placeholder="请输入排序号,数字越小越靠前" />
+            <el-form-item label="启用状态" prop="status">
+              <el-radio-group v-model="form.status">
+                <el-radio label="1">启用</el-radio>
+                <el-radio label="0">停用</el-radio>
+              </el-radio-group>
             </el-form-item>
           </el-col>
           <el-col :span="24">
             <el-form-item label="备注" prop="remark">
-              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+              <el-input
+                v-model="form.remark"
+                type="textarea"
+                :rows="3"
+                maxlength="500"
+                show-word-limit
+                placeholder="请输入备注"
+              />
             </el-form-item>
           </el-col>
         </el-row>
-        <el-divider content-position="center">问答相似问信息</el-divider>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="1.5">
-            <el-button type="primary" icon="Plus" @click="handleAddRobotOpsFaqSimilar">添加</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="danger" icon="Delete" @click="handleDeleteRobotOpsFaqSimilar">删除</el-button>
-          </el-col>
-        </el-row>
-        <el-table :data="robotOpsFaqSimilarList" @selection-change="handleRobotOpsFaqSimilarSelectionChange" ref="robotOpsFaqSimilar">
-          <el-table-column type="selection" width="50" align="center" />
-          <el-table-column label="序号" width="60">
-            <template #default="{ $index }">
-              {{ $index + 1 }}
-            </template>
-          </el-table-column>
-          <!-- 新增:相似问文本列 -->
-          <el-table-column label="相似问文本" prop="similarQuestion" min-width="200">
-            <template #default="scope">
-              <el-input v-model="scope.row.similarQuestion" placeholder="请输入相似问文本" />
-            </template>
-          </el-table-column>
-          <el-table-column label="排序号,数字越小越靠前" prop="sortNo" width="150">
-            <template #default="scope">
-              <el-input v-model="scope.row.sortNo" placeholder="请输入排序号,数字越小越靠前" />
-            </template>
-          </el-table-column>
-        </el-table>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -179,12 +226,11 @@ const { proxy } = getCurrentInstance()
 const { robot_faq_category } = useDict('robot_faq_category')
 
 const faqList = ref([])
-const robotOpsFaqSimilarList = ref([])
+const similarQuestionsText = ref("")
 const open = ref(false)
 const loading = ref(true)
 const showSearch = ref(true)
 const ids = ref([])
-const checkedRobotOpsFaqSimilar = ref([])
 const single = ref(true)
 const multiple = ref(true)
 const total = ref(0)
@@ -197,11 +243,12 @@ const data = reactive({
     pageSize: 10,
     categoryType: undefined,
     question: undefined,
-    answer: undefined,
-    sortNo: undefined,
     status: undefined,
   },
   rules: {
+    categoryType: [
+      { required: true, message: "请选择问题分类", trigger: "change" }
+    ],
     question: [
       { required: true, message: "标准问题不能为空", trigger: "blur" }
     ],
@@ -209,19 +256,23 @@ const data = reactive({
       { required: true, message: "答案内容不能为空", trigger: "blur" }
     ],
     status: [
-      { required: true, message: "启用状态:0停用,1启用不能为空", trigger: "change" }
-    ],
+      { required: true, message: "请选择启用状态", trigger: "change" }
+    ]
   }
 })
 
 const { queryParams, form, rules } = toRefs(data)
 
-/** 查询问答库管理列表 */
+/** 查询问答库列表 */
 function getList() {
   loading.value = true
   listFaq(queryParams.value).then(response => {
-    faqList.value = response.rows
-    total.value = response.total
+    faqList.value = response.rows || []
+    total.value = response.total || 0
+  }).catch(() => {
+    faqList.value = []
+    total.value = 0
+  }).finally(() => {
     loading.value = false
   })
 }
@@ -239,15 +290,15 @@ function reset() {
     categoryType: null,
     question: null,
     answer: null,
-    sortNo: null,
-    status: null,
+    sortNo: 0,
+    status: "1",
     remark: null,
     createTime: null,
     updateTime: null,
     createBy: null,
     updateBy: null
   }
-  robotOpsFaqSimilarList.value = []
+  similarQuestionsText.value = ""
   proxy.resetForm("faqRef")
 }
 
@@ -274,37 +325,74 @@ function handleSelectionChange(selection) {
 function handleAdd() {
   reset()
   open.value = true
-  title.value = "添加问答库管理"
+  title.value = "新增问答"
 }
 
 /** 修改按钮操作 */
 function handleUpdate(row) {
   reset()
-  const _id = row.id || ids.value
+  const _id = row.id || ids.value[0]
   getFaq(_id).then(response => {
-    form.value = response.data
-    robotOpsFaqSimilarList.value = response.data.robotOpsFaqSimilarList
+    const data = response.data || {}
+    form.value = {
+      ...data,
+      categoryType: data.categoryType != null ? String(data.categoryType) : null,
+      status: data.status != null ? String(data.status) : "1",
+      sortNo: data.sortNo != null ? Number(data.sortNo) : 0
+    }
+    const similarList = data.robotOpsFaqSimilarList || data.similarQuestions || []
+    if (Array.isArray(similarList)) {
+      similarQuestionsText.value = similarList
+        .map(item => typeof item === "string" ? item : item.similarQuestion)
+        .filter(Boolean)
+        .join("\n")
+    } else {
+      similarQuestionsText.value = ""
+    }
     open.value = true
-    title.value = "修改问答库管理"
+    title.value = "修改问答"
+  }).catch(() => {
+    proxy.$modal.msgError("获取问答详情失败")
   })
 }
 
+/** 将相似问多行文本转换为子表列表 */
+function buildSimilarQuestionList() {
+  const uniqueList = Array.from(new Set(
+    similarQuestionsText.value
+      .split("\n")
+      .map(item => item.trim())
+      .filter(Boolean)
+  ))
+  return uniqueList.map((text, index) => ({
+    similarQuestion: text,
+    sortNo: index + 1
+  }))
+}
+
 /** 提交按钮 */
 function submitForm() {
   proxy.$refs["faqRef"].validate(valid => {
     if (valid) {
-      form.value.robotOpsFaqSimilarList = robotOpsFaqSimilarList.value
+      const similarList = buildSimilarQuestionList()
+      form.value.sortNo = form.value.sortNo != null ? Number(form.value.sortNo) : 0
+      form.value.robotOpsFaqSimilarList = similarList
+      form.value.similarQuestions = similarList.map(item => item.similarQuestion)
       if (form.value.id != null) {
         updateFaq(form.value).then(() => {
           proxy.$modal.msgSuccess("修改成功")
           open.value = false
           getList()
+        }).catch(() => {
+          proxy.$modal.msgError("修改失败")
         })
       } else {
         addFaq(form.value).then(() => {
           proxy.$modal.msgSuccess("新增成功")
           open.value = false
           getList()
+        }).catch(() => {
+          proxy.$modal.msgError("新增失败")
         })
       }
     }
@@ -314,7 +402,7 @@ function submitForm() {
 /** 删除按钮操作 */
 function handleDelete(row) {
   const _ids = row.id || ids.value
-  proxy.$modal.confirm('是否确认删除问答库管理编号为"' + _ids + '"的数据项?').then(function() {
+  proxy.$modal.confirm("确认删除选中的问答数据吗?删除后不可恢复。").then(function() {
     return delFaq(_ids)
   }).then(() => {
     getList()
@@ -322,38 +410,64 @@ function handleDelete(row) {
   }).catch(() => {})
 }
 
-/** 问答相似问添加按钮操作 */
-function handleAddRobotOpsFaqSimilar() {
-  let obj = {}
-  obj.similarQuestion = undefined // 初始化相似问文本
-  obj.sortNo = undefined
-  robotOpsFaqSimilarList.value.push(obj)
-}
-
-/** 问答相似问删除按钮操作 */
-function handleDeleteRobotOpsFaqSimilar() {
-  if (checkedRobotOpsFaqSimilar.value.length == 0) {
-    proxy.$modal.msgError("请先选择要删除的问答相似问数据")
-  } else {
-    const robotOpsFaqSimilars = robotOpsFaqSimilarList.value
-    const checkedRobotOpsFaqSimilars = checkedRobotOpsFaqSimilar.value
-    robotOpsFaqSimilarList.value = robotOpsFaqSimilars.filter(function(item) {
-      return checkedRobotOpsFaqSimilars.indexOf(item.index) == -1
+/** 启用/停用问答 */
+function handleStatusChange(row, status) {
+  const actionText = status === "1" ? "启用" : "停用"
+  proxy.$modal.confirm('确认' + actionText + '问答“' + row.question + '”吗?').then(() => {
+    return getFaq(row.id)
+  }).then(response => {
+    const data = response.data || {}
+    return updateFaq({
+      ...data,
+      status,
+      categoryType: data.categoryType != null ? String(data.categoryType) : data.categoryType,
+      robotOpsFaqSimilarList: data.robotOpsFaqSimilarList || []
     })
-  }
-}
-
-/** 复选框选中数据 */
-function handleRobotOpsFaqSimilarSelectionChange(selection) {
-  checkedRobotOpsFaqSimilar.value = selection.map(item => item.index)
+  }).then(() => {
+    proxy.$modal.msgSuccess(actionText + "成功")
+    getList()
+  }).catch(() => {})
 }
 
 /** 导出按钮操作 */
 function handleExport() {
   proxy.download('base/faq/export', {
     ...queryParams.value
-  }, `faq_${new Date().getTime()}.xlsx`)
+  }, `问答库_${new Date().getTime()}.xlsx`)
+}
+
+/** 获取相似问数量 */
+function getSimilarCount(row) {
+  if (row.similarCount !== undefined && row.similarCount !== null) {
+    return row.similarCount
+  }
+  if (Array.isArray(row.robotOpsFaqSimilarList)) {
+    return row.robotOpsFaqSimilarList.length
+  }
+  return 0
+}
+
+/** 格式化答案摘要 */
+function formatAnswerSummary(answer) {
+  if (!answer) return "-"
+  return answer.length > 80 ? answer.slice(0, 80) + "..." : answer
 }
 
 getList()
 </script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+.form-tip {
+  margin-top: 6px;
+  font-size: 12px;
+  line-height: 1.5;
+  color: #909399;
+}
+:deep(.el-table .cell) {
+  line-height: 22px;
+}
+</style>
+

+ 69 - 11
迎宾巡逻安防机器人运维端Web管理系统详细设计开发文档_V2.1.html

@@ -100,7 +100,7 @@
       <tbody>
         <tr><td>首页</td><td>首页总览</td><td>定制开发</td><td>否</td><td>首页涉及机器人实时状态、统计卡片、告警摘要、快捷操作入口,属于聚合看板页面,不能直接按单表 CRUD 生成。</td></tr>
         <tr><td rowspan="7">内容管理</td><td>欢迎语配置</td><td>半定制开发</td><td>部分适合</td><td>可基于 robot_ops_welcome_config 生成基础表单,但页面更接近单配置页,需定制保存、恢复默认、测试播报等操作。</td></tr>
-        <tr><td>问答库管理</td><td>RuoYi 生成后定制</td><td>部分适合</td><td>可基于 robot_ops_faq、robot_ops_faq_similar 生成基础 CRUD;问题分类使用 RuoYi 字典 robot_faq_category,不单独生成问答分类管理页面;需补充相似问多行编辑、导入导出、分类字典下拉等逻辑。</td></tr>
+        <tr><td>问答库管理</td><td>RuoYi 主子表生成后定制</td><td>部分适合</td><td>可基于 robot_ops_faq、robot_ops_faq_similar 生成基础 CRUD;问题分类使用 RuoYi 字典 robot_faq_category,不单独生成问答分类管理页面;前端需将主子表明细表格调整为"相似问多行输入,一行一个"的交互方式;sortNo 作为保留字段,不在页面展示和编辑;启用/停用、导出、分类字典回显需按业务微调。一期暂不支持问答库导入,后续如运营需要批量维护再扩展。</td></tr>
         <tr><td>素材管理</td><td>RuoYi 生成后定制</td><td>部分适合</td><td>基础列表、查询、编辑可生成;上传、缩略图展示、图片/视频预览、引用保护需要定制。</td></tr>
         <tr><td>播放方案管理</td><td>定制开发</td><td>否</td><td>涉及主子表、素材选择、拖拽排序、播放时长、复制方案、预览方案等复杂交互,建议 Cursor 或开发人员手工实现。</td></tr>
         <tr><td>播报内容管理</td><td>RuoYi 生成后微调</td><td>适合</td><td>典型单表 CRUD,可基于 robot_ops_broadcast_content 生成,再补充测试播报按钮。</td></tr>
@@ -137,7 +137,19 @@
 
     <h3>6.3 内容管理</h3>
     <h4>6.3.1 欢迎语配置页面</h4><table><thead><tr><th>字段/功能</th><th>类型</th><th>详细设计</th></tr></thead><tbody><tr><td>欢迎语文本(welcomeText)</td><td>textarea</td><td>欢迎语文本,最大 200 字。</td></tr><tr><td>是否启用语音播报(voiceEnabled)</td><td>switch</td><td>是否启用语音播报。</td></tr><tr><td>触发冷却时间(cooldownSeconds)</td><td>number</td><td>触发冷却时间,单位秒,默认 30。</td></tr><tr><td>启用状态(status)</td><td>switch</td><td>启用/停用。</td></tr><tr><td>保存</td><td>button</td><td>保存当前配置。</td></tr><tr><td>恢复默认</td><td>button</td><td>恢复系统默认欢迎语配置。</td></tr><tr><td>测试播报</td><td>button</td><td>下发测试播报指令。</td></tr></tbody></table>
-    <h4>6.3.2 问答库管理页面</h4><table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody><tr><td>查询条件</td><td>问题分类(categoryType,数据来源:RuoYi 字典 robot_faq_category)、标准问题关键字、启用状态、更新时间范围。</td></tr><tr><td>列表字段</td><td>问题分类、标准问题、相似问数量、答案摘要、状态、排序、更新时间、操作。</td></tr><tr><td>操作按钮</td><td>新增、编辑、删除、启用/停用、导入、导出、批量删除。</td></tr><tr><td>编辑弹窗字段</td><td>问题分类(categoryType,RuoYi 字典 robot_faq_category)、标准问题(question)、相似问(similarQuestions)、答案内容(answer)、排序(sortNo)、启用状态(status)、备注(remark)。</td></tr><tr><td>交互规则</td><td>similarQuestions 用多行输入,一行一个;answer 最多 2000 字。</td></tr><tr><td>导入规则</td><td>Excel 字段:问题分类、标准问题、相似问、答案、排序、状态;问题分类按 RuoYi 字典 robot_faq_category 的字典标签或字典值匹配;相似问用英文分号分隔。</td></tr></tbody></table>
+    <h4>6.3.2 问答库管理页面</h4>
+<table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody>
+<tr><td>页面目标</td><td>维护机器人 FAQ 问答内容,支持按问题分类管理标准问题、相似问和答案内容。页面基于 robot_ops_faq 主表和 robot_ops_faq_similar 相似问表实现,前端以一个"问答库管理"页面统一维护,不单独建设相似问管理菜单。</td></tr>
+<tr><td>查询条件</td><td>问题分类(categoryType,数据来源:RuoYi 字典 robot_faq_category)、标准问题关键字、启用状态。</td></tr>
+<tr><td>列表字段</td><td>问题分类、标准问题、相似问数量、答案摘要、启用状态、更新时间、操作。</td></tr>
+<tr><td>操作按钮</td><td>新增、编辑、删除、批量删除、启用/停用、导出。</td></tr>
+<tr><td>编辑弹窗字段</td><td>问题分类(categoryType,RuoYi 字典 robot_faq_category)、标准问题(question)、相似问(similarQuestions)、答案内容(answer)、启用状态(status)、备注(remark)。</td></tr>
+<tr><td>相似问交互</td><td>相似问使用多行文本框维护,一行一个相似问;保存时前端转换为相似问列表,后端写入 robot_ops_faq_similar 表。</td></tr>
+<tr><td>答案内容规则</td><td>答案内容最多 2000 字,列表中只展示答案摘要,完整答案在编辑弹窗中维护。</td></tr>
+<tr><td>排序规则</td><td>sortNo / sort_no 作为保留字段,数据库继续保留;前端页面一期不展示、不编辑。新增问答时默认 sortNo=0,编辑问答时保持原值。后续如需在机器人屏幕端展示推荐问答或人工排序,再重新设计推荐/置顶/排序能力。</td></tr>
+<tr><td>业务规则</td><td>同一分类下标准问题建议不重复,新增和编辑时由后端进行重复校验。删除主问答时,应同步删除其相似问数据。</td></tr>
+<tr><td>导入说明</td><td>问答库一期暂不支持导入。后续如运营确实需要批量维护问答内容,再单独扩展 Excel 导入模板、问题分类匹配、相似问拆分、重复校验和失败明细回显能力。</td></tr>
+</tbody></table>
     <h4>6.3.3 素材管理页面</h4><table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody><tr><td>查询条件</td><td>素材名称、素材类型、启用状态、上传时间范围。</td></tr><tr><td>列表字段</td><td>缩略图(thumbnailUrl)、素材名称(assetName)、素材类型(assetType)、文件格式(fileFormat)、文件大小(fileSize)、时长秒数(durationSeconds)、分辨率(resolution)、上传时间(createTime)、引用状态(quotedFlag)、启用状态(status)、操作。</td></tr><tr><td>操作按钮</td><td>上传、预览、编辑名称、删除、启用/停用、批量删除。</td></tr><tr><td>上传规则</td><td>图片支持 jpg/png/webp;视频支持 mp4;单文件大小默认上限 500MB。</td></tr><tr><td>引用保护</td><td>被播放方案引用的素材不可直接删除,需先解除引用。</td></tr><tr><td>预览规则</td><td>图片弹窗预览;视频弹窗播放器预览;无法播放时提示格式不支持。</td></tr></tbody></table>
     <h4>6.3.4 播放方案管理页面</h4><table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody><tr><td>查询条件</td><td>方案名称、是否默认、启用状态。</td></tr><tr><td>列表字段</td><td>方案名称、素材数、循环方式、默认方案、启用状态、更新时间、操作。</td></tr><tr><td>编辑页面字段</td><td>方案名称(planName)、循环方式(loopMode)、是否默认(isDefault)、启用状态(status)、备注(remark)、素材明细列表(itemList)。</td></tr><tr><td>素材明细字段</td><td>素材 ID(assetId)、素材名称(assetName,关联素材表展示字段)、素材类型(assetType,关联素材表展示字段)、播放顺序(playOrder)、停留时长(staySeconds)、转场方式(transitionType)。</td></tr><tr><td>操作按钮</td><td>新增、编辑、复制、删除、设为默认、启用/停用、预览。</td></tr><tr><td>交互规则</td><td>支持拖拽排序;图片素材必须填写停留时长;视频素材默认播完切换。</td></tr></tbody></table>
     <h4>6.3.5 播报内容管理页面</h4><table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody><tr><td>查询条件</td><td>内容名称、内容分类、启用状态。</td></tr><tr><td>列表字段</td><td>内容名称、内容分类、播报文本摘要、启用状态、更新时间、操作。</td></tr><tr><td>编辑字段</td><td>内容名称(contentName)、内容分类(contentType)、播报文本(broadcastText)、启用状态(status)、备注(remark)。</td></tr><tr><td>操作按钮</td><td>新增、编辑、删除、启用/停用、测试播报。</td></tr><tr><td>内容分类</td><td>通知、宣传、提示、安防提醒、自定义。</td></tr></tbody></table>
@@ -326,16 +338,19 @@
 
     <h4>7.4.2 问答库接口</h4>
     <table><thead><tr><th>接口</th><th>方法</th><th>说明</th><th>请求参数</th><th>返回/处理字段</th><th>数据库表</th></tr></thead><tbody>
-      <tr><td>/robot-ops/content/faq/page</td><td>GET</td><td>问答分页</td><td>问题分类(categoryType,字典值)、关键字(keyword)、启用状态(status)、pageNum、pageSize</td><td>问答ID(id)、问题分类名称(categoryName,按字典回显)、标准问题(question)、相似问数量(similarCount)、答案摘要(answerSummary)、排序(sortNo)、状态(status)、更新时间(updateTime)</td><td>robot_ops_faq、robot_ops_faq_similar;分类名称通过 RuoYi 字典 robot_faq_category 回显</td></tr>
-      <tr><td>/robot-ops/content/faq/{id}</td><td>GET</td><td>问答详情</td><td>问答ID(id)</td><td>categoryType、question、similarQuestions、answer、sortNo、status、remark</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
-      <tr><td>/robot-ops/content/faq</td><td>POST</td><td>新增问答</td><td>categoryType、question、similarQuestions、answer、sortNo、status、remark</td><td>新增后的问答ID(id)</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
-      <tr><td>/robot-ops/content/faq</td><td>PUT</td><td>编辑问答</td><td>id、categoryType、question、similarQuestions、answer、sortNo、status、remark</td><td>无</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
+      <tr><td>/robot-ops/content/faq/page</td><td>GET</td><td>问答分页</td><td>问题分类(categoryType,字典值)、标准问题关键字(question)、启用状态(status)、pageNum、pageSize</td><td>问答ID(id)、问题分类(categoryType,按字典回显)、标准问题(question)、相似问数量(similarCount)、答案摘要(answerSummary)、启用状态(status)、更新时间(updateTime)</td><td>robot_ops_faq、robot_ops_faq_similar;分类名称通过 RuoYi 字典 robot_faq_category 回显</td></tr>
+      <tr><td>/robot-ops/content/faq/{id}</td><td>GET</td><td>问答详情</td><td>问答ID(id)</td><td>categoryType、question、similarQuestions 或 robotOpsFaqSimilarList、answer、sortNo、status、remark</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
+      <tr><td>/robot-ops/content/faq</td><td>POST</td><td>新增问答</td><td>categoryType、question、similarQuestions 或 robotOpsFaqSimilarList、answer、status、remark;sortNo 由前端默认传 0 或后端默认写入 0</td><td>新增后的问答ID(id)</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
+      <tr><td>/robot-ops/content/faq</td><td>PUT</td><td>编辑问答</td><td>id、categoryType、question、similarQuestions 或 robotOpsFaqSimilarList、answer、sortNo、status、remark;前端页面不展示 sortNo,编辑时保持原值</td><td>无</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
       <tr><td>/robot-ops/content/faq/{id}</td><td>DELETE</td><td>删除问答</td><td>问答ID(id)</td><td>无</td><td>robot_ops_faq、robot_ops_faq_similar</td></tr>
-      <tr><td>/robot-ops/content/faq/import</td><td>POST</td><td>导入问答</td><td>Excel文件(file)</td><td>导入总数(total)、成功数(successCount)、失败数(failCount)、失败明细(failList)</td><td>robot_ops_faq、robot_ops_faq_similar;问题分类按 RuoYi 字典 robot_faq_category 匹配</td></tr>
-      <tr><td>/robot-ops/content/faq/export</td><td>GET</td><td>导出问答</td><td>问题分类(categoryType)、关键字、状态</td><td>Excel文件</td><td>robot_ops_faq、robot_ops_faq_similar;分类名称按 RuoYi 字典 robot_faq_category 回显</td></tr>
+      <tr><td>/robot-ops/content/faq/export</td><td>GET</td><td>导出问答</td><td>问题分类(categoryType)、标准问题关键字(question)、启用状态(status)</td><td>Excel文件;导出字段建议包括问题分类、标准问题、相似问、答案内容、启用状态、更新时间、备注,不导出 sortNo</td><td>robot_ops_faq、robot_ops_faq_similar;分类名称按 RuoYi 字典 robot_faq_category 回显</td></tr>
     </tbody></table>
 
-    <div class="note">问答分类不单独建设业务表和管理页面,统一使用 RuoYi 字典维护,字典类型建议为 <code class="inline">robot_faq_category</code>。导入时根据分类名称或分类字典值匹配该字典;如匹配失败,提示导入失败明细,不自动创建业务分类。</div>
+    <div class="note">问答分类不单独建设业务表和管理页面,统一使用 RuoYi 字典维护,字典类型为 <code class="inline">robot_faq_category</code>。当前字典项为:1=问候寒暄,2=产品介绍,3=业务咨询,4=访客引导,5=场所引导,6=安防提示,7=设备使用,8=售后服务,9=常见问题,10=其他。</div>
+    <div class="note">问答库前端页面使用多行文本维护相似问,一行一个;提交时可同时携带 similarQuestions 和 robotOpsFaqSimilarList,以兼容主子表接口和后续简化接口。后端保存时需写入 robot_ops_faq_similar 表。</div>
+    <div class="note">问答库一期不提供导入接口。由于问答导入涉及分类字典匹配、标准问题重复校验、相似问拆分、主子表写入和失败明细回显,后续如运营需要批量维护,再单独扩展导入能力。</div>
+    <div class="note">sortNo / sort_no 为保留字段,前端页面一期不展示、不编辑。新增时默认 0,编辑时保持原值。后续如需推荐、置顶或屏幕端展示排序,再重新设计排序能力。</div>
+    <div class="note">删除问答时需同步删除 robot_ops_faq_similar 中对应 faq_id 的相似问数据;启用/停用仅影响主问答状态,相似问不单独设置状态。</div>
 
     <h4>7.4.3 素材管理接口</h4>
     <table><thead><tr><th>接口</th><th>方法</th><th>说明</th><th>请求参数</th><th>返回/处理字段</th><th>数据库表</th></tr></thead><tbody>
@@ -500,7 +515,8 @@
   <div class="section" id="s8"><h2>8. 数据库表设计</h2>
     <div class="note">说明:以下表结构按运维端主库设计,命名采用 <code class="inline">robot_ops_</code> 前缀。第 6 章括号内字段为前端/接口字段,采用 camelCase;第 8 章字段为数据库字段,采用 snake_case,例如 robotName 对应 robot_name。机器人基础信息、实时运行状态、资源占用状态、模块状态、视频流状态等由机器人侧实时接口提供,一期不建设 robot_ops_robot_info 和 robot_ops_device_status_snapshot 两张表。</div>
     <div class="warn">数据库建表语句以 MySQL 8.x 为基线,字段中文说明通过 COMMENT 标注。若项目实际使用 RuoYi 默认字段规范,可在开发时结合 create_by、create_time、update_by、update_time、remark 等公共字段做统一封装。</div>
-    <div class="note">问答分类使用 RuoYi 系统字典能力维护,不单独建设 robot_ops_faq_category 表。建议在 RuoYi 字典中新增字典类型 <code class="inline">robot_faq_category</code>,字典项可配置为:接待问候、业务咨询、场馆介绍、访客引导、安防提示、设备说明、其他。</div>
+    <div class="note">公共字段约定:除日志流水类表外,内容管理类、访客管理类、运维配置类、系统配置类等业务表统一包含 create_by、create_time、update_by、update_time 四个公共字段,用于记录创建人、创建时间、更新人和更新时间。日志流水类表以业务时间、操作人、处理人等字段为主,不强制补齐全部公共字段。</div>
+    <div class="note">问答分类使用 RuoYi 系统字典能力维护,不单独建设 robot_ops_faq_category 表。RuoYi 字典类型为 <code class="inline">robot_faq_category</code>,当前字典项为:1=问候寒暄,2=产品介绍,3=业务咨询,4=访客引导,5=场所引导,6=安防提示,7=设备使用,8=售后服务,9=常见问题,10=其他。</div>
 
     <h3>8.1 基础与权限表</h3>
     <h4>8.1.1 本地账号表 robot_ops_user</h4>
@@ -528,7 +544,9 @@
   `system_logo` VARCHAR(255) DEFAULT NULL COMMENT '后台系统Logo地址',
   `footer_text` VARCHAR(255) DEFAULT NULL COMMENT '页脚文案',
   `record_no` VARCHAR(100) DEFAULT NULL COMMENT '备案号/版权信息',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统基础配置表';</div>
@@ -542,7 +560,9 @@
   `cooldown_seconds` INT DEFAULT 30 COMMENT '触发冷却时间,单位秒',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='欢迎语配置表';</div>
@@ -556,12 +576,15 @@
   `sort_no` INT DEFAULT 0 COMMENT '排序号,数字越小越靠前',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_faq_category_type` (`category_type`),
   KEY `idx_robot_ops_faq_status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问答库主表';</div>
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问答库主表';
+    <div class="note">说明:sort_no 为保留字段,前端页面一期不展示、不编辑。新增问答默认写入 0,编辑问答时保持原值。后续如果需要推荐问答、置顶问答或机器人屏幕端展示排序,再重新设计排序和推荐能力。</div>
 
     <h4>8.2.3 相似问表 robot_ops_faq_similar</h4>
     <div class="code">CREATE TABLE `robot_ops_faq_similar` (
@@ -569,6 +592,10 @@
   `faq_id` BIGINT NOT NULL COMMENT '问答ID,关联robot_ops_faq.id',
   `similar_question` VARCHAR(500) NOT NULL COMMENT '相似问文本',
   `sort_no` INT DEFAULT 0 COMMENT '排序号,数字越小越靠前',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
+  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
+  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_faq_similar_faq_id` (`faq_id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问答相似问表';</div>
@@ -587,7 +614,9 @@
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `quoted_flag` CHAR(1) NOT NULL DEFAULT '0' COMMENT '是否被播放方案引用:0否,1是',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间/上传时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_media_asset_type` (`asset_type`),
@@ -602,7 +631,9 @@
   `is_default` CHAR(1) NOT NULL DEFAULT '0' COMMENT '是否默认方案:0否,1是',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_play_plan_default` (`is_default`),
@@ -617,6 +648,10 @@
   `play_order` INT DEFAULT 0 COMMENT '播放顺序,数字越小越靠前',
   `stay_seconds` INT DEFAULT NULL COMMENT '停留时长,图片必填,视频可为空',
   `transition_type` VARCHAR(50) DEFAULT NULL COMMENT '转场方式',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
+  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
+  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_play_plan_item_plan_id` (`plan_id`),
   KEY `idx_robot_ops_play_plan_item_asset_id` (`asset_id`)
@@ -630,7 +665,9 @@
   `broadcast_text` VARCHAR(2000) NOT NULL COMMENT '播报文本',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_broadcast_content_type` (`content_type`),
@@ -649,7 +686,9 @@
   `cycle_value` VARCHAR(255) DEFAULT NULL COMMENT '循环取值:cycle_type=1时保存星期值,如1,2,3,4,5;cycle_type=2时保存日期值,如2026-03-20,2026-03-21',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_broadcast_task_content_id` (`content_id`),
@@ -670,7 +709,9 @@
   `welcome_sub_title` VARCHAR(500) DEFAULT NULL COMMENT '欢迎副标题',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `current_enabled` CHAR(1) NOT NULL DEFAULT '0' COMMENT '是否当前启用主题:0否,1是',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_theme_current_enabled` (`current_enabled`),
@@ -693,7 +734,9 @@
   `visited_person` VARCHAR(100) DEFAULT NULL COMMENT '被访对象,可为被访人、房号、部门、接待单位等',
   `visit_time` DATETIME NOT NULL COMMENT '来访/登记时间',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_visitor_record_name` (`visitor_name`),
@@ -721,7 +764,9 @@
   `sync_time` DATETIME DEFAULT NULL COMMENT '同步到本地时间',
   `source_platform` VARCHAR(50) DEFAULT NULL COMMENT '来源平台',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   UNIQUE KEY `uk_robot_ops_appointment_no` (`appointment_no`),
@@ -742,7 +787,9 @@
   `valid_end_time` DATETIME DEFAULT NULL COMMENT '有效结束时间,不填表示长期有效',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_whitelist_mobile` (`mobile`),
@@ -852,6 +899,10 @@
   `sort_no` INT DEFAULT 0 COMMENT '排序号,数字越小越靠前',
   `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '启用状态:0停用,1启用',
   `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
+  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
+  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   UNIQUE KEY `uk_robot_ops_param_group_code` (`group_code`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='运行参数分组表';</div>
@@ -904,7 +955,9 @@
   `result_status` VARCHAR(20) DEFAULT NULL COMMENT '检查结果:NORMAL正常,WARN告警,FAIL失败',
   `detail_msg` VARCHAR(1000) DEFAULT NULL COMMENT '详情描述',
   `last_check_time` DATETIME DEFAULT NULL COMMENT '最后检查时间',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   UNIQUE KEY `uk_robot_ops_diagnosis_item_code` (`item_code`)
@@ -919,7 +972,9 @@
   `current_version` VARCHAR(50) DEFAULT NULL COMMENT '当前版本号',
   `install_time` DATETIME DEFAULT NULL COMMENT '安装时间',
   `run_status` VARCHAR(20) DEFAULT NULL COMMENT '运行状态:RUNNING运行中,STOPPED已停止,ERROR异常',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
   `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   UNIQUE KEY `uk_robot_ops_version_module_code` (`module_code`)
@@ -935,7 +990,10 @@
   `file_size` BIGINT DEFAULT NULL COMMENT '文件大小,单位字节',
   `upload_by` VARCHAR(64) DEFAULT NULL COMMENT '上传人',
   `upload_time` DATETIME DEFAULT NULL COMMENT '上传完成时间',
+  `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
   `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
+  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
   KEY `idx_robot_ops_upgrade_package_module` (`module_code`),
   KEY `idx_robot_ops_upgrade_package_version` (`target_version`)