Sfoglia il codice sorgente

完善展示主题配置

yawuga 1 settimana fa
parent
commit
da79b1add7

+ 1 - 9
src/api/base/opsScreenThemeConfig.js

@@ -1,6 +1,6 @@
 import request from '@/utils/request'
 
-// 查询展示主题配置列表
+// 查询展示主题配置列表(RuoYi 生成接口,当前页面用于查询 configKey=default)
 export function listOpsScreenThemeConfig(query) {
   return request({
     url: '/base/opsScreenThemeConfig/list',
@@ -9,14 +9,6 @@ export function listOpsScreenThemeConfig(query) {
   })
 }
 
-// 查询展示主题配置详细
-export function getOpsScreenThemeConfig(id) {
-  return request({
-    url: '/base/opsScreenThemeConfig/' + id,
-    method: 'get'
-  })
-}
-
 // 新增展示主题配置
 export function addOpsScreenThemeConfig(data) {
   return request({

+ 264 - 299
src/views/base/opsScreenThemeConfig/index.vue

@@ -1,361 +1,326 @@
 <template>
-  <div class="app-container">
-    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="配置标识,默认配置固定为default" prop="configKey">
-        <el-input
-          v-model="queryParams.configKey"
-          placeholder="请输入配置标识,默认配置固定为default"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="品牌标题/机器人名称" prop="robotName">
-        <el-input
-          v-model="queryParams.robotName"
-          placeholder="请输入品牌标题/机器人名称"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="品牌副标题" prop="brandSubtitle">
-        <el-input
-          v-model="queryParams.brandSubtitle"
-          placeholder="请输入品牌副标题"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="欢迎主标题" prop="welcomeTitle">
-        <el-input
-          v-model="queryParams.welcomeTitle"
-          placeholder="请输入欢迎主标题"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="欢迎副标题" prop="welcomeSubtitle">
-        <el-input
-          v-model="queryParams.welcomeSubtitle"
-          placeholder="请输入欢迎副标题"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="主按钮文案" prop="touchText">
-        <el-input
-          v-model="queryParams.touchText"
-          placeholder="请输入主按钮文案"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="主按钮颜色" prop="buttonColor">
-        <el-input
-          v-model="queryParams.buttonColor"
-          placeholder="请输入主按钮颜色"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-      </el-form-item>
-    </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          v-hasPermi="['base:opsScreenThemeConfig:add']"
-        >新增</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['base:opsScreenThemeConfig:edit']"
-        >修改</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['base:opsScreenThemeConfig:remove']"
-        >删除</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="Download"
-          @click="handleExport"
-          v-hasPermi="['base:opsScreenThemeConfig:export']"
-        >导出</el-button>
-      </el-col>
-      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
+  <div class="app-container theme-config-page">
+    <el-card class="theme-card" shadow="never">
+      <template #header>
+        <div>
+          <div class="page-title">展示主题配置</div>
+          <div class="page-desc">用于配置机器人屏幕待机页的品牌信息、背景图、欢迎文案和按钮样式。</div>
+        </div>
+      </template>
 
-    <el-table v-loading="loading" :data="opsScreenThemeConfigList" @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="配置标识,默认配置固定为default" align="center" prop="configKey" />
-      <el-table-column label="Logo图片地址" align="center" prop="logoUrl" />
-      <el-table-column label="品牌标题/机器人名称" align="center" prop="robotName" />
-      <el-table-column label="品牌副标题" align="center" prop="brandSubtitle" />
-      <el-table-column label="待机页背景图地址" align="center" prop="backgroundImage" width="100">
-        <template #default="scope">
-          <image-preview :src="scope.row.backgroundImage" :width="50" :height="50"/>
-        </template>
-      </el-table-column>
-      <el-table-column label="欢迎主标题" align="center" prop="welcomeTitle" />
-      <el-table-column label="欢迎副标题" align="center" prop="welcomeSubtitle" />
-      <el-table-column label="主按钮文案" align="center" prop="touchText" />
-      <el-table-column label="主按钮颜色" align="center" prop="buttonColor" />
-      <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-        <template #default="scope">
-          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['base:opsScreenThemeConfig:edit']">修改</el-button>
-          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['base:opsScreenThemeConfig:remove']">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    
-    <pagination
-      v-show="total>0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
+      <el-alert
+        v-if="!hasRemoteConfig"
+        title="当前未配置待机页主题,屏幕端将使用本地默认主题。如需自定义展示内容,请填写配置并保存。"
+        type="info"
+        :closable="false"
+        show-icon
+        class="mb16"
+      />
 
-    <!-- 添加或修改展示主题配置对话框 -->
-    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
-      <el-form ref="opsScreenThemeConfigRef" :model="form" :rules="rules" label-width="100px">
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="配置标识,默认配置固定为default" prop="configKey">
-              <el-input v-model="form.configKey" placeholder="请输入配置标识,默认配置固定为default" />
-            </el-form-item>
-          </el-col>
+      <el-form
+        ref="opsScreenThemeConfigRef"
+        :model="form"
+        :rules="rules"
+        label-width="120px"
+        v-loading="loading"
+      >
+        <!-- 品牌信息 -->
+        <el-divider content-position="left">品牌信息</el-divider>
+        <el-row :gutter="20">
           <el-col :span="24">
-            <el-form-item label="Logo图片地址" prop="logoUrl">
-              <el-input v-model="form.logoUrl" type="textarea" placeholder="请输入内容" />
+            <el-form-item label="Logo 图片" prop="logoUrl">
+              <image-upload v-model="form.logoUrl" :limit="1" :file-size="0.2" />
+              <div class="form-tip">建议上传 png/jpg/jpeg 格式图片,大小不超过 200KB;未配置时屏幕端使用本地默认 Logo。</div>
             </el-form-item>
           </el-col>
-          <el-col :span="24">
-            <el-form-item label="品牌标题/机器人名称" prop="robotName">
-              <el-input v-model="form.robotName" placeholder="请输入品牌标题/机器人名称" />
+          <el-col :span="12">
+            <el-form-item label="品牌标题" prop="robotName">
+              <el-input v-model="form.robotName" placeholder="请输入品牌标题" maxlength="50" show-word-limit />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="品牌副标题" prop="brandSubtitle">
-              <el-input v-model="form.brandSubtitle" placeholder="请输入品牌副标题" />
+              <el-input v-model="form.brandSubtitle" placeholder="请输入品牌副标题" maxlength="100" show-word-limit />
             </el-form-item>
           </el-col>
+        </el-row>
+
+        <!-- 背景设置 -->
+        <el-divider content-position="left">背景设置</el-divider>
+        <el-row :gutter="20">
           <el-col :span="24">
-            <el-form-item label="待机页背景图地址" prop="backgroundImage">
-              <image-upload v-model="form.backgroundImage"/>
+            <el-form-item label="背景图" prop="backgroundImage">
+              <image-upload v-model="form.backgroundImage" :limit="1" :file-size="2" />
+              <div class="form-tip">建议上传适配屏幕比例的横图,png/jpg/jpeg 格式,大小不超过 2MB;未配置时屏幕端使用本地默认背景。</div>
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+        </el-row>
+
+        <!-- 欢迎文案 -->
+        <el-divider content-position="left">欢迎文案</el-divider>
+        <el-row :gutter="20">
+          <el-col :span="12">
             <el-form-item label="欢迎主标题" prop="welcomeTitle">
-              <el-input v-model="form.welcomeTitle" placeholder="请输入欢迎主标题" />
+              <el-input v-model="form.welcomeTitle" placeholder="请输入欢迎主标题" maxlength="50" show-word-limit />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="欢迎副标题" prop="welcomeSubtitle">
-              <el-input v-model="form.welcomeSubtitle" placeholder="请输入欢迎副标题" />
+              <el-input v-model="form.welcomeSubtitle" placeholder="请输入欢迎副标题" maxlength="150" show-word-limit />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
-            <el-form-item label="主按钮文案" prop="touchText">
-              <el-input v-model="form.touchText" placeholder="请输入主按钮文案" />
+        </el-row>
+
+        <!-- 按钮设置 -->
+        <el-divider content-position="left">按钮设置</el-divider>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="按钮文案" prop="touchText">
+              <el-input v-model="form.touchText" placeholder="请输入按钮文案" maxlength="50" show-word-limit />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
-            <el-form-item label="主按钮颜色" prop="buttonColor">
-              <el-input v-model="form.buttonColor" placeholder="请输入主按钮颜色" />
+          <el-col :span="12">
+            <el-form-item label="按钮颜色" prop="buttonColor">
+              <div class="color-row">
+                <el-color-picker v-model="form.buttonColor" />
+                <el-input v-model="form.buttonColor" placeholder="#2f8ee5" class="color-input" />
+                <el-button @click="form.buttonColor = DEFAULT_FORM.buttonColor">默认蓝色</el-button>
+              </div>
+              <div class="form-tip">按钮阴影颜色由屏幕端根据按钮颜色自动生成,不单独配置。</div>
             </el-form-item>
           </el-col>
+        </el-row>
+
+        <!-- 备注 -->
+        <el-divider content-position="left">备注</el-divider>
+        <el-row :gutter="20">
           <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" placeholder="请输入备注" maxlength="500" show-word-limit :rows="3" />
             </el-form-item>
           </el-col>
         </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">确 定</el-button>
-          <el-button @click="cancel">取 消</el-button>
+
+        <!-- 底部操作 -->
+        <div class="bottom-actions">
+          <el-button icon="Refresh" @click="handleRefresh">刷新</el-button>
+          <el-button icon="Delete" @click="handleClearConfig">清空配置</el-button>
+          <el-button type="primary" icon="Check" @click="submitForm">保存配置</el-button>
         </div>
-      </template>
-    </el-dialog>
+      </el-form>
+    </el-card>
   </div>
 </template>
 
 <script setup name="OpsScreenThemeConfig">
-import { listOpsScreenThemeConfig, getOpsScreenThemeConfig, delOpsScreenThemeConfig, addOpsScreenThemeConfig, updateOpsScreenThemeConfig } from "@/api/base/opsScreenThemeConfig"
+import { listOpsScreenThemeConfig, addOpsScreenThemeConfig, updateOpsScreenThemeConfig, delOpsScreenThemeConfig } from '@/api/base/opsScreenThemeConfig'
 
 const { proxy } = getCurrentInstance()
 
-const opsScreenThemeConfigList = ref([])
-const open = ref(false)
-const loading = ref(true)
-const showSearch = ref(true)
-const ids = ref([])
-const single = ref(true)
-const multiple = ref(true)
-const total = ref(0)
-const title = ref("")
+const loading = ref(false)
+const hasRemoteConfig = ref(false)
 
-const data = reactive({
-  form: {},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    configKey: undefined,
-    logoUrl: undefined,
-    robotName: undefined,
-    brandSubtitle: undefined,
-    backgroundImage: undefined,
-    welcomeTitle: undefined,
-    welcomeSubtitle: undefined,
-    touchText: undefined,
-    buttonColor: undefined,
-  },
-  rules: {
-    configKey: [
-      { required: true, message: "配置标识,默认配置固定为default不能为空", trigger: "blur" }
-    ],
-  }
-})
-
-const { queryParams, form, rules } = toRefs(data)
-
-/** 查询展示主题配置列表 */
-function getList() {
-  loading.value = true
-  listOpsScreenThemeConfig(queryParams.value).then(response => {
-    opsScreenThemeConfigList.value = response.rows
-    total.value = response.total
-    loading.value = false
-  })
+const DEFAULT_FORM = {
+  id: null,
+  configKey: 'default',
+  logoUrl: null,
+  robotName: null,
+  brandSubtitle: null,
+  backgroundImage: null,
+  welcomeTitle: null,
+  welcomeSubtitle: null,
+  touchText: null,
+  buttonColor: '#2f8ee5',
+  remark: null,
+  createBy: null,
+  createTime: null,
+  updateBy: null,
+  updateTime: null
 }
 
-/** 取消按钮 */
-function cancel() {
-  open.value = false
-  reset()
+const form = ref({ ...DEFAULT_FORM })
+
+const rules = {
+  robotName: [
+    { max: 50, message: '品牌标题不能超过 50 字', trigger: 'blur' }
+  ],
+  brandSubtitle: [
+    { max: 100, message: '品牌副标题不能超过 100 字', trigger: 'blur' }
+  ],
+  welcomeTitle: [
+    { max: 50, message: '欢迎主标题不能超过 50 字', trigger: 'blur' }
+  ],
+  welcomeSubtitle: [
+    { max: 150, message: '欢迎副标题不能超过 150 字', trigger: 'blur' }
+  ],
+  touchText: [
+    { max: 50, message: '按钮文案不能超过 50 字', trigger: 'blur' }
+  ],
+  buttonColor: [
+    { validator: validateColor, trigger: 'blur' }
+  ],
+  remark: [
+    { max: 500, message: '备注不能超过 500 字', trigger: 'blur' }
+  ]
 }
 
-/** 表单重置 */
-function reset() {
-  form.value = {
-    id: null,
-    configKey: null,
-    logoUrl: null,
-    robotName: null,
-    brandSubtitle: null,
-    backgroundImage: null,
-    welcomeTitle: null,
-    welcomeSubtitle: null,
-    touchText: null,
-    buttonColor: null,
-    remark: null,
-    createBy: null,
-    createTime: null,
-    updateBy: null,
-    updateTime: null
+function validateColor(rule, value, callback) {
+  if (!value) {
+    callback()
+    return
+  }
+  const reg = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/
+  if (!reg.test(value)) {
+    callback(new Error('按钮颜色格式不正确,请输入类似 #2f8ee5 的颜色值'))
+    return
   }
-  proxy.resetForm("opsScreenThemeConfigRef")
+  callback()
 }
 
-/** 搜索按钮操作 */
-function handleQuery() {
-  queryParams.value.pageNum = 1
-  getList()
+/** 加载配置 */
+function loadConfig(showSuccess = false) {
+  loading.value = true
+  listOpsScreenThemeConfig({ configKey: 'default', pageNum: 1, pageSize: 1 }).then(response => {
+    const rows = response.rows || []
+    if (rows.length > 0) {
+      form.value = normalizeConfig(rows[0])
+      hasRemoteConfig.value = true
+    } else {
+      form.value = { ...DEFAULT_FORM }
+      hasRemoteConfig.value = false
+    }
+    if (showSuccess) {
+      proxy.$modal.msgSuccess('刷新成功')
+    }
+  }).catch(() => {
+    form.value = { ...DEFAULT_FORM }
+    hasRemoteConfig.value = false
+    if (showSuccess) {
+      proxy.$modal.msgError('刷新失败,已显示空配置表单')
+    }
+  }).finally(() => {
+    loading.value = false
+  })
 }
 
-/** 重置按钮操作 */
-function resetQuery() {
-  proxy.resetForm("queryRef")
-  handleQuery()
+function normalizeConfig(config) {
+  return {
+    ...DEFAULT_FORM,
+    ...(config || {}),
+    configKey: 'default'
+  }
 }
 
-/** 多选框选中数据 */
-function handleSelectionChange(selection) {
-  ids.value = selection.map(item => item.id)
-  single.value = selection.length != 1
-  multiple.value = !selection.length
+/** 刷新 */
+function handleRefresh() {
+  loadConfig(true)
 }
 
-/** 新增按钮操作 */
-function handleAdd() {
-  reset()
-  open.value = true
-  title.value = "添加展示主题配置"
+/** 清空配置 */
+function handleClearConfig() {
+  if (!form.value.id) {
+    form.value = { ...DEFAULT_FORM }
+    hasRemoteConfig.value = false
+    proxy.$modal.msgSuccess('当前未配置待机页主题,屏幕端将使用本地默认主题')
+    return
+  }
+  proxy.$modal.confirm('确认清空配置吗?该操作将删除当前运维端主题配置,删除后屏幕端将使用本地默认主题。').then(() => {
+    return delOpsScreenThemeConfig(form.value.id)
+  }).then(() => {
+    proxy.$modal.msgSuccess('已清空配置,屏幕端将使用本地默认主题')
+    form.value = { ...DEFAULT_FORM }
+    hasRemoteConfig.value = false
+  }).catch(() => {})
 }
 
-/** 修改按钮操作 */
-function handleUpdate(row) {
-  reset()
-  const _id = row.id || ids.value
-  getOpsScreenThemeConfig(_id).then(response => {
-    form.value = response.data
-    open.value = true
-    title.value = "修改展示主题配置"
+/** 保存配置 */
+function normalizePayload(data) {
+  const payload = {
+    ...data,
+    configKey: 'default'
+  }
+  const stringFields = [
+    'logoUrl',
+    'robotName',
+    'brandSubtitle',
+    'backgroundImage',
+    'welcomeTitle',
+    'welcomeSubtitle',
+    'touchText',
+    'buttonColor',
+    'remark'
+  ]
+  stringFields.forEach(key => {
+    if (typeof payload[key] === 'string') {
+      const value = payload[key].trim()
+      payload[key] = value === '' ? null : value
+    }
   })
+  if (!payload.buttonColor) {
+    payload.buttonColor = DEFAULT_FORM.buttonColor
+  }
+  return payload
 }
 
-/** 提交按钮 */
 function submitForm() {
-  proxy.$refs["opsScreenThemeConfigRef"].validate(valid => {
-    if (valid) {
-      if (form.value.id != null) {
-        updateOpsScreenThemeConfig(form.value).then(() => {
-          proxy.$modal.msgSuccess("修改成功")
-          open.value = false
-          getList()
-        })
-      } else {
-        addOpsScreenThemeConfig(form.value).then(() => {
-          proxy.$modal.msgSuccess("新增成功")
-          open.value = false
-          getList()
-        })
-      }
-    }
+  proxy.$refs.opsScreenThemeConfigRef.validate(valid => {
+    if (!valid) return
+    const payload = normalizePayload(form.value)
+    const request = payload.id ? updateOpsScreenThemeConfig(payload) : addOpsScreenThemeConfig(payload)
+    request.then(() => {
+      proxy.$modal.msgSuccess('保存成功')
+      loadConfig()
+    }).catch(() => {
+      proxy.$modal.msgError('保存失败,请稍后重试')
+    })
   })
 }
 
-/** 删除按钮操作 */
-function handleDelete(row) {
-  const _ids = row.id || ids.value
-  proxy.$modal.confirm('是否确认删除展示主题配置编号为"' + _ids + '"的数据项?').then(function() {
-    return delOpsScreenThemeConfig(_ids)
-  }).then(() => {
-    getList()
-    proxy.$modal.msgSuccess("删除成功")
-  }).catch(() => {})
-}
+onMounted(() => {
+  loadConfig()
+})
+</script>
 
-/** 导出按钮操作 */
-function handleExport() {
-  proxy.download('base/opsScreenThemeConfig/export', {
-    ...queryParams.value
-  }, `opsScreenThemeConfig_${new Date().getTime()}.xlsx`)
+<style scoped>
+.theme-config-page {
+  min-height: calc(100vh - 84px);
 }
-
-getList()
-</script>
+.theme-card {
+  max-width: 1100px;
+}
+.page-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+}
+.page-desc {
+  margin-top: 6px;
+  font-size: 13px;
+  color: #909399;
+}
+.mb16 {
+  margin-bottom: 16px;
+}
+.form-tip {
+  width: 100%;
+  margin-top: 4px;
+  font-size: 12px;
+  color: #909399;
+  line-height: 1.5;
+}
+.color-row {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+.color-input {
+  width: 130px;
+}
+.bottom-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+  padding-top: 18px;
+  border-top: 1px solid #ebeef5;
+}
+</style>

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

@@ -78,7 +78,7 @@
   <div class="section" id="s5"><h2>5. 菜单结构设计</h2>
     <table><thead><tr><th>一级菜单</th><th>二级菜单</th><th>页面职责</th><th>一期优先级</th></tr></thead><tbody>
       <tr><td>首页</td><td>首页总览</td><td>展示机器人实时状态、摘要统计、异常告警与快捷操作入口。</td><td>P0</td></tr>
-      <tr><td rowspan="7">内容管理</td><td>欢迎语配置</td><td>维护机器人默认欢迎语和触发控制参数。</td><td>P0</td></tr><tr><td>问答库管理</td><td>维护 FAQ 问答数据,支持字典分类、相似问、导出;一期暂不支持导入。问答分类使用 RuoYi 字典,不单独建设问答分类管理菜单。</td><td>P0</td></tr><tr><td>素材管理</td><td>维护图片、视频素材。</td><td>P0</td></tr><tr><td>播放方案管理</td><td>维护素材播放编排关系、时长、顺序和当前播放方案。</td><td>P0</td></tr><tr><td>播报内容管理</td><td>维护可被播报任务引用的播报文本模板。</td><td>P0</td></tr><tr><td>播报任务管理</td><td>维护播报时间策略、频率、启停状态。</td><td>P0</td></tr><tr><td>展示主题配置</td><td>维护机器人对外展示界面的品牌与主题风格。</td><td>P1</td></tr>
+      <tr><td rowspan="7">内容管理</td><td>欢迎语配置</td><td>维护机器人默认欢迎语和触发控制参数。</td><td>P0</td></tr><tr><td>问答库管理</td><td>维护 FAQ 问答数据,支持字典分类、相似问、导出;一期暂不支持导入。问答分类使用 RuoYi 字典,不单独建设问答分类管理菜单。</td><td>P0</td></tr><tr><td>素材管理</td><td>维护图片、视频素材。</td><td>P0</td></tr><tr><td>播放方案管理</td><td>维护素材播放编排关系、时长、顺序和当前播放方案。</td><td>P0</td></tr><tr><td>播报内容管理</td><td>维护可被播报任务引用的播报文本模板。</td><td>P0</td></tr><tr><td>播报任务管理</td><td>维护播报时间策略、频率、启停状态。</td><td>P0</td></tr><tr><td>展示主题配置</td><td>维护机器人屏幕待机页的展示内容,包括 Logo、品牌文案、背景图、欢迎文案、按钮文案和按钮颜色。</td><td>P1</td></tr>
       <tr><td rowspan="3">访客管理</td><td>访客记录</td><td>查看访客登记记录,支持查询、详情、导出。</td><td>P1</td></tr><tr><td>预约记录</td><td>查看主控平台同步的预约记录。</td><td>P1</td></tr><tr><td>白名单管理</td><td>维护人员白名单数据,支持通过人脸照片、身份证号、手机号进行白名单匹配。</td><td>P1</td></tr>
       <tr><td rowspan="4">监控管理</td><td>视频预览</td><td>查看机器人摄像头实时画面。</td><td>P1</td></tr><tr><td>远程喊话</td><td>下发喊话内容、查看执行结果。</td><td>P1</td></tr><tr><td>对话日志</td><td>查看人机交互日志。</td><td>P1</td></tr><tr><td>安防告警日志</td><td>查看机器人侧安防告警记录。</td><td>P1</td></tr>
       <tr><td rowspan="6">运维管理</td><td>设备状态</td><td>查看详细设备状态、资源占用、模块状态。</td><td>P0</td></tr><tr><td>设备控制</td><td>提供一键充电、停止充电、重启、关机、服务重启等操作。</td><td>P0</td></tr><tr><td>运行参数配置</td><td>动态读取参数分组与字段,支持编辑与保存。</td><td>P0</td></tr><tr><td>系统诊断</td><td>查看诊断检查结果、自检结果与关键资源状态。</td><td>P1</td></tr><tr><td>日志中心</td><td>统一查看系统、设备、升级、操作等日志。</td><td>P0</td></tr><tr><td>软件版本 / OTA 升级</td><td>查看版本、上传安装包、执行升级、查看升级记录。</td><td>P0</td></tr>
@@ -105,7 +105,7 @@
         <tr><td>播放方案管理</td><td>RuoYi 主子表生成后定制</td><td>部分适合</td><td>播放方案由主表 robot_ops_play_plan 和子表 robot_ops_play_plan_item 组成,适合先使用 RuoYi 主子表生成基础列表、表单、Controller、Service、Mapper,再进行定制。前端需将原始子表表格调整为“选择素材 + 素材编排”交互,支持素材选择、顺序调整、图片停留时长、视频默认播完切换、播放状态切换、预览方案。播放状态 status=1 表示当前播放方案,status=0 表示备用方案;同一时间只允许一个播放方案处于当前播放状态,该规则需由后端事务控制。素材 quotedFlag 维护需由后端补充业务逻辑。</td></tr>
         <tr><td>播报内容管理</td><td>RuoYi 生成后微调</td><td>适合</td><td>典型单表 CRUD,可基于 robot_ops_broadcast_content 生成,再补充测试播报按钮。</td></tr>
         <tr><td>播报任务管理</td><td>RuoYi 生成后定制</td><td>部分适合</td><td>基础 CRUD 可生成;时间段、频率、循环规则、复制任务等需要定制表单校验和交互。</td></tr>
-        <tr><td>展示主题配置</td><td>RuoYi 生成后定制</td><td>部分适合</td><td>基础 CRUD 可生成;Logo/背景上传、颜色选择器、主题预览、设为启用需要定制。</td></tr>
+        <tr><td>展示主题配置</td><td>RuoYi 生成后改造成单配置页</td><td>部分适合</td><td>本模块一期按“待机页展示配置”设计,为单配置页,不做列表、新增、删除、多主题切换和启用状态。后端可先基于 robot_ops_screen_theme_config 使用 RuoYi 生成基础 CRUD,再改造成按 config_key=default 查询和保存的接口;前端建议参考欢迎语配置页面定制为单配置表单页。页面字段包括 Logo 图片、品牌标题、品牌副标题、背景图、欢迎主标题、欢迎副标题、按钮文案、按钮颜色和备注。一期不做预览页面,后续如有需要再扩展待机页预览。</td></tr>
         <tr><td rowspan="3">访客管理</td><td>访客记录</td><td>RuoYi 生成后定制</td><td>部分适合</td><td>可基于 robot_ops_visitor_record 生成只读列表和详情页面;需去掉新增、编辑、删除,补充到访类型、登记方式、访客来源、来访事由、照片预览、时间范围查询、详情弹窗和导出字段优化。列表中访客照片前置到身份证号后,便于快速识别访客身份。</td></tr>
         <tr><td>预约记录</td><td>RuoYi 生成后微调</td><td>适合</td><td>典型查询列表和详情页面,可基于 robot_ops_appointment_record 生成,数据来源为主控平台同步。</td></tr>
         <tr><td>白名单管理</td><td>RuoYi 生成后定制</td><td>部分适合</td><td>可基于 robot_ops_whitelist 生成基础 CRUD;需补充身份证号、人脸照片上传/预览、有效期、人员类型、启用/停用、导入导出,以及手机号/身份证号/人脸照片至少填写一种的表单校验。</td></tr>
@@ -182,14 +182,32 @@
 <tr><td>播放状态规则</td><td>status=1 表示当前播放方案,status=0 表示备用方案。同一时间只允许一个播放方案 status=1。启用某个方案为当前播放时,后端应在事务中将其他方案 status 置为 0,将当前方案 status 置为 1。车端只读取 status=1 的播放方案。</td></tr>
 <tr><td>删除规则</td><td>删除方案时需要同步删除其素材明细,并重新计算相关素材的 quotedFlag。如删除当前播放方案,可能导致车端无可播放方案,建议后端根据实际业务策略进行限制或提示。</td></tr>
 <tr><td>素材引用规则</td><td>播放方案新增、编辑、删除后,后端需要重新计算相关素材的 quotedFlag。只要素材被任意播放方案明细引用,则 quotedFlag=1;不再被任何播放方案引用,则 quotedFlag=0。</td></tr>
-<tr><td>预览规则</td><td>一期前端已基于播放方案详情接口实现预览弹窗。点击"预览"后,前端调用详情接口获取方案信息和素材明细,按 playOrder 顺序展示播放清单;左侧展示当前素材的大图或视频播放器,右侧展示播放清单,支持上一个、下一个和点击清单切换。图片按 staySeconds 展示停留时长;视频使用 fileUrl 播放,默认播完后切换到下一个素材。若后续后端提供独立 preview 接口,可仅替换预览数据源,页面结构无需大改。</td></tr>
+<tr><td>预览规则</td><td>一期前端已基于播放方案详情接口实现预览弹窗。点击“预览”后,前端调用详情接口获取方案信息和素材明细,按 playOrder 顺序展示播放清单;左侧展示当前素材的大图或视频播放器,右侧展示播放清单,支持上一个、下一个和点击清单切换。图片按 staySeconds 展示停留时长;视频使用 fileUrl 播放,默认播完后切换到下一个素材。若后续后端提供独立 preview 接口,可仅替换预览数据源,页面结构无需大改。</td></tr>
 <tr><td>业务规则</td><td>新增/编辑时至少选择一个素材。停用素材不可被新播放方案选择,但历史方案中已引用的停用素材仍需支持回显。</td></tr>
 <tr><td>素材信息回显</td><td>播放方案详情、编辑回显和预览接口需要关联 robot_ops_media_asset 返回素材展示信息,包括 assetName、assetType、fileUrl、thumbnailUrl、durationSeconds、resolution、assetStatus 等。明细表本身不保存这些快照字段。</td></tr>
 </tbody></table>
     <div class="note">字典建议:loopMode 可使用 RuoYi 字典 play_plan_loop_mode,字典项:loop=循环播放,once=播放一次。transitionType 为预留字段,一期不开放配置。</div>
     <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>
     <h4>6.3.6 播报任务管理页面</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>任务名称(taskName)、关联播报内容(contentId,页面显示内容名称)、开始时间(startTime)、结束时间(endTime)、播报频率分钟数(frequencyMinutes,单位:分钟)、循环类型(cycleType)、循环取值(cycleValue)、启用状态(status)、备注(remark)。</td></tr><tr><td>cycleType</td><td>使用 RuoYi 字典 <code class="inline">broadcast_task_cycle_type</code>,字典值:1=按星期,2=按日期。</td></tr><tr><td>cycleValue</td><td>当 cycleType=1(按星期)时,保存星期值,1=星期一、2=星期二、3=星期三、4=星期四、5=星期五、6=星期六、7=星期日,多个值用英文逗号分隔,例如 1,2,3,4,5。当 cycleType=2(按日期)时,保存指定日期,多个日期用英文逗号分隔,例如 2026-03-20,2026-03-21。</td></tr><tr><td>操作按钮</td><td>新增、编辑、复制、删除、启用/停用。</td></tr><tr><td>校验规则</td><td>结束时间必须大于开始时间;frequencyMinutes 必须大于 0,单位为分钟;当循环类型为按星期时,至少选择一个星期;当循环类型为按日期时,至少选择一个指定日期。</td></tr><tr><td>交互规则</td><td>关联播报内容列表显示内容名称;新增/编辑时仅允许选择启用状态的播报内容;历史任务关联的播报内容如已停用,编辑时仍需可回显,并显示“已停用”提示,但不可重新选择停用内容。</td></tr></tbody></table>
-    <h4>6.3.7 展示主题配置页面</h4><table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody><tr><td>查询条件</td><td>主题名称、启用状态。</td></tr><tr><td>列表字段</td><td>主题名称、Logo、背景资源、主色、启用状态、当前启用标识、更新时间、操作。</td></tr><tr><td>编辑字段</td><td>主题名称(themeName)、Logo 地址(logoUrl)、背景类型(backgroundType)、背景资源地址(backgroundUrl)、主色(primaryColor)、辅助色(secondaryColor)、欢迎标题(welcomeTitle)、欢迎副标题(welcomeSubTitle)、启用状态(status)。</td></tr><tr><td>操作按钮</td><td>新增、编辑、删除、设为启用、预览。</td></tr><tr><td>业务规则</td><td>同一时刻仅允许一个主题处于“当前启用”状态。</td></tr></tbody></table>
+    <h4>6.3.7 展示主题配置页面</h4>
+<table><thead><tr><th>模块</th><th>详细设计</th></tr></thead><tbody>
+<tr><td>页面目标</td><td>维护机器人屏幕端待机欢迎页的展示内容。该页面为单配置页,不提供列表、新增、删除、多主题切换和启用状态;页面打开后直接加载 config_key=default 的默认配置。</td></tr>
+<tr><td>页面形态</td><td>类似欢迎语配置页面,采用单表单配置页。页面由配置表单和操作按钮组成,一期暂不做实时预览页面。</td></tr>
+<tr><td>基础说明</td><td>本模块只配置待机页中可运营维护的展示内容,包括 Logo、品牌文案、背景图、欢迎文案、按钮文案和按钮颜色。状态、电量、网络、时间日期等动态信息由屏幕端实时展示,不在后台配置。</td></tr>
+<tr><td>Logo 图片(logoUrl)</td><td>用于配置待机页左上角 Logo 图片。支持上传 png、jpg、jpeg、webp 图片,建议限制 2MB 以内。Logo 颜色由图片自身决定,后台不提供颜色配置。</td></tr>
+<tr><td>品牌标题(robotName)</td><td>用于配置左上角品牌标题,例如“迎宾巡逻机器人”。必填,建议最多 50 字。</td></tr>
+<tr><td>品牌副标题(brandSubtitle)</td><td>用于配置左上角品牌副标题,例如“智能接待 · 路线引导 · 信息服务”。选填,建议最多 100 字。</td></tr>
+<tr><td>背景图(backgroundImage)</td><td>用于配置待机页整屏背景图。支持上传 jpg、png、webp 图片,建议使用适配屏幕比例的横图,大小建议 5MB 以内。背景适配方式由屏幕端固定处理,后台不提供选择项。</td></tr>
+<tr><td>欢迎主标题(welcomeTitle)</td><td>用于配置待机页中间主标题,例如“您好,欢迎光临”。必填,建议最多 50 字。该字段用于屏幕展示,不等同于欢迎语配置中的语音播报文本。</td></tr>
+<tr><td>欢迎副标题(welcomeSubtitle)</td><td>用于配置待机页中间说明文案,例如“我可以为您提供访客登记、路线引导、通知公告查询与现场帮助服务”。选填,建议最多 150 字。</td></tr>
+<tr><td>按钮文案(touchText)</td><td>用于配置底部主按钮文案,例如“触摸屏幕进入服务”。必填,建议最多 50 字。</td></tr>
+<tr><td>按钮颜色(buttonColor)</td><td>用于配置底部主按钮颜色,默认 #2f8ee5。按钮阴影颜色不单独配置,由屏幕端根据按钮颜色自动生成。</td></tr>
+<tr><td>备注(remark)</td><td>后台备注说明,选填,最多 500 字。</td></tr>
+<tr><td>操作按钮</td><td>保存配置、恢复默认、刷新。恢复默认由前端本地恢复默认值,用户点击保存配置后才写入数据库。</td></tr>
+<tr><td>上传规则</td><td>Logo 图片和背景图可复用现有上传能力,例如 /common/uploadMediaFile 或通用上传接口。前端只取返回的 fileUrl / url 写入 logoUrl 或 backgroundImage。</td></tr>
+<tr><td>业务规则</td><td>配置标识固定为 default。展示主题配置属于可选覆盖配置,后端数据库可以不预置默认配置。页面加载时如后端返回空数据或未查询到 config_key='default' 配置,运维端后台可展示空表单,并提示"当前未配置待机页主题,屏幕端将使用本地默认主题"。用户填写并点击"保存配置"后,后端按 config_key='default' 执行有则更新、无则新增。屏幕端必须内置本地默认主题,用于后端无配置、接口异常、网络异常或字段缺失时兜底展示。</td></tr>
+<tr><td>一期不做</td><td>一期不做多主题列表、主题启用状态、主题复制、主题删除、实时预览、背景适配方式、柔光层开关、状态栏开关、时间日期开关、Logo 颜色、状态点颜色、标题颜色、字体大小、按钮阴影颜色和复杂布局配置。</td></tr>
+</tbody></table>
 
     <h3>6.4 访客管理</h3>
     <h4>6.4.1 访客记录页面</h4>
@@ -492,17 +510,17 @@
     <div class="note">播报任务循环类型使用 RuoYi 字典 <code class="inline">broadcast_task_cycle_type</code>,字典值约定为:1=按星期,2=按日期。按星期时,cycleValue 保存 1-7 的星期值,多个值用英文逗号分隔;按日期时,cycleValue 保存 YYYY-MM-DD 日期值,多个日期用英文逗号分隔。</div>
     <div class="note">播报任务列表和详情接口建议返回 contentName 和 contentStatus,便于前端展示关联播报内容名称,以及识别关联内容是否已停用。新增/编辑播报任务时,前端仅允许选择启用状态的播报内容;历史任务关联的停用内容需要支持回显。</div>
 
-    <h4>7.4.6 展示主题接口</h4>
-    <table><thead><tr><th>接口</th><th>方法</th><th>说明</th><th>请求/返回字段</th><th>数据库表</th></tr></thead><tbody>
-      <tr><td>/robot-ops/content/theme/page</td><td>GET</td><td>主题分页</td><td>themeName、status、pageNum、pageSize;返回 logoUrl、backgroundType、backgroundUrl、primaryColor、currentEnabled、updateTime</td><td>robot_ops_theme</td></tr>
-      <tr><td>/robot-ops/content/theme/{id}</td><td>GET</td><td>主题详情</td><td>id、themeName、logoUrl、backgroundType、backgroundUrl、primaryColor、secondaryColor、welcomeTitle、welcomeSubTitle、status、currentEnabled</td><td>robot_ops_theme</td></tr>
-      <tr><td>/robot-ops/content/theme</td><td>POST</td><td>新增主题</td><td>themeName、logoUrl、backgroundType、backgroundUrl、primaryColor、secondaryColor、welcomeTitle、welcomeSubTitle、status</td><td>robot_ops_theme</td></tr>
-      <tr><td>/robot-ops/content/theme</td><td>PUT</td><td>编辑主题</td><td>id、themeName、logoUrl、backgroundType、backgroundUrl、primaryColor、secondaryColor、welcomeTitle、welcomeSubTitle、status</td><td>robot_ops_theme</td></tr>
-      <tr><td>/robot-ops/content/theme/{id}</td><td>DELETE</td><td>删除主题</td><td>主题ID(id)</td><td>robot_ops_theme</td></tr>
-      <tr><td>/robot-ops/content/theme/{id}/enable</td><td>POST</td><td>启用主题</td><td>主题ID(id)</td><td>robot_ops_theme</td></tr>
-    </tbody></table>
-    <div class="note">主题 Logo、背景资源可通过通用文件上传接口获取 fileUrl 后,再写入 logoUrl、backgroundUrl;也可根据项目实现复用素材上传接口。</div>
-    <div class="warn">启用主题时需要将其他主题 current_enabled 置为 0,当前主题置为 1,保证同一时间只有一个主题生效。</div>
+    <h4>7.4.6 展示主题配置接口</h4>
+<table><thead><tr><th>接口</th><th>方法</th><th>说明</th><th>请求/返回字段</th><th>数据库表</th></tr></thead><tbody>
+<tr><td>/robot-ops/content/screen-theme-config</td><td>GET</td><td>获取待机页主题配置</td><td>返回:configKey(固定 default)、logoUrl、robotName、brandSubtitle、backgroundImage、welcomeTitle、welcomeSubtitle、touchText、buttonColor、remark。后端以 config_key='default' 查询;如数据库暂无 config_key='default' 配置,可返回 null、空对象或空 data;运维端后台可展示空表单并提示当前未配置,屏幕端继续使用本地默认主题。</td><td>robot_ops_screen_theme_config</td></tr>
+<tr><td>/robot-ops/content/screen-theme-config</td><td>PUT</td><td>保存待机页主题配置</td><td>请求:configKey(固定 default,可由前端传入,也可由后端默认处理)、logoUrl、robotName、brandSubtitle、backgroundImage、welcomeTitle、welcomeSubtitle、touchText、buttonColor、remark。后端保存时应以 config_key='default' 作为定位条件,存在则更新,不存在则新增;因此数据库不强制要求预置默认数据。</td><td>robot_ops_screen_theme_config</td></tr>
+</tbody></table>
+<div class="note">展示主题配置为单配置页,前端当前会在保存时携带 configKey='default';后端也应支持不传 configKey 时默认按 default 处理。</div>
+<div class="note">Logo 图片和背景图可复用现有上传能力,例如 <code class="inline">/common/uploadMediaFile</code> 或通用上传接口。前端只取返回的 fileUrl / url 写入 logoUrl 或 backgroundImage。</div>
+<div class="note">恢复默认由前端本地重置表单完成,不单独调用后端恢复默认接口;用户点击“保存配置”后才真正写入数据库。</div>
+<div class="note">按钮颜色 buttonColor 只控制底部主按钮颜色;按钮阴影颜色由屏幕端根据 buttonColor 自动生成。Logo 颜色、状态点颜色、时间日期颜色、标题颜色一期不开放配置。</div>
+<div class="note">屏幕端必须内置一套本地默认待机页配置。当后端配置接口不可用、数据库未配置、返回空数据或字段缺失时,屏幕端使用本地默认配置兜底展示;后端返回配置采用覆盖合并策略,只覆盖已返回字段。</div>
+<div class="note">运维端后台不强制内置默认表单值。当 GET 接口未查询到 config_key='default' 配置时,页面可展示空表单,并提示"当前未配置待机页主题,屏幕端将使用本地默认主题"。用户填写并点击"保存配置"后,后端再新增 default 配置记录。</div>
 
     <h3>7.5 访客管理接口</h3>
     <table><thead><tr><th>接口</th><th>方法</th><th>说明</th><th>请求参数</th><th>返回/处理字段</th><th>数据库表</th></tr></thead><tbody>
@@ -810,28 +828,34 @@ VALUES
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='播报任务表';
     <div class="note">播报任务循环类型使用 RuoYi 字典 <code class="inline">broadcast_task_cycle_type</code>,字典项建议配置为:1=按星期,2=按日期。按星期时,cycle_value 中 1-7 分别代表星期一到星期日。</div></div>
 
-    <h4>8.2.9 展示主题表 robot_ops_theme</h4>
-    <div class="code">CREATE TABLE `robot_ops_theme` (
+    <h4>8.2.9 屏幕待机页主题配置表 robot_ops_screen_theme_config</h4>
+<div class="code">CREATE TABLE `robot_ops_screen_theme_config` (
   `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `theme_name` VARCHAR(100) NOT NULL COMMENT '主题名称',
-  `logo_url` VARCHAR(255) DEFAULT NULL COMMENT 'Logo地址',
-  `background_type` VARCHAR(20) DEFAULT NULL COMMENT '背景类型:image图片,video视频,color纯色',
-  `background_url` VARCHAR(255) DEFAULT NULL COMMENT '背景资源地址',
-  `primary_color` VARCHAR(20) DEFAULT NULL COMMENT '主题主色',
-  `secondary_color` VARCHAR(20) DEFAULT NULL COMMENT '辅助色',
-  `welcome_title` VARCHAR(200) DEFAULT NULL COMMENT '欢迎标题',
-  `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是',
+  `config_key` VARCHAR(50) NOT NULL DEFAULT 'default' COMMENT '配置标识,默认配置固定为default',
+  `logo_url` VARCHAR(500) DEFAULT NULL COMMENT 'Logo图片地址',
+  `robot_name` VARCHAR(100) DEFAULT '迎宾巡逻机器人' COMMENT '品牌标题/机器人名称',
+  `brand_subtitle` VARCHAR(200) DEFAULT '智能接待 · 路线引导 · 信息服务' COMMENT '品牌副标题',
+  `background_image` VARCHAR(500) DEFAULT NULL COMMENT '待机页背景图地址',
+  `welcome_title` VARCHAR(100) DEFAULT '您好,欢迎光临' COMMENT '欢迎主标题',
+  `welcome_subtitle` VARCHAR(300) DEFAULT '我可以为您提供访客登记、路线引导、通知公告查询与现场帮助服务' COMMENT '欢迎副标题',
+  `touch_text` VARCHAR(100) DEFAULT '触摸屏幕进入服务' COMMENT '主按钮文案',
+  `button_color` VARCHAR(20) DEFAULT '#2f8ee5' 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_theme_current_enabled` (`current_enabled`),
-  KEY `idx_robot_ops_theme_status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='机器人展示主题表';</div>
-
+  UNIQUE KEY `uk_robot_ops_screen_theme_config_key` (`config_key`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='屏幕待机页主题配置表';</div>
+<div class="note">说明:展示主题配置一期为单配置页,不作为多条数据列表管理。config_key 用于标识固定配置项,默认配置固定为 default;后端查询和保存时应以 config_key='default' 作为业务定位条件。数据库可以不预置默认记录,保存接口需支持有则更新、无则新增。未配置时不视为异常,屏幕端使用本地默认主题展示。</div>
+<div class="note">说明:本表仅保存待机页可运营维护的展示内容。背景适配方式、柔光层、状态栏、时间日期、标题颜色、按钮阴影等由屏幕端固定规则处理,不在后台配置。</div>
+<div class="note">说明:button_color 仅用于控制主按钮颜色,按钮阴影颜色由屏幕端根据 button_color 自动生成。</div>
+<div class="note">可选初始化数据:以下 INSERT 语句不是必须执行项。若希望数据库中预置一套默认主题配置,可执行该初始化 SQL;若不执行,运维端后台在未查询到配置时可显示空表单并提示当前未配置,屏幕端继续使用本地默认主题。用户首次保存后,后端再写入 config_key='default' 的配置记录。</div>
+<div class="code">INSERT INTO `robot_ops_screen_theme_config`
+(`config_key`, `robot_name`, `brand_subtitle`, `welcome_title`, `welcome_subtitle`, `touch_text`, `button_color`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`)
+VALUES
+('default', '迎宾巡逻机器人', '智能接待 · 路线引导 · 信息服务', '您好,欢迎光临', '我可以为您提供访客登记、路线引导、通知公告查询与现场帮助服务', '触摸屏幕进入服务', '#2f8ee5', '系统默认待机页主题配置', 'system', NOW(), 'system', NOW());</div>
     <h3>8.3 访客管理表</h3>
     <h4>8.3.1 访客记录表 robot_ops_visitor_record</h4>
     <div class="code">CREATE TABLE `robot_ops_visitor_record` (
@@ -1146,7 +1170,7 @@ VALUES
 
   <div class="section" id="s10"><h2>10. 权限与账号设计</h2><table><thead><tr><th>角色</th><th>默认权限</th></tr></thead><tbody><tr><td>ADMIN</td><td>全量权限,包括账号管理、参数配置、设备控制、OTA 升级。</td></tr><tr><td>OPS</td><td>首页、内容管理、访客管理、监控管理、运维管理(除账号管理)。</td></tr><tr><td>VIEWER</td><td>仅查看权限,不可执行新增、编辑、删除、升级、控制等动作。</td></tr></tbody></table><p>RuoYi 菜单权限与按钮权限均需保留,避免后期返工。即使一期只有 admin,也要按标准权限框架开发。</p></div>
 
-  <div class="section" id="s11"><h2>11. 开发优先级与实施顺序</h2><table><thead><tr><th>阶段</th><th>模块</th><th>说明</th></tr></thead><tbody><tr><td>阶段一</td><td>登录、首页、设备状态、设备控制、参数配置、日志中心、版本/OTA</td><td>先打通基础运维闭环。</td></tr><tr><td>阶段二</td><td>欢迎语、问答库、素材管理、播放方案、播报内容、播报任务、主题配置</td><td>打通内容配置闭环。</td></tr><tr><td>阶段三</td><td>访客记录、预约记录、白名单、视频预览、远程喊话、对话日志、安防告警日志</td><td>补齐业务查询和监控能力。</td></tr><tr><td>阶段四</td><td>优化、导入导出、性能提升、操作审计完善</td><td>稳定化阶段。</td></tr></tbody></table></div>
+  <div class="section" id="s11"><h2>11. 开发优先级与实施顺序</h2><table><thead><tr><th>阶段</th><th>模块</th><th>说明</th></tr></thead><tbody><tr><td>阶段一</td><td>登录、首页、设备状态、设备控制、参数配置、日志中心、版本/OTA</td><td>先打通基础运维闭环。</td></tr><tr><td>阶段二</td><td>欢迎语、问答库、素材管理、播放方案、播报内容、播报任务、主题配置(单配置页)</td><td>打通内容配置闭环。</td></tr><tr><td>阶段三</td><td>访客记录、预约记录、白名单、视频预览、远程喊话、对话日志、安防告警日志</td><td>补齐业务查询和监控能力。</td></tr><tr><td>阶段四</td><td>优化、导入导出、性能提升、操作审计完善</td><td>稳定化阶段。</td></tr></tbody></table></div>
 
   <div class="section" id="s12"><h2>12. 对其他团队的配合要求</h2><div class="danger">以下内容不再作为“待定事项”,而是作为其他团队必须按本文配合实现的内容。</div><ul><li><strong>机器人侧:</strong>需提供首页状态接口、设备状态接口、控制接口、视频流信息接口、喊话接口、参数接口、日志接口、版本与升级接口。</li><li><strong>主控平台侧:</strong>需提供预约记录同步接口、可选白名单同步接口。</li><li><strong>展示端:</strong>需支持欢迎语、播放方案、播报任务、展示主题配置的读取与应用。</li><li><strong>算法 / 安防侧:</strong>需向运维端提供安防告警记录标准数据结构。</li></ul><div class="ok">结论:本文件已经作为一期开发基线文档定版。后续若有调整,应基于本文迭代版本,而不是推翻本文重新回到需求澄清阶段。</div></div>