Compare commits

..

2 Commits

Author SHA1 Message Date
En
7bc8c10d9a feat: 系统品牌更名为"智创未来"及相关配置调整
- 前后端所有"乐绘世界"统一更名为"智创未来"
- 生产环境乐读派API地址更新为公网地址
- 公众端登录页调整用户名/密码字段显示逻辑
- 同步更新文档、测试用例、主题样式中的品牌名称

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 19:30:26 +08:00
En
ffb5c449fb fix(乐读派): B3对账时B2详情接口缺少phone字段导致无法关联用户
B3批量查询返回phone,但调用B2获取详情后phone丢失。
将B3列表中的phone合并到B2详情数据中再传给syncWork。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 19:28:58 +08:00
27 changed files with 39 additions and 37 deletions

View File

@ -22,7 +22,7 @@
升级后:绘本创作社区 + 活动平台(高频、主动)
┌──────────────────────────────────────────────────┐
乐绘世界 用户端 │
智创未来 用户端 │
│ │
│ 创作工具 → 作品库 → 发布广场 → 社区互动 │
│ ↓ │

View File

@ -2,7 +2,7 @@
## 1. 项目背景
广东省立中山图书馆(以下简称"广东省图")计划举办一场面向全国的少儿绘本创作活动。乐绘世界创想活动乐园作为活动管理平台,需要支撑从活动发布、用户注册、报名参与、作品提交、评审打分到成果发布的完整流程。
广东省立中山图书馆(以下简称"广东省图")计划举办一场面向全国的少儿绘本创作活动。智创未来作为活动管理平台,需要支撑从活动发布、用户注册、报名参与、作品提交、评审打分到成果发布的完整流程。
### 1.1 业务场景

View File

@ -49,7 +49,7 @@
| 类型标识 | 名称 | 说明 | 举例 |
|---------|------|------|------|
| `platform` | 平台租户 | 系统运营方,全局唯一 | 乐绘世界 |
| `platform` | 平台租户 | 系统运营方,全局唯一 | 智创未来 |
| `library` | 图书馆 | 公共图书馆机构 | 广东省立中山图书馆 |
| `kindergarten` | 幼儿园 | 幼儿教育机构 | XX幼儿园 |
| `school` | 学校 | 中小学校 | XX小学 |
@ -173,7 +173,7 @@
```
┌────────────────────────────────────────┐ Web 端
│ 顶部导航栏 │
│ [Logo 乐绘世界] [活动大厅] [个人中心] │
│ [Logo 智创未来] [活动大厅] [个人中心] │
├────────────────────────────────────────┤
│ │
│ 页面内容区 │

View File

@ -117,7 +117,7 @@ CREATE INDEX idx_tenants_type ON tenants(tenant_type);
| 值 | 说明 |
|----|------|
| `platform` | 平台租户(乐绘世界,全局唯一) |
| `platform` | 平台租户(智创未来,全局唯一) |
| `library` | 图书馆 |
| `kindergarten` | 幼儿园 |
| `school` | 学校 |

View File

@ -48,7 +48,7 @@
- "比赛/赛事" → "活动"(前后端 46 个文件 + 数据库)
- "个人赛/团队赛" → "个人参与/团队参与"25 个文件 + 数据库)
- "赛果" → "成果"25 个文件 + 数据库菜单/权限)
- 系统名称 → "乐绘世界创想活动乐园"
- 系统名称 → "智创未来"
- Logo 替换为 LeSingle 品牌标志
**UI 主题全面改造6 个核心文件):**

View File

@ -2,7 +2,7 @@
## 1. 系统改名记录
本系统从"比赛管理系统"改造为"乐绘世界创想活动乐园"。以下为所有术语变更对照。
本系统从"比赛管理系统"改造为"智创未来"。以下为所有术语变更对照。
### 1.1 核心术语
@ -10,8 +10,8 @@
|--------|--------|------|
| 比赛 | 活动 | 全局替换 |
| 赛事 | 活动 | 全局替换 |
| 比赛管理系统 | 乐绘世界创想活动乐园 | 系统名称 |
| CMS | 乐绘世界 | 简称 |
| 比赛管理系统 | 智创未来 | 系统名称 |
| CMS | 智创未来 | 简称 |
### 1.2 活动类型
@ -57,6 +57,6 @@
|------|---------|
| 2026-03-24 | 所有"比赛""赛事"替换为"活动"(前后端代码+数据库) |
| 2026-03-24 | "个人赛"→"个人参与""团队赛"→"团队参与""赛果"→"成果" |
| 2026-03-24 | 系统名称改为"乐绘世界创想活动乐园" |
| 2026-03-24 | 系统名称改为"智创未来" |
| 2026-03-24 | Logo 替换为 LeSingle 品牌标志 |
| 2026-03-24 | UI 主题全面升级Creative Indigo 主色调、Nunito 字体、圆角化组件 |

View File

@ -2,11 +2,11 @@
## 1. 系统架构概览
乐绘世界创想活动乐园采用**多端 + 多租户**架构,共分为 3 个端:
智创未来采用**多端 + 多租户**架构,共分为 3 个端:
```
┌──────────────────────────────────────────────────────────┐
乐绘世界创想活动乐园
智创未来
├──────────┬───────────────────┬───────────────────────────┤
│ 公众端 │ 机构管理端 │ 平台管理端(超管) │
│ /p/... │ /:tenantCode/... │ /super/... │

