Bladeren bron

feat(website): 数字化底座顶部配置化

malk 1 week geleden
bovenliggende
commit
c7c4808ab7

+ 23 - 0
AGENTS.md

@@ -0,0 +1,23 @@
+# 云璞官网维护说明
+
+## 项目属性
+
+- 本仓库是已上线运行的云璞官网项目,稳定性优先于重构、统一风格或技术升级。
+- 当前生产代码基线必须在每次发布前从线上和远端仓库重新确认,不能仅依据本地副本判断。
+- 根目录 `lonyue-web/` 是当前公众官网前端;`LonYue-master/lonyue-ui/` 是后台管理端;`LonYue-master/lonyue-admin/` 与 `LonYue-master/LonYue-business/` 是后端启动及官网业务模块。
+- `LonYue-master/lonyue-web/` 是较早的前端副本,除非任务明确指定,不作为当前官网修改目标。
+
+## 修改约束
+
+- 修改前必须先说明问题根因、候选方案、影响模块、数据库或接口兼容性、验证方式和发布顺序,再实施变更。
+- 只做用户明确要求的增量功能和 Bug 修复,不顺手重构、优化、升级依赖、格式化无关文件或调整既有业务行为。
+- 优先沿用现有数据模型、接口、组件和页面结构;确需新增字段时,保留默认值和兼容回退,避免旧数据或接口异常导致页面不可用。
+- 变更范围必须可追溯,验证聚焦于修改文件及直接关联链路;发现范围外问题只记录和报告,未经确认不处理。
+- 不在本地开发或预览时写入生产数据。后台和后端默认配置可能连接线上服务,启动前必须核对目标环境。
+
+## 发布约束
+
+- 默认只完成本地修改和验证,不自动提交、推送或部署。
+- 发布前必须回读线上最新后端程序、前端产物、数据库结构和远端分支,合并到线上最新基线后再构建。
+- 涉及数据库字段时,先确认兼容性并执行迁移,再发布依赖新字段的后端,最后发布后台与官网前端。
+- 发布后必须回读接口并完成实际业务回归;构建成功或接口返回成功不能替代功能验收。

+ 24 - 0
LonYue-master/LonYue-business/src/main/java/com/lonyue/business/domain/GlobalConfig.java

@@ -72,4 +72,28 @@ public class GlobalConfig extends BaseEntity {
     @ApiModelProperty("办公到访说明")
     private String visitNotice;
 
+    @Column(columnDefinition = "varchar(500) default '' comment '数字化底座顶部Banner'")
+    @ApiModelProperty("数字化底座顶部Banner")
+    private String digitalBaseBannerUrl;
+
+    @Column(columnDefinition = "varchar(100) default '' comment '数字化底座Banner辅助标题'")
+    @ApiModelProperty("数字化底座Banner辅助标题")
+    private String digitalBaseEyebrow;
+
+    @Column(columnDefinition = "varchar(300) default '' comment '数字化底座Banner主标题'")
+    @ApiModelProperty("数字化底座Banner主标题")
+    private String digitalBaseTitle;
+
+    @Column(columnDefinition = "varchar(200) default '' comment '数字化底座Banner副标题'")
+    @ApiModelProperty("数字化底座Banner副标题")
+    private String digitalBaseSubtitle;
+
+    @Column(columnDefinition = "varchar(100) default '' comment '数字化底座版本一名称'")
+    @ApiModelProperty("数字化底座版本一名称")
+    private String digitalBaseType1Name;
+
+    @Column(columnDefinition = "varchar(100) default '' comment '数字化底座版本二名称'")
+    @ApiModelProperty("数字化底座版本二名称")
+    private String digitalBaseType2Name;
+
 }

+ 25 - 1
LonYue-master/LonYue-business/src/main/resources/mapper/business/GlobalConfigMapper.xml

@@ -23,10 +23,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="businessHours"    column="business_hours"    />
         <result property="schemaOpeningHours"    column="schema_opening_hours"    />
         <result property="visitNotice"    column="visit_notice"    />
+        <result property="digitalBaseBannerUrl"    column="digital_base_banner_url"    />
+        <result property="digitalBaseEyebrow"    column="digital_base_eyebrow"    />
+        <result property="digitalBaseTitle"    column="digital_base_title"    />
+        <result property="digitalBaseSubtitle"    column="digital_base_subtitle"    />
+        <result property="digitalBaseType1Name"    column="digital_base_type1_name"    />
+        <result property="digitalBaseType2Name"    column="digital_base_type2_name"    />
     </resultMap>
 
     <sql id="selectGlobalConfigVo">
