提交 843e729c authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 d1d0f463
node_modules
.pnpm-store
.DS_Store
dist
\ No newline at end of file
# 页面参数说明
本文档说明各个页面通过 `callbackInFlutterComponent` 函数接收的参数。
## 参数传递方式
所有页面都通过全局函数 `callbackInFlutterComponent` 接收参数,该函数由 Flutter 端调用。
## 各页面参数详情
### 1. evaluating.html (测评页面)
**参数格式**: 逗号分隔的字符串
```javascript
callbackInFlutterComponent('baseURL,book_id,chapter_id,token,position')
```
**参数说明**:
- `baseURL` (string): API 基础地址
- `book_id` (string): 书籍 ID,例如: "175"
- `chapter_id` (string): 章节 ID,例如: "335"
- `token` (string): 用户认证令牌
- `position` (string): 位置标识,例如: "0vm56t7l"
**示例**:
```javascript
callbackInFlutterComponent('https://api.example.com,175,335,726cca8efcb328672202656f63e176e8,bgi0jn6p')
```
---
### 2. evaluating_result.html (测评结果页面)
**参数格式**: 逗号分隔的字符串
```javascript
callbackInFlutterComponent('baseURL,book_id,chapter_id,token,position')
```
**参数说明**:
- `baseURL` (string): API 基础地址
- `book_id` (string): 书籍 ID,例如: "323"
- `chapter_id` (string): 章节 ID,例如: "2635"
- `token` (string): 用户认证令牌
- `position` (string): 位置标识,例如: "ab4bg8qf"
**示例**:
```javascript
callbackInFlutterComponent('https://api.example.com,175,2834,726cca8efcb328672202656f63e176e8,bgi0jn6p')
```
---
### 3. evaluating_wrong.html (错题页面)
**参数格式**: 逗号分隔的字符串
```javascript
callbackInFlutterComponent('baseURL,book_id,token')
```
**参数说明**:
- `baseURL` (string): API 基础地址
- `book_id` (string): 书籍 ID
- `token` (string): 用户认证令牌
**示例**:
```javascript
callbackInFlutterComponent('https://api.example.com,175,726cca8efcb328672202656f63e176e8')
```
---
### 4. read.html (阅读页面)
**参数格式**: 逗号分隔的字符串
```javascript
callbackInFlutterComponent('baseURL,book_id,chapter_id,token,noteId,searchText')
```
**参数说明**:
- `baseURL` (string): API 基础地址
- `book_id` (string): 书籍 ID,例如: "175" 或 "358"
- `chapter_id` (string): 章节 ID,例如: "335" 或 "1931"
- `token` (string): 用户认证令牌
- `noteId` (string, 可选): 笔记 ID
- `searchText` (string, 可选): 搜索文本
**示例**:
```javascript
callbackInFlutterComponent('https://api.example.com,175,335,2f85d063f94485c0c2ef31e652875bd5,,')
```
---
### 5. read_unline.html (在线阅读页面)
**参数格式**: 对象形式
```javascript
callbackInFlutterComponent({
book_id: '175',
chapter_id: '335',
next_chapter: {...}, // 下一章节信息
up_chapter: {...}, // 上一章节信息
color_line: {...}, // 高亮信息
direction: 'scrollUp' // 可选,滚动方向
})
```
**参数说明**:
- `book_id` (string): 书籍 ID
- `chapter_id` (string): 章节 ID
- `next_chapter` (object, 可选): 下一章节信息对象
- `up_chapter` (object, 可选): 上一章节信息对象
- `color_line` (object, 可选): 高亮线条信息
- `direction` (string, 可选): 滚动方向,例如: "scrollUp"
**注意**: 此页面会将参数对象直接传递给 `getBookChapterData` 方法处理。
---
### 6. read_info.html (阅读信息页面)
**参数格式**: 对象形式
```javascript
callbackInFlutterComponent({
base_url: 'https://api.example.com',
book_id: '175',
chapter_id: '2834',
token: '726cca8efcb328672202656f63e176e8',
position: '49732578',
type: 'gallery', // 或 'expand'
})
```
**参数说明**:
- `base_url` (string): API 基础地址
- `book_id` (string): 书籍 ID,例如: "175" 或 "358"
- `chapter_id` (string): 章节 ID,例如: "2253" 或 "2825"
- `token` (string): 用户认证令牌
- `position` (string): 位置标识,例如: "73736505" 或 "75972319"
- `type` (string): 类型,可选值: "gallery" (画廊) 或 "expand" (扩展内容)
**示例**:
```javascript
callbackInFlutterComponent({
base_url: 'https://api.example.com',
book_id: 175,
chapter_id: 2834,
token: '726cca8efcb328672202656f63e176e8',
position: '49732578',
type: 'gallery',
})
```
---
### 7. read_img.html (阅读图片页面)
**参数格式**: 对象形式
```javascript
callbackInFlutterComponent({
url: 'https://example.com/image.jpg',
title: '图片标题',
})
```
**参数说明**:
- `url` (string): 图片 URL
- `title` (string): 图片标题(如果为 "图片展示" 则不显示标题)
**示例**:
```javascript
callbackInFlutterComponent({
url: 'https://example.com/image.jpg',
title: '图片标题',
})
```
---
## 通用说明
1. **Token 存储**: 所有页面都会将 `token` 存储到 `localStorage`
2. **数据加载**: 调用 `callbackInFlutterComponent` 后,页面会自动加载相应的数据
3. **Flutter 交互**: 页面通过 `window.flutter_inappwebview.callHandler` 与 Flutter 端通信
## 开发测试
在浏览器控制台中可以直接调用 `callbackInFlutterComponent` 函数进行测试:
```javascript
// 测评页面测试
callbackInFlutterComponent('https://api.example.com,175,335,token123,position456')
// 阅读页面测试
callbackInFlutterComponent('https://api.example.com,175,335,token123,,')
```
# Book App H5
这是一个基于 Vue 2 的多页面 H5 应用项目。
## 技术栈
- Vue 2
- Vite 7
- pnpm
## 开发
### 安装依赖
```bash
pnpm install
```
### 启动开发服务器
```bash
pnpm dev
```
开发服务器将在 `http://localhost:3000` 启动。
### 构建生产版本
```bash
pnpm build
```
构建产物将输出到 `dist` 目录。
### 预览生产构建
```bash
pnpm preview
```
## 项目结构
- `*.html` - 多页面入口文件
- `assets/` - 静态资源目录
- `css/` - 样式文件
- `js/` - JavaScript 文件
- `images/` - 图片资源
- `fonts/` - 字体文件
## 页面说明
- `evaluating.html` - 测评页面
- `evaluating_result.html` - 测评结果页面
- `evaluating_wrong.html` - 错题页面
- `read.html` - 阅读页面
- `read_unline.html` - 在线阅读页面
- `read_info.html` - 阅读信息页面
- `read_img.html` - 阅读图片页面
# read.html 逻辑与通信机制说明
## 概述
`read.html` 是一个基于 Vue 2 的阅读页面,支持章节阅读、文本选择、划线、高亮、笔记等功能。页面通过 `flutter_inappwebview` 与 Flutter 原生应用进行双向通信。
## 核心逻辑流程
### 1. 初始化流程
```
Flutter 调用 callbackInFlutterComponent()
解析参数 (baseURL, book_id, chapter_id, token, noteId, searchText)
存储 token 到 localStorage
调用 getBookChapterData() 加载章节内容
显示加载状态 (showLoadingCallback)
请求 API 获取章节数据
渲染内容、初始化交互功能
隐藏加载状态 (dismissLoadingCallback)
```
### 2. 数据加载流程
**主要方法**: `getBookChapterData(chapterId, scroll)`
1. **防重复加载**: 检查 `nextChapterLoading` 标志
2. **清空内容**: 重置章节内容和选区状态
3. **API 请求**: 调用 `/v1/book/Information/getChapterContent` 获取:
- 章节内容 (`content`)
- 下一章节信息 (`next_chapter`)
- 上一章节信息 (`up_chapter`)
- 高亮数据 (`color_line`)
- 划线数据 (`line_list`)
4. **内容处理**:
- 代码高亮 (highlight.js)
- 视频转音频处理
- 渲染划线和高亮
- 搜索文本定位
5. **进度上报**: 计算并上报阅读进度
6. **事件监听**: 初始化触摸、滚动等交互事件
### 3. 阅读进度上报
**定时上报**: 每 5 秒上报一次 (`uploadReadInterval`)
**进度计算逻辑**:
```javascript
// 如果内容高度 <= 屏幕高度,进度 = 100%
// 否则根据滚动位置计算:
progress = (已滚动高度 + 屏幕高度) / 总内容高度 * 100
```
**上报接口**:
- `/v1/book/Information/uploadReadProgress` - 阅读进度
- `/v1/book/Information/uploadReadRecord` - 阅读记录
## 与 Flutter 的通信机制
### 通信方式
使用 `window.flutter_inappwebview.callHandler` 进行通信,这是一个双向通信机制。
### 1. Flutter → H5 (接收数据)
#### `callbackInFlutterComponent(args)`
**参数格式**: 逗号分隔的字符串
```
baseURL,book_id,chapter_id,token,noteId,searchText
```
**功能**: 初始化页面,加载章节数据
#### `refreshTokenSuccess(args)`
**参数格式**: 对象
```javascript
{ token: 'new_token' }
```
**功能**: Token 过期后刷新,重新加载数据
### 2. H5 → Flutter (发送数据)
#### `callHandlerNoticeFlutterSubmit(funcname, data)`
**核心方法**,用于向 Flutter 发送各种事件通知:
```javascript
callHandlerNoticeFlutterSubmit(funcname, data)
```
**常用回调函数名**:
| 回调函数名 | 触发时机 | 数据格式 | 说明 |
|----------|---------|---------|------|
| `showLoadingCallback` | 开始加载数据 | - | 显示加载状态 |
| `dismissLoadingCallback` | 数据加载完成 | - | 隐藏加载状态 |
| `refreshTokenCallback` | Token 过期 (403) | - | 请求刷新 Token |
| `loadChapterCallBack` | 切换章节 | `[chapter_id, chapter_name]` | 通知章节切换 |
| `openLinkCallback` | 点击链接 | `href` | 打开外部链接 |
| `readInfoCallback` | 点击扩展内容 | `[position, type, title]` | 打开画廊/扩展内容 |
| `scaleImageCallback` | 点击图片 | `[imgUrl, title]` | 放大图片 |
| `answerResultCallBack` | 点击练习 | `[chapter_id, position, counts, title]` | 打开练习页面 |
| `payCallback` | 点击付费内容 | - | 打开支付页面 |
| `dbClickCallBack` | 双击屏幕 | - | 显示/隐藏工具栏 |
| `offlineAddNoteCallBack` | 添加笔记 | `{...noteData, notes_id}` | 离线添加笔记 |
| `offlineUpdateNoteCallBack` | 更新笔记 | `{...noteData}` | 离线更新笔记 |
| `offlineDelNoteCallBack` | 删除笔记 | `{...noteData}` | 离线删除笔记 |
## 核心功能模块
### 1. 文本选择与操作
**监听选择**: `selectionRangeOperation()`
- 监听 `selectionchange` 事件
- 获取选中文本和位置信息
- 显示操作工具栏(划线、高亮、复制等)
**划线功能**:
- `rangeTextInLine()`: 添加划线
- `delLine()`: 删除划线
- API: `/v1/book/Information/addNotes` (type=1)
**高亮功能**:
- `rangeTextInLight()`: 添加/编辑高亮
- `delLight()`: 删除高亮
- API: `/v1/book/Information/addNotes` (type=2)
### 2. 滚动与翻页
**触摸事件处理**:
- `touchStartEvent`: 记录起始位置
- `touchMoveEvent`: 实时更新滚动位置
- `touchEndEvent`: 处理滚动结束、章节切换
**章节切换**:
- **下拉**: 加载上一章节 (`prev_chapter`)
- **上拉**: 加载下一章节 (`next_chapter`)
- 通过 `translateY` CSS 变换实现滚动效果
### 3. 交互功能
**气泡提示** (`tooltipOpa`):
- 点击特定位置显示气泡内容
- API: `/v1/book/Information/getBubbleByPosition`
**交互练习** (`practiceOpa`):
- 点击练习按钮
- API: `/v1/book/Information/checkChapterQuestion`
- 回调: `answerResultCallBack`
**图片处理**:
- 点击图片可放大查看
- 回调: `scaleImageCallback``readInfoCallback`
**链接处理**:
- 内部链接: 加载对应章节
- 外部链接: 回调 `openLinkCallback` 由 Flutter 处理
### 4. 内容渲染
**划线和高亮渲染**:
- `line_listFilterShow()`: 渲染已保存的划线
- `color_lineFilterShow()`: 渲染已保存的高亮
- 使用 DOM 操作在内容中插入标记元素
**代码高亮**:
- 使用 `highlight.js` 处理 `<pre><code>` 标签
**视频转音频**:
- `replaceVideoToAudio()`: 将视频标签转换为音频播放器
## 数据流图
```
┌─────────────┐
│ Flutter │
└──────┬──────┘
│ callbackInFlutterComponent()
│ (初始化参数)
┌─────────────────┐
│ read.html │
│ (Vue App) │
└──────┬──────────┘
├─→ getBookChapterData()
│ └─→ API 请求
│ └─→ 渲染内容
├─→ 用户交互
│ ├─→ 文本选择 → 划线/高亮
│ ├─→ 滚动 → 章节切换
│ └─→ 点击 → 各种回调
└─→ callHandlerNoticeFlutterSubmit()
└─→ Flutter 处理
```
## 关键状态管理
### 主要状态变量
```javascript
{
book_id: '', // 书籍ID
chapter_id: '', // 章节ID
token: '', // 认证令牌
chapterContent: '', // 章节内容
next_chapter: {}, // 下一章节
prev_chapter: {}, // 上一章节
line_list: [], // 划线列表
color_line: [], // 高亮列表
selectedText: '', // 选中的文本
boolControllStatus: false, // 操作工具栏显示状态
nextChapterLoading: false, // 章节加载中
lockedContent: false, // 内容是否锁定
translateY: 0, // 滚动位置
}
```
## 错误处理
1. **Token 过期 (403)**:
- 调用 `refreshTokenCallback`
- Flutter 刷新 Token 后调用 `refreshTokenSuccess`
2. **章节锁定 (3001)**:
- 显示锁定界面
- 显示"获取完整版"按钮
3. **网络错误**:
- 显示错误提示
- 隐藏加载状态
## 性能优化
1. **防抖处理**: 文本选择、滚动等操作使用防抖
2. **懒加载**: 章节内容按需加载
3. **定时上报**: 阅读进度每 5 秒上报一次,避免频繁请求
4. **CSS 变换**: 使用 `transform` 而非 `top/left` 实现滚动,性能更好
## 开发调试
在浏览器控制台可以直接测试:
```javascript
// 初始化页面
callbackInFlutterComponent('https://api.example.com,175,335,token123,,searchText')
// 刷新 Token
refreshTokenSuccess({ token: 'new_token' })
```
## 注意事项
1. **Flutter 环境**: 必须在 `flutter_inappwebview` 环境中运行
2. **Token 管理**: Token 会自动存储到 `localStorage`
3. **离线支持**: 笔记操作支持离线,通过回调同步到 Flutter
4. **触摸事件**: 移动端使用触摸事件,桌面端可能需要适配
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>清控紫荆数智学堂隐私政策</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,initial-scale=1.0"/>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="2113.3">
<style type="text/css">
*{ margin: 0px; padding: 0px; line-height: 1.8rem}
body{ margin: 20px; font-size: 1rem;}
body h2{ padding: 15px 0px; font-size: 1.5rem;}
a { color: black;}
.p2{ margin:10px 0;}
</style>
</head>
<body>
<h2><b>清控紫荆数智学堂隐私政策</b></h2>
<p class="p2"><b>更新日期:</b>2026年04月28日</p>
<p class="p2"><b>生效日期:</b>2026年04月28日</p>
<p class="p2"><b>版本:</b>v1.2</p>
<p class="p2"><b>特别提示</b></p>
<p class="p3">清控紫荆(北京)教育科技股份有限公司,( 以下统称“我们”)深知用户个人隐私和及信息的重要性,并非常重视用户个人隐私和信息的保护,我们将按照法律法规的要求,采取相应的措施保护您个人信息的安全可控。基于前述的理念和目的,我们制定《清控紫荆数智学堂隐私政策》(以下简称“本隐私政策”)并对您做出如下提示:</p>
<p class="p3">本隐私政策适用于清控紫荆数智学堂APP,您在使用我们的清控紫荆数智学堂APP时,我们可能会收集和使用您的个人信息。我们通过本隐私政策向您说明我们如何收集、使用、保存您的个人信息以及我们为您提供的访问、更新、删除和保护这些信息的方式。本隐私政策主要内容如下:</p>
<p class="p3">1.    我们将逐一说明我们收集您的个人信息类型及其对应的用途,以便您了解我们针对某一特定功能所收集的具体个人信息的类别、使用理由及收集方式。</p>
<p class="p3">2.    当您使用一些功能时,我们会在获得您的同意后,收集您的一些敏感信息,除非按照相关法律法规要求必须收集,拒绝提供这些信息仅会使您无法使用相关特定功能。</p>
<p class="p3">3.    我们不会主动共享或转让您的个人信息至我们外的第三方,如存在其他共享或转让您的个人信息或您需要我们将您的个人信息共享或转让至我们外的第三方情形时,我们会直接征得或确认第三方征是否征得您对上述行为的同意,但因维护社会公共利益或安全需要除外。</p>
<p class="p3">4.    您可以通过本隐私政策所列途径访问、更正、删除您的个人信息,也可以关闭授权或注销帐号。</p>
<p class="p3">5.    为了在本隐私政策下收集您的信息,或者向您提供服务、优化我们的服务以及保障您的帐号安全,我们将需要向您索取相关的权限;其中的敏感权限例如:摄像头、麦克风、相册均不会默认开启,只有在您明确同意后才会向我们授权。</p>
<p class="p3">需要特别说明的是,获得敏感权限是我们收集特定信息的必要而非充分条件。我们获得具体某一项敏感权限并不代表我们必然会收集您的相关信息;即使我们已经获得敏感权限,也仅在必要时、根据本隐私政策来收集您的相关信息。</p>
<p class="p3"><h3>目录</h3></p>
<p class="p3">一、定义</p>
<p class="p3">二、我们如何收集和使用您的个人信息</p>
<p class="p3">三、我们如何共享、转让、公开披露您的个人信息</p>
<p class="p3">四、我们如何保护和保存您的个人信息</p>
<p class="p3">五、您如何管理您的个人信息</p>
<p class="p3">六、通知和修订</p>
<p class="p3">一、定义</p>
<p class="p3">(一)个人信息</p>
<p class="p3">个人信息是以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息。</p>
<p class="p3">本隐私政策中可能涉及的个人信息包括:</p>
<p class="p3">1.个人基本信息(包括个人姓名、性别、生日、个人手机号码、电子邮箱),此项并非强制收集,您可根据自我意愿进行填写和提供;</p>
<p class="p3">2.网络身份标识信息(包括账号);</p>
<p class="p3">3.个人教育及职业信息(包括学历、行业、职业、公司名称),此项并非强制收集,您可根据自我意愿进行填写和提供;</p>
<p class="p3">4.个人财产信息(包括APP内的交易和消费记录、优惠券等虚拟财产信息);</p>
<p class="p3">5.音频信息(您录制的语音笔记等内容);</p>
<p class="p3">6.日志信息(包括APP课程学习记录)。</p>
<p class="p3">(二)个人敏感信息</p>
<p class="p3">敏感个人信息是一旦泄露或者非法使用,容易导致自然人的人格尊严受到侵害或者人身、财产安全受到危害的个人信息,以及不满十四周岁未成年人的个人信息。</p>
<p class="p3">(三)匿名化</p>
<p class="p3">是指个人信息经过处理无法识别特定自然人且不能复原的过程。</p>
<p class="p3">(四)去标识化</p>
<p class="p3">是指个人信息经过处理,使其在不借助额外信息的情况下无法识别特定自然人的过程。</p>
<p class="p3">(五)虚拟商品</p>
<p class="p3">本隐私政策内所称虚拟商品,是指APP内可以通过下载或在线等形式使用的数字产品与/或服务。</p>
<p class="p3">二、我们如何收集和使用您的个人信息</p>
<p class="p3">1.当我们要收集和使用您的个人信息前,我们会事先告知您,我们因何原因收集您的何种信息,并取得您的相应同意。我们会根据本隐私政策的约定并为实现我们的产品与/或服务功能对所收集的个人信息进行使用。</p>
<p class="p3">2.在收集您的个人信息后,我们将采取必要措施保障您的个人信息数据安全。为了改进及优化我们的服务体验以及保障您的帐号安全,我们或我们需要向第三方合作伙伴等,使用或分享已经匿名化或去标识化处理后的信息,我们将要求自己及第三方严格遵守我们关于数据隐私保护的措施与规定,保障个人信息安全。</p>
<p class="p3">3.在收集您的敏感个人信息、公开展示您的个人信息或当我们要将您的个人信息用于您非事先同意的其它用途时,会通过您主动做出勾选等形式事先征求您的同意。</p>
<p class="p3">4.您授权我们收集和使用的个人信息,可以通过主动删除或者系统设置的方式拒绝我们继续收集或使用。同时,在您注销账号时,我们将停止使用并删除您的个人信息。</p>
<p class="p3">5.我们会对我们的产品与/或服务使用情况进行统计,并可能会与公众或第三方共享这些统计信息,以展示我们的产品与/或服务的整体使用趋势,但这些统计信息不包含您的任何身份识别信息。</p>
<p class="p3">6.当我们展示您的个人信息时,我们会采用包括内容替换、匿名处理方式对您的信息进行脱敏,以保护您的信息安全。</p>
<p class="p3">在您使用我们的产品及/或服务时,我们需要/可能需要收集和使用的您的个人信息包括如下两种:</p>
<p class="p3">1.为实现向您提供我们产品及/或服务的基本功能,您须授权我们收集、使用的必要的信息。如您拒绝提供相应信息,您将无法正常使用我们的产品及/或服务;</p>
<p class="p3">2.为实现向您提供我们产品及/或服务的附加功能,您可选择授权我们收集、使用的信息。如您拒绝提供,您将无法正常使用相关附加功能或无法达到我们拟达到的功能效果,但并不会影响您正常使用我们产品及/或服务的基本功能。</p>
<p class="p3">我们仅会出于本隐私政策所述的以下目的,收集和使用您的个人信息:</p>
<p class="p3"><b>设备权限调用说明</b></p>
<p class="p3">为确保相关业务功能的正常实现,我们需要根据具体的使用场景调用对应的必要权限,并在调用前向您弹窗询问。以下为权限列表及其对应的业务功能:</p>
<p class="p3">1.<b>相机权限</b>:用于拍摄头像、拍摄笔记配图。仅在您主动使用拍照功能时调用。</p>
<p class="p3">2.<b>麦克风权限</b>:用于录制语音笔记。仅在您主动使用录音功能时调用。</p>
<p class="p3">3.<b>相册(照片)权限</b>:用于从相册中选择图片作为头像或笔记配图。仅在您主动选择图片时调用。</p>
<p class="p3">以上权限均不会默认开启,只有在您明确同意后才会向我们授权。您可以在系统设置中随时关闭上述权限,但可能影响相关功能的使用。</p>
<p class="p3">(一)账号的注册与登录</p>
<p class="p3">您在进行账号注册时,我们会收集您注册时填写的个人手机号码以及您设置的账号密码用于创建您的账号;注册成功后,您的个人手机号码即为您的账号,您可通过输入账号和密码或发送的手机验证码登录。</p>
<p class="p3">对于需要通过登录账号才能使用的服务,我们可能会根据您提供的上述信息校验您的身份,确保我们是在为您本人提供服务。但是,如您仅使用虚拟商品的浏览和搜索服务,您不需要注册成为我们的用户及提供以上的信息。</p>
<p class="p3">您可以编辑修改您的资料,包括头像、昵称、性别,您还可以更换手机号码,前述信息有助于我们为您提供个性化服务和产品推进以及更优质的使用体验和功能,但如果您不提供这些信息,不会影响您使用APP的基本功能。</p>
<p class="p3">(二)商品的展示与购买</p>
<p class="p3">1.虚拟商品的下单与支付</p>
<p class="p3">APP内的付费类虚拟商品,包括但不限于课程等,需要您支付相应金额的货币下单并支付完成后使用,为实现付费类虚拟商品的下单功能,我们需要获取您的账号,下单完成后,您可选择与我们合作的第三方支付机构(包括微信支付、支付宝支付、苹果应用内购买,以下称”支付机构”)所提供的支付服务,支付功能仅收集您的账号,但我们需要将您的订单号和交易金额与这些支付机构共享以实现其确认您的支付指令并完成支付。</p>
<p class="p3">2.图书馆功能的使用</p>
<p class="p3">图书馆主要以虚拟商品的展示和销售为主,在您使用图书馆内的以下功能时,我们按照最少够用原则收集您的个人信息并用于相应功能的实现:</p>
<p class="p3">(1)商品的展示、加购与搜索功能</p>
<p class="p3">为保证您准确挑选您所需的商品或服务,我们在APP图书馆内为您提供商品展示、搜索及加入购物车的功能,为此我们会收集您的账号。</p>
<p class="p3">(2)商品的购买</p>
<p class="p3">当您下单您选购的商品或服务时,系统会生成您购买该商品或服务的订单,我们会收集您的账号。</p>
<p class="p3">下单完成后,您可选择与合作的支付机构所提供的支付服务,支付功能仅会收集您的账号,但我们需要将您的订单号和交易金额与这些支付机构共享以实现其确认您的支付指令并完成支付。</p>
<p class="p3">3.订单管理功能</p>
<p class="p3">为便于您了解查询订单信息并对订单信息进行管理,我们会收集您在使用我们服务过程中产生的订单信息用于向您展示及便于您对订单进行管理。</p>
<p class="p3">(三)客服与售后功能</p>
<p class="p3">当您与我们联系或提出售中售后、争议纠纷处理申请时,为了保障您的账号安全,我们需要您提供必要的个人信息以核验您的用户身份。</p>
<p class="p3">为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的通信/通话记录及相关内容(包括账号信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息),如果您针对具体订单进行咨询、投诉或提供建议的,我们会使用您的账号信息和订单信息。</p>
<p class="p3">为了提供服务及改进服务质量的合理需要,我们还可能使用的您的其他信息,包括您与客服联系时您提供的相关信息。</p>
<p class="p3">(四)保障交易安全</p>
<p class="p3">为提高您使用我们、合作伙伴提供服务的安全性,保护您或其他用户或公众的人身财产安全免遭侵害,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或相关协议规则的情况,我们可能使用或整合您的账号信息、交易信息、设备信息、软件使用记录、点击记录以及我们关联公司、合作伙伴取得您授权或依据法律共享的信息,来综合判断您账户及交易风险、进行身份验证、检测及防范安全事件,并依法采取必要的记录、审计、分析、处置措施。</p>
<p class="p3">(五)虚拟商品在线使用</p>
<p class="p3">对于APP内的虚拟商品,我们为您提供了在线使用功能(每一个具体虚拟商品的在线使用功能可能略有不同,以APP内显示的功能为准),您可以在相应的界面中进行做笔记、评论、录语音,也可以进行收藏、下载,为此,我们需要收集您的账号、软件使用记录,并在经过您同意后访问您的手机存储权限,以实现前述功能。</p>
<p class="p3">您公开发布的信息中可能会涉及您或他人的个人信息甚至敏感个人信息,请您更加谨慎地考虑,是否在使用我们的服务时共享甚至公开分享相关信息。</p>
<p class="p3">请您注意,根据国家相关法律法规的规定,以下情形中,我们收集、使用您的个人信息无需征得您的授权同意:</p>
<p class="p3">1.与国家安全、国防安全直接相关的;</p>
<p class="p3">2.与公共安全、公共卫生、重大公共利益直接相关的;</p>
<p class="p3">3.与刑事侦查、起诉、审判和判决执行等直接相关的;</p>
<p class="p3">4.出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;</p>
<p class="p3">5.所涉及的个人信息是您自行向社会公众公开的,但您明确拒绝我们使用的除外;</p>
<p class="p3">6.从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道,但当事人明确拒绝我们使用的除外;</p>
<p class="p3">7.用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障; </p>
<p class="p3">8.履行法律、行政法规规定的义务相关的。</p>
<p class="p3">三、我们如何共享、转让、公开披露您的个人信息</p>
<p class="p3">(一)共享</p>
<p class="p3">1.我们不会与第三方公司、组织和个人共享您的个人信息,但以下情况除外:</p>
<p class="p3">(1)事先获得您明确的同意或授权;</p>
<p class="p3">(2)根据适用的法律法规、法律程序的要求、强制性的行政或司法要求所必须的情况下进行提供;</p>
<p class="p3">(3)在法律法规允许的范围内,为维护您、其他用户或我们的正当利益或安全免遭损害而有必要提供;</p>
<p class="p3">(4) 只有共享您的信息,才能实现我们的产品与/或服务的核心功能或提供您需要的服务;</p>
<p class="p3">(5)应您需求为您处理您与他人的纠纷或争议;</p>
<p class="p3">(6)符合与您签署的相关协议(包括在线签署的电子协议以及相应的规则)或其他的法律文件约定所提供;</p>
<p class="p3">(7)基于符合法律法规的社会公共利益而使用。</p>
<p class="p3">2.我们可能会将您的个人信息与我们的关联公司共享,但我们只会共享必要的个人信息,且受本隐私政策中所声明目的的约束。</p>
<p class="p3">3.我们可能会向合作伙伴等第三方共享您的订单信息、账号信息、设备信息,以保障为您提供的服务顺利完成。但我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作伙伴无权将共享的个人信息用于任何其他用途。</p>
<p class="p3">我们的合作伙伴包括以下类型:</p>
<p class="p3">(1)商品或技术服务的供应商。我们可能会将您的个人信息共享给支持我们功能的第三方。这些支持包括为我们提供基础设施技术服务、支付服务、数据处理等。我们共享这些信息的目的是可以实现我们产品与/或服务的核心购物功能,比如我们需要将您的订单号和订单金额与第三方支付机构共享以实现其确认您的支付指令并完成支付等。我们会对合作方获取信息的软件工具开发包(SDK)、应用程序接口(API)进行严格的安全监测,以保护数据安全。</p>
<p class="p3">接入第三方SDK:</p>
<p class="p3">1.为保障APP相关功能的实现与应用安全稳定的运行,我们可能会接入由第三方提供的软件开发包(SDK)实现相关目的。</p>
<p class="p3">2.我们会对合作方获取信息的软件工具开发包(SDK)进行严格的安全检测,以保护数据安全。</p>
<p class="p3">3.我们对接入的相关第三方SDK在目录中列明:</p>
<p class="p3"><b>微信支付SDK(fluwx)</b></p>
<p class="p3">应用场景:用于实现微信支付功能</p>
<p class="p3">收集个人信息的类型:网络状态信息、WLAN状态、设备信息(设备型号、操作系统版本、唯一设备标识符、设备序列号(SN)、MAC地址、IP地址)</p>
<p class="p3">收集方式:SDK本机采集</p>
<p class="p3">第三方SDK提供方:深圳市腾讯计算机系统有限公司</p>
<p class="p3"><a href="https://pay.weixin.qq.com/index.php/public/apply_sign/protocol_v2">微信支付隐私政策</a></p>
<p class="p4"><br></p>
<p class="p3"><b>支付宝支付SDK(tobias)</b></p>
<p class="p3">应用场景:用于实现支付宝支付功能</p>
<p class="p3">收集个人信息的类型:网络状态信息、WLAN状态、设备信息(设备型号、操作系统版本、唯一设备标识符、设备序列号(SN)、MAC地址、IP地址)</p>
<p class="p3">收集方式:SDK本机采集</p>
<p class="p3">第三方SDK提供方:支付宝(中国)网络技术有限公司</p>
<p class="p3"><a href="https://opendocs.alipay.com/open/54/01g6qm">支付宝客户端SDK隐私政策</a></p>
<p class="p4"><br></p>
<p class="p3"><b>苹果应用内购买SDK(flutter_inapp_purchase)</b></p>
<p class="p3">应用场景:用于实现iOS端应用内购买功能</p>
<p class="p3">收集个人信息的类型:交易记录、设备信息(设备型号、操作系统版本)</p>
<p class="p3">收集方式:SDK本机采集</p>
<p class="p3">第三方SDK提供方:Apple Inc.</p>
<p class="p3"><a href="https://www.apple.com/legal/privacy/">Apple隐私政策</a></p>
<p class="p4"><br></p>
<p class="p3"><b>阿里云OSS SDK(flutter_oss_aliyun)</b></p>
<p class="p3">应用场景:用于将图片、音频等文件上传至云端存储</p>
<p class="p3">收集个人信息的类型:无(文件上传直传至OSS,不经过SDK收集个人信息)</p>
<p class="p3">第三方SDK提供方:阿里云计算有限公司</p>
<p class="p3"><a href="https://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html">阿里云隐私政策</a></p>
<p class="p4"><br></p>
<p class="p3"><b>图片选择器SDK(image_picker)</b></p>
<p class="p3">应用场景:用于调用系统相机拍照或从相册选择图片</p>
<p class="p3">收集个人信息的类型:图片或视频内容</p>
<p class="p3">第三方SDK提供方:Google Flutter团队</p>
<p class="p3">仅调用系统原生API,不单独收集信息。</p>
<p class="p4"><br></p>
<p class="p3">4.为了遵守法律、执行或适用我们的使用条件和其他协议,或者为了保护我们、您或其他用户的权利及其财产或安全,比如为防止欺诈等违法活动和减少信用风险,而与其他公司和组织交换信息。但这并不包括违反本隐私政策中所作的承诺而为获利目的出售、出租、共享或以其它方式披露的个人信息。</p>
<p class="p3">(二)转让</p>
<p class="p3">我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:</p>
<p class="p3">1.事先获得您明确的同意或授权;</p>
<p class="p3">2.根据适用的法律法规、法律程序的要求、强制性的行政或司法要求所必须的情况进行提供;</p>
<p class="p3">3.符合与您签署的相关协议(包括在线签署的电子协议以及相应的平台规则)或其他的法律文件约定所提供;</p>
<p class="p3">4.在涉及合并、收购、资产转让或类似的交易时,如涉及到个人信息转让,我们会要求新的持有您个人信息的公司、组织继续受本隐私政策的约束,否则,我们将要求该公司、组织重新向您征求授权同意。</p>
<p class="p3">(三)公开披露</p>
<p class="p3">我们仅会在以下情况下,才会公开披露您的个人信息:</p>
<p class="p3">1.根据您的需求,在您明确同意的披露方式下披露您所指定的个人信息;</p>
<p class="p3">2.根据法律、法规的要求、强制性的行政执法或司法要求所必须提供您个人信息的情况下,我们可能会依据所要求的个人信息类型和披露方式公开披露您的个人信息。在符合法律法规的前提下,当我们收到上述披露信息的请求时,我们会要求必须出具与之相应的法律文件,如传票或调查函。我们坚信,对于要求我们提供的信息,应该在法律允许的范围内尽可能保持透明。我们对所有的请求都进行了慎重的审查,以确保其具备合法依据,且仅限于执法部门因特定调查目的且有合法权利获取的数据。在法律法规许可的前提下,我们披露的文件均在加密密钥的保护之下。</p>
<p class="p3">(四)例外情形</p>
<p class="p3">以下情形中,共享、转让、公开披露您的个人信息无需事先征得您的授权同意:</p>
<p class="p3">1.与国家安全、国防安全有关的;</p>
<p class="p3">2.与公共安全、公共卫生、重大公共利益有关的;</p>
<p class="p3">3.与犯罪侦查、起诉、审判和判决执行等司法或行政执法有关的;</p>
<p class="p3">4.出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</p>
<p class="p3">5.您已经向社会公众公开的个人信息,但您明确拒绝我们使用的除外;</p>
<p class="p3">6.从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道,但当事人明确拒绝我们使用的除外。</p>
<p class="p3">四、我们如何保护和保存您的个人信息</p>
<p class="p3">(一)您个人信息的保护</p>
<p class="p3">1.我们已使用符合行业标准的安全防护措施保护您提供的个人信息, 防止数据遭到未经授权访问、公开披露、使用、修改、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息。例如:我们采用了https的加密方式传输您的个人信息,在您的浏览器与 “服务”之间交换数据(如信用卡信息)时受 SSL 加密保护,我们会使用加密技术确保数据的保密性,我们会使用受信赖的保护机制防止数据遭到恶意攻击,我们会部署访问控制机制,确保只有授权人员才可访问个人信息。</p>
<p class="p3">2.我们将在合理的安全水平内使用各种安全保护措施以保障信息的安全。例如,我们使用加密技术(例如,TLS、SSL)、匿名化处理等手段来保护您的个人信息。为了预防病毒、木马程序或其他恶意程序、网站,我们可能会检测您设备安装的应用、正在运行的进程或设备内存中寄存的信息是否存在安全隐患;为了预防诈骗、盗号、仿冒他人等不法行为和进行安全检查我们可能会分析利用唯一设备标识符、登录IP地址、操作日志等数据,以便于采取安全措施或对用户进行安全提示等。</p>
<p class="p3">3.我们建立专门的管理制度、流程和组织确保信息安全。例如,我们严格限制访问信息的人员范围,要求他们遵守保密义务,并进行审查。</p>
<p class="p3">4.我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本隐私政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。</p>
<p class="p3">5.在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。</p>
<p class="p3">(二)您个人信息的保存</p>
<p class="p3">1.您的个人信息将全被存储于中华人民共和国境内。以下情形除外:</p>
<p class="p3">(1)适用的法律有明确规定;</p>
<p class="p3">(2)获得您的明确授权。</p>
<p class="p3">2.请您注意,当您成功申请注销账号后,我们将对您的账号注销申请进行审核,审核通过后,我们将根据法律法规的要求尽快对您的个人信息进行删除或匿名化处理。</p>
<p class="p3">3.如果我们终止服务或运营,我们会提前向您通知,并在终止服务或运营后对您的个人信息进行删除或匿名化处理。</p>
<p class="p3">4.我们在法律法规规定的期限内或为您提供满足产品与/或服务目的所必需且最短的期限内保存您的个人信息。</p>
<p class="p3">五、您如何管理您的个人信息</p>
<p class="p3">(一)访问您的个人信息</p>
<p class="p3">您有权查询您的信息,您可以通过以下方式自行进行:</p>
<p class="p3">1.打开APP,点击“我的”,点击头像或个人资料,访问您的个人资料;</p>
<p class="p3">2.打开APP,点击“我的”,可以查看虚拟商品订单、充值记录、消费记录以及赠送记录;</p>
<p class="p3">3..打开APP,点击“我的”,点击“笔记”,可以查看您的学习时记录的笔记,点击“讨论”,可以查看您发布的讨论内容,点击“收藏”,可以查看您的收藏内容;</p>
<p class="p3">(二)更正、补充您的个人信息</p>
<p class="p3">当您发现我们处理的关于您的个人信息有错误时,您有权要求我们做出更正。您可以通过“(一)访问您的个人信息”中罗列的方式提出更正申请。</p>
<p class="p3">(三)删除您的个人信息</p>
<p class="p3">在以下情形中,您可以向我们提出删除个人信息的请求:</p>
<p class="p3">1.如果我们处理个人信息的行为违反法律法规;</p>
<p class="p3">2.如果我们收集、使用您的个人信息,却未征得您的同意;</p>
<p class="p3">3.如果我们处理个人信息的行为违反了与您的约定;</p>
<p class="p3">4.如果您不再使用我们的产品或服务,或您注销了账号;</p>
<p class="p3">5.如果我们不再为您提供产品或服务。 </p>
<p class="p3">请知悉,如果您公开发布了信息,任何登录的用户都将可以阅读到您的信息,或收集、使用。您可以自己在应用程序内删除,如您自己无法将您的个人信息从社区论坛中删除,可以联系客服进行相应咨询和操作。有时,我们可能无法删除您的个人信息,在这种情况下我们会将这一情况及其原因告知于您。</p>
<p class="p3">若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。</p>
<p class="p3">(四)注销您的账号</p>
<p class="p3">如果您希望注销您的账号,您可以通过以下路径进行操作:</p>
<p class="p3">打开APP,点击“我的”,点击下方“账号安全”,点击“账号注销”。</p>
<p class="p3">(五)其他</p>
<p class="p3">1.在您访问、修改和删除相关信息时,我们可能会要求您进行身份验证,以保障帐号的安全。</p>
<p class="p3">2.响应您的上述请求</p>
<p class="p3">我们将在十五天内做出答复。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视情收取一定成本费用。对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际(例如,涉及备份磁带上存放的信息)的请求,我们可能会予以拒绝。</p>
<p class="p3">在以下情形中,我们将无法响应您的请求:</p>
<p class="p3">(1)与国家安全、国防安全直接相关的;</p>
<p class="p3">(2)与公共安全、公共卫生、重大公共利益直接相关的;</p>
<p class="p3">(3)与刑事侦查、起诉、审判和执行判决等直接相关的;</p>
<p class="p3">(4)我们有充分证据表明您存在主观恶意或滥用权利的;</p>
<p class="p3">(5)出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</p>
<p class="p3">(6)响应个人信息主体的请求将导致个人信息主体或其他个人、组织的合法权益受到严重损害的;</p>
<p class="p3">(7)涉及商业秘密的;</p>
<p class="p3">(8)与我们履行法律法规规定的义务相关的。</p>
<p class="p3">六、通知和修订</p>
<p class="p3">1.为给您提供更好的服务以及随着我们业务的发展,本隐私政策也会随之更新。但未经您明确同意,我们不会削减您依据本隐私政策所应享有的权利。我们会通过在APP上发出更新版本并在生效前通过我们或以其他适当方式提醒您相关内容的更新,也请您访问APP以便及时了解最新的隐私政策。</p>
<p class="p3">2.对于重大变更,我们还会提供更为显著的通知(我们会通过包括但不限于邮件、短信或在浏览页面做特别提示等方式,说明隐私政策的具体变更内容)。</p>
<p class="p3">本隐私政策所指的重大变更包括但不限于:</p>
<p class="p3">(1)我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;</p>
<p class="p3">(2)我们在业务调整、破产并购等引起的所有者变更等;</p>
<p class="p3">(3)个人信息共享、转让或公开披露的主要对象发生变化;</p>
<p class="p3">(4)您参与个人信息处理方面的权利及其行使方式发生重大变化。</p>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>清控紫荆数智学堂充值服务协议</title>
<meta
name="viewport"
content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,initial-scale=1.0" />
<style>
* {
margin: 0px;
padding: 0px;
line-height: 1.8rem;
}
body {
margin: 20px;
font-size: 1rem;
}
body h2 {
padding: 15px 0px;
font-size: 1.5rem;
}
a {
color: black;
}
.p2 {
margin: 10px 0;
}
</style>
</head>
<body>
<h2>清控紫荆数智学堂充值服务协议</h2>
<p class="p2"><b>更新日期:</b>2024年02月29日</p>
<p class="p2"><b>生效日期:</b>2024年02月29日</p>
<p class="p2"><b>版本:</b>v1.0</p>
<p>
本协议是由您(以下简称“用户”)与本充值清控紫荆数智学堂APP服务平台(以下简称“平台”)达成的,以明确双方权益和义务的法律文件。请您在使用本平台提供的充值服务之前,仔细阅读并理解本协议的全部内容。
</p>
<p>一、协议的接受与生效</p>
<p>
1.1
用户在使用本平台充值服务之前,必须认真阅读并同意本协议的全部内容。用户通过点击“同意”按钮,即表示用户已完全接受并同意本协议的所有条款。
</p>
<p>1.2 本协议生效之日起,用户与平台之间即建立起了协议关系。</p>
<p>二、充值服务简介</p>
<p>
2.1
平台提供的充值服务指的是用户通过平台的充值页面,充值一定金额的虚拟货币(紫金币)到用户账户,以便用于在平台上进行支付或其他有关活动。
</p>
<p>2.2 平台所提供的充值服务不涉及任何实物交易,仅限于虚拟货币(紫金币)的充值及使用。</p>
<p>三、用户充值的方式和规则</p>
<p>3.1 用户可以通过平台提供的充值页面进行充值,包括支付宝、微信等方式。</p>
<p>3.2 用户在充值时需按平台规定的金额范围进行充值,超出规定范围的金额将无法充值成功。</p>
<p>3.3 充值金额一经成功后,不可退换。</p>
<p>3.4 用户在进行充值时需确保所提供的充值信息真实、准确、完整,如因信息错误导致的充值失败或损失由用户自行承担。</p>
<p>3.5 平台有权根据业务需要或监管要求,对用户在充值服务上的使用额度进行限制。</p>
<p>四、用户权益与义务</p>
<p>
4.1
用户享有按平台规定方式进行充值的权益,平台将根据用户的实际充值金额,及时将对应的虚拟货币(紫金币)充值到用户的账户上。
</p>
<p>4.2 用户在进行充值时必须保证所使用的支付账户合法、有效,并承担因违反该义务而产生的一切责任。</p>
<p>4.3 用户在使用充值服务过程中,必须遵守平台的相关规定及国家法律法规,不得利用充值服务进行任何非法活动。</p>
<p>4.4 用户充值成功后,所获得的虚拟货币(紫金币)不可提现,仅限于在平台内进行消费和使用。</p>
<p>4.5 用户应妥善保管自己的账户及充值相关信息,避免账户被他人非法使用。</p>
<p>4.6 用户在使用充值服务过程中,如遇到任何问题或疑问,应及时与平台客服联系,寻求帮助和解决方案。</p>
<p>五、免责与争议解决</p>
<p>
5.1
平台在任何情况下均不对用户在充值服务过程中的损失、延误或其他不良影响承担责任,包括但不限于因网络故障、技术问题、操作失误等原因导致的损失。
</p>
<p>
5.2
用户在使用充值服务过程中,如遇到纠纷或争议,应与平台友好协商解决。如协商不果,任何一方均有权向有管辖权的人民法院提起诉讼解决争议。
</p>
<p>六、协议的终止</p>
<p>6.1 用户可随时终止本协议,终止后用户将不再享有本协议下的充值服务权益。</p>
<p>6.2 平台在用户违反本协议内容或国家法律法规的情况下,有权终止本协议,并保留采取法律手段追究用户责任的权利。</p>
<p>七、协议的修改</p>
<p>
7.1
平台有权随时对本协议进行修改,修改后的协议一经公布即生效。用户在继续使用充值服务时,视为用户已完全接受并同意修改后的协议。
</p>
<p>7.2 如用户不同意修改后的协议内容,可停止使用充值服务。</p>
<p>八、其他条款</p>
<p>8.1 本协议的订立、执行和解释及争议解决适用中华人民共和国法律。</p>
<p>8.2 如协议的任何条款被认定为无效或不具有执行力,不影响其他条款的效力。</p>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>清控紫荆数智学堂用户协议</title>
<meta
name="viewport"
content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,initial-scale=1.0" />
<style>
* {
margin: 0px;
padding: 0px;
line-height: 1.8rem;
}
body {
margin: 20px;
font-size: 1rem;
}
body h2 {
padding: 15px 0px;
font-size: 1.5rem;
}
a {
color: black;
}
.p2 {
margin: 10px 0;
}
</style>
</head>
<body>
<h2>清控紫荆数智学堂用户协议</h2>
<p class="p2"><b>更新日期:</b>2024年02月29日</p>
<p class="p2"><b>生效日期:</b>2024年02月29日</p>
<p class="p2"><b>版本:</b>v1.0</p>
<p>
尊敬的用户,欢迎使用清控紫荆数智学堂APP提供的服务。在使用前请您阅读如下用户协议,使用本应用即表示您同意接受本协议,本协议产生法律效力,特别涉及免除或者限制清控紫荆数智学堂责任的条款,请仔细阅读。如有任何问题,可向清控紫荆数智学堂咨询。
</p>
<p>1. 用户协议的确认和接受</p>
<p>通过访问或使用本应用,表示用户同意接受本协议的所有条件和条款。</p>
<p>2. 用户协议的变更和修改</p>
<p>
清控紫荆数智学堂有权在必要时修改本条款,本条款一旦发生变更,将会在重要页面上提示修改内容。如果不同意所改动的内容,用户可以放弃获得的本应用信息服务。如果用户继续享用本应用的信息服务,则视为接受用户协议的变更。本应用保留随时修改或中断服务而不需要通知用户的权利。本应用行使修改或中断服务的权利,不需对用户或第三方负责。
</p>
<p>3. 用户行为</p>
<p>3.1 用户账号、密码和安全</p>
<p>
用户一旦注册成功,便成为清控紫荆数智学堂的合法用户,用户应采取合理措施维护其密码和帐号的安全。用户对利用该密码和帐号所进行的一切活动负全部责任;由该等活动所导致的任何损失或损害由用户承担,清控紫荆数智学堂不承担任何责任。
用户的密码和帐号遭到未授权的使用或发生其他任何安全问题,用户可以立即通知清控紫荆数智学堂,并且用户在每次连线结束,应结束帐号使用,否则用户可能得不到清控紫荆数智学堂的安全保护。对于用户长时间未使用的帐号,清控紫荆数智学堂有权予以关闭并注销其内容。
</p>
<p>3.2 账号注册时的禁止行为</p>
<p>(1)请勿以党和国家领导人或其他社会名人的真实姓名、字号、艺名、笔名注册;</p>
<p>(2)冒充任何人或机构,或以虚伪不实的方式谎称或使人误认为与任何人或任何机构有关的名称;</p>
<p>(3)请勿注册和其他网友之名相近、相仿的名字;</p>
<p>(4)请勿注册不文明、不健康名字,或包含歧视、侮辱、猥亵类词语的名字;</p>
<p>(5)请勿注册易产生歧义、引起他人误解的名字;</p>
<p>3.3 用户在本应用上不得发布下列违法信息和照片:</p>
<p>(1)反对宪法所确定的基本原则的;</p>
<p>(2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;</p>
<p>(3)损害国家荣誉和利益的;</p>
<p>(4)煽动民族仇恨、民族歧视,破坏民族团结的;</p>
<p>(5)破坏国家宗教政策,宣扬邪教和封建迷信的;</p>
<p>(6)散布谣言,扰乱社会秩序,破坏社会稳定的;</p>
<p>(7)散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;</p>
<p>(8)侮辱或者诽谤他人,侵害他人合法权益的;</p>
<p>(9)含有法律、行政法规禁止的其他内容的;</p>
<p>(10)禁止骚扰、毁谤、威胁、仿冒网站其他用户;</p>
<p>(11)严禁煽动非法集会、结社、游行、示威、聚众扰乱社会秩序;</p>
<p>
(12)严禁发布可能会妨害第三方权益的文件或者信息,例如(包括但不限于):病毒代码、黑客程序、软件破解注册信息。
</p>
<p>(13)禁止上传他人作品。其中包括您从互联网上下载、截图或收集的他人的作品;</p>
<p>(14)禁止上传广告、横幅、标志等网络图片;</p>
<p>4. 上传或发布的内容</p>
<p>
用户上传的内容是指用户在清控紫荆数智学堂上传或发布的视频或其它任何形式的内容包括文字、图片、音频等。除非清控紫荆数智学堂收到相关通知,否则清控紫荆数智学堂将用户视为其在本应用上传或发布的内容的版权拥有人。作为内容的发表者,需自行对所发表内容负责,因所发表内容引发的一切纠纷,由该内容的发表者承担全部法律及连带责任。清控紫荆数智学堂不承担任何法律及连带责任。
</p>
<p>
对于经由本应用而传送的内容,清控紫荆数智学堂不保证前述其合法性、正当性、准确性、完整性或品质。用户在使用本应用时,有可能会接触到令人不快、不适当或令人厌恶的内容。在任何情况下,清控紫荆数智学堂均不对任何内容承担任何责任,包括但不限于任何内容发生任何错误或纰漏以及衍生的任何损失或损害。清控紫荆数智学堂有权(但无义务)自行拒绝或删除经由本应用提供的任何内容。
</p>
<p>
个人或单位如认为清控紫荆数智学堂存在侵犯自身合法权益的内容,应准备好具有法律效应的证明材料,及时与清控紫荆数智学堂取得联系,以便清控紫荆数智学堂迅速作出处理。
</p>
</body>
</html>
{
"name": "book-app-h5",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^7.3.0",
"glob": "^11.0.0"
}
}
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
glob:
specifier: ^11.0.0
version: 11.1.0
vite:
specifier: ^7.3.0
version: 7.3.0
packages:
'@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@isaacs/balanced-match@4.0.1':
resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
engines: {node: 20 || >=22}
'@isaacs/brace-expansion@5.0.0':
resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
engines: {node: 20 || >=22}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
'@rollup/rollup-android-arm-eabi@4.54.0':
resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.54.0':
resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.54.0':
resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.54.0':
resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.54.0':
resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.54.0':
resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.54.0':
resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.54.0':
resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-musl@4.54.0':
resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-loong64-gnu@4.54.0':
resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-riscv64-musl@4.54.0':
resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.54.0':
resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==}
cpu: [s390x]
os: [linux]
'@rollup/rollup-linux-x64-gnu@4.54.0':
resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==}
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-musl@4.54.0':
resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==}
cpu: [x64]
os: [linux]
'@rollup/rollup-openharmony-arm64@4.54.0':
resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==}
cpu: [arm64]
os: [openharmony]
'@rollup/rollup-win32-arm64-msvc@4.54.0':
resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.54.0':
resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-gnu@4.54.0':
resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==}
cpu: [x64]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.54.0':
resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==}
cpu: [x64]
os: [win32]
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
esbuild@0.27.2:
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
engines: {node: '>=18'}
hasBin: true
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
foreground-child@3.3.1:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
glob@11.1.0:
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
engines: {node: 20 || >=22}
hasBin: true
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
jackspeak@4.1.1:
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
engines: {node: 20 || >=22}
lru-cache@11.2.4:
resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
engines: {node: 20 || >=22}
minimatch@10.1.1:
resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
engines: {node: 20 || >=22}
minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-scurry@2.0.1:
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
engines: {node: 20 || >=22}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
rollup@4.54.0:
resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string-width@5.1.2:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-ansi@7.1.2:
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
tinyglobby@0.2.15:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
engines: {node: '>=12.0.0'}
vite@7.3.0:
resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0
jiti: '>=1.21.0'
less: ^4.0.0
lightningcss: ^1.21.0
sass: ^1.70.0
sass-embedded: ^1.70.0
stylus: '>=0.54.8'
sugarss: ^5.0.0
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
jiti:
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
tsx:
optional: true
yaml:
optional: true
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
wrap-ansi@8.1.0:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
snapshots:
'@esbuild/aix-ppc64@0.27.2':
optional: true
'@esbuild/android-arm64@0.27.2':
optional: true
'@esbuild/android-arm@0.27.2':
optional: true
'@esbuild/android-x64@0.27.2':
optional: true
'@esbuild/darwin-arm64@0.27.2':
optional: true
'@esbuild/darwin-x64@0.27.2':
optional: true
'@esbuild/freebsd-arm64@0.27.2':
optional: true
'@esbuild/freebsd-x64@0.27.2':
optional: true
'@esbuild/linux-arm64@0.27.2':
optional: true
'@esbuild/linux-arm@0.27.2':
optional: true
'@esbuild/linux-ia32@0.27.2':
optional: true
'@esbuild/linux-loong64@0.27.2':
optional: true
'@esbuild/linux-mips64el@0.27.2':
optional: true
'@esbuild/linux-ppc64@0.27.2':
optional: true
'@esbuild/linux-riscv64@0.27.2':
optional: true
'@esbuild/linux-s390x@0.27.2':
optional: true
'@esbuild/linux-x64@0.27.2':
optional: true
'@esbuild/netbsd-arm64@0.27.2':
optional: true
'@esbuild/netbsd-x64@0.27.2':
optional: true
'@esbuild/openbsd-arm64@0.27.2':
optional: true
'@esbuild/openbsd-x64@0.27.2':
optional: true
'@esbuild/openharmony-arm64@0.27.2':
optional: true
'@esbuild/sunos-x64@0.27.2':
optional: true
'@esbuild/win32-arm64@0.27.2':
optional: true
'@esbuild/win32-ia32@0.27.2':
optional: true
'@esbuild/win32-x64@0.27.2':
optional: true
'@isaacs/balanced-match@4.0.1': {}
'@isaacs/brace-expansion@5.0.0':
dependencies:
'@isaacs/balanced-match': 4.0.1
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
strip-ansi: 7.1.2
strip-ansi-cjs: strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
'@rollup/rollup-android-arm-eabi@4.54.0':
optional: true
'@rollup/rollup-android-arm64@4.54.0':
optional: true
'@rollup/rollup-darwin-arm64@4.54.0':
optional: true
'@rollup/rollup-darwin-x64@4.54.0':
optional: true
'@rollup/rollup-freebsd-arm64@4.54.0':
optional: true
'@rollup/rollup-freebsd-x64@4.54.0':
optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.54.0':
optional: true
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.54.0':
optional: true
'@rollup/rollup-linux-arm64-musl@4.54.0':
optional: true
'@rollup/rollup-linux-loong64-gnu@4.54.0':
optional: true
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
optional: true
'@rollup/rollup-linux-riscv64-musl@4.54.0':
optional: true
'@rollup/rollup-linux-s390x-gnu@4.54.0':
optional: true
'@rollup/rollup-linux-x64-gnu@4.54.0':
optional: true
'@rollup/rollup-linux-x64-musl@4.54.0':
optional: true
'@rollup/rollup-openharmony-arm64@4.54.0':
optional: true
'@rollup/rollup-win32-arm64-msvc@4.54.0':
optional: true
'@rollup/rollup-win32-ia32-msvc@4.54.0':
optional: true
'@rollup/rollup-win32-x64-gnu@4.54.0':
optional: true
'@rollup/rollup-win32-x64-msvc@4.54.0':
optional: true
'@types/estree@1.0.8': {}
ansi-regex@5.0.1: {}
ansi-regex@6.2.2: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ansi-styles@6.2.3: {}
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
eastasianwidth@0.2.0: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
esbuild@0.27.2:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.2
'@esbuild/android-arm': 0.27.2
'@esbuild/android-arm64': 0.27.2
'@esbuild/android-x64': 0.27.2
'@esbuild/darwin-arm64': 0.27.2
'@esbuild/darwin-x64': 0.27.2
'@esbuild/freebsd-arm64': 0.27.2
'@esbuild/freebsd-x64': 0.27.2
'@esbuild/linux-arm': 0.27.2
'@esbuild/linux-arm64': 0.27.2
'@esbuild/linux-ia32': 0.27.2
'@esbuild/linux-loong64': 0.27.2
'@esbuild/linux-mips64el': 0.27.2
'@esbuild/linux-ppc64': 0.27.2
'@esbuild/linux-riscv64': 0.27.2
'@esbuild/linux-s390x': 0.27.2
'@esbuild/linux-x64': 0.27.2
'@esbuild/netbsd-arm64': 0.27.2
'@esbuild/netbsd-x64': 0.27.2
'@esbuild/openbsd-arm64': 0.27.2
'@esbuild/openbsd-x64': 0.27.2
'@esbuild/openharmony-arm64': 0.27.2
'@esbuild/sunos-x64': 0.27.2
'@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 0.27.2
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
foreground-child@3.3.1:
dependencies:
cross-spawn: 7.0.6
signal-exit: 4.1.0
fsevents@2.3.3:
optional: true
glob@11.1.0:
dependencies:
foreground-child: 3.3.1
jackspeak: 4.1.1
minimatch: 10.1.1
minipass: 7.1.2
package-json-from-dist: 1.0.1
path-scurry: 2.0.1
is-fullwidth-code-point@3.0.0: {}
isexe@2.0.0: {}
jackspeak@4.1.1:
dependencies:
'@isaacs/cliui': 8.0.2
lru-cache@11.2.4: {}
minimatch@10.1.1:
dependencies:
'@isaacs/brace-expansion': 5.0.0
minipass@7.1.2: {}
nanoid@3.3.11: {}
package-json-from-dist@1.0.1: {}
path-key@3.1.1: {}
path-scurry@2.0.1:
dependencies:
lru-cache: 11.2.4
minipass: 7.1.2
picocolors@1.1.1: {}
picomatch@4.0.3: {}
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
rollup@4.54.0:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.54.0
'@rollup/rollup-android-arm64': 4.54.0
'@rollup/rollup-darwin-arm64': 4.54.0
'@rollup/rollup-darwin-x64': 4.54.0
'@rollup/rollup-freebsd-arm64': 4.54.0
'@rollup/rollup-freebsd-x64': 4.54.0
'@rollup/rollup-linux-arm-gnueabihf': 4.54.0
'@rollup/rollup-linux-arm-musleabihf': 4.54.0
'@rollup/rollup-linux-arm64-gnu': 4.54.0
'@rollup/rollup-linux-arm64-musl': 4.54.0
'@rollup/rollup-linux-loong64-gnu': 4.54.0
'@rollup/rollup-linux-ppc64-gnu': 4.54.0
'@rollup/rollup-linux-riscv64-gnu': 4.54.0
'@rollup/rollup-linux-riscv64-musl': 4.54.0
'@rollup/rollup-linux-s390x-gnu': 4.54.0
'@rollup/rollup-linux-x64-gnu': 4.54.0
'@rollup/rollup-linux-x64-musl': 4.54.0
'@rollup/rollup-openharmony-arm64': 4.54.0
'@rollup/rollup-win32-arm64-msvc': 4.54.0
'@rollup/rollup-win32-ia32-msvc': 4.54.0
'@rollup/rollup-win32-x64-gnu': 4.54.0
'@rollup/rollup-win32-x64-msvc': 4.54.0
fsevents: 2.3.3
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
shebang-regex@3.0.0: {}
signal-exit@4.1.0: {}
source-map-js@1.2.1: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string-width@5.1.2:
dependencies:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
strip-ansi: 7.1.2
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-ansi@7.1.2:
dependencies:
ansi-regex: 6.2.2
tinyglobby@0.2.15:
dependencies:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
vite@7.3.0:
dependencies:
esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.54.0
tinyglobby: 0.2.15
optionalDependencies:
fsevents: 2.3.3
which@2.0.2:
dependencies:
isexe: 2.0.0
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@8.1.0:
dependencies:
ansi-styles: 6.2.3
string-width: 5.1.2
strip-ansi: 7.1.2
import { defineConfig } from 'vite'
import { resolve, dirname } from 'path'
import { fileURLToPath } from 'url'
import { glob } from 'glob'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
// 获取所有 HTML 文件作为入口
function getHtmlEntries() {
const htmlFiles = glob.sync('*.html', { cwd: __dirname })
const entries = {}
htmlFiles.forEach((file) => {
const name = file.replace(/\.html$/, '')
entries[name] = resolve(__dirname, file)
})
return entries
}
export default defineConfig({
root: '.',
build: {
outDir: 'dist',
rollupOptions: {
input: getHtmlEntries(),
output: {
entryFileNames: 'assets/js/[name]-[hash].js',
chunkFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: (assetInfo) => {
const info = assetInfo.name.split('.')
const ext = info[info.length - 1]
if (/\.(css)$/.test(assetInfo.name)) {
return `assets/css/[name]-[hash].${ext}`
}
if (/\.(png|jpe?g|svg|gif|tiff|bmp|ico)$/i.test(assetInfo.name)) {
return `assets/images/[name]-[hash].${ext}`
}
if (/\.(woff2?|eot|ttf|otf)$/i.test(assetInfo.name)) {
return `assets/fonts/[name]-[hash].${ext}`
}
return `assets/[name]-[hash].${ext}`
},
},
},
// 保持原始 HTML 结构
minify: false,
},
server: {
port: 3000,
open: true,
host: true,
},
resolve: {
alias: {
'@': resolve(__dirname, './'),
},
},
})
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论