View File

@ -18,7 +18,7 @@
## 项目背景
乐绘世界创想活动乐园(原比赛管理系统)承办广东省立中山图书馆面向全国的少儿绘本创作活动。该项目需要将原有的机构内部管理系统改造为**面向公众开放**的活动管理平台。
智创未来(原比赛管理系统)承办广东省立中山图书馆面向全国的少儿绘本创作活动。该项目需要将原有的机构内部管理系统改造为**面向公众开放**的活动管理平台。
## 核心改造方向

View File

@ -68,6 +68,8 @@ public class LeaiReconcileTask {
Map<String, Object> fullData = leaiApiClient.fetchWorkDetail(workId);
if (fullData != null) {
// B2 详情接口不返回 phone B3 列表中的 phone 合并进去
fullData.put("phone", phone);
try {
leaiSyncService.syncWork(workId, fullData, "B3对账");
synced++;

View File

@ -19,7 +19,7 @@ public class SmsConfig {
private String accessKeySecret;
/** 短信签名名称 */
private String signName = "乐绘世界";
private String signName = "智创未来";
/** 验证码模板 CODE */
private String templateCode;

View File

@ -51,7 +51,7 @@ jwt:
leai:
org-id: ${LEAI_ORG_ID:gdlib}
app-secret: ${LEAI_APP_SECRET:leai_mnoi9q1a_mtcawrn8y}
api-url: ${LEAI_API_URL:http://192.168.1.250:8267}
api-url: ${LEAI_API_URL:http://121.40.20.224:8267}
reconcile-interval: 1800000 # B3对账间隔30分钟生产环境
reconcile-initial-delay: 60000 # 初始延迟60秒

View File

@ -15,7 +15,7 @@ test.describe('管理端登录流程', () => {
await page.goto(`/${TENANT_CODE}/login`)
// 验证页面标题
await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
await expect(page.locator('.login-header h2')).toHaveText('智创未来')
// 验证表单字段可见
await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible()

View File

@ -9,7 +9,7 @@ test.describe('侧边栏导航', () => {
const page = adminPage
// 验证侧边栏 Logo 区域
await expect(page.locator('.logo-title-main')).toHaveText('乐绘世界')
await expect(page.locator('.logo-title-main')).toHaveText('智创未来')
// 验证菜单项存在Ant Design 菜单项)
const menuItems = page.locator('.ant-menu-item, .ant-menu-submenu')

View File

@ -7,7 +7,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<title>乐绘世界创想活动乐园</title>
<title>智创未来</title>
</head>
<body>
<div id="app"></div>

View File

@ -15,7 +15,7 @@
Error: expect(locator).toHaveText(expected) failed
Locator: locator('.login-header h2')
Expected: "乐绘世界创想活动乐园"
Expected: "智创未来"
Timeout: 10000ms
Error: element(s) not found
@ -45,7 +45,7 @@ Call log:
15 | await page.goto(`/${TENANT_CODE}/login`)
16 |
17 | // 验证页面标题
> 18 | await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
> 18 | await expect(page.locator('.login-header h2')).toHaveText('智创未来')
| ^ Error: expect(locator).toHaveText(expected) failed
19 |
20 | // 验证表单字段可见

View File

@ -38,7 +38,7 @@ Call log:
15 | await page.goto(`/${TENANT_CODE}/login`)
16 |
17 | // 验证页面标题
18 | await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
18 | await expect(page.locator('.login-header h2')).toHaveText('智创未来')
19 |
20 | // 验证表单字段可见
21 | await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible()

View File

@ -38,7 +38,7 @@ Call log:
15 | await page.goto(`/${TENANT_CODE}/login`)
16 |
17 | // 验证页面标题
18 | await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
18 | await expect(page.locator('.login-header h2')).toHaveText('智创未来')
19 |
20 | // 验证表单字段可见
21 | await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible()

View File

@ -38,7 +38,7 @@ Call log:
15 | await page.goto(`/${TENANT_CODE}/login`)
16 |
17 | // 验证页面标题
18 | await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
18 | await expect(page.locator('.login-header h2')).toHaveText('智创未来')
19 |
20 | // 验证表单字段可见
21 | await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible()

View File

@ -38,7 +38,7 @@ Call log:
15 | await page.goto(`/${TENANT_CODE}/login`)
16 |
17 | // 验证页面标题
18 | await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
18 | await expect(page.locator('.login-header h2')).toHaveText('智创未来')
19 |
20 | // 验证表单字段可见
21 | await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible()

View File

@ -38,7 +38,7 @@ Call log:
15 | await page.goto(`/${TENANT_CODE}/login`)
16 |
17 | // 验证页面标题
18 | await expect(page.locator('.login-header h2')).toHaveText('乐绘世界创想活动乐园')
18 | await expect(page.locator('.login-header h2')).toHaveText('智创未来')
19 |
20 | // 验证表单字段可见
21 | await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible()

View File

@ -12,7 +12,7 @@ import type { Locale } from "ant-design-vue/es/locale"
// ant-design-vue
const locale: Locale = zhCN
//
//
//
const themeConfig: ConfigProviderProps["theme"] = {
token: {

View File

@ -9,9 +9,9 @@
<div class="sider-content">
<div class="sider-top">
<div class="logo" :class="{ 'logo-collapsed': collapsed }">
<img src="../assets/images/logo-icon.png" alt="乐绘世界" class="logo-img" />
<img src="../assets/images/logo-icon.png" alt="智创未来" class="logo-img" />
<div v-if="!collapsed" class="logo-text">
<span class="logo-title-main">乐绘世界</span>
<span class="logo-title-main">智创未来</span>
<span class="logo-title-sub">创想活动乐园</span>
</div>
</div>

View File

@ -4,8 +4,8 @@
<header class="public-header">
<div class="header-inner">
<div class="header-brand" @click="goHome">
<img src="@/assets/images/logo-icon.png" alt="乐绘世界" class="header-logo" />
<span class="header-title">乐绘世界</span>
<img src="@/assets/images/logo-icon.png" alt="智创未来" class="header-logo" />
<span class="header-title">智创未来</span>
</div>
<!-- 桌面端导航菜单 -->
<nav class="header-nav">

View File

@ -1,4 +1,4 @@
// 乐绘世界创想活动乐园 主题定制
// 智创未来 主题定制
// 风格活泼艺术少儿绘本创作
// 主色调Creative Indigo#6366F1 激发创造力与想象力

View File

@ -10,8 +10,8 @@
<div class="login-card">
<div class="login-header">
<img src="@/assets/images/logo-icon.png" alt="乐绘世界" class="login-logo" />
<h2>乐绘世界创想活动乐园</h2>
<img src="@/assets/images/logo-icon.png" alt="智创未来" class="login-logo" />
<h2>智创未来</h2>
<p class="login-subtitle">{{ tenantName ? tenantName + ' — 管理端登录' : '管理端登录' }}</p>
</div>

View File

@ -1,7 +1,7 @@
<template>
<div class="public-auth-page">
<div class="auth-card">
<img src="@/assets/images/logo-icon.png" alt="乐绘世界" class="auth-logo" />
<img src="@/assets/images/logo-icon.png" alt="智创未来" class="auth-logo" />
<h2 class="auth-title">{{ isRegister ? "创建账号" : "登录" }}</h2>
<p class="auth-subtitle">
{{ isRegister ? "加入乐绘世界,开启创作之旅" : "欢迎回来,继续你的创作" }}
@ -154,8 +154,8 @@ const isPhoneValid = computed(() => /^1[3-9]\d{9}$/.test(form.phone))
const showNicknameField = computed(() => isRegister.value)
const showPhoneField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'sms'))
const showSmsCodeField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'sms'))
const showUsernameField = computed(() => !isRegister.value && loginMethod.value === 'password')
const showPasswordField = computed(() => !isRegister.value && loginMethod.value === 'password')
const showUsernameField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'password'))
const showPasswordField = computed(() => isRegister.value || (!isRegister.value && loginMethod.value === 'password'))
//
const baseRules: Record<string, Rule[]> = {

View File

@ -114,7 +114,7 @@ const store = useAicreateStore()
const fromWorks = new URLSearchParams(window.location.search).get('from') === 'works'
|| sessionStorage.getItem('le_from') === 'works'
const brandName = '乐绘世界'
const brandName = '智创未来'
function handleBack() {
if (fromWorks) {