-        select id, create_by, create_time, remark, search_value, update_by, update_time, ding_qr_code, phone_number, public_qr_code, we_chat_qr_code, brand_name, legal_name, website_url, service_areas, business_hours, schema_opening_hours, visit_notice from global_config
+        select id, create_by, create_time, remark, search_value, update_by, update_time, ding_qr_code, phone_number, public_qr_code, we_chat_qr_code, brand_name, legal_name, website_url, service_areas, business_hours, schema_opening_hours, visit_notice, digital_base_banner_url, digital_base_eyebrow, digital_base_title, digital_base_subtitle, digital_base_type1_name, digital_base_type2_name from global_config
     </sql>
 
     <select id="selectGlobalConfigList" parameterType="GlobalConfig" resultMap="GlobalConfigResult">
@@ -66,6 +72,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="businessHours != null">business_hours,</if>
             <if test="schemaOpeningHours != null">schema_opening_hours,</if>
             <if test="visitNotice != null">visit_notice,</if>
+            <if test="digitalBaseBannerUrl != null">digital_base_banner_url,</if>
+            <if test="digitalBaseEyebrow != null">digital_base_eyebrow,</if>
+            <if test="digitalBaseTitle != null">digital_base_title,</if>
+            <if test="digitalBaseSubtitle != null">digital_base_subtitle,</if>
+            <if test="digitalBaseType1Name != null">digital_base_type1_name,</if>
+            <if test="digitalBaseType2Name != null">digital_base_type2_name,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="id != null">#{id},</if>
@@ -86,6 +98,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="businessHours != null">#{businessHours},</if>
             <if test="schemaOpeningHours != null">#{schemaOpeningHours},</if>
             <if test="visitNotice != null">#{visitNotice},</if>
+            <if test="digitalBaseBannerUrl != null">#{digitalBaseBannerUrl},</if>
+            <if test="digitalBaseEyebrow != null">#{digitalBaseEyebrow},</if>
+            <if test="digitalBaseTitle != null">#{digitalBaseTitle},</if>
+            <if test="digitalBaseSubtitle != null">#{digitalBaseSubtitle},</if>
+            <if test="digitalBaseType1Name != null">#{digitalBaseType1Name},</if>
+            <if test="digitalBaseType2Name != null">#{digitalBaseType2Name},</if>
          </trim>
     </insert>
 
@@ -109,6 +127,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="businessHours != null">business_hours = #{businessHours},</if>
             <if test="schemaOpeningHours != null">schema_opening_hours = #{schemaOpeningHours},</if>
             <if test="visitNotice != null">visit_notice = #{visitNotice},</if>
+            <if test="digitalBaseBannerUrl != null">digital_base_banner_url = #{digitalBaseBannerUrl},</if>
+            <if test="digitalBaseEyebrow != null">digital_base_eyebrow = #{digitalBaseEyebrow},</if>
+            <if test="digitalBaseTitle != null">digital_base_title = #{digitalBaseTitle},</if>
+            <if test="digitalBaseSubtitle != null">digital_base_subtitle = #{digitalBaseSubtitle},</if>
+            <if test="digitalBaseType1Name != null">digital_base_type1_name = #{digitalBaseType1Name},</if>
+            <if test="digitalBaseType2Name != null">digital_base_type2_name = #{digitalBaseType2Name},</if>
         </trim>
         where id = #{id}
     </update>

+ 26 - 1
LonYue-master/lonyue-ui/src/views/business/globalConfig/index.vue

@@ -28,6 +28,25 @@
         <el-form-item label="办公到访说明" prop="visitNotice">
           <el-input v-model="form.visitNotice" type="textarea" :rows="2" placeholder="例如:三地办公地点均可公开展示;如需到访,请提前预约。" />
         </el-form-item>
+        <el-divider content-position="left">数字化底座顶部展示</el-divider>
+        <el-form-item label="顶部 Banner" prop="digitalBaseBannerUrl">
+          <image-upload v-model="form.digitalBaseBannerUrl" :limit="1" />
+        </el-form-item>
+        <el-form-item label="Banner 辅助标题" prop="digitalBaseEyebrow">
+          <el-input v-model="form.digitalBaseEyebrow" maxlength="100" show-word-limit placeholder="例如:基于钉钉" />
+        </el-form-item>
+        <el-form-item label="Banner 主标题" prop="digitalBaseTitle">
+          <el-input v-model="form.digitalBaseTitle" maxlength="300" show-word-limit placeholder="请输入 Banner 主标题" />
+        </el-form-item>
+        <el-form-item label="Banner 副标题" prop="digitalBaseSubtitle">
+          <el-input v-model="form.digitalBaseSubtitle" maxlength="200" show-word-limit placeholder="例如:驱动组织效能与业务创新" />
+        </el-form-item>
+        <el-form-item label="专业版名称" prop="digitalBaseType1Name">
+          <el-input v-model="form.digitalBaseType1Name" maxlength="100" show-word-limit placeholder="例如:钉钉专业版" />
+        </el-form-item>
+        <el-form-item label="专属版名称" prop="digitalBaseType2Name">
+          <el-input v-model="form.digitalBaseType2Name" maxlength="100" show-word-limit placeholder="例如:钉钉专属版" />
+        </el-form-item>
         <el-divider content-position="left">联系与二维码</el-divider>
         <el-form-item label="钉钉二维码" prop="dingQrCode">
           <image-upload v-model="form.dingQrCode" :limit="1" />
