refactor(official): 使用演示数据兜底官网内容展示
- 在关于我们页补充企业优势和联系方式演示数据展示 - 资讯列表页增加分类标签,实现按分类筛选资讯 - 文章详情页新增相关推荐文章展示逻辑 - 主页使用演示数据兜底导航、Banner、核心业务、公司简介和文章列表 - 各页面均优化站点信息使用,优先展示真实数据,缺失时使用演示数据 - 留言页增加公司联系信息展示,提升体验 - 个人中心页支持分享官网,展示演示数据防止空白 - 主页Banner支持无图时使用渐变背景和文字占位 - 统一使用演示数据,保证页面无空白,提升整体稳定性和用户体验
This commit is contained in:
Generated
+21
-13
@@ -4,8 +4,15 @@
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="2de94e4f-0587-4c9b-8bfd-e87e0ae95b81" name="更改" comment="refactor(common): 移除公共组件中的 NutUI Button,改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 两个组件全部替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见的问题,确保按钮正常显示 - `FixedButton` 组件虽然未被调用,仍保留但调整实现,icon 由 prop 改为 children 渲染 - 统一主色使用 tailwind 的 `bg-red-500`,弃用原 NutUI primary 颜色 - 全局修复微信小程序原生 button 的 `::after` 灰色描边问题,在全局样式中设置 `button::after { border: none; }` - NutUI Button 的引用文件数由 27 减至 25,`src/components/common/` 完全无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现">
|
||||
<list default="true" id="2de94e4f-0587-4c9b-8bfd-e87e0ae95b81" name="更改" comment="refactor(common): 移除 NutUI Button 并改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 组件替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见问题,确保按钮正常显示 - `FixedButton` 组件调整实现,icon 由 prop 改为 children 渲染 - 统一主色改用 tailwind 的 `bg-red-500`,弃用 NutUI primary 颜色 - 全局样式修复微信小程序原生 button 的 `::after` 灰色描边问题 - NutUI Button 引用文件数由 27 减至 25,`src/components/common/` 无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/official/about/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/official/about/index.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/official/article-detail/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/official/article-detail/index.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/official/article/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/official/article/index.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/official/index/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/official/index/index.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/official/message/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/official/message/index.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/official/mine/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/official/mine/index.tsx" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -120,15 +127,8 @@
|
||||
<workItem from="1784638429525" duration="16147000" />
|
||||
<workItem from="1784798575885" duration="4896000" />
|
||||
<workItem from="1784873955217" duration="3822000" />
|
||||
<workItem from="1786371937331" duration="12399000" />
|
||||
</task>
|
||||
<task id="LOCAL-00034" summary="feat(app): 添加应用入口文件和配置文件 - 新增 index.tsx 作为应用的主入口文件 - 新增 index.config.ts 用于应用的配置管理">
|
||||
<option name="closed" value="true" />
|
||||
<created>1782804461646</created>
|
||||
<option name="number" value="00034" />
|
||||
<option name="presentableId" value="LOCAL-00034" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1782804461646</updated>
|
||||
<workItem from="1786371937331" duration="13654000" />
|
||||
<workItem from="1786532924218" duration="478000" />
|
||||
</task>
|
||||
<task id="LOCAL-00035" summary="fix(tailwind): 更新配置以兼容微信小程序 - 启用 autoprefixer 并新增 postcss-nested 插件支持嵌套语法 - 扩展主题颜色,添加 primary 色系 - 更新 content 路径包含 public/index.html - 禁用 preflight 以移除默认样式重置 - 移除多数 corePlugins 禁用项,保留 preflight 禁用,简化兼容性配置">
|
||||
<option name="closed" value="true" />
|
||||
@@ -514,7 +514,15 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1786417944432</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="83" />
|
||||
<task id="LOCAL-00083" summary="refactor(common): 移除 NutUI Button 并改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 组件替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见问题,确保按钮正常显示 - `FixedButton` 组件调整实现,icon 由 prop 改为 children 渲染 - 统一主色改用 tailwind 的 `bg-red-500`,弃用 NutUI primary 颜色 - 全局样式修复微信小程序原生 button 的 `::after` 灰色描边问题 - NutUI Button 引用文件数由 27 减至 25,`src/components/common/` 无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现">
|
||||
<option name="closed" value="true" />
|
||||
<created>1786434456515</created>
|
||||
<option name="number" value="00083" />
|
||||
<option name="presentableId" value="LOCAL-00083" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1786434456515</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="84" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@@ -534,7 +542,6 @@
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="CHECK_NEW_TODO" value="false" />
|
||||
<MESSAGE value="feat(pay): 支付成功后自动跳转到已购产品页面 - 支付成功后显示成功提示 - 延迟1.5秒自动跳转到已购产品页面 - 处理跳转失败时回退到用户首页 - 优化用户支付完成后的使用体验" />
|
||||
<MESSAGE value="feat(pay-bak): 新增小程序支付页面及相关配置 - 新增确认支付页面配置,设置导航栏标题和样式 - 实现小程序支付页完整组件逻辑,包括加载订单、发起JSAPI支付等 - 支持通过 scene 或 subscriptionNo 获取订单参数 - 完善支付流程接口请求及错误处理,支持自动登录和支付确认 - 增加支付成功、支付中、支付失败、取消等状态页面展示 - 支持支付成功后跳转已购产品页或用户页 - 提供取消支付返回逻辑和界面展示 - 细化支付金额显示和提示用户支付后可使用应用功能" />
|
||||
<MESSAGE value="feat(address): 新增收货地址与售后申请功能 - 新增地址编辑页面,支持地址智能识别、地图选点、地区选择和默认地址设置 - 实现地址列表页面,支持地址查看、删除、设为默认及选择返回结算页 - 新增售后申请页面,支持退款类型选择、商品选择、原因填写、图片上传和提交审核 - 修复 passport 分包配置,移除不存在分包并补充缺失声明,避免 Taro 编译报错 - 新增地址类型定义,增强前端地址数据结构类型安全 - 优化页面交互体验,完善表单校验及错误提示逻辑 - 统一代码格式与命名规范,保持代码风格一致性" />
|
||||
<MESSAGE value="feat(passport): 迁移并修复小程序支付页面访问 websopy API 问题 - 迁移 src/passport/pay 相关代码至当前项目,无需替换文件 - 新增环境变量 WEBSOPY_API_BASE_URL,提供 websopy API 基础地址 - 在 config/app.ts 导出 WebsopyBaseUrl,供代码引用 - 配置 env.d.ts 类型定义,消除 TypeScript 隐式 any 错误 - request 请求方法支持自定义 baseUrl 以调用不同接口地址 - passport/pay 页面调用订阅接口统一传入 WebsopyBaseUrl - 修正 tenantId 类型为 number,调整登录用户类型断言 - 确认编译成功,dist 目录生成对应文件及正确请求地址 - 说明 type-check 依赖库问题不影响正常构建和运行" />
|
||||
@@ -559,7 +566,8 @@
|
||||
<MESSAGE value="feat(official): 实现企业官网分包及内容展示 - 新增官方分包目录及页面(首页、资讯列表、详情、关于我们、留言、我的) - 自定义实现底部导航组件 OfficialTabBar,解决微信 tabBar 不支持分包问题 - 统一接口调用走 shop-api 代理,无新增 CMS 域名,减少合法域名负担 - 新增 CMS 站点信息获取接口及留言咨询提交与查询接口 - 设计并完善官网富文本样式,品牌色统一为 #185FA5,并更新 tailwind 配置 - 首页新增企业官网入口卡片,方便用户访问官网内容 - 完成官网分包构建验证,解决 Taro 构建批量删除保护问题 - 规范 CMS 字段使用,适配字段名称及状态含义 - 后续计划对历史页面 NutUI 组件进行空壳化整改,及更新 UI 设计文档" />
|
||||
<MESSAGE value="refactor(cms): 迁移CMS模块接口到独立cms-api服务 - 新增cmsRequest工具,基于request封装,默认baseURL为cms-api - 改用cmsRequest替换所有cms相关请求,确保请求走独立域名 - 配置三环境新增CMS_API_BASE_URL及导出CmsBaseUrl常量 - 解决CMS接口走shop-api时返回404的问题,避免小程序域名白名单冲突 - 统一修改34个cms API模块的261处调用,保持接口行为一致 - 修复部分拼接全URL方式改为相对路径调用cmsRequest - 更新注释说明并调整相关接口调用代码 - 兼容macOS sed替换问题,采用perl命令完成批量替换" />
|
||||
<MESSAGE value="refactor(common): 移除公共组件中的 NutUI Button,改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 两个组件全部替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见的问题,确保按钮正常显示 - `FixedButton` 组件虽然未被调用,仍保留但调整实现,icon 由 prop 改为 children 渲染 - 统一主色使用 tailwind 的 `bg-red-500`,弃用原 NutUI primary 颜色 - 全局修复微信小程序原生 button 的 `::after` 灰色描边问题,在全局样式中设置 `button::after { border: none; }` - NutUI Button 的引用文件数由 27 减至 25,`src/components/common/` 完全无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="refactor(common): 移除公共组件中的 NutUI Button,改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 两个组件全部替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见的问题,确保按钮正常显示 - `FixedButton` 组件虽然未被调用,仍保留但调整实现,icon 由 prop 改为 children 渲染 - 统一主色使用 tailwind 的 `bg-red-500`,弃用原 NutUI primary 颜色 - 全局修复微信小程序原生 button 的 `::after` 灰色描边问题,在全局样式中设置 `button::after { border: none; }` - NutUI Button 的引用文件数由 27 减至 25,`src/components/common/` 完全无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现" />
|
||||
<MESSAGE value="refactor(common): 移除 NutUI Button 并改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 组件替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见问题,确保按钮正常显示 - `FixedButton` 组件调整实现,icon 由 prop 改为 children 渲染 - 统一主色改用 tailwind 的 `bg-red-500`,弃用 NutUI primary 颜色 - 全局样式修复微信小程序原生 button 的 `::after` 灰色描边问题 - NutUI Button 引用文件数由 27 减至 25,`src/components/common/` 无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="refactor(common): 移除 NutUI Button 并改用 Taro 原生 Button - `EmptyState` 和 `FixedButton` 组件替换 NutUI Button 为 Taro 原生 Button - 解决空状态按钮在微信小程序端不可见问题,确保按钮正常显示 - `FixedButton` 组件调整实现,icon 由 prop 改为 children 渲染 - 统一主色改用 tailwind 的 `bg-red-500`,弃用 NutUI primary 颜色 - 全局样式修复微信小程序原生 button 的 `::after` 灰色描边问题 - NutUI Button 引用文件数由 27 减至 25,`src/components/common/` 无 NutUI 依赖 - CMS 请求链路调整,所有 CMS 接口改用独立 `cmsRequest` 实现" />
|
||||
<option name="NON_MODAL_COMMIT_POSTPONE_SLOW_CHECKS" value="false" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -10,6 +10,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build:weapp": "taro build --type weapp",
|
||||
"build:weapp:safe": "bash scripts/safe-build-weapp.sh",
|
||||
"build:swan": "taro build --type swan",
|
||||
"build:alipay": "taro build --type alipay",
|
||||
"build:tt": "taro build --type tt",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
# 安全构建小程序:规避 Taro emptyOutputDir 触发的 SAFE_DELETE 批量删除守卫
|
||||
# (dist 文件数 > 50 时守卫会中断构建,导致 official/index 等页面 .js 缺失而白屏)
|
||||
set -e
|
||||
|
||||
BAK_ROOT="/tmp/taro-dist-bak"
|
||||
if [ -d dist ]; then
|
||||
mkdir -p "$BAK_ROOT"
|
||||
BAK="$BAK_ROOT/dist-$(date +%s)"
|
||||
mv dist "$BAK"
|
||||
echo "[safe-build] 已备份旧 dist -> $BAK"
|
||||
fi
|
||||
|
||||
echo "[safe-build] 开始构建 weapp ..."
|
||||
./node_modules/.bin/taro build --type weapp
|
||||
echo "[safe-build] 构建完成"
|
||||
@@ -6,6 +6,7 @@ import type { CmsWebsite } from '@/api/official'
|
||||
import { getCompressedImageUrl } from '@/utils/image'
|
||||
import OfficialTabBar from '../components/OfficialTabBar'
|
||||
import NavBar from '@/components/NavBar'
|
||||
import { DEMO_SITE, DEMO_ADVANTAGES } from '../data/demo'
|
||||
|
||||
definePageConfig({
|
||||
navigationBarTitleText: '关于我们',
|
||||
@@ -22,8 +23,15 @@ const About: React.FC = () => {
|
||||
.finally(() => setLoading(false))
|
||||
}, [])
|
||||
|
||||
const effectiveSite: CmsWebsite = site ?? (DEMO_SITE as CmsWebsite)
|
||||
const aboutHtml =
|
||||
(site as any)?.config?.about || (site as any)?.description || ''
|
||||
(site as any)?.config?.about || (site as any)?.description || DEMO_SITE.config?.about || ''
|
||||
|
||||
const contact = {
|
||||
phone: effectiveSite.phone || DEMO_SITE.phone,
|
||||
email: effectiveSite.email || DEMO_SITE.email,
|
||||
address: effectiveSite.address || DEMO_SITE.address,
|
||||
}
|
||||
|
||||
return (
|
||||
<View className='flex flex-col h-screen bg-gray-50'>
|
||||
@@ -31,15 +39,21 @@ const About: React.FC = () => {
|
||||
<ScrollView scrollY className='flex-1'>
|
||||
<View className='p-4'>
|
||||
<View className='flex items-center mb-4'>
|
||||
{site?.websiteLogo && (
|
||||
{effectiveSite.websiteLogo ? (
|
||||
<Image
|
||||
src={getCompressedImageUrl(site.websiteLogo, { width: 120 })}
|
||||
src={getCompressedImageUrl(effectiveSite.websiteLogo, { width: 120 })}
|
||||
className='w-16 h-16 rounded mr-3'
|
||||
mode='aspectFill'
|
||||
/>
|
||||
) : (
|
||||
<View className='w-16 h-16 rounded bg-brand-600 flex items-center justify-center mr-3'>
|
||||
<Text className='text-white text-2xl font-bold'>
|
||||
{(effectiveSite.websiteName || '官').slice(0, 1)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text className='text-lg font-semibold text-gray-800'>
|
||||
{site?.websiteName || '企业官网'}
|
||||
{effectiveSite.websiteName || '企业官网'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -51,10 +65,30 @@ const About: React.FC = () => {
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{/* 企业优势 */}
|
||||
<View className='mt-5'>
|
||||
<View className='flex items-center mb-3'>
|
||||
<View className='w-1 h-4 bg-brand-600 rounded mr-2' />
|
||||
<Text className='text-base font-semibold text-gray-800'>企业优势</Text>
|
||||
</View>
|
||||
<View className='flex flex-wrap -mx-1'>
|
||||
{DEMO_ADVANTAGES.map((a) => (
|
||||
<View key={a.title} className='w-1/2 px-1 mb-2'>
|
||||
<View className='bg-white rounded-lg p-3 h-full'>
|
||||
<Text className='text-xl'>{a.icon}</Text>
|
||||
<Text className='text-sm font-medium text-gray-800 block mt-1'>{a.title}</Text>
|
||||
<Text className='text-xs text-gray-400 mt-0.5 leading-snug block'>{a.desc}</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 联系方式 */}
|
||||
<View className='mt-4 bg-white rounded-lg p-4'>
|
||||
<Text className='text-sm text-gray-500 block'>联系电话:{site?.phone || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block mt-2'>邮箱:{site?.email || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block mt-2'>地址:{site?.address || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block'>联系电话:{contact.phone || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block mt-2'>邮箱:{contact.email || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block mt-2'>地址:{contact.address || '—'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { View, Text, ScrollView, RichText } from '@tarojs/components'
|
||||
import Taro, { useRouter } from '@tarojs/taro'
|
||||
import { getCmsArticle } from '@/api/official'
|
||||
import { getCmsArticle, pageCmsArticle } from '@/api/official'
|
||||
import type { CmsArticle } from '@/api/official'
|
||||
import ArticleCard from '../components/ArticleCard'
|
||||
import NavBar from '@/components/NavBar'
|
||||
|
||||
definePageConfig({
|
||||
@@ -13,6 +14,7 @@ const ArticleDetail: React.FC = () => {
|
||||
const router = useRouter()
|
||||
const id = router.params.id
|
||||
const [article, setArticle] = useState<CmsArticle>()
|
||||
const [related, setRelated] = useState<CmsArticle[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -21,6 +23,13 @@ const ArticleDetail: React.FC = () => {
|
||||
.then((a) => setArticle(a))
|
||||
.catch(() => {})
|
||||
.finally(() => setLoading(false))
|
||||
// 相关推荐:取最新几条,排除当前
|
||||
pageCmsArticle({ status: 0, deleted: 0, page: 1, limit: 4 })
|
||||
.then((r) => {
|
||||
const list = (r?.list || []).filter((x) => x.articleId !== Number(id)).slice(0, 3)
|
||||
setRelated(list)
|
||||
})
|
||||
.catch(() => {})
|
||||
}, [id])
|
||||
|
||||
return (
|
||||
@@ -43,10 +52,22 @@ const ArticleDetail: React.FC = () => {
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* 相关推荐 */}
|
||||
{related.length > 0 && (
|
||||
<View className='px-3 pb-4'>
|
||||
<View className='flex items-center mb-2'>
|
||||
<View className='w-1 h-4 bg-brand-600 rounded mr-2' />
|
||||
<Text className='text-base font-semibold text-gray-800'>相关推荐</Text>
|
||||
</View>
|
||||
{related.map((a) => (
|
||||
<ArticleCard key={a.articleId} article={a} />
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
<View
|
||||
className='px-4 py-3 bg-white border-t border-gray-200 safe-area-bottom'
|
||||
>
|
||||
|
||||
<View className='px-4 py-3 bg-white border-t border-gray-200 safe-area-bottom'>
|
||||
<View
|
||||
className='bg-brand-600 rounded-full py-3 text-center'
|
||||
onClick={() => Taro.navigateTo({ url: '/official/message' })}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import React, { useState, useEffect, useCallback } from 'react'
|
||||
import { View, Text, ScrollView } from '@tarojs/components'
|
||||
import Taro, { useRouter } from '@tarojs/taro'
|
||||
import { pageCmsArticle } from '@/api/official'
|
||||
import type { CmsArticle } from '@/api/official'
|
||||
import { pageCmsArticle, treeNavigation } from '@/api/official'
|
||||
import type { CmsArticle, CmsNavigation } from '@/api/official'
|
||||
import ArticleCard from '../components/ArticleCard'
|
||||
import OfficialTabBar from '../components/OfficialTabBar'
|
||||
import NavBar from '@/components/NavBar'
|
||||
@@ -13,13 +13,26 @@ definePageConfig({
|
||||
|
||||
const ArticleList: React.FC = () => {
|
||||
const router = useRouter()
|
||||
const categoryId = router.params.categoryId
|
||||
const initCategory = router.params.categoryId ? Number(router.params.categoryId) : undefined
|
||||
|
||||
const [cats, setCats] = useState<{ id?: number; title: string }[]>([{ id: undefined, title: '全部' }])
|
||||
const [activeCat, setActiveCat] = useState<number | undefined>(initCategory)
|
||||
const [articles, setArticles] = useState<CmsArticle[]>([])
|
||||
const [page, setPage] = useState(1)
|
||||
const [finished, setFinished] = useState(false)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const load = async (p: number) => {
|
||||
useEffect(() => {
|
||||
treeNavigation({ top: 1 })
|
||||
.then((res) => {
|
||||
const list = (res || []).map((n: CmsNavigation) => ({ id: n.navigationId, title: n.title }))
|
||||
if (list.length) setCats([{ id: undefined, title: '全部' }, ...list])
|
||||
})
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
const load = useCallback(
|
||||
async (p: number, cat?: number) => {
|
||||
if (loading || finished) return
|
||||
setLoading(true)
|
||||
try {
|
||||
@@ -28,7 +41,7 @@ const ArticleList: React.FC = () => {
|
||||
deleted: 0,
|
||||
page: p,
|
||||
limit: 10,
|
||||
categoryId: categoryId ? Number(categoryId) : undefined,
|
||||
categoryId: cat,
|
||||
})
|
||||
const list = res?.list || []
|
||||
setArticles((prev) => (p === 1 ? list : [...prev, ...list]))
|
||||
@@ -39,16 +52,45 @@ const ArticleList: React.FC = () => {
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
},
|
||||
[loading, finished]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
load(1)
|
||||
}, [])
|
||||
setArticles([])
|
||||
setPage(1)
|
||||
setFinished(false)
|
||||
load(1, activeCat)
|
||||
}, [activeCat])
|
||||
|
||||
const onTab = (id?: number) => {
|
||||
if (id === activeCat) return
|
||||
setActiveCat(id)
|
||||
}
|
||||
|
||||
return (
|
||||
<View className='flex flex-col h-screen bg-gray-50'>
|
||||
<NavBar title='资讯' />
|
||||
<ScrollView scrollY className='flex-1' onScrollToLower={() => load(page + 1)}>
|
||||
{/* 分类 tab */}
|
||||
<ScrollView scrollX className='bg-white border-b border-gray-100' style={{ whiteSpace: 'nowrap' }}>
|
||||
<View className='inline-flex px-2'>
|
||||
{cats.map((c) => {
|
||||
const on = c.id === activeCat
|
||||
return (
|
||||
<View
|
||||
key={String(c.id)}
|
||||
className={`inline-block px-3 py-3 ${on ? 'text-brand-600' : 'text-gray-500'}`}
|
||||
onClick={() => onTab(c.id)}
|
||||
>
|
||||
<Text className={`text-sm ${on ? 'font-semibold' : ''}`}>{c.title}</Text>
|
||||
{on ? <View className='mx-auto mt-1 h-0.5 w-6 bg-brand-600 rounded' /> : null}
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
<ScrollView scrollY className='flex-1' onScrollToLower={() => load(page + 1, activeCat)}>
|
||||
<View className='p-3'>
|
||||
{articles.length > 0 ? (
|
||||
articles.map((a) => <ArticleCard key={a.articleId} article={a} />)
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 官网演示兜底数据
|
||||
* 当 CMS 后台未配置对应内容(站点信息 / 导航 / Banner / 文章等)时,
|
||||
* 前端使用下方数据渲染成型页面,保证「打开即见官网」而非空白。
|
||||
* 一旦 CMS 返回真实数据,页面自动以真实数据覆盖(见各页 merge 逻辑)。
|
||||
*
|
||||
* 注意:图片类字段统一留空,由组件用 CSS 渐变 / 首字母占位渲染,
|
||||
* 避免演示环境外链裂图。
|
||||
*/
|
||||
import type { CmsWebsite, CmsNavigation } from '@/api/cms/cmsWebsite/model'
|
||||
import type { CmsArticle } from '@/api/cms/cmsArticle/model'
|
||||
|
||||
/** 站点信息兜底(对应 getCmsWebsiteSiteInfo 返回结构,按需取字段) */
|
||||
export const DEMO_SITE: Partial<CmsWebsite> = {
|
||||
websiteName: '星辰科技企业',
|
||||
websiteLogo: '',
|
||||
description: '专注于为企业提供数字化转型与智能营销一体化解决方案,助力品牌增长。',
|
||||
phone: '400-888-6666',
|
||||
email: 'contact@example.com',
|
||||
address: '广东省深圳市南山区科技园',
|
||||
icpNo: '粤ICP备2024000000号',
|
||||
config: {
|
||||
about:
|
||||
'<p>星辰科技成立于 2015 年,是一家以技术与服务驱动的数字化服务商,致力于帮助企业在移动互联网时代实现增长。</p>' +
|
||||
'<p>我们已服务超过 <b>2000+</b> 家企业客户,覆盖零售、制造、教育、本地生活等多个行业,提供从战略咨询到系统落地的一站式服务。</p>',
|
||||
},
|
||||
}
|
||||
|
||||
/** 顶部快捷导航宫格兜底 */
|
||||
export const DEMO_NAVS: CmsNavigation[] = [
|
||||
{ navigationId: 1, title: '公司简介', icon: '🏢', color: '#EAF2FB', path: '/official/about' },
|
||||
{ navigationId: 2, title: '产品中心', icon: '📦', color: '#EAF2FB' },
|
||||
{ navigationId: 3, title: '解决方案', icon: '💡', color: '#EAF2FB' },
|
||||
{ navigationId: 4, title: '新闻资讯', icon: '📰', color: '#EAF2FB', path: '/official/article' },
|
||||
{ navigationId: 5, title: '客户案例', icon: '🤝', color: '#EAF2FB' },
|
||||
{ navigationId: 6, title: '留言咨询', icon: '💬', color: '#EAF2FB', path: '/official/message' },
|
||||
{ navigationId: 7, title: '关于我们', icon: 'ℹ️', color: '#EAF2FB', path: '/official/about' },
|
||||
{ navigationId: 8, title: '联系我们', icon: '📞', color: '#EAF2FB', path: '/official/message' },
|
||||
]
|
||||
|
||||
/** Banner 兜底(渐变 + 标题,无外链图片) */
|
||||
export interface DemoBanner {
|
||||
title: string
|
||||
subtitle: string
|
||||
gradient: string
|
||||
}
|
||||
export const DEMO_BANNERS: DemoBanner[] = [
|
||||
{ title: '数字化转型专家', subtitle: '让增长更简单', gradient: 'linear-gradient(135deg,#185FA5,#3D86CE)' },
|
||||
{ title: '智能营销一体化', subtitle: '全渠道触达你的客户', gradient: 'linear-gradient(135deg,#12518C,#1E6BB8)' },
|
||||
{ title: '2000+ 企业信赖', subtitle: '专业服务值得托付', gradient: 'linear-gradient(135deg,#0E4070,#185FA5)' },
|
||||
]
|
||||
|
||||
/** 首页「核心业务」横向卡片兜底 */
|
||||
export interface DemoBusiness {
|
||||
id: number
|
||||
title: string
|
||||
desc: string
|
||||
icon: string
|
||||
}
|
||||
export const DEMO_BUSINESS: DemoBusiness[] = [
|
||||
{ id: 1, title: '数字化转型', desc: '从战略到落地的全链路咨询与实施', icon: '🚀' },
|
||||
{ id: 2, title: '智能营销', desc: '私域运营 + 全渠道增长引擎', icon: '📈' },
|
||||
{ id: 3, title: '客户管理', desc: '一体化 CRM 与会员体系', icon: '👥' },
|
||||
{ id: 4, title: '数据洞察', desc: '可视化看板辅助经营决策', icon: '📊' },
|
||||
]
|
||||
|
||||
/** 资讯列表兜底 */
|
||||
export const DEMO_ARTICLES: CmsArticle[] = [
|
||||
{
|
||||
articleId: 101,
|
||||
title: '星辰科技发布全新一代智能营销平台',
|
||||
overview: '集成私域运营、内容分发与数据洞察,帮助企业以更低成本获取并留住客户。',
|
||||
image: '',
|
||||
source: '公司新闻',
|
||||
author: '星辰科技',
|
||||
createTime: '2026-08-01',
|
||||
},
|
||||
{
|
||||
articleId: 102,
|
||||
title: '零售行业数字化转型的 5 个关键步骤',
|
||||
overview: '从会员体系到门店数字化,拆解一套可落地的转型路线图。',
|
||||
image: '',
|
||||
source: '行业洞察',
|
||||
author: '研究院',
|
||||
createTime: '2026-07-20',
|
||||
},
|
||||
{
|
||||
articleId: 103,
|
||||
title: '客户案例:某连锁品牌会员复购提升 38%',
|
||||
overview: '通过一体化客户管理与精准触达,实现显著增长。',
|
||||
image: '',
|
||||
source: '客户案例',
|
||||
author: '星辰科技',
|
||||
createTime: '2026-07-08',
|
||||
},
|
||||
{
|
||||
articleId: 104,
|
||||
title: '小程序官网能力上新:留言咨询与内容管理',
|
||||
overview: '企业可自助维护站点内容,客户一键发起咨询。',
|
||||
image: '',
|
||||
source: '产品动态',
|
||||
author: '产品团队',
|
||||
createTime: '2026-06-25',
|
||||
},
|
||||
]
|
||||
|
||||
/** 关于页「企业优势」兜底 */
|
||||
export interface DemoAdvantage {
|
||||
title: string
|
||||
desc: string
|
||||
icon: string
|
||||
}
|
||||
export const DEMO_ADVANTAGES: DemoAdvantage[] = [
|
||||
{ title: '技术领先', desc: '自研增长引擎,稳定支撑高并发业务', icon: '⚙️' },
|
||||
{ title: '服务专业', desc: '一对一顾问,从咨询到落地全程陪伴', icon: '🎯' },
|
||||
{ title: '数据安全', desc: '金融级加密与权限管控,合规可靠', icon: '🔒' },
|
||||
{ title: '持续迭代', desc: '产品按月更新,紧跟行业趋势', icon: '🔄' },
|
||||
]
|
||||
+100
-10
@@ -12,12 +12,27 @@ import type { CmsAd, CmsWebsite, CmsArticle, CmsNavigation } from '@/api/officia
|
||||
import OfficialTabBar from '../components/OfficialTabBar'
|
||||
import ArticleCard from '../components/ArticleCard'
|
||||
import SectionTitle from '../components/SectionTitle'
|
||||
import {
|
||||
DEMO_SITE,
|
||||
DEMO_NAVS,
|
||||
DEMO_BANNERS,
|
||||
DEMO_BUSINESS,
|
||||
DEMO_ARTICLES,
|
||||
} from '../data/demo'
|
||||
|
||||
definePageConfig({
|
||||
navigationBarTitleText: '企业官网',
|
||||
enableShareAppMessage: true,
|
||||
})
|
||||
|
||||
interface Slide {
|
||||
key: string
|
||||
src?: string
|
||||
title?: string
|
||||
subtitle?: string
|
||||
gradient?: string
|
||||
}
|
||||
|
||||
const OfficialIndex: React.FC = () => {
|
||||
const [site, setSite] = useState<CmsWebsite>()
|
||||
const [banners, setBanners] = useState<CmsAd[]>([])
|
||||
@@ -42,10 +57,14 @@ const OfficialIndex: React.FC = () => {
|
||||
siteRes?.topNavs && siteRes.topNavs.length
|
||||
? siteRes.topNavs
|
||||
: (navRes || [])
|
||||
setNavs(topNavs)
|
||||
setArticles(artRes?.list || [])
|
||||
setNavs(topNavs.length ? topNavs : DEMO_NAVS)
|
||||
const realArticles = artRes?.list || []
|
||||
setArticles(realArticles.length ? realArticles : DEMO_ARTICLES)
|
||||
} catch (e) {
|
||||
console.error('官网首页加载失败', e)
|
||||
// 任意异常都回退到演示内容,保证页面成型
|
||||
setNavs(DEMO_NAVS)
|
||||
setArticles(DEMO_ARTICLES)
|
||||
} finally {
|
||||
if (mounted) setLoading(false)
|
||||
}
|
||||
@@ -55,54 +74,85 @@ const OfficialIndex: React.FC = () => {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const bannerSlides = banners.flatMap((b) =>
|
||||
const effectiveSite: CmsWebsite = site ?? (DEMO_SITE as CmsWebsite)
|
||||
|
||||
const slides: Slide[] = (() => {
|
||||
const real = banners.flatMap((b) =>
|
||||
b.imageList && b.imageList.length
|
||||
? b.imageList.map((img, i) => ({ key: `${b.adId}-${i}`, src: (img as any).url || '' }))
|
||||
: b.image
|
||||
? [{ key: `${b.adId}-0`, src: b.image }]
|
||||
? [{ key: `${b.adId}-0`, src: b.image as string }]
|
||||
: []
|
||||
)
|
||||
if (real.length) return real
|
||||
return DEMO_BANNERS.map((b, i) => ({ key: `demo-${i}`, ...b }))
|
||||
})()
|
||||
|
||||
const onNavClick = (n: CmsNavigation) => {
|
||||
if (n.path) {
|
||||
Taro.navigateTo({ url: n.path.startsWith('/') ? n.path : `/${n.path}` })
|
||||
} else if (n.children && n.children.length) {
|
||||
Taro.navigateTo({ url: `/official/article?categoryId=${n.navigationId}` })
|
||||
} else {
|
||||
Taro.navigateTo({ url: '/official/article' })
|
||||
}
|
||||
}
|
||||
|
||||
const contact = {
|
||||
phone: effectiveSite.phone || DEMO_SITE.phone,
|
||||
email: effectiveSite.email || DEMO_SITE.email,
|
||||
address: effectiveSite.address || DEMO_SITE.address,
|
||||
icpNo: effectiveSite.icpNo || DEMO_SITE.icpNo,
|
||||
}
|
||||
|
||||
return (
|
||||
<View className='flex flex-col h-screen bg-gray-50'>
|
||||
{/* 顶部品牌栏 */}
|
||||
<View className='flex items-center px-4 py-3 bg-white'>
|
||||
{site?.websiteLogo ? (
|
||||
{effectiveSite.websiteLogo ? (
|
||||
<Image
|
||||
src={getCompressedImageUrl(site.websiteLogo, { width: 80 })}
|
||||
src={getCompressedImageUrl(effectiveSite.websiteLogo, { width: 80 })}
|
||||
className='w-8 h-8 rounded mr-2'
|
||||
mode='aspectFill'
|
||||
/>
|
||||
) : null}
|
||||
) : (
|
||||
<View className='w-8 h-8 rounded bg-brand-600 flex items-center justify-center mr-2'>
|
||||
<Text className='text-white text-sm font-bold'>
|
||||
{(effectiveSite.websiteName || '官').slice(0, 1)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text className='text-lg font-semibold text-gray-800'>
|
||||
{site?.websiteName || '企业官网'}
|
||||
{effectiveSite.websiteName || '企业官网'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<ScrollView scrollY className='flex-1'>
|
||||
{/* Banner 轮播 */}
|
||||
{bannerSlides.length > 0 && (
|
||||
{slides.length > 0 && (
|
||||
<Swiper
|
||||
autoplay
|
||||
interval={3000}
|
||||
className='mx-3 mt-3 rounded-lg overflow-hidden'
|
||||
style={{ height: '150px' }}
|
||||
>
|
||||
{bannerSlides.map((s) => (
|
||||
{slides.map((s) => (
|
||||
<SwiperItem key={s.key}>
|
||||
{s.src ? (
|
||||
<Image
|
||||
src={getCompressedImageUrl(s.src, { width: 750 })}
|
||||
className='w-full h-full'
|
||||
mode='aspectFill'
|
||||
/>
|
||||
) : (
|
||||
<View
|
||||
className='w-full h-full flex flex-col items-center justify-center'
|
||||
style={{ background: s.gradient }}
|
||||
>
|
||||
<Text className='text-white text-lg font-semibold'>{s.title}</Text>
|
||||
<Text className='text-white text-xs mt-1 opacity-80'>{s.subtitle}</Text>
|
||||
</View>
|
||||
)}
|
||||
</SwiperItem>
|
||||
))}
|
||||
</Swiper>
|
||||
@@ -131,6 +181,36 @@ const OfficialIndex: React.FC = () => {
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 公司简介 */}
|
||||
<View className='mx-3 mt-3 bg-white rounded-lg p-4'>
|
||||
<View className='flex items-center mb-2'>
|
||||
<View className='w-1 h-4 bg-brand-600 rounded mr-2' />
|
||||
<Text className='text-base font-semibold text-gray-800'>公司简介</Text>
|
||||
</View>
|
||||
<Text className='text-sm text-gray-500 leading-relaxed'>
|
||||
{effectiveSite.description || DEMO_SITE.description}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* 核心业务 */}
|
||||
<View className='mt-1'>
|
||||
<SectionTitle title='核心业务' moreUrl='/official/article' />
|
||||
<ScrollView scrollX className='whitespace-nowrap px-3' style={{ overflow: 'hidden' }}>
|
||||
{DEMO_BUSINESS.map((b) => (
|
||||
<View
|
||||
key={b.id}
|
||||
className='inline-flex flex-col w-36 mr-3 bg-white rounded-lg p-3 align-top'
|
||||
style={{ height: '104px' }}
|
||||
onClick={() => Taro.navigateTo({ url: '/official/article' })}
|
||||
>
|
||||
<Text className='text-2xl'>{b.icon}</Text>
|
||||
<Text className='text-sm font-medium text-gray-800 mt-1'>{b.title}</Text>
|
||||
<Text className='text-xs text-gray-400 mt-1 leading-snug'>{b.desc}</Text>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
{/* 资讯动态 */}
|
||||
<View className='mt-1'>
|
||||
<SectionTitle title='资讯动态' moreUrl='/official/article' />
|
||||
@@ -156,6 +236,16 @@ const OfficialIndex: React.FC = () => {
|
||||
<Text className='text-white text-sm font-medium'>📩 留言咨询</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 底部联系方式 */}
|
||||
<View className='mx-3 mb-4 bg-white rounded-lg p-4'>
|
||||
<Text className='text-sm text-gray-500 block'>联系电话:{contact.phone || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block mt-2'>邮箱:{contact.email || '—'}</Text>
|
||||
<Text className='text-sm text-gray-500 block mt-2'>地址:{contact.address || '—'}</Text>
|
||||
{contact.icpNo ? (
|
||||
<Text className='text-xs text-gray-300 block mt-3'>{contact.icpNo}</Text>
|
||||
) : null}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
<OfficialTabBar active='home' />
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React, { useState } from 'react'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { View, Text, Input, Textarea } from '@tarojs/components'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { submitCmsContactLead } from '@/api/official'
|
||||
import { submitCmsContactLead, getCmsWebsiteSiteInfo } from '@/api/official'
|
||||
import type { CmsWebsite } from '@/api/official'
|
||||
import NavBar from '@/components/NavBar'
|
||||
import { DEMO_SITE } from '../data/demo'
|
||||
|
||||
definePageConfig({
|
||||
navigationBarTitleText: '留言咨询',
|
||||
@@ -18,6 +20,20 @@ interface FormState {
|
||||
const Message: React.FC = () => {
|
||||
const [form, setForm] = useState<FormState>({ name: '', phone: '', company: '', need: '' })
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [site, setSite] = useState<CmsWebsite>()
|
||||
|
||||
useEffect(() => {
|
||||
getCmsWebsiteSiteInfo()
|
||||
.then((s) => setSite(s))
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
const effectiveSite: CmsWebsite = site ?? (DEMO_SITE as CmsWebsite)
|
||||
const contact = {
|
||||
phone: effectiveSite.phone || DEMO_SITE.phone,
|
||||
email: effectiveSite.email || DEMO_SITE.email,
|
||||
address: effectiveSite.address || DEMO_SITE.address,
|
||||
}
|
||||
|
||||
const set = (k: keyof FormState, v: string) =>
|
||||
setForm((prev) => ({ ...prev, [k]: v }))
|
||||
@@ -47,6 +63,19 @@ const Message: React.FC = () => {
|
||||
<View className='flex flex-col h-screen bg-gray-50'>
|
||||
<NavBar title='留言咨询' />
|
||||
<View className='flex-1 p-4'>
|
||||
{/* 公司联系信息 */}
|
||||
<View className='bg-white rounded-lg p-4 mb-3'>
|
||||
<Text className='text-sm text-gray-800 font-medium block'>
|
||||
{effectiveSite.websiteName || '企业官网'}
|
||||
</Text>
|
||||
<Text className='text-xs text-gray-400 block mt-1'>填写下方信息,我们将尽快与您联系</Text>
|
||||
<View className='mt-3 pt-3 border-t border-gray-100'>
|
||||
<Text className='text-xs text-gray-500 block'>电话:{contact.phone || '—'}</Text>
|
||||
<Text className='text-xs text-gray-500 block mt-1'>邮箱:{contact.email || '—'}</Text>
|
||||
<Text className='text-xs text-gray-500 block mt-1'>地址:{contact.address || '—'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className='bg-white rounded-lg p-4'>
|
||||
<Field label='称呼' placeholder='请输入您的称呼' value={form.name} onInput={(v) => set('name', v)} />
|
||||
<Field
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { View, Text, ScrollView } from '@tarojs/components'
|
||||
import { View, Text, ScrollView, Button } from '@tarojs/components'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { getCmsWebsiteSiteInfo, pageCmsContactLead } from '@/api/official'
|
||||
import type { CmsWebsite } from '@/api/official'
|
||||
import OfficialTabBar from '../components/OfficialTabBar'
|
||||
import NavBar from '@/components/NavBar'
|
||||
import { DEMO_SITE } from '../data/demo'
|
||||
|
||||
definePageConfig({
|
||||
navigationBarTitleText: '我的',
|
||||
enableShareAppMessage: true,
|
||||
})
|
||||
|
||||
const Mine: React.FC = () => {
|
||||
@@ -23,6 +25,14 @@ const Mine: React.FC = () => {
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
const effectiveSite: CmsWebsite = site ?? (DEMO_SITE as CmsWebsite)
|
||||
const siteName = effectiveSite.websiteName || '企业官网'
|
||||
|
||||
Taro.useShareAppMessage(() => ({
|
||||
title: `${siteName} · 企业官网`,
|
||||
path: '/official/index',
|
||||
}))
|
||||
|
||||
const menus = [
|
||||
{ label: '我的留言', value: leadCount ? `${leadCount} 条` : '暂无', url: '/official/message' },
|
||||
{ label: '关于我们', url: '/official/about' },
|
||||
@@ -35,12 +45,10 @@ const Mine: React.FC = () => {
|
||||
<ScrollView scrollY className='flex-1'>
|
||||
<View className='flex items-center p-4 bg-white'>
|
||||
<View className='w-14 h-14 rounded-full bg-brand-600 flex items-center justify-center'>
|
||||
<Text className='text-white text-xl'>{(site?.websiteName || '官').slice(0, 1)}</Text>
|
||||
<Text className='text-white text-xl'>{(siteName || '官').slice(0, 1)}</Text>
|
||||
</View>
|
||||
<View className='ml-3'>
|
||||
<Text className='text-base font-semibold text-gray-800'>
|
||||
{site?.websiteName || '企业官网'}
|
||||
</Text>
|
||||
<Text className='text-base font-semibold text-gray-800'>{siteName}</Text>
|
||||
<Text className='text-xs text-gray-400 mt-1'>企业账号</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -56,6 +64,24 @@ const Mine: React.FC = () => {
|
||||
<Text className='text-xs text-gray-400'>{m.value || '›'}</Text>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{/* 分享官网 */}
|
||||
<Button
|
||||
openType='share'
|
||||
className='flex items-center justify-between px-4 py-4 w-full text-left bg-white'
|
||||
>
|
||||
<Text className='text-sm text-gray-700'>分享官网</Text>
|
||||
<Text className='text-xs text-gray-400'>›</Text>
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<View className='mt-4 mx-4'>
|
||||
<View
|
||||
className='bg-brand-600 rounded-full py-3 text-center'
|
||||
onClick={() => Taro.navigateTo({ url: '/official/message' })}
|
||||
>
|
||||
<Text className='text-white text-sm font-medium'>留言咨询</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
<OfficialTabBar active='mine' />
|
||||
|
||||
Reference in New Issue
Block a user