From 6fe9e040301ea76a9ed565362045ee0dabd38c71 Mon Sep 17 00:00:00 2001 From: 13121765685 Date: Wed, 14 Jan 2026 17:22:13 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=8D=8F=E8=AE=AE=E8=A1=A5?= =?UTF-8?q?=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .trae/documents/协议管理页面实现计划.md | 95 +++ apps/FrontendDesigner/package.json | 2 + .../src/components/common/RichTextEditor.vue | 116 ++++ .../src/locales/lang/en-US.js | 29 +- .../src/locales/lang/zh-CN.js | 61 +- apps/FrontendDesigner/src/router/index.js | 13 +- .../src/views/AdminLogin/AdminLogin.vue | 8 +- .../src/views/admin/Adminagreement/index.js | 124 ++++ .../src/views/admin/Adminagreement/index.vue | 539 ++++++++++++++++++ .../src/components/auth/PhoneLoginForm.vue | 140 ++++- .../src/components/layout/AppHeader.vue | 8 +- apps/frontend/src/locales/index.js | 28 + apps/frontend/src/router/index.js | 6 + apps/frontend/src/views/Login/Login.vue | 7 +- apps/frontend/src/views/user/agreement.vue | 520 +++++++++++++++++ apps/frontend/vite.config.js | 4 +- .../src/api/FrontendDesigner/agreement.js | 9 + .../utils/src/api/FrontendDesigner/index.js | 2 + packages/utils/src/api/frontend/agreement.js | 4 + packages/utils/src/api/frontend/index.js | 2 + packages/utils/src/utils/request.js | 6 + pnpm-lock.yaml | 432 ++++++++++++++ 22 files changed, 2109 insertions(+), 46 deletions(-) create mode 100644 .trae/documents/协议管理页面实现计划.md create mode 100644 apps/FrontendDesigner/src/components/common/RichTextEditor.vue create mode 100644 apps/FrontendDesigner/src/views/admin/Adminagreement/index.js create mode 100644 apps/FrontendDesigner/src/views/admin/Adminagreement/index.vue create mode 100644 apps/frontend/src/views/user/agreement.vue create mode 100644 packages/utils/src/api/FrontendDesigner/agreement.js create mode 100644 packages/utils/src/api/frontend/agreement.js diff --git a/.trae/documents/协议管理页面实现计划.md b/.trae/documents/协议管理页面实现计划.md new file mode 100644 index 0000000..f76cb8c --- /dev/null +++ b/.trae/documents/协议管理页面实现计划.md @@ -0,0 +1,95 @@ +# 协议管理页面实现计划 + +## 1. 需求分析 +根据 `index.js` 中的 API 功能,需要实现以下功能: +- 协议列表展示 +- 协议状态修改 +- 协议删除 +- 协议详情查看 +- 协议创建 +- 协议更新 + +## 2. 页面设计 +遵循 Element Plus 企业级管理系统设计风格,页面包含: +- 卡片式布局 +- 表格展示协议列表 +- 状态标签显示协议状态 +- 操作按钮(编辑、删除、启用/禁用) +- 表单用于创建/编辑协议 +- 弹窗用于详情查看和表单操作 + +## 3. 实现步骤 + +### 3.1 页面结构设计 +- 使用 `el-card` 包裹主要内容 +- 卡片头部包含标题和创建按钮 +- 表格展示协议列表,包含协议类型、版本、状态、语言、创建时间等字段 +- 操作列包含查看详情、编辑、删除、启用/禁用按钮 + +### 3.2 功能实现 +- **列表查询**:调用 `getAgreementList` API 获取协议列表 +- **状态修改**:点击启用/禁用按钮,调用 `updateAgreementStatus` API +- **删除协议**:点击删除按钮,调用 `deleteAgreement` API,带确认提示 +- **查看详情**:点击详情按钮,弹窗展示协议详情 +- **创建协议**:点击创建按钮,弹窗显示表单,调用 `createAgreement` API +- **编辑协议**:点击编辑按钮,弹窗显示表单,调用 `updateAgreement` API + +### 3.3 路由配置 +在 `permissionRoutes` 数组中添加协议管理路由: +- 路径:`agreement-management` +- 名称:`AdminAgreement` +- 组件:`AdminAgreement` +- 标题:`admin.layout.agreementManagement` +- 图标:`Document` +- 菜单顺序:合理位置 + +### 3.4 响应式设计 +- 表格在移动端自动调整布局 +- 弹窗在移动端自适应宽度 +- 表单元素在不同屏幕尺寸下保持良好的用户体验 + +## 4. 代码实现 + +### 4.1 创建 `index.vue` 文件 +- 使用 Composition API +- 导入必要的组件和 API 类 +- 实现数据响应式 +- 实现方法逻辑 +- 实现模板结构 +- 添加样式 + +### 4.2 Vue3 属性绑定语法 +所有属性绑定严格使用 Vue3 语法: +- 错误:`label="{{label}}"` +- 正确:`:label="label"` +- 示例: + - `:data="tableData"` + - `:loading="loading"` + - `:visible.sync="dialogVisible"` + - `:type="scope.row.status === 1 ? 'success' : 'warning'"` + - `@click="handleEdit(scope.row)"` + +### 4.3 具体实现细节 +- **表格配置**:使用 `:data` 绑定表格数据,`:loading` 绑定加载状态 +- **弹窗配置**:使用 `:visible.sync` 控制弹窗显示/隐藏 +- **表单配置**:使用 `v-model` 绑定表单数据,`:rules` 绑定验证规则 +- **按钮配置**:使用 `@click` 绑定点击事件,`:type` 绑定按钮类型 +- **状态标签**:使用 `:type` 绑定标签类型,动态根据状态值变化 + +### 4.4 更新路由配置 +在 `router/index.js` 中添加协议管理路由 + +## 5. 预期效果 +- 页面布局符合设计风格指南 +- 所有功能正常工作 +- 响应式设计适配不同设备 +- 交互流畅,反馈清晰 +- 严格遵循 Vue3 属性绑定语法 + +## 6. 技术要点 +- Vue3 Composition API +- Element Plus 组件库 +- API 异步调用 +- 响应式设计 +- 中英文切换支持 +- 严格的 Vue3 属性绑定语法 \ No newline at end of file diff --git a/apps/FrontendDesigner/package.json b/apps/FrontendDesigner/package.json index 9808da6..59fc908 100644 --- a/apps/FrontendDesigner/package.json +++ b/apps/FrontendDesigner/package.json @@ -16,6 +16,8 @@ "@element-plus/icons-vue": "^2.3.2", "@google/genai": "^1.27.0", "@types/three": "^0.180.0", + "@wangeditor/editor": "^5.1.23", + "@wangeditor/editor-for-vue": "^5.1.12", "element-china-area-data": "^6.1.0", "element-plus": "^2.11.7", "konva": "^10.0.12", diff --git a/apps/FrontendDesigner/src/components/common/RichTextEditor.vue b/apps/FrontendDesigner/src/components/common/RichTextEditor.vue new file mode 100644 index 0000000..82672fb --- /dev/null +++ b/apps/FrontendDesigner/src/components/common/RichTextEditor.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/apps/FrontendDesigner/src/locales/lang/en-US.js b/apps/FrontendDesigner/src/locales/lang/en-US.js index 1412ae8..a471746 100644 --- a/apps/FrontendDesigner/src/locales/lang/en-US.js +++ b/apps/FrontendDesigner/src/locales/lang/en-US.js @@ -21,6 +21,7 @@ export default { back: 'Back', submit: 'Submit', all: 'All', + operation:'Operation', }, // Shop Management @@ -115,6 +116,7 @@ export default { pointsList: 'Points List' } }, + // Employee Management employee: { idCardImageTip: 'Please upload ID card image', @@ -422,7 +424,8 @@ export default { adminAgent: 'Admin Agent', logout: 'Logout', profile: 'Profile', - settings: 'Settings' + settings: 'Settings', + agreementManagement: 'Agreement Management', }, roleManagement: { title: 'Role Management', @@ -1195,6 +1198,30 @@ export default { userPhone: 'Enter user phone', userNickname: 'Enter user nickname' } + }, + agreementManagement: { + title: 'Agreement Management', + create: 'Create Agreement', + agreementType: 'Agreement Type', + selectType: 'Please select agreement type', + userAgreement: 'User Agreement', + privacyPolicy: 'Privacy Policy', + serviceTerms: 'Service Terms', + status: 'Status', + selectStatus: 'Please select status', + enabled: 'Enabled', + disabled: 'Disabled', + disable: 'Disable', + enable: 'Enable', + lang: 'Language', + selectLang: 'Please select language', + version: 'Version', + enterVersion: 'Please enter version', + content: 'Content', + enterContent: 'Please enter content', + createdAt: 'Created At', + updatedAt: 'Updated At', + deleteConfirm: 'Are you sure you want to delete this agreement?', } }, modelUpload: { diff --git a/apps/FrontendDesigner/src/locales/lang/zh-CN.js b/apps/FrontendDesigner/src/locales/lang/zh-CN.js index 7db5a7f..a8e8b5b 100644 --- a/apps/FrontendDesigner/src/locales/lang/zh-CN.js +++ b/apps/FrontendDesigner/src/locales/lang/zh-CN.js @@ -1,30 +1,5 @@ // 中文语言包 export default { - // 通用 - common: { - confirm: '确认', - cancel: '取消', - save: '保存', - delete: '删除', - edit: '编辑', - add: '添加', - search: '搜索', - reset: '重置', - loading: '加载中...', - noData: '暂无数据', - error: '出错了', - success: '操作成功', - warning: '警告', - info: '提示', - active: '活跃', - inactive: '非活跃', - detail: '详情', - saveSuccess: '保存成功', - saveFailed: '保存失败', - deleteSuccess: '删除成功', - deleteFailed: '删除失败', - all: '全部', - }, orderManagement: { title: '订单', description: '查看和管理您的购买和订阅信息', @@ -194,6 +169,33 @@ orderManagement: { // 管理后台 admin: { title: '管理后台', + layout: { + agreementManagement: '协议管理', + }, + agreementManagement: { + title: '协议管理', + create: '创建协议', + agreementType: '协议类型', + selectType: '请选择协议类型', + userAgreement: '用户协议', + privacyPolicy: '隐私政策', + serviceTerms: '服务条款', + status: '状态', + selectStatus: '请选择状态', + enabled: '启用', + disabled: '禁用', + disable: '禁用', + enable: '启用', + lang: '语言', + selectLang: '请选择语言', + version: '版本', + enterVersion: '请输入版本号', + content: '内容', + enterContent: '请输入协议内容', + createdAt: '创建时间', + updatedAt: '更新时间', + deleteConfirm: '确定要删除该协议吗?', + }, login: { title: '管理员登录', username: '用户名', @@ -268,7 +270,8 @@ orderManagement: { invalidate: '作废', requestFailed: '请求失败', operationSuccess: '操作成功', - operationFailed: '操作失败' + operationFailed: '操作失败', + operation:'操作' }, layout: { employee: '员工管理', @@ -296,7 +299,8 @@ orderManagement: { logout: '退出登录', profile: '个人资料', settings: '设置', - notifications: '通知' + notifications: '通知', + agreementManagement: '协议管理', }, roleManagement: { title: '角色管理', @@ -1113,7 +1117,8 @@ orderManagement: { info: '信息', close: '关闭', back: '返回', - submit: '提交' + submit: '提交', + operation:'操作' }, // 店铺管理 diff --git a/apps/FrontendDesigner/src/router/index.js b/apps/FrontendDesigner/src/router/index.js index 3a2d4a3..194a3d6 100644 --- a/apps/FrontendDesigner/src/router/index.js +++ b/apps/FrontendDesigner/src/router/index.js @@ -29,6 +29,7 @@ const AdminAgent = () => import('@/views/admin/Adminagent/index.vue') const AdminCommissionWithdrawal = () => import('@/views/admin/AdminCommissionManagement/AdminCommissionWithdrawal.vue') const AdminShop = () => import('@/views/admin/AdminShop/shop.vue') const AdminEmployee = () => import('@/views/admin/AdminShop/employee.vue') +const AdminAgreement = () => import('@/views/admin/Adminagreement/index.vue') //权限路由映射表 export const permissionRoutes = [ { @@ -235,7 +236,17 @@ export const permissionRoutes = [ requiresAuth: true } }, - + { + path: 'agreement-management', + name: 'AdminAgreement', + component: AdminAgreement, + meta: { + title: 'admin.layout.agreementManagement', + icon: 'Document', + menuOrder: 6, + requiresAuth: true + } + }, { path: 'permission', diff --git a/apps/FrontendDesigner/src/views/AdminLogin/AdminLogin.vue b/apps/FrontendDesigner/src/views/AdminLogin/AdminLogin.vue index 6d60863..e8f3056 100644 --- a/apps/FrontendDesigner/src/views/AdminLogin/AdminLogin.vue +++ b/apps/FrontendDesigner/src/views/AdminLogin/AdminLogin.vue @@ -142,10 +142,10 @@ const handleLogin = async () => { loading.value = true // 发送登录请求 const response = await requestUtils.common(adminApi.default.LOGIN, { - username: loginForm.username, - password: loginForm.password, - code: loginForm.code, - uuid: uuid.value + username: loginForm.username.trim(), + password: loginForm.password.trim(), + code: loginForm.code.trim(), + uuid: uuid.value.trim() } ) if(response.code !== 0){ diff --git a/apps/FrontendDesigner/src/views/admin/Adminagreement/index.js b/apps/FrontendDesigner/src/views/admin/Adminagreement/index.js new file mode 100644 index 0000000..b34c90d --- /dev/null +++ b/apps/FrontendDesigner/src/views/admin/Adminagreement/index.js @@ -0,0 +1,124 @@ +import {adminApi,requestUtils} from '@deotaland/utils'; +export class AdminAgreement { + constructor(){ + } + // 修改协议状态 + async updateAgreementStatus(id,data){ + let parmas = { + id:data.id, + status:data.status,//状态: 0禁用 1启用 + } + const requestUrl = { + method:adminApi.default.updateAgreementStatus.method, + url:adminApi.default.updateAgreementStatus.url.replace('{id}',parmas.id).replace('{status}',parmas.status), + } + return await requestUtils.common(requestUrl,parmas); + } + //删除协议 + async deleteAgreement(id){ + let parmas = { + id:id, + } + const requestUrl = { + method:adminApi.default.removeAgreement.method, + url:adminApi.default.removeAgreement.url.replace('{id}',parmas.id), + } + return await requestUtils.common(requestUrl,parmas); + } + //获取协议详情 + async getAgreementDetail(id){ + let parmas = { + id:id, + } + const requestUrl = { + method:adminApi.default.getAgreementDetail.method, + url:adminApi.default.getAgreementDetail.url.replace('{id}',parmas.id), + } + return await requestUtils.common(requestUrl,parmas); + /** + 返回示例: + { + "code": 0, + "success": true, + "data": { + "id": 1073741824, + "agreementType": "string", + "agreementTypeName": "string", + "content": "string", + "version": "string", + "status": 1073741824, + "createdAt": "2026-01-14T07:37:06.427Z", + "updatedAt": "2026-01-14T07:37:06.427Z", + "lang": "string" + }, + "message": "操作成功" +} + */ + } + //获取协议列表 + async getAgreementList(data){ + let parmas = { + pageNum:data.pageNum, + pageSize:data.pageSize, + agreementType:data.agreementType,//协议类型: user_agreement/privacy_policy/service_terms + status:data.status,//状态: 0禁用 1启用 + lang:data.lang,//语言类型: en/zh + } + const requestUrl = { + method:adminApi.default.getAgreementList.method, + url:adminApi.default.getAgreementList.url, + } + return await requestUtils.common(requestUrl,parmas); + /** + 返回示例: + { + "total": 9007199254740991, + "rows": [ + { + "id": 1073741824, + "agreementType": "string", + "agreementTypeName": "string", + "content": "string", + "version": "string", + "status": 1073741824, + "createdAt": "2026-01-14T07:37:46.846Z", + "updatedAt": "2026-01-14T07:37:46.846Z", + "lang": "string" + } + ], + "code": 1073741824, + "msg": "string" +} + */ + } + //创建协议 + async createAgreement(data){ + let parmas = { + agreementType:data.agreementType,//协议类型: user_agreement/privacy_policy/service_terms + version:data.version,//版本号 + content:data.content,//协议内容 + lang:data.lang,//语言类型: en/zh + } + const requestUrl = { + method:adminApi.default.addAgreement.method, + url:adminApi.default.addAgreement.url, + } + return await requestUtils.common(requestUrl,parmas); + } + //更新协议 + async updateAgreement(data){ + let parmas = { + id:data.id, + agreementType:data.agreementType,//协议类型: user_agreement/privacy_policy/service_terms + version:data.version,//版本号 + content:data.content,//协议内容 + lang:data.lang,//语言类型: en/zh + status:data.status,//状态: 0禁用 1启用 + } + const requestUrl = { + method:adminApi.default.editAgreement.method, + url:adminApi.default.editAgreement.url.replace('{id}',parmas.id), + } + return await requestUtils.common(requestUrl,parmas); + } +} \ No newline at end of file diff --git a/apps/FrontendDesigner/src/views/admin/Adminagreement/index.vue b/apps/FrontendDesigner/src/views/admin/Adminagreement/index.vue new file mode 100644 index 0000000..ec29977 --- /dev/null +++ b/apps/FrontendDesigner/src/views/admin/Adminagreement/index.vue @@ -0,0 +1,539 @@ + + + + + \ No newline at end of file diff --git a/apps/frontend/src/components/auth/PhoneLoginForm.vue b/apps/frontend/src/components/auth/PhoneLoginForm.vue index 4619e4d..378da99 100644 --- a/apps/frontend/src/components/auth/PhoneLoginForm.vue +++ b/apps/frontend/src/components/auth/PhoneLoginForm.vue @@ -135,7 +135,32 @@
{{ passwordError }}
- + +
+ +