@@ -108,7 +127,13 @@ export default {
           serviceAreas: null,
           businessHours: null,
           schemaOpeningHours: null,
-          visitNotice: null
+          visitNotice: null,
+          digitalBaseBannerUrl: null,
+          digitalBaseEyebrow: "基于钉钉",
+          digitalBaseTitle: "为您的企业打造统一协同、安全可靠、随需扩展的数字基座",
+          digitalBaseSubtitle: "驱动组织效能与业务创新",
+          digitalBaseType1Name: "钉钉专业版",
+          digitalBaseType2Name: "钉钉专属版"
       }
       this.resetForm("form")
     },

+ 35 - 0
LonYue-master/sql/20261026_global_config_digital_base_header.sql

@@ -0,0 +1,35 @@
+ALTER TABLE global_config
+  ADD COLUMN digital_base_banner_url varchar(500) NULL DEFAULT '' COMMENT '数字化底座顶部Banner',
+  ADD COLUMN digital_base_eyebrow varchar(100) NULL DEFAULT '' COMMENT '数字化底座Banner辅助标题',
+  ADD COLUMN digital_base_title varchar(300) NULL DEFAULT '' COMMENT '数字化底座Banner主标题',
+  ADD COLUMN digital_base_subtitle varchar(200) NULL DEFAULT '' COMMENT '数字化底座Banner副标题',
+  ADD COLUMN digital_base_type1_name varchar(100) NULL DEFAULT '' COMMENT '数字化底座版本一名称',
+  ADD COLUMN digital_base_type2_name varchar(100) NULL DEFAULT '' COMMENT '数字化底座版本二名称';
+
+UPDATE global_config
+SET digital_base_banner_url = CASE
+      WHEN digital_base_banner_url IS NULL OR digital_base_banner_url = ''
+        THEN 'https://img.cloudpure.cn/prod-api/profile/upload/images/digitalBase/banner.png'
+      ELSE digital_base_banner_url
+    END,
+    digital_base_eyebrow = CASE
+      WHEN digital_base_eyebrow IS NULL OR digital_base_eyebrow = '' THEN '基于钉钉'
+      ELSE digital_base_eyebrow
+    END,
+    digital_base_title = CASE
+      WHEN digital_base_title IS NULL OR digital_base_title = ''
+        THEN '为您的企业打造统一协同、安全可靠、随需扩展的数字基座'
+      ELSE digital_base_title
+    END,
+    digital_base_subtitle = CASE
+      WHEN digital_base_subtitle IS NULL OR digital_base_subtitle = '' THEN '驱动组织效能与业务创新'
+      ELSE digital_base_subtitle
+    END,
+    digital_base_type1_name = CASE
+      WHEN digital_base_type1_name IS NULL OR digital_base_type1_name = '' THEN '钉钉专业版'
+      ELSE digital_base_type1_name
+    END,
+    digital_base_type2_name = CASE
+      WHEN digital_base_type2_name IS NULL OR digital_base_type2_name = '' THEN '钉钉专属版'
+      ELSE digital_base_type2_name
+    END;

+ 14 - 2
lonyue-web/src/store/index.js

@@ -116,7 +116,13 @@ export default new Vuex.Store({
           serviceAreas: row.serviceAreas,
           businessHours: row.businessHours,
           schemaOpeningHours: row.schemaOpeningHours,
-          visitNotice: row.visitNotice
+          visitNotice: row.visitNotice,
+          digitalBaseBannerUrl: buildMediaUrl(row.digitalBaseBannerUrl),
+          digitalBaseEyebrow: row.digitalBaseEyebrow,
+          digitalBaseTitle: row.digitalBaseTitle,
+          digitalBaseSubtitle: row.digitalBaseSubtitle,
+          digitalBaseType1Name: row.digitalBaseType1Name,
+          digitalBaseType2Name: row.digitalBaseType2Name
         })
       } catch (e) {
         console.error('[globalConfig/list] 请求失败:', e)
@@ -131,7 +137,13 @@ export default new Vuex.Store({
           serviceAreas: '',
           businessHours: '',
           schemaOpeningHours: '',
-          visitNotice: ''
+          visitNotice: '',
+          digitalBaseBannerUrl: '',
+          digitalBaseEyebrow: '',
+          digitalBaseTitle: '',
+          digitalBaseSubtitle: '',
+          digitalBaseType1Name: '',
+          digitalBaseType2Name: ''
         })
       }
     },

+ 40 - 11
lonyue-web/src/views/MenuPages/DigitalBase.vue

@@ -7,11 +7,11 @@
     >
       <div class="db-inner db-hero__inner">
         <div class="db-hero__content">
-          <p class="db-hero__eyebrow">基于钉钉</p>
+          <p class="db-hero__eyebrow">{{ bannerEyebrow }}</p>
           <h1 class="db-hero__title">
-            为您的企业打造统一协同、安全可靠、随需扩展的数字基座
+            {{ bannerTitle }}
           </h1>
-          <p class="db-hero__gradient">驱动组织效能与业务创新</p>
+          <p class="db-hero__gradient">{{ bannerSubtitle }}</p>
         </div>
         <div class="db-hero__tabs" role="tablist" aria-label="页面模块">
           <button
@@ -34,7 +34,7 @@
     <section id="db-pro" class="db-mod db-mod--section">
       <div class="db-inner">
         <header class="db-sec-head">
-          <h2 class="db-sec-head__title">钉钉专业版</h2>
+          <h2 class="db-sec-head__title">{{ type1Name }}</h2>
           <p class="db-sec-head__sub">中小企业深度协同的首选</p>
         </header>
 
@@ -178,7 +178,7 @@
     <section id="db-exclusive" class="db-mod db-mod--section db-mod--alt">
       <div class="db-inner">
         <header class="db-sec-head">
-          <h2 class="db-sec-head__title">钉钉专属版</h2>
+          <h2 class="db-sec-head__title">{{ type2Name }}</h2>
           <p class="db-sec-head__sub">
             企业的专属数字化平台 · 中大型企业安全可控的基石
           </p>
@@ -259,19 +259,21 @@ import { getDigitalBaseCategoryList, getDigitalBaseOfficialList } from "@/api/in
 import request from "@/utils/request";
 import { SITE_NAME, SITE_URL } from "@/config/seo";
 
+const DEFAULT_BANNER_URL = "https://img.cloudpure.cn/prod-api/profile/upload/images/digitalBase/banner.png";
+const DEFAULT_BANNER_EYEBROW = "基于钉钉";
+const DEFAULT_BANNER_TITLE = "为您的企业打造统一协同、安全可靠、随需扩展的数字基座";
+const DEFAULT_BANNER_SUBTITLE = "驱动组织效能与业务创新";
+const DEFAULT_TYPE_1_NAME = "钉钉专业版";
+const DEFAULT_TYPE_2_NAME = "钉钉专属版";
+
 export default {
   name: "DigitalBasePage",
   data() {
     return {
-      bannerBg:'https://img.cloudpure.cn/prod-api/profile/upload/images/digitalBase/banner.png',
-      placeholderImg:'https://img.cloudpure.cn/prod-api/profile/upload/images/digitalBase/banner.png',
+      placeholderImg: DEFAULT_BANNER_URL,
       activeNavId: "pro",
       scrollLock: false,
       scrollSpyRaf: null,
-      navItems: [
-        { id: "pro", label: "钉钉专业版" },
-        { id: "exclusive", label: "钉钉专属版" },
-      ],
       uiState: {
         "m-pro-asset": { p: 0, m: 0 },
         "m-pro-collab": { p: 0, m: 0 },
@@ -292,6 +294,33 @@ export default {
     };
   },
   computed: {
+    digitalBaseConfig() {
+      return this.$store.state.globalConfig || {};
+    },
+    bannerBg() {
+      return this.digitalBaseConfig.digitalBaseBannerUrl || DEFAULT_BANNER_URL;
+    },
+    bannerEyebrow() {
+      return String(this.digitalBaseConfig.digitalBaseEyebrow || "").trim() || DEFAULT_BANNER_EYEBROW;
+    },
+    bannerTitle() {
+      return String(this.digitalBaseConfig.digitalBaseTitle || "").trim() || DEFAULT_BANNER_TITLE;
+    },
+    bannerSubtitle() {
+      return String(this.digitalBaseConfig.digitalBaseSubtitle || "").trim() || DEFAULT_BANNER_SUBTITLE;
+    },
+    type1Name() {
+      return String(this.digitalBaseConfig.digitalBaseType1Name || "").trim() || DEFAULT_TYPE_1_NAME;
+    },
+    type2Name() {
+      return String(this.digitalBaseConfig.digitalBaseType2Name || "").trim() || DEFAULT_TYPE_2_NAME;
+    },
+    navItems() {
+      return [
+        { id: "pro", label: this.type1Name },
+        { id: "exclusive", label: this.type2Name },
+      ];
+    },
     assetVisualKey() {
       const s = this.uiState["m-pro-asset"] || { p: 0, m: 0 };
       return `asset-${s.p}-${s.m}`;