更新项目代码:新增彩种模块、组件优化、管理后台功能完善

This commit is contained in:
lihanqi
2026-02-13 17:43:41 +08:00
parent d395295aa0
commit 3d7358079a
146 changed files with 48171 additions and 8804 deletions

View File

@@ -1,402 +0,0 @@
package com.xy.xyaicpzs.controller;
import com.xy.xyaicpzs.common.ErrorCode;
import com.xy.xyaicpzs.common.ResultUtils;
import com.xy.xyaicpzs.common.response.ApiResponse;
import com.xy.xyaicpzs.domain.entity.LotteryDraws;
import com.xy.xyaicpzs.domain.entity.PredictRecord;
import com.xy.xyaicpzs.service.BallAnalysisService;
import com.xy.xyaicpzs.service.LotteryDrawsService;
import com.xy.xyaicpzs.service.PredictRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* 球号分析控制器
* 提供球号分析算法的API接口
*/
@Slf4j
@RestController
@RequestMapping("/ball-analysis")
@Tag(name = "球号分析", description = "球号分析算法API")
public class BallAnalysisController {
@Autowired
private BallAnalysisService ballAnalysisService;
@Autowired
private LotteryDrawsService lotteryDrawsService;
@Autowired
private PredictRecordService predictRecordService;
@GetMapping("/predict-records/{userId}")
@Operation(summary = "获取用户推测记录", description = "根据用户ID获取该用户的所有推测记录按推测时间倒序排列")
public ApiResponse<List<PredictRecord>> getPredictRecordsByUserId(
@Parameter(description = "用户ID例如1001", required = true)
@PathVariable Long userId
, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
if (loginUser == null){
return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
}
try {
log.info("接收到获取用户推测记录请求用户ID={}", userId);
// 调用服务获取用户推测记录
List<PredictRecord> result = predictRecordService.getPredictRecordsByUserId(userId);
log.info("获取用户推测记录完成用户ID{},返回{}条记录", userId, result.size());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("获取用户推测记录失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取用户推测记录失败:" + e.getMessage());
}
}
/**
* 获取近期开奖信息
* @param limit 获取条数可选参数默认15条
* @return 近期开奖信息列表
*/
@GetMapping("/recent-draws")
@Operation(summary = "获取近期开奖信息", description = "获取最近的开奖信息默认返回15条按开奖期号倒序排列")
public ApiResponse<List<LotteryDraws>> getRecentDraws(
@Parameter(description = "获取条数默认15条", required = false)
@RequestParam(required = false, defaultValue = "15") Integer limit) {
try {
log.info("接收到获取近期开奖信息请求:条数={}", limit);
// 调用服务获取近期开奖信息
List<LotteryDraws> result = lotteryDrawsService.getRecentDraws(limit);
log.info("获取近期开奖信息完成,返回{}条记录", result.size());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("获取近期开奖信息失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取近期开奖信息失败:" + e.getMessage());
}
}
/**
* 根据日期范围查询开奖信息
* @param startDate 开始日期可选格式yyyy-MM-dd
* @param endDate 结束日期可选格式yyyy-MM-dd
* @return 开奖信息列表
*/
@GetMapping("/query-draws")
@Operation(summary = "按日期范围查询开奖信息", description = "根据日期范围查询开奖信息,支持单边日期查询")
public ApiResponse<List<LotteryDraws>> queryDraws(
@Parameter(description = "开始日期格式yyyy-MM-dd例如2025-01-01", required = false)
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@Parameter(description = "结束日期格式yyyy-MM-dd例如2025-01-31", required = false)
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
try {
log.info("接收到按日期范围查询开奖信息请求:开始日期={},结束日期={}", startDate, endDate);
// 日期范围验证
if (startDate != null && endDate != null && startDate.after(endDate)) {
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "开始日期不能晚于结束日期");
}
// 调用服务按日期范围查询开奖信息
List<LotteryDraws> result = lotteryDrawsService.getByDateRange(startDate, endDate);
log.info("按日期范围查询开奖信息完成,返回{}条记录", result.size());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("按日期范围查询开奖信息失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖信息失败:" + e.getMessage());
}
}
/**
* 根据期号精准查询单条开奖信息
* @param drawId 开奖期号
* @return 开奖信息
*/
@GetMapping("/draw/{drawId}")
@Operation(summary = "根据期号查询开奖信息", description = "根据期号精准查询单条开奖信息")
public ApiResponse<LotteryDraws> getDrawById(
@Parameter(description = "开奖期号例如2025056", required = true)
@PathVariable Long drawId) {
try {
log.info("接收到根据期号查询开奖信息请求:期号={}", drawId);
// 调用服务查询开奖信息
LotteryDraws result = lotteryDrawsService.getByDrawId(drawId);
if (result == null) {
log.warn("未找到期号为{}的开奖信息", drawId);
return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到期号为" + drawId + "的开奖信息");
}
log.info("根据期号查询开奖信息完成:{}", result.getDrawId());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("根据期号查询开奖信息失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖信息失败:" + e.getMessage());
}
}
/**
* 创建推测记录
* @param userId 用户ID
* @param drawId 开奖期号
* @param drawDate 开奖日期
* @param redBalls 6个红球号码用逗号分隔
* @param blueBall 蓝球号码
* @return 创建的推测记录
*/
@PostMapping("/create-predict")
@Operation(summary = "创建推测记录", description = "向predict_record表插入一条推测记录数据")
public ApiResponse<PredictRecord> createPredictRecord(
@Parameter(description = "用户ID例如1001", required = true)
@RequestParam Long userId,
@Parameter(description = "开奖期号例如2025056", required = true)
@RequestParam Long drawId,
@Parameter(description = "开奖日期格式yyyy-MM-dd", required = true)
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date drawDate,
@Parameter(description = "6个红球号码用逗号分隔例如1,5,12,18,25,33", required = true)
@RequestParam String redBalls,
@Parameter(description = "蓝球号码例如8", required = true)
@RequestParam Integer blueBall) {
try {
log.info("接收到创建推测记录请求用户ID={},期号={},开奖日期={},红球={},蓝球={}",
userId, drawId, drawDate, redBalls, blueBall);
// 解析红球号码
List<Integer> redBallList = parseRedBalls(redBalls, 6, "红球");
// 调用服务创建推测记录
PredictRecord result = predictRecordService.createPredictRecord(userId, drawId, drawDate, redBallList, blueBall);
log.info("创建推测记录完成用户ID{}记录ID{}", userId, result.getId());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("创建推测记录失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "创建推测记录失败:" + e.getMessage());
}
}
/**
* 球号分析算法
* @param level 高位/中位/低位标识 (H/M/L)
* @param redBalls 6个红球号码用逗号分隔
* @param blueBall 蓝球号码
* @return 分析结果出现频率最高的前11位数字
*/
@PostMapping("/analyze")
@Operation(summary = "首球算法", description = "根据输入的级别、红球和蓝球分析出现频率最高的前11位数字")
public ApiResponse<List<Integer>> analyzeBalls(
@Parameter(description = "级别H(高位)/M(中位)/L(低位)", required = true)
@RequestParam String level,
@Parameter(description = "6个红球号码用逗号分隔例如1,5,12,18,25,33", required = true)
@RequestParam String redBalls,
@Parameter(description = "蓝球号码例如8", required = true)
@RequestParam Integer blueBall) {
try {
log.info("接收到球号分析请求:级别={},红球={},蓝球={}", level, redBalls, blueBall);
// 解析红球号码
List<Integer> redBallList = parseRedBalls(redBalls, 6, "红球");
// 调用分析服务
List<Integer> result = ballAnalysisService.analyzeBalls(level, redBallList, blueBall);
log.info("球号分析完成,结果:{}", result);
return ResultUtils.success(result);
} catch (Exception e) {
log.error("球号分析失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "球号分析失败:" + e.getMessage());
}
}
/**
* 跟随球号分析算法
* @param level 高位/中位/低位标识 (H/M/L)
* @param firstThreeRedBalls 前3个红球号码用逗号分隔
* @param lastSixRedBalls 后6个红球号码用逗号分隔
* @param blueBall 蓝球号码
* @return 分析结果出现频率最高的前8位数字
*/
@PostMapping("/fallow")
@Operation(summary = "跟随球号分析算法", description = "根据输入的级别、前3个红球、后6个红球和蓝球分析出现频率最高的前8位数字")
public ApiResponse<List<Integer>> fallowBallAnalysis(
@Parameter(description = "级别H(高位)/M(中位)/L(低位)", required = true)
@RequestParam String level,
@Parameter(description = "前3个红球号码用逗号分隔例如7,24,27", required = true)
@RequestParam String firstThreeRedBalls,
@Parameter(description = "后6个红球号码用逗号分隔例如21,10,5,15,23,28", required = true)
@RequestParam String lastSixRedBalls,
@Parameter(description = "蓝球号码例如16", required = true)
@RequestParam Integer blueBall) {
try {
log.info("接收到跟随球号分析请求:级别={}前3个红球={}后6个红球={},蓝球={}",
level, firstThreeRedBalls, lastSixRedBalls, blueBall);
// 解析红球号码
List<Integer> firstThreeRedBallList = parseRedBalls(firstThreeRedBalls, 3, "前3个红球");
List<Integer> lastSixRedBallList = parseRedBalls(lastSixRedBalls, 6, "后6个红球");
// 调用分析服务
List<Integer> result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBallList, lastSixRedBallList, blueBall);
log.info("跟随球号分析完成,结果:{}", result);
return ResultUtils.success(result);
} catch (Exception e) {
log.error("跟随球号分析失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "跟随球号分析失败:" + e.getMessage());
}
}
/**
* 解析红球号码字符串
*/
private List<Integer> parseRedBalls(String redBalls, int expectedCount, String ballType) {
if (redBalls == null || redBalls.trim().isEmpty()) {
throw new IllegalArgumentException(ballType + "号码不能为空");
}
try {
String[] parts = redBalls.split(",");
if (parts.length != expectedCount) {
throw new IllegalArgumentException(ballType + "数量必须为" + expectedCount + "个,实际:" + parts.length);
}
List<Integer> result = Arrays.stream(parts)
.map(String::trim)
.map(Integer::parseInt)
.collect(java.util.stream.Collectors.toList());
// 验证红球号码范围
for (Integer ball : result) {
if (ball < 1 || ball > 33) {
throw new IllegalArgumentException(ballType + "号码必须在1-33范围内错误值" + ball);
}
}
return result;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ballType + "号码格式错误,请使用逗号分隔的数字");
}
}
/**
* 蓝球分析算法
* @param level 高位/中位/低位标识 (H/M/L)
* @param predictedRedBalls 6个推测红球号码用逗号分隔
* @param predictedBlueBalls 2个推测蓝球号码用逗号分隔
* @param lastRedBalls 6个上期红球号码用逗号分隔
* @param lastBlueBall 上期蓝球号码
* @return 分析结果频率最高的前4个蓝球号码
*/
@PostMapping("/blue-ball")
@Operation(summary = "蓝球分析算法", description = "根据输入的级别、推测红球、推测蓝球、上期红球和上期蓝球分析出频率最高的前4个蓝球号码")
public ApiResponse<List<Integer>> blueBallAnalysis(
@Parameter(description = "级别H(高位)/M(中位)/L(低位)", required = true)
@RequestParam String level,
@Parameter(description = "6个推测红球号码用逗号分隔例如26,20,18,32,10,14", required = true)
@RequestParam String predictedRedBalls,
@Parameter(description = "2个推测蓝球号码用逗号分隔例如5,8", required = true)
@RequestParam String predictedBlueBalls,
@Parameter(description = "6个上期红球号码用逗号分隔例如7,24,27,21,10,5", required = true)
@RequestParam String lastRedBalls,
@Parameter(description = "上期蓝球号码例如16", required = true)
@RequestParam Integer lastBlueBall) {
try {
log.info("接收到蓝球分析请求:级别={},推测红球={},推测蓝球={},上期红球={},上期蓝球={}",
level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall);
// 解析球号
List<Integer> predictedRedBallList = parseRedBalls(predictedRedBalls, 6, "推测红球");
List<Integer> predictedBlueBallList = parseBlueBalls(predictedBlueBalls, 2, "推测蓝球");
List<Integer> lastRedBallList = parseRedBalls(lastRedBalls, 6, "上期红球");
// 调用分析服务
List<Integer> result = ballAnalysisService.blueBallAnalysis(
level, predictedRedBallList, predictedBlueBallList, lastRedBallList, lastBlueBall);
log.info("蓝球分析完成,结果:{}", result);
return ResultUtils.success(result);
} catch (Exception e) {
log.error("蓝球分析失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "蓝球分析失败:" + e.getMessage());
}
}
/**
* 解析蓝球号码字符串
*/
private List<Integer> parseBlueBalls(String blueBalls, int expectedCount, String ballType) {
if (blueBalls == null || blueBalls.trim().isEmpty()) {
throw new IllegalArgumentException(ballType + "号码不能为空");
}
try {
String[] parts = blueBalls.split(",");
if (parts.length != expectedCount) {
throw new IllegalArgumentException(ballType + "数量必须为" + expectedCount + "个,实际:" + parts.length);
}
List<Integer> result = Arrays.stream(parts)
.map(String::trim)
.map(Integer::parseInt)
.collect(java.util.stream.Collectors.toList());
// 验证蓝球号码范围
for (Integer ball : result) {
if (ball < 1 || ball > 16) {
throw new IllegalArgumentException(ballType + "号码必须在1-16范围内错误值" + ball);
}
}
return result;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ballType + "号码格式错误,请使用逗号分隔的数字");
}
}
}

View File

@@ -0,0 +1,351 @@
# Store 登录状态管理增强说明
## 📋 问题背景
在多设备登录踢出场景中,仅依赖 API 拦截器**被动响应**是不够的Store 层面也需要:
1. **主动检查**登录状态是否有效
2. **标记状态**区分正常登出和被踢出
3. **提供方法**供其他组件调用检查
---
## ✅ 已实现的增强功能
### 1. **新增状态字段**
```javascript
export const userStore = reactive({
user: null,
isLoggedIn: false,
isKickedOut: false, // 🆕 标记是否被其他设备踢出
lastCheckTime: null, // 🆕 最后一次检查登录状态的时间
// ...
})
```
### 2. **增强 `logout()` 方法**
支持标记被踢出状态:
```javascript
// 正常登出
userStore.logout()
// 被踢出时登出
userStore.logout(true) // 会标记 isKickedOut = true
```
**实现代码:**
```javascript
logout(isKickedOut = false) {
// 如果是被踢出,标记状态
if (isKickedOut) {
this.isKickedOut = true
console.log('[安全] 账号在其他设备登录,当前会话已被踢出')
}
this.user = null
this.isLoggedIn = false
this.lastCheckTime = null
// 清除本地存储...
}
```
### 3. **增强 `adminLogout()` 方法**
同样支持标记被踢出:
```javascript
adminLogout(isKickedOut = false) {
if (isKickedOut) {
this.isKickedOut = true
console.log('[安全] 管理员账号在其他设备登录,当前会话已被踢出')
}
// 清除状态和存储...
}
```
### 4. **新增 `checkLoginStatus()` 方法** 🔥
主动检查登录状态是否仍然有效:
```javascript
async checkLoginStatus() {
// 1⃣ 如果没有登录,直接返回
if (!this.isLoggedIn) {
return { valid: false, reason: 'not_logged_in' }
}
// 2⃣ 避免频繁检查10秒内只检查一次
const now = Date.now()
if (this.lastCheckTime && (now - this.lastCheckTime) < 10000) {
return { valid: true, reason: 'recently_checked' }
}
try {
// 3⃣ 调用后端接口验证登录状态
const response = await lotteryApi.getLoginUser()
if (response.success === true) {
// ✅ 登录状态有效
this.lastCheckTime = now
this.isKickedOut = false
return { valid: true, reason: 'verified' }
} else {
// ❌ 登录状态无效
const message = response.message || ''
// 检查是否是被踢出
if (message.includes('其他设备登录') || message.includes('当前会话已失效')) {
this.logout(true) // 标记为被踢出
return { valid: false, reason: 'kicked_out', message }
} else {
this.logout(false)
return { valid: false, reason: 'session_expired', message }
}
}
} catch (error) {
// ⚠️ 网络错误等情况,不清除登录状态,让用户继续使用
console.error('[Store] 检查登录状态失败:', error)
return { valid: true, reason: 'check_failed', error }
}
}
```
### 5. **新增 `resetKickedOutStatus()` 方法**
用于重新登录后重置被踢出状态:
```javascript
resetKickedOutStatus() {
this.isKickedOut = false
}
```
### 6. **增强 `login()` 方法**
登录时自动重置被踢出状态:
```javascript
login(userInfo) {
// ... 设置用户信息
this.isLoggedIn = true
this.isKickedOut = false // 🆕 重置被踢出状态
this.lastCheckTime = Date.now() // 🆕 记录登录时间
// 保存到本地存储...
}
```
---
## 🎯 使用场景
### 场景 1组件中主动检查登录状态
```javascript
// 在关键操作前检查登录状态
async function performCriticalAction() {
const status = await userStore.checkLoginStatus()
if (!status.valid) {
if (status.reason === 'kicked_out') {
ElMessage.warning('您的账号已在其他设备登录')
// 跳转到登录页
router.push('/login')
} else {
ElMessage.error('登录已过期,请重新登录')
router.push('/login')
}
return
}
// 继续执行操作
// ...
}
```
### 场景 2路由守卫中使用
```javascript
// router/index.js
router.beforeEach(async (to, from, next) => {
if (to.meta.requiresAuth) {
const status = await userStore.checkLoginStatus()
if (!status.valid) {
next('/login')
return
}
}
next()
})
```
### 场景 3定期心跳检测可选
```javascript
// 在 App.vue 中设置定期检查
import { onMounted, onUnmounted } from 'vue'
import { userStore } from '@/store/user'
let heartbeatTimer = null
onMounted(() => {
// 每 5 分钟检查一次登录状态
heartbeatTimer = setInterval(async () => {
if (userStore.isLoggedIn) {
await userStore.checkLoginStatus()
}
}, 5 * 60 * 1000) // 5分钟
})
onUnmounted(() => {
if (heartbeatTimer) {
clearInterval(heartbeatTimer)
}
})
```
### 场景 4判断被踢出状态
```javascript
// 在登录页面显示提示
if (userStore.isKickedOut) {
ElMessage.warning({
message: '您的账号已在其他设备登录,请重新登录',
duration: 5000
})
userStore.resetKickedOutStatus() // 重置状态
}
```
---
## 🔄 完整流程
### 被动检测API 拦截器)
```
用户操作 → API 请求 → 后端检测 token 不一致 → 返回错误
API 拦截器捕获 → 调用 userStore.logout(true)
标记 isKickedOut = true → 显示提示 → 跳转登录页
```
### 主动检测Store 方法)
```
组件调用 checkLoginStatus()
10秒内检查过
├─ 是 → 返回缓存结果
└─ 否 → 调用后端 API
token 有效?
├─ 是 → 更新检查时间,返回 valid: true
└─ 否 → 检查错误类型
├─ 被踢出 → logout(true), 返回 kicked_out
└─ 其他 → logout(false), 返回 session_expired
```
---
## 🛡️ 防护机制
### 1. **防止频繁检查**
- 10 秒内只检查一次
- 避免给后端造成压力
### 2. **容错处理**
- 网络错误时不清除登录状态
- 让用户继续使用,避免误判
### 3. **状态标记**
- 明确区分正常登出和被踢出
- 便于显示不同的提示信息
### 4. **自动恢复**
- 登录时自动重置被踢出状态
- 提供手动重置方法
---
## 📊 返回值说明
`checkLoginStatus()` 方法返回对象:
```typescript
interface CheckResult {
valid: boolean // 登录状态是否有效
reason: string // 原因
message?: string // 错误消息(可选)
error?: Error // 错误对象(可选)
}
```
### Reason 枚举值:
| Reason | 说明 | valid |
|--------|------|-------|
| `not_logged_in` | 未登录 | false |
| `recently_checked` | 10秒内已检查过 | true |
| `verified` | 后端验证通过 | true |
| `kicked_out` | 被其他设备踢出 | false |
| `session_expired` | 会话过期 | false |
| `check_failed` | 检查失败(网络错误等) | true |
---
## ✅ 配合 API 拦截器
API 拦截器已更新,会在检测到被踢出时调用:
```javascript
// src/api/index.js
userStore.logout(true) // 前台用户
userStore.adminLogout(true) // 后台管理员
```
这样确保了**被动响应**和**主动检查**两种机制的完美配合。
---
## 🎨 最佳实践
### ✅ 推荐
1. **关键操作前检查**:支付、提交表单等操作前主动检查
2. **路由守卫检查**:切换到需要登录的页面时检查
3. **显示友好提示**:根据 `isKickedOut` 显示不同的提示信息
4. **定期心跳检测**:长时间停留在页面时定期检查(可选)
### ❌ 避免
1. **过度频繁检查**:利用 10 秒缓存机制,避免每次操作都检查
2. **忽略返回值**:检查失败时要及时处理,引导用户登录
3. **混淆状态**:不区分正常登出和被踢出,提示信息不明确
---
## 🔧 相关文件
-`src/store/user.js` - Store 状态管理(已增强)
-`src/api/index.js` - API 拦截器(已更新)
- 📄 `前端多设备登录处理方案.md` - 总体方案说明
---
## 🎉 总结
通过在 Store 层面添加:
- ✅ 被踢出状态标记 `isKickedOut`
- ✅ 主动检查方法 `checkLoginStatus()`
- ✅ 增强的登出方法 `logout(isKickedOut)`
- ✅ 防频繁检查机制10秒缓存
实现了**被动响应 + 主动检查**的双重保障机制,确保多设备登录场景下的安全性和用户体验!

Binary file not shown.

195
lottery-app/DEPLOY.md Normal file
View File

@@ -0,0 +1,195 @@
# 部署说明文档
## 🚀 打包部署流程
### 1. 打包前准备
确保已安装依赖:
```bash
npm install
```
### 2. 执行打包
```bash
npm run build
```
打包完成后,会在项目根目录生成 `dist` 文件夹。
### 3. 缓存控制策略
本项目已配置完善的缓存控制策略,避免浏览器缓存导致更新不生效:
#### ✅ 已配置的缓存方案
1. **文件名 Hash 化**`vite.config.js` 已配置)
- 所有 JS、CSS、图片等资源文件名都会带上 hash 值
- 例如:`index.a1b2c3d4.js``style.e5f6g7h8.css`
- 每次构建后,修改过的文件 hash 会变化,自动避免缓存
2. **HTML 文件不缓存**
- `index.html` 设置为不缓存,每次都会获取最新版本
- 通过服务器配置实现(见下方)
#### 📝 服务器配置
##### Apache 服务器(使用 .htaccess
项目已包含 `public/.htaccess` 文件,打包后会自动复制到 `dist` 目录。
##### Nginx 服务器
参考项目根目录的 `nginx.conf.example` 文件,配置说明:
```nginx
# HTML 文件不缓存
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 静态资源长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
```
### 4. 部署步骤
#### 方法一:手动部署
1.`dist` 目录下的所有文件上传到服务器
2. 配置服务器Apache 或 Nginx
3. 重启服务器
#### 方法二:使用 FTP/SFTP
```bash
# 上传 dist 目录到服务器
scp -r dist/* user@your-server:/var/www/html/
```
#### 方法三:使用 Docker可选
创建 `Dockerfile`
```dockerfile
FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf.example /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
### 5. 更新部署注意事项
#### ⚠️ 每次更新部署时:
1. **清理旧文件**
```bash
# 删除服务器上的旧文件
rm -rf /var/www/html/*
```
2. **上传新文件**
```bash
# 上传新的 dist 文件
scp -r dist/* user@your-server:/var/www/html/
```
3. **清理服务器缓存**(如果使用了缓存服务器)
```bash
# Nginx
nginx -s reload
# Apache
systemctl reload apache2
```
4. **通知用户清理浏览器缓存**(可选)
- 可以在系统中添加版本提示
- 或者使用 Service Worker 强制更新
### 6. 验证部署
部署完成后,验证步骤:
1. **清除浏览器缓存**
- Chrome: `Ctrl + Shift + Delete` 或 `Cmd + Shift + Delete`
- 或使用隐身模式访问
2. **检查文件版本**
- 打开浏览器开发者工具F12
- 查看 Network 标签
- 确认 JS/CSS 文件名带有新的 hash 值
3. **检查 HTML 缓存**
- 查看 `index.html` 的响应头
- 确认 `Cache-Control: no-cache`
### 7. 常见问题
#### Q1: 用户反馈看到的还是旧版本?
**解决方案:**
1. 确认服务器配置正确(.htaccess 或 nginx 配置)
2. 清理 CDN 缓存(如果使用了 CDN
3. 通知用户强制刷新Ctrl + F5 或 Cmd + Shift + R
#### Q2: 静态资源 404 错误?
**解决方案:**
1. 检查资源路径配置
2. 确认 `vite.config.js` 中的 `base` 配置正确
3. 检查服务器的静态文件路径
#### Q3: SPA 路由刷新 404
**解决方案:**
- Apache: 确保 `.htaccess` 中的 rewrite 规则生效
- Nginx: 确保配置了 `try_files $uri $uri/ /index.html;`
### 8. 自动化部署(可选)
#### 使用 GitHub Actions
创建 `.github/workflows/deploy.yml`
```yaml
name: Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Deploy to server
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: /var/www/html/
```
### 9. 性能优化建议
1. **启用 Gzip/Brotli 压缩**
2. **使用 CDN 加速静态资源**
3. **配置 HTTP/2**
4. **启用 HTTPS**
## 📞 技术支持
如有部署问题,请联系技术团队。

View File

@@ -0,0 +1,19 @@
# Git 初始化并上传到远程仓库的命令
# 1. 初始化 Git 仓库
git init
# 2. 添加所有文件到暂存区
git add .
# 3. 提交代码
git commit -m "初始提交:彩票推测系统前端代码"
# 4. 添加远程仓库
git remote add origin http://49.234.3.145:3018/lihanqi/cpzs-frontend.git
# 5. 将当前分支重命名为 main
git branch -M main
# 6. 推送到远程仓库并设置上游分支
git push -u origin main

View File

@@ -0,0 +1,41 @@
# Nginx 服务器配置示例
# 使用方法:将此配置添加到你的 Nginx 配置文件中
server {
listen 80;
server_name your-domain.com; # 修改为你的域名
root /path/to/lottery-app/dist; # 修改为你的项目路径
index index.html;
# Gzip 压缩配置
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss image/svg+xml;
# HTML 文件不缓存
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
# 静态资源长期缓存带hash的JS、CSS、图片等
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 代理 API 请求(如果需要)
location /api/ {
proxy_pass http://localhost:8123; # 修改为你的后端地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

View File

@@ -10,7 +10,8 @@
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.10.0",
"element-plus": "^2.10.4",
"echarts": "^6.0.0",
"element-plus": "^2.11.8",
"qrcode": "^1.5.4",
"vue": "^3.5.13",
"vue-router": "^4.5.1",
@@ -18,6 +19,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.3",
"terser": "^5.44.0",
"vite": "^6.2.4",
"vite-plugin-vue-devtools": "^7.7.2"
}
@@ -501,9 +503,9 @@
}
},
"node_modules/@element-plus/icons-vue": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
"integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
"version": "2.3.2",
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
"integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
"license": "MIT",
"peerDependencies": {
"vue": "^3.2.0"
@@ -994,6 +996,17 @@
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.11",
"resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
@@ -1704,6 +1717,19 @@
}
}
},
"node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -1794,6 +1820,13 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/bundle-name": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz",
@@ -1894,6 +1927,13 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT"
},
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -1939,9 +1979,9 @@
"license": "MIT"
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"version": "1.11.19",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.19.tgz",
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
"license": "MIT"
},
"node_modules/debug": {
@@ -2043,6 +2083,16 @@
"node": ">= 0.4"
}
},
"node_modules/echarts": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-6.0.0.tgz",
"integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "2.3.0",
"zrender": "6.0.0"
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.167",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz",
@@ -2051,24 +2101,23 @@
"license": "ISC"
},
"node_modules/element-plus": {
"version": "2.10.4",
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.10.4.tgz",
"integrity": "sha512-UD4elWHrCnp1xlPhbXmVcaKFLCRaRAY6WWRwemGfGW3ceIjXm9fSYc9RNH3AiOEA6Ds1p9ZvhCs76CR9J8Vd+A==",
"version": "2.11.8",
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.11.8.tgz",
"integrity": "sha512-2wzSj2uubFU1f0t/gHkkE1d09mUgV18fSZX5excw3Ar6hyWcxph4E57U8dgYLDt7HwkKYv1BiqPyBdy0WqWlOA==",
"license": "MIT",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.3.1",
"@element-plus/icons-vue": "^2.3.2",
"@floating-ui/dom": "^1.0.1",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"@types/lodash": "^4.14.182",
"@types/lodash-es": "^4.17.6",
"@types/lodash": "^4.17.20",
"@types/lodash-es": "^4.17.12",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.13",
"escape-html": "^1.0.3",
"dayjs": "^1.11.18",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-unified": "^1.0.2",
"lodash-unified": "^1.0.3",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
},
@@ -2200,12 +2249,6 @@
"node": ">=6"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
@@ -3201,6 +3244,16 @@
"node": ">=18"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -3210,6 +3263,17 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/speakingurl": {
"version": "14.0.1",
"resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz",
@@ -3272,6 +3336,25 @@
"node": ">=16"
}
},
"node_modules/terser": {
"version": "5.44.0",
"resolved": "https://registry.npmmirror.com/terser/-/terser-5.44.0.tgz",
"integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tinyglobby": {
"version": "0.2.14",
"resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.14.tgz",
@@ -3299,6 +3382,12 @@
"node": ">=6"
}
},
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"license": "0BSD"
},
"node_modules/unicorn-magic": {
"version": "0.3.0",
"resolved": "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
@@ -3657,6 +3746,15 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-6.0.0.tgz",
"integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==",
"license": "BSD-3-Clause",
"dependencies": {
"tslib": "2.3.0"
}
}
}
}

View File

@@ -6,12 +6,14 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"build:clean": "rm -rf dist && vite build",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.10.0",
"element-plus": "^2.10.4",
"echarts": "^6.0.0",
"element-plus": "^2.11.8",
"qrcode": "^1.5.4",
"vue": "^3.5.13",
"vue-router": "^4.5.1",
@@ -19,6 +21,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.3",
"terser": "^5.44.0",
"vite": "^6.2.4",
"vite-plugin-vue-devtools": "^7.7.2"
}

View File

@@ -0,0 +1,32 @@
# 缓存控制配置Apache服务器
# 禁用 HTML 文件的缓存
<FilesMatch "\.(html|htm)$">
FileETag None
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</FilesMatch>
# 静态资源长期缓存带hash的文件
<FilesMatch "\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$">
Header set Cache-Control "max-age=31536000, public, immutable"
</FilesMatch>
# 启用 Gzip 压缩
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml
</IfModule>
# SPA 路由支持
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>

View File

@@ -0,0 +1 @@
<svg t="1764145401887" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7812" width="32" height="32"><path d="M378.5 613.6l23.7-12.8 90.9 51V526.3l-18.2-9.1-90.9-52.8v103.7L364 579l-76.4-43.6-91 50.9v105.5l91 50.9 90.9-50.9zM656.9 579l-18.2-10.9V464.4l-109.2 61.9v125.5l91-51 23.6 12.8v78.2l91 50.9 91-50.9V586.3l-91-50.9z" fill="#1296db" p-id="7813"></path><path d="M656.9 251.6v83.6l96.4 52.8v94.6l9.1 5.5 63.7 36.3V344.3zM602.3 730l-91 49.1-90.9-49.1-14.6 9.1-60 32.8 165.5 90.9 165.6-90.9-60.1-32.8zM269.4 482.6V388l96.4-52.8v-83.6l-169.2 92.7v180.1l63.7-36.3z" fill="#1296db" p-id="7814"></path><path d="M402.2 433.5l109.1 61.8 18.2-10.9 91-50.9-91-51v-12.7l72.8-41.8V224.3l-91-52.8-90.9 52.8V328l72.7 41.8v12.7z" fill="#1296db" p-id="7815"></path></svg>

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 34 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34.000000" height="32.000000" fill="none" customFrame="#000000">
<g id="组合 6">
<path id="矢量 2" d="M33.6376 12.1729C33.0976 10.8747 32.0622 9.91164 31.2913 9.32996L20.4162 1.15565C18.3678 -0.385217 15.6118 -0.385217 13.5596 1.15565L2.68827 9.32996C1.92105 9.90779 0.893132 10.867 0.356826 12.1729C-0.209275 13.5519 -0.101269 14.985 0.67712 16.3178C1.20225 17.2192 2.23762 17.747 3.75716 17.8779C3.96572 17.8972 4.17056 17.9049 4.36423 17.9088L4.36423 25.7518C4.36423 29.1956 7.07555 32 10.4051 32L23.5781 32C26.9077 32 29.619 29.1956 29.619 25.7518L29.619 17.9434C29.7941 17.9434 29.9766 17.9396 30.1665 17.9242C31.1982 17.851 32.5762 17.5158 33.2913 16.3371C34.0994 15.0081 34.2186 13.5674 33.6376 12.1729L33.6376 12.1729ZM21.5856 22.4505C20.3491 23.5175 18.7179 24.1069 16.986 24.1069C15.2654 24.1069 13.6416 23.5252 12.4088 22.4697C11.9321 22.0614 11.8688 21.3333 12.2598 20.8441C12.6546 20.351 13.3585 20.2855 13.8315 20.69C14.6658 21.4027 15.7831 21.7956 16.9823 21.7956C18.189 21.7956 19.3138 21.3988 20.148 20.6785C20.621 20.2701 21.3249 20.3356 21.7234 20.8248C22.1219 21.3141 22.0586 22.0421 21.5856 22.4505Z" fill="rgba(125, 127, 129, 1)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 34 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34.000000" height="32.000000" fill="none" customFrame="#000000">
<g id="组合 6">
<path id="矢量 2" d="M33.6376 12.1729C33.0976 10.8747 32.0622 9.91164 31.2913 9.32996L20.4162 1.15565C18.3678 -0.385217 15.6118 -0.385217 13.5596 1.15565L2.68827 9.32996C1.92105 9.90779 0.893132 10.867 0.356826 12.1729C-0.209275 13.5519 -0.101269 14.985 0.67712 16.3178C1.20225 17.2192 2.23762 17.747 3.75716 17.8779C3.96572 17.8972 4.17056 17.9049 4.36423 17.9088L4.36423 25.7518C4.36423 29.1956 7.07555 32 10.4051 32L23.5781 32C26.9077 32 29.619 29.1956 29.619 25.7518L29.619 17.9434C29.7941 17.9434 29.9766 17.9396 30.1665 17.9242C31.1982 17.851 32.5762 17.5158 33.2913 16.3371C34.0994 15.0081 34.2186 13.5674 33.6376 12.1729L33.6376 12.1729ZM21.5856 22.4505C20.3491 23.5175 18.7179 24.1069 16.986 24.1069C15.2654 24.1069 13.6416 23.5252 12.4088 22.4697C11.9321 22.0614 11.8688 21.3333 12.2598 20.8441C12.6546 20.351 13.3585 20.2855 13.8315 20.69C14.6658 21.4027 15.7831 21.7956 16.9823 21.7956C18.189 21.7956 19.3138 21.3988 20.148 20.6785C20.621 20.2701 21.3249 20.3356 21.7234 20.8248C22.1219 21.3141 22.0586 22.0421 21.5856 22.4505Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 33 31" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="33.000000" height="31.000000" fill="none" customFrame="#000000">
<g id="组合 7">
<path id="矢量 3" d="M22.43 1.44478e-06C24.3598 1.44478e-06 26.1129 1.16653 26.8974 2.9807L30.1494 2.9807L30.3041 2.98449C31.7552 3.06781 32.9153 4.25706 32.9963 5.75309L33 5.91216L32.9963 6.26818C32.9079 12.8772 31.0444 16.6836 27.2509 17.1267C26.2455 21.7208 22.5846 25.031 18.2719 25.6863L18.2719 28.4852L22.7504 28.4852C23.4244 28.4852 23.9731 29.0495 23.9731 29.7426C23.9731 30.4357 23.4244 31 22.7504 31L10.5341 31C9.86008 31 9.31132 30.4357 9.31132 29.7426C9.31132 29.0495 9.86008 28.4852 10.5341 28.4852L15.8301 28.4852L15.8301 25.762C11.1381 25.3719 7.22678 21.9064 6.16241 17.1873C1.94175 17.0358 -0.0470348 13.0439 0.000843521 5.89322C0.0118925 4.34417 1.19412 3.07159 2.69676 2.98827L2.85144 2.98448L6.48282 2.98448C7.26729 1.1741 9.013 0.00378736 10.9392 0.00378736C10.9392 0 22.43 0 22.43 0L22.43 1.44478e-06ZM22.43 2.51485L10.9429 2.51485C9.65015 2.51863 8.5821 3.55639 8.50844 4.88577L8.50476 5.03348L8.52317 16.5548L8.57473 16.782C9.34447 19.9256 11.7678 22.3533 14.8394 23.0729L15.0751 23.126C19.4615 24.016 23.7264 21.2057 24.8128 16.8048L24.8681 16.5586L24.8681 5.0259C24.8681 3.69652 23.8589 2.59438 22.5699 2.51863L22.43 2.51485L22.43 2.51485ZM16.6993 7.54075C17.4506 7.54075 18.1172 7.98009 18.4119 8.66561L18.8833 9.69579L19.9403 9.84728C20.629 9.94576 21.1704 10.404 21.4356 11.0593L21.4871 11.2032C21.7339 11.9417 21.5387 12.7484 21.0157 13.2522L20.2386 14.0816L20.4338 15.2557C20.5259 15.9526 20.2939 16.6646 19.804 17.0812L19.6972 17.1646C19.1153 17.6418 18.3088 17.71 17.6606 17.3312L16.7288 16.8123L15.7823 17.3388C15.5318 17.4714 15.2887 17.5547 15.0236 17.5774L14.8615 17.585C14.4711 17.585 14.0844 17.4486 13.7309 17.1911C13.1416 16.7214 12.8543 15.9715 12.9979 15.2557L13.1858 14.1081L12.3792 13.2484C11.9225 12.7598 11.731 12.0591 11.8747 11.3509L11.9115 11.1994C12.1546 10.4684 12.7254 9.94954 13.4583 9.8435L14.5153 9.692L15.0015 8.63152C15.3145 8.0066 15.9001 7.59377 16.5594 7.54075L16.6993 7.54075L16.6993 7.54075ZM16.6993 9.21478C16.5962 9.22236 16.5041 9.28296 16.4599 9.37764L15.6128 11.2297L13.683 11.5062C13.5799 11.5213 13.4988 11.5971 13.4657 11.6955C13.4289 11.8319 13.462 11.9834 13.5541 12.0894L14.9315 13.5589L14.6 15.5701C14.5816 15.6723 14.6184 15.7784 14.6958 15.8465C14.7437 15.8844 14.8026 15.9071 14.8652 15.9109C14.9204 15.9071 14.9757 15.8882 15.0236 15.8579L16.7325 14.9035L18.4524 15.8617C18.5408 15.9147 18.6181 15.9071 18.7397 15.8125C18.7986 15.7708 18.8465 15.6382 18.8317 15.5057L18.5039 13.5249L19.8777 12.0553C19.9624 11.972 19.9919 11.8546 19.955 11.741C19.9035 11.5857 19.8261 11.5137 19.723 11.5024L17.7931 11.2259L16.9313 9.36249C16.8908 9.26781 16.8098 9.21478 16.6993 9.21478L16.6993 9.21478ZM6.06297 5.49554L2.85513 5.49554C2.63047 5.49554 2.45 5.68112 2.44632 5.91216C2.40581 11.7296 3.67274 14.4376 6.0777 14.6649L6.06297 5.49554L6.06297 5.49554ZM30.1494 5.49554L27.3172 5.49554L27.3172 14.5588C29.3686 14.0286 30.4882 11.4115 30.5545 6.24924L30.5582 5.91595L30.5508 5.8402C30.5214 5.66976 30.3888 5.53342 30.2231 5.50312L30.1494 5.49554L30.1494 5.49554Z" fill="rgb(125,127,129)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 33 31" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="33.000000" height="31.000000" fill="none" customFrame="#000000">
<g id="组合 7">
<path id="矢量 3" d="M22.43 1.44478e-06C24.3598 1.44478e-06 26.1129 1.16653 26.8974 2.9807L30.1494 2.9807L30.3041 2.98449C31.7552 3.06781 32.9153 4.25706 32.9963 5.75309L33 5.91216L32.9963 6.26818C32.9079 12.8772 31.0444 16.6836 27.2509 17.1267C26.2455 21.7208 22.5846 25.031 18.2719 25.6863L18.2719 28.4852L22.7504 28.4852C23.4244 28.4852 23.9731 29.0495 23.9731 29.7426C23.9731 30.4357 23.4244 31 22.7504 31L10.5341 31C9.86008 31 9.31132 30.4357 9.31132 29.7426C9.31132 29.0495 9.86008 28.4852 10.5341 28.4852L15.8301 28.4852L15.8301 25.762C11.1381 25.3719 7.22678 21.9064 6.16241 17.1873C1.94175 17.0358 -0.0470348 13.0439 0.000843521 5.89322C0.0118925 4.34417 1.19412 3.07159 2.69676 2.98827L2.85144 2.98448L6.48282 2.98448C7.26729 1.1741 9.013 0.00378736 10.9392 0.00378736C10.9392 0 22.43 0 22.43 0L22.43 1.44478e-06ZM22.43 2.51485L10.9429 2.51485C9.65015 2.51863 8.5821 3.55639 8.50844 4.88577L8.50476 5.03348L8.52317 16.5548L8.57473 16.782C9.34447 19.9256 11.7678 22.3533 14.8394 23.0729L15.0751 23.126C19.4615 24.016 23.7264 21.2057 24.8128 16.8048L24.8681 16.5586L24.8681 5.0259C24.8681 3.69652 23.8589 2.59438 22.5699 2.51863L22.43 2.51485L22.43 2.51485ZM16.6993 7.54075C17.4506 7.54075 18.1172 7.98009 18.4119 8.66561L18.8833 9.69579L19.9403 9.84728C20.629 9.94576 21.1704 10.404 21.4356 11.0593L21.4871 11.2032C21.7339 11.9417 21.5387 12.7484 21.0157 13.2522L20.2386 14.0816L20.4338 15.2557C20.5259 15.9526 20.2939 16.6646 19.804 17.0812L19.6972 17.1646C19.1153 17.6418 18.3088 17.71 17.6606 17.3312L16.7288 16.8123L15.7823 17.3388C15.5318 17.4714 15.2887 17.5547 15.0236 17.5774L14.8615 17.585C14.4711 17.585 14.0844 17.4486 13.7309 17.1911C13.1416 16.7214 12.8543 15.9715 12.9979 15.2557L13.1858 14.1081L12.3792 13.2484C11.9225 12.7598 11.731 12.0591 11.8747 11.3509L11.9115 11.1994C12.1546 10.4684 12.7254 9.94954 13.4583 9.8435L14.5153 9.692L15.0015 8.63152C15.3145 8.0066 15.9001 7.59377 16.5594 7.54075L16.6993 7.54075L16.6993 7.54075ZM16.6993 9.21478C16.5962 9.22236 16.5041 9.28296 16.4599 9.37764L15.6128 11.2297L13.683 11.5062C13.5799 11.5213 13.4988 11.5971 13.4657 11.6955C13.4289 11.8319 13.462 11.9834 13.5541 12.0894L14.9315 13.5589L14.6 15.5701C14.5816 15.6723 14.6184 15.7784 14.6958 15.8465C14.7437 15.8844 14.8026 15.9071 14.8652 15.9109C14.9204 15.9071 14.9757 15.8882 15.0236 15.8579L16.7325 14.9035L18.4524 15.8617C18.5408 15.9147 18.6181 15.9071 18.7397 15.8125C18.7986 15.7708 18.8465 15.6382 18.8317 15.5057L18.5039 13.5249L19.8777 12.0553C19.9624 11.972 19.9919 11.8546 19.955 11.741C19.9035 11.5857 19.8261 11.5137 19.723 11.5024L17.7931 11.2259L16.9313 9.36249C16.8908 9.26781 16.8098 9.21478 16.6993 9.21478L16.6993 9.21478ZM6.06297 5.49554L2.85513 5.49554C2.63047 5.49554 2.45 5.68112 2.44632 5.91216C2.40581 11.7296 3.67274 14.4376 6.0777 14.6649L6.06297 5.49554L6.06297 5.49554ZM30.1494 5.49554L27.3172 5.49554L27.3172 14.5588C29.3686 14.0286 30.4882 11.4115 30.5545 6.24924L30.5582 5.91595L30.5508 5.8402C30.5214 5.66976 30.3888 5.53342 30.2231 5.50312L30.1494 5.49554L30.1494 5.49554Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,6 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32.000000" height="32.000000" fill="none" customFrame="#000000">
<g id="组合 10">
<path id="矢量 6" d="M21.3008 3.19995C21.2793 3.31568 21.261 3.43191 21.2459 3.54864C21.2307 3.66537 21.2188 3.78243 21.2101 3.89982C21.2014 4.01721 21.1959 4.13474 21.1937 4.25243C21.1914 4.37012 21.1924 4.48778 21.1966 4.60541C21.2008 4.72304 21.2082 4.84047 21.2188 4.9577C21.2295 5.07493 21.2433 5.19177 21.2604 5.30824C21.2774 5.42471 21.2976 5.54062 21.321 5.65598C21.3444 5.77134 21.371 5.88597 21.4007 5.99987C21.4303 6.11377 21.4631 6.22678 21.499 6.33888C21.5349 6.45099 21.5738 6.56202 21.6158 6.67199C21.6578 6.78196 21.7028 6.8907 21.7507 6.9982C21.7986 7.1057 21.8495 7.21181 21.9032 7.31653C21.957 7.42124 22.0136 7.5244 22.073 7.62601C22.1324 7.72763 22.1946 7.82753 22.2595 7.92573C22.3244 8.02393 22.3919 8.12028 22.4621 8.21478C22.5323 8.30928 22.605 8.40178 22.6803 8.49229C22.7555 8.5828 22.8332 8.67118 22.9133 8.75742C22.9934 8.84367 23.0758 8.92766 23.1605 9.00939C23.2452 9.09112 23.3321 9.17046 23.4212 9.24743C23.5102 9.32439 23.6013 9.39885 23.6945 9.47082C23.7876 9.54279 23.8827 9.61214 23.9796 9.6789C24.0766 9.74565 24.1753 9.8097 24.2757 9.87104C24.3762 9.93238 24.4783 9.99092 24.582 10.0467C24.6856 10.1024 24.7908 10.1553 24.8973 10.2052C25.0039 10.2552 25.1118 10.3022 25.2209 10.3463C25.3301 10.3903 25.4403 10.4314 25.5517 10.4694C25.6631 10.5074 25.7755 10.5423 25.8888 10.5742C26.0021 10.606 26.1162 10.6348 26.2311 10.6603C26.346 10.6859 26.4615 10.7084 26.5777 10.7276C26.6938 10.7469 26.8103 10.7629 26.9273 10.7758C27.0444 10.7887 27.1616 10.7983 27.2792 10.8047C27.3967 10.8112 27.5143 10.8144 27.632 10.8144C28.024 10.8127 28.416 10.7743 28.8 10.7024L28.8 23.4576C28.8 28.8255 25.6336 31.9999 20.2592 31.9999L8.5536 31.9999C3.168 31.9999 0 28.8255 0 23.4575L0 11.7695C0 6.40315 3.1664 3.19995 8.5536 3.19995L21.3008 3.19995ZM21.4944 12.7903L21.3072 12.8031C21.1509 12.8256 21.0051 12.8777 20.8699 12.9593C20.7347 13.041 20.6207 13.1457 20.528 13.2736L16.672 18.2335L12.2832 14.7775C12.2211 14.7292 12.1549 14.6874 12.0845 14.6523C12.0141 14.6171 11.941 14.5893 11.865 14.5687C11.7891 14.5481 11.7118 14.5353 11.6333 14.5301C11.5548 14.5249 11.4766 14.5276 11.3986 14.538C11.3206 14.5484 11.2444 14.5664 11.17 14.592C11.0956 14.6177 11.0245 14.6504 10.9566 14.6902C10.8888 14.73 10.8255 14.7761 10.7668 14.8285C10.7081 14.8809 10.6552 14.9386 10.608 15.0015L5.8816 21.0975C5.70985 21.311 5.62505 21.5548 5.6272 21.8287L5.632 22.0047C5.64397 22.1274 5.6744 22.2453 5.72329 22.3585C5.77218 22.4716 5.83719 22.5745 5.91831 22.6673C5.99944 22.7601 6.09281 22.8383 6.19841 22.9018C6.30401 22.9654 6.4168 23.0113 6.53677 23.0395C6.65674 23.0677 6.77816 23.0769 6.90102 23.0671C7.02388 23.0573 7.1423 23.029 7.25629 22.9821C7.37027 22.9353 7.47437 22.8721 7.56858 22.7926C7.66278 22.7132 7.74259 22.6212 7.808 22.5167L11.7616 17.4031L16.152 20.8447C16.2138 20.8945 16.2799 20.9376 16.3504 20.9741C16.4208 21.0105 16.4942 21.0396 16.5705 21.0613C16.6468 21.083 16.7246 21.0969 16.8037 21.103C16.8828 21.1091 16.9617 21.1072 17.0404 21.0975C17.1191 21.0877 17.1961 21.0702 17.2713 21.0449C17.3465 21.0197 17.4185 20.9872 17.4871 20.9475C17.5558 20.9078 17.6199 20.8616 17.6793 20.8091C17.7387 20.7565 17.7923 20.6985 17.84 20.6351L22.4128 14.7343L22.4128 14.7039C22.4595 14.6414 22.4997 14.5749 22.5335 14.5045C22.5673 14.4341 22.594 14.3611 22.6136 14.2855C22.6332 14.21 22.6454 14.1332 22.6501 14.0553C22.6548 13.9773 22.652 13.8997 22.6416 13.8223C22.6313 13.7449 22.6136 13.6692 22.5885 13.5953C22.5634 13.5213 22.5315 13.4505 22.4927 13.3827C22.4539 13.315 22.4089 13.2516 22.3578 13.1926C22.3067 13.1336 22.2503 13.08 22.1888 13.0319C22.0635 12.9355 21.9244 12.8672 21.7714 12.8272C21.6184 12.7872 21.4637 12.7787 21.3072 12.8015L21.4944 12.7903Z" fill="rgb(125,127,129)" fill-rule="nonzero" />
<path id="矢量 7" d="M24 4C24 4.131 24.0064 4.26169 24.0193 4.39207C24.0321 4.52244 24.0513 4.65187 24.0769 4.78036C24.1024 4.90885 24.1342 5.03577 24.1722 5.16114C24.2103 5.2865 24.2543 5.4097 24.3045 5.53073C24.3546 5.65176 24.4106 5.77005 24.4723 5.88558C24.5341 6.00112 24.6013 6.11335 24.6741 6.22228C24.7469 6.33121 24.8249 6.4363 24.908 6.53757C24.9911 6.63884 25.0789 6.73579 25.1716 6.82843C25.2642 6.92106 25.3612 7.00893 25.4624 7.09204C25.5637 7.17515 25.6688 7.25309 25.7777 7.32588C25.8866 7.39866 25.9989 7.46593 26.1144 7.52768C26.2299 7.58944 26.3482 7.64538 26.4693 7.69552C26.5903 7.74565 26.7135 7.78973 26.8389 7.82776C26.9642 7.86579 27.0912 7.89758 27.2196 7.92314C27.3481 7.9487 27.4776 7.9679 27.6079 7.98074C27.7383 7.99358 27.869 8 28 8C28.131 8 28.2617 7.99358 28.3921 7.98074C28.5224 7.9679 28.6519 7.9487 28.7804 7.92314C28.9089 7.89758 29.0358 7.86579 29.1611 7.82776C29.2865 7.78973 29.4097 7.74565 29.5307 7.69552C29.6518 7.64538 29.7701 7.58944 29.8856 7.52768C30.0011 7.46593 30.1134 7.39866 30.2223 7.32588C30.3312 7.25309 30.4363 7.17515 30.5376 7.09204C30.6388 7.00893 30.7358 6.92106 30.8284 6.82843C30.9211 6.73579 31.0089 6.63884 31.092 6.53757C31.1752 6.4363 31.2531 6.33121 31.3259 6.22228C31.3987 6.11335 31.4659 6.00112 31.5277 5.88558C31.5894 5.77005 31.6454 5.65176 31.6955 5.53073C31.7457 5.4097 31.7897 5.2865 31.8278 5.16114C31.8658 5.03577 31.8976 4.90885 31.9231 4.78036C31.9487 4.65187 31.9679 4.52244 31.9807 4.39207C31.9936 4.26169 32 4.131 32 4C32 3.86899 31.9936 3.7383 31.9807 3.60793C31.9679 3.47756 31.9487 3.34813 31.9231 3.21964C31.8976 3.09115 31.8658 2.96422 31.8278 2.83886C31.7897 2.7135 31.7457 2.5903 31.6955 2.46927C31.6454 2.34823 31.5894 2.22995 31.5277 2.11441C31.4659 1.99888 31.3987 1.88665 31.3259 1.77772C31.2531 1.66879 31.1752 1.56369 31.092 1.46243C31.0089 1.36116 30.9211 1.26421 30.8284 1.17157C30.7358 1.07894 30.6388 0.991067 30.5376 0.907958C30.4363 0.824849 30.3312 0.746904 30.2223 0.674121C30.1134 0.601339 30.0011 0.53407 29.8856 0.472315C29.7701 0.410559 29.6518 0.354615 29.5307 0.304482C29.4097 0.254348 29.2865 0.210267 29.1611 0.172239C29.0358 0.13421 28.9089 0.102417 28.7804 0.0768588C28.6519 0.0513011 28.5224 0.0321018 28.3921 0.0192611C28.2617 0.00642036 28.131 0 28 0C27.869 0 27.7383 0.00642036 27.6079 0.0192611C27.4776 0.0321018 27.3481 0.0513011 27.2196 0.0768588C27.0912 0.102417 26.9642 0.13421 26.8389 0.172239C26.7135 0.210267 26.5903 0.254348 26.4693 0.304482C26.3482 0.354615 26.2299 0.410559 26.1144 0.472315C25.9989 0.53407 25.8866 0.601339 25.7777 0.674121C25.6688 0.746904 25.5637 0.824849 25.4624 0.907958C25.3612 0.991067 25.2642 1.07894 25.1716 1.17157C25.0789 1.26421 24.9911 1.36116 24.908 1.46243C24.8249 1.56369 24.7469 1.66879 24.6741 1.77772C24.6013 1.88665 24.5341 1.99888 24.4723 2.11441C24.4106 2.22995 24.3546 2.34823 24.3045 2.46927C24.2543 2.5903 24.2103 2.7135 24.1722 2.83886C24.1342 2.96422 24.1024 3.09115 24.0769 3.21964C24.0513 3.34813 24.0321 3.47756 24.0193 3.60793C24.0064 3.7383 24 3.86899 24 4Z" fill="rgb(125,127,129)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,6 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32.000000" height="32.000000" fill="none" customFrame="#000000">
<g id="组合 10">
<path id="矢量 6" d="M21.3008 3.19995C21.2793 3.31568 21.261 3.43191 21.2459 3.54864C21.2307 3.66537 21.2188 3.78243 21.2101 3.89982C21.2014 4.01721 21.1959 4.13474 21.1937 4.25243C21.1914 4.37012 21.1924 4.48778 21.1966 4.60541C21.2008 4.72304 21.2082 4.84047 21.2188 4.9577C21.2295 5.07493 21.2433 5.19177 21.2604 5.30824C21.2774 5.42471 21.2976 5.54062 21.321 5.65598C21.3444 5.77134 21.371 5.88597 21.4007 5.99987C21.4303 6.11377 21.4631 6.22678 21.499 6.33888C21.5349 6.45099 21.5738 6.56202 21.6158 6.67199C21.6578 6.78196 21.7028 6.8907 21.7507 6.9982C21.7986 7.1057 21.8495 7.21181 21.9032 7.31653C21.957 7.42124 22.0136 7.5244 22.073 7.62601C22.1324 7.72763 22.1946 7.82753 22.2595 7.92573C22.3244 8.02393 22.3919 8.12028 22.4621 8.21478C22.5323 8.30928 22.605 8.40178 22.6803 8.49229C22.7555 8.5828 22.8332 8.67118 22.9133 8.75742C22.9934 8.84367 23.0758 8.92766 23.1605 9.00939C23.2452 9.09112 23.3321 9.17046 23.4212 9.24743C23.5102 9.32439 23.6013 9.39885 23.6945 9.47082C23.7876 9.54279 23.8827 9.61214 23.9796 9.6789C24.0766 9.74565 24.1753 9.8097 24.2757 9.87104C24.3762 9.93238 24.4783 9.99092 24.582 10.0467C24.6856 10.1024 24.7908 10.1553 24.8973 10.2052C25.0039 10.2552 25.1118 10.3022 25.2209 10.3463C25.3301 10.3903 25.4403 10.4314 25.5517 10.4694C25.6631 10.5074 25.7755 10.5423 25.8888 10.5742C26.0021 10.606 26.1162 10.6348 26.2311 10.6603C26.346 10.6859 26.4615 10.7084 26.5777 10.7276C26.6938 10.7469 26.8103 10.7629 26.9273 10.7758C27.0444 10.7887 27.1616 10.7983 27.2792 10.8047C27.3967 10.8112 27.5143 10.8144 27.632 10.8144C28.024 10.8127 28.416 10.7743 28.8 10.7024L28.8 23.4576C28.8 28.8255 25.6336 31.9999 20.2592 31.9999L8.5536 31.9999C3.168 31.9999 0 28.8255 0 23.4575L0 11.7695C0 6.40315 3.1664 3.19995 8.5536 3.19995L21.3008 3.19995ZM21.4944 12.7903L21.3072 12.8031C21.1509 12.8256 21.0051 12.8777 20.8699 12.9593C20.7347 13.041 20.6207 13.1457 20.528 13.2736L16.672 18.2335L12.2832 14.7775C12.2211 14.7292 12.1549 14.6874 12.0845 14.6523C12.0141 14.6171 11.941 14.5893 11.865 14.5687C11.7891 14.5481 11.7118 14.5353 11.6333 14.5301C11.5548 14.5249 11.4766 14.5276 11.3986 14.538C11.3206 14.5484 11.2444 14.5664 11.17 14.592C11.0956 14.6177 11.0245 14.6504 10.9566 14.6902C10.8888 14.73 10.8255 14.7761 10.7668 14.8285C10.7081 14.8809 10.6552 14.9386 10.608 15.0015L5.8816 21.0975C5.70985 21.311 5.62505 21.5548 5.6272 21.8287L5.632 22.0047C5.64397 22.1274 5.6744 22.2453 5.72329 22.3585C5.77218 22.4716 5.83719 22.5745 5.91831 22.6673C5.99944 22.7601 6.09281 22.8383 6.19841 22.9018C6.30401 22.9654 6.4168 23.0113 6.53677 23.0395C6.65674 23.0677 6.77816 23.0769 6.90102 23.0671C7.02388 23.0573 7.1423 23.029 7.25629 22.9821C7.37027 22.9353 7.47437 22.8721 7.56858 22.7926C7.66278 22.7132 7.74259 22.6212 7.808 22.5167L11.7616 17.4031L16.152 20.8447C16.2138 20.8945 16.2799 20.9376 16.3504 20.9741C16.4208 21.0105 16.4942 21.0396 16.5705 21.0613C16.6468 21.083 16.7246 21.0969 16.8037 21.103C16.8828 21.1091 16.9617 21.1072 17.0404 21.0975C17.1191 21.0877 17.1961 21.0702 17.2713 21.0449C17.3465 21.0197 17.4185 20.9872 17.4871 20.9475C17.5558 20.9078 17.6199 20.8616 17.6793 20.8091C17.7387 20.7565 17.7923 20.6985 17.84 20.6351L22.4128 14.7343L22.4128 14.7039C22.4595 14.6414 22.4997 14.5749 22.5335 14.5045C22.5673 14.4341 22.594 14.3611 22.6136 14.2855C22.6332 14.21 22.6454 14.1332 22.6501 14.0553C22.6548 13.9773 22.652 13.8997 22.6416 13.8223C22.6313 13.7449 22.6136 13.6692 22.5885 13.5953C22.5634 13.5213 22.5315 13.4505 22.4927 13.3827C22.4539 13.315 22.4089 13.2516 22.3578 13.1926C22.3067 13.1336 22.2503 13.08 22.1888 13.0319C22.0635 12.9355 21.9244 12.8672 21.7714 12.8272C21.6184 12.7872 21.4637 12.7787 21.3072 12.8015L21.4944 12.7903Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 7" d="M24 4C24 4.131 24.0064 4.26169 24.0193 4.39207C24.0321 4.52244 24.0513 4.65187 24.0769 4.78036C24.1024 4.90885 24.1342 5.03577 24.1722 5.16114C24.2103 5.2865 24.2543 5.4097 24.3045 5.53073C24.3546 5.65176 24.4106 5.77005 24.4723 5.88558C24.5341 6.00112 24.6013 6.11335 24.6741 6.22228C24.7469 6.33121 24.8249 6.4363 24.908 6.53757C24.9911 6.63884 25.0789 6.73579 25.1716 6.82843C25.2642 6.92106 25.3612 7.00893 25.4624 7.09204C25.5637 7.17515 25.6688 7.25309 25.7777 7.32588C25.8866 7.39866 25.9989 7.46593 26.1144 7.52768C26.2299 7.58944 26.3482 7.64538 26.4693 7.69552C26.5903 7.74565 26.7135 7.78973 26.8389 7.82776C26.9642 7.86579 27.0912 7.89758 27.2196 7.92314C27.3481 7.9487 27.4776 7.9679 27.6079 7.98074C27.7383 7.99358 27.869 8 28 8C28.131 8 28.2617 7.99358 28.3921 7.98074C28.5224 7.9679 28.6519 7.9487 28.7804 7.92314C28.9089 7.89758 29.0358 7.86579 29.1611 7.82776C29.2865 7.78973 29.4097 7.74565 29.5307 7.69552C29.6518 7.64538 29.7701 7.58944 29.8856 7.52768C30.0011 7.46593 30.1134 7.39866 30.2223 7.32588C30.3312 7.25309 30.4363 7.17515 30.5376 7.09204C30.6388 7.00893 30.7358 6.92106 30.8284 6.82843C30.9211 6.73579 31.0089 6.63884 31.092 6.53757C31.1752 6.4363 31.2531 6.33121 31.3259 6.22228C31.3987 6.11335 31.4659 6.00112 31.5277 5.88558C31.5894 5.77005 31.6454 5.65176 31.6955 5.53073C31.7457 5.4097 31.7897 5.2865 31.8278 5.16114C31.8658 5.03577 31.8976 4.90885 31.9231 4.78036C31.9487 4.65187 31.9679 4.52244 31.9807 4.39207C31.9936 4.26169 32 4.131 32 4C32 3.86899 31.9936 3.7383 31.9807 3.60793C31.9679 3.47756 31.9487 3.34813 31.9231 3.21964C31.8976 3.09115 31.8658 2.96422 31.8278 2.83886C31.7897 2.7135 31.7457 2.5903 31.6955 2.46927C31.6454 2.34823 31.5894 2.22995 31.5277 2.11441C31.4659 1.99888 31.3987 1.88665 31.3259 1.77772C31.2531 1.66879 31.1752 1.56369 31.092 1.46243C31.0089 1.36116 30.9211 1.26421 30.8284 1.17157C30.7358 1.07894 30.6388 0.991067 30.5376 0.907958C30.4363 0.824849 30.3312 0.746904 30.2223 0.674121C30.1134 0.601339 30.0011 0.53407 29.8856 0.472315C29.7701 0.410559 29.6518 0.354615 29.5307 0.304482C29.4097 0.254348 29.2865 0.210267 29.1611 0.172239C29.0358 0.13421 28.9089 0.102417 28.7804 0.0768588C28.6519 0.0513011 28.5224 0.0321018 28.3921 0.0192611C28.2617 0.00642036 28.131 0 28 0C27.869 0 27.7383 0.00642036 27.6079 0.0192611C27.4776 0.0321018 27.3481 0.0513011 27.2196 0.0768588C27.0912 0.102417 26.9642 0.13421 26.8389 0.172239C26.7135 0.210267 26.5903 0.254348 26.4693 0.304482C26.3482 0.354615 26.2299 0.410559 26.1144 0.472315C25.9989 0.53407 25.8866 0.601339 25.7777 0.674121C25.6688 0.746904 25.5637 0.824849 25.4624 0.907958C25.3612 0.991067 25.2642 1.07894 25.1716 1.17157C25.0789 1.26421 24.9911 1.36116 24.908 1.46243C24.8249 1.56369 24.7469 1.66879 24.6741 1.77772C24.6013 1.88665 24.5341 1.99888 24.4723 2.11441C24.4106 2.22995 24.3546 2.34823 24.3045 2.46927C24.2543 2.5903 24.2103 2.7135 24.1722 2.83886C24.1342 2.96422 24.1024 3.09115 24.0769 3.21964C24.0513 3.34813 24.0321 3.47756 24.0193 3.60793C24.0064 3.7383 24 3.86899 24 4Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,3 @@
<svg viewBox="0 0 65 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="65.000000" height="64.000000" fill="none" customFrame="#000000">
<path id="矢量 53" d="M28.414 37.709L28.7398 37.8194L29.0111 34.3554C29.0111 34.3554 27.6723 35.2355 26.6232 36.1695C27.7084 36.8298 28.414 37.709 28.414 37.709ZM36.3555 17.1854C36.7805 16.377 36.365 15.8579 35.6229 15.7416C35.4428 16.3616 35.2627 16.981 35.0831 17.6005C35.3636 17.6084 35.6417 17.6181 35.9161 17.6307C36.0872 17.5351 36.2373 17.3866 36.3555 17.1854ZM32.5 0C14.5507 0 0 14.3268 0 32C0 49.673 14.5508 64 32.5 64C50.4491 64 65 49.673 65 32C64.9998 14.3267 50.4491 0 32.5 0ZM26.1686 16.0343C26.817 14.2698 28.5399 13.8174 30.6398 13.8088C30.4077 14.5715 30.1746 15.3345 29.9417 16.0973C28.5678 15.8506 28.1141 17.2746 29.0891 17.8153C29.3231 17.7945 29.5604 17.7753 29.7998 17.7568L31.9331 11.3055L34.5558 11.1725L34.1983 12.0959L32.6481 12.2462L30.7429 17.6912C30.8422 17.685 30.9412 17.6787 31.0413 17.6729L32.8492 12.4621L35.4495 12.34L35.0856 13.339L33.4855 13.4144L32.0487 17.6224C32.1447 17.6183 32.2399 17.6138 32.3368 17.6101L33.6747 13.6472L36.5778 13.5299C38.5093 13.8963 39.5396 16.182 38.7289 17.8492C48.3578 18.9089 53.4342 22.7555 53.4342 22.7555C53.4342 22.7555 46.5929 20.1611 34.1649 19.7649L33.1432 22.3482L30.7239 22.3874L31.6248 19.7191C31.5271 19.719 31.4298 19.7191 31.3327 19.7195L30.913 20.9488L29.8892 20.9938L30.3273 19.7311C30.227 19.7331 30.1267 19.735 30.027 19.7373L30.0191 19.7598L29.1197 19.8134L29.1358 19.7649C29.0159 19.7694 28.8968 19.7744 28.7778 19.7796L28.7773 19.7812C28.7753 19.7808 28.7734 19.7802 28.7713 19.7799C18.9205 20.208 12.2957 22.7555 12.2957 22.7555C12.2957 22.7555 16.4311 19.4819 26.2946 18.1296C25.9424 17.524 25.8484 16.8029 26.1686 16.0343ZM52.1853 45.6806C49.8224 48.2598 45.338 50.5487 42.2572 51.5406C38.3322 52.8049 35.3067 52.8273 35.3067 52.8273L37.6401 40.6231L36.5 39.4137L35.0891 46.3957L26.7315 46.3957C26.7315 46.3957 25.4023 48.2232 21.6347 49.1304C19.1078 49.8072 15.4474 50.1921 11.264 48.4843C10.4294 48.0384 9.80655 47.4829 9.34453 46.8774C7.43412 44.3711 8.27905 41.0082 8.27905 41.0082C8.27905 41.0082 12.8742 40.9712 14.9001 41.0082C14.4747 42.7925 15.0352 43.9666 16.2027 44.4711C18.2617 44.9328 20.9247 44.026 21.5755 42.4372C23.4029 38.4788 18.5906 36.5543 18.5906 36.5543C25.4472 33.9525 23.855 30.8003 23.0409 30.1772C19.3684 27.8867 17.7765 32.1564 17.7765 32.1564L10.9383 32.1564C11.5716 28.4546 15.4249 24.6796 22.0098 24.6796C28.5951 24.6065 30.5301 28.0882 30.5301 28.0882L31.5615 23.5251L43.4473 23.5251C49.7056 23.4706 52.9062 28.196 52.9439 28.2519C51.5959 28.6141 50.6019 29.8575 50.6019 31.3366C50.6019 33.0992 52.0138 34.5283 53.7546 34.5283C54.3755 34.5283 54.9539 34.3457 55.4419 34.032C55.4656 34.2591 56.1715 41.2999 52.1853 45.6806ZM42.7456 28.9709C39.1791 28.9709 36.2878 31.9014 36.2878 35.5171C36.2878 39.1328 39.179 42.0633 42.7456 42.0633C46.3121 42.0633 49.2034 39.1328 49.2034 35.5171C49.2034 31.9013 46.3121 28.9709 42.7456 28.9709Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 65 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="65.000000" height="64.000000" fill="none" customFrame="#000000">
<g id="组合 20">
<path id="矢量 53" d="M28.414 37.709L28.7398 37.8194L29.0111 34.3554C29.0111 34.3554 27.6723 35.2355 26.6232 36.1695C27.7084 36.8298 28.414 37.709 28.414 37.709ZM36.3555 17.1854C36.7805 16.377 36.365 15.8579 35.6229 15.7416C35.4428 16.3616 35.2627 16.981 35.0831 17.6005C35.3636 17.6084 35.6417 17.6181 35.9161 17.6307C36.0872 17.5351 36.2373 17.3866 36.3555 17.1854ZM32.5 0C14.5507 0 0 14.3268 0 32C0 49.673 14.5508 64 32.5 64C50.4491 64 65 49.673 65 32C64.9998 14.3267 50.4491 0 32.5 0ZM26.1686 16.0343C26.817 14.2698 28.5399 13.8174 30.6398 13.8088C30.4077 14.5715 30.1746 15.3345 29.9417 16.0973C28.5678 15.8506 28.1141 17.2746 29.0891 17.8153C29.3231 17.7945 29.5604 17.7753 29.7998 17.7568L31.9331 11.3055L34.5558 11.1725L34.1983 12.0959L32.6481 12.2462L30.7429 17.6912C30.8422 17.685 30.9412 17.6787 31.0413 17.6729L32.8492 12.4621L35.4495 12.34L35.0856 13.339L33.4855 13.4144L32.0487 17.6224C32.1447 17.6183 32.2399 17.6138 32.3368 17.6101L33.6747 13.6472L36.5778 13.5299C38.5093 13.8963 39.5396 16.182 38.7289 17.8492C48.3578 18.9089 53.4342 22.7555 53.4342 22.7555C53.4342 22.7555 46.5929 20.1611 34.1649 19.7649L33.1432 22.3482L30.7239 22.3874L31.6248 19.7191C31.5271 19.719 31.4298 19.7191 31.3327 19.7195L30.913 20.9488L29.8892 20.9938L30.3273 19.7311C30.227 19.7331 30.1267 19.735 30.027 19.7373L30.0191 19.7598L29.1197 19.8134L29.1358 19.7649C29.0159 19.7694 28.8968 19.7744 28.7778 19.7796L28.7773 19.7812C28.7753 19.7808 28.7734 19.7802 28.7713 19.7799C18.9205 20.208 12.2957 22.7555 12.2957 22.7555C12.2957 22.7555 16.4311 19.4819 26.2946 18.1296C25.9424 17.524 25.8484 16.8029 26.1686 16.0343ZM52.1853 45.6806C49.8224 48.2598 45.338 50.5487 42.2572 51.5406C38.3322 52.8049 35.3067 52.8273 35.3067 52.8273L37.6401 40.6231L36.5 39.4137L35.0891 46.3957L26.7315 46.3957C26.7315 46.3957 25.4023 48.2232 21.6347 49.1304C19.1078 49.8072 15.4474 50.1921 11.264 48.4843C10.4294 48.0384 9.80655 47.4829 9.34453 46.8774C7.43412 44.3711 8.27905 41.0082 8.27905 41.0082C8.27905 41.0082 12.8742 40.9712 14.9001 41.0082C14.4747 42.7925 15.0352 43.9666 16.2027 44.4711C18.2617 44.9328 20.9247 44.026 21.5755 42.4372C23.4029 38.4788 18.5906 36.5543 18.5906 36.5543C25.4472 33.9525 23.855 30.8003 23.0409 30.1772C19.3684 27.8867 17.7765 32.1564 17.7765 32.1564L10.9383 32.1564C11.5716 28.4546 15.4249 24.6796 22.0098 24.6796C28.5951 24.6065 30.5301 28.0882 30.5301 28.0882L31.5615 23.5251L43.4473 23.5251C49.7056 23.4706 52.9062 28.196 52.9439 28.2519C51.5959 28.6141 50.6019 29.8575 50.6019 31.3366C50.6019 33.0992 52.0138 34.5283 53.7546 34.5283C54.3755 34.5283 54.9539 34.3457 55.4419 34.032C55.4656 34.2591 56.1715 41.2999 52.1853 45.6806ZM42.7456 28.9709C39.1791 28.9709 36.2878 31.9014 36.2878 35.5171C36.2878 39.1328 39.179 42.0633 42.7456 42.0633C46.3121 42.0633 49.2034 39.1328 49.2034 35.5171C49.2034 31.9013 46.3121 28.9709 42.7456 28.9709Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,3 @@
<svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="64.000000" fill="none" customFrame="#000000">
<path id="矢量 52" d="M32.0001 0C14.327 0 0 14.3269 0 32C0 49.6731 14.327 64 32.0001 64C49.6731 64 64 49.6731 64 32C63.9999 14.3269 49.6731 0 32.0001 0ZM52.9746 16.5337C52.6756 17.2649 52.3764 17.9962 52.0773 18.7274C51.1994 19.7145 47.1946 19.5488 45.4964 19.874C42.1244 20.5198 39.9534 21.2417 39.4142 24.71C39.4973 24.71 39.5803 24.71 39.6634 24.71C40.5607 24.5936 41.4583 24.4773 42.3556 24.3609C42.6713 23.2643 42.987 22.1672 43.3027 21.0705C44.6488 20.8046 45.9951 20.5387 47.341 20.2728C47.0586 21.4194 46.7759 22.5663 46.4935 23.7128C48.205 23.4469 49.917 23.181 51.6285 22.9151C51.6285 22.9318 51.6285 22.9484 51.6285 22.965C51.3294 23.7791 51.0302 24.5936 50.731 25.4079C49.0694 25.6571 47.4073 25.9064 45.7456 26.1557C45.4466 27.2357 45.1474 28.3162 44.8483 29.3962C44.0136 32.1402 43.3776 34.6959 39.4141 33.4843C38.8158 33.2517 38.2175 33.019 37.6193 32.7863C36.2625 33.7702 34.5113 34.7079 32.1353 34.3817C32.667 32.8532 33.1988 31.3239 33.7306 29.7951C34.8589 30.0452 35.0517 30.2694 36.3231 29.9945C35.7405 27.7268 38.2097 26.4735 39.5138 27.9504C40.4855 29.0511 39.3013 30.3223 39.2147 31.1412C39.3808 31.1578 39.5471 31.1744 39.7133 31.1911C40.8362 30.4825 41.3541 28.2227 41.6077 26.7041C39.2149 27.0696 36.8214 27.4353 34.4287 27.8009C34.7776 27.0199 35.1266 26.2386 35.4756 25.4577C36.6667 22.7403 37.6389 20.0061 40.3614 18.827C44.2905 17.1253 50.4798 17.3788 53.6227 14.9383C53.7043 15.3733 53.1544 16.1221 52.9746 16.5337ZM12.2433 51.831C12.8581 49.7041 13.4731 47.5765 14.0879 45.4496C14.9643 42.9914 16.2414 40.7002 17.3783 38.4699C18.3255 36.6255 19.2729 34.7805 20.22 32.936C22.0178 30.1368 24.3002 27.551 26.3522 24.9592C27.753 23.1899 29.6255 21.7209 30.8889 19.8242C29.4233 20.7224 28.614 20.7901 26.4519 21.1204C25.6875 21.1537 24.9229 21.1869 24.1586 21.2201C20.5085 22.0271 18.6903 23.9875 17.7772 27.5018C16.1154 27.7677 14.4533 28.0337 12.7917 28.2996C12.7917 28.2829 12.7917 28.2663 12.7917 28.2497C13.8385 24.8931 14.8857 21.5355 15.9325 18.179C17.1954 18.046 18.4586 17.9131 19.7215 17.7802C19.7048 18.0958 19.6883 18.4117 19.6716 18.7274C23.2753 17.1819 26.3396 15.3956 30.6397 14.4897C34.6711 13.6404 36.9813 15.362 39.0154 12.0967C39.6965 12.0302 40.3781 11.9637 41.0593 11.8972C41.1591 11.8972 41.2588 11.8972 41.3584 11.8972C40.6273 13.3761 39.896 14.8554 39.1649 16.3343C37.1111 19.6083 34.4669 22.4572 32.4345 25.8067C31.7864 27.1693 31.1381 28.5322 30.4901 29.8948C29.3875 32.3979 28.1812 35.1502 27.2994 37.8716C26.0723 41.6581 25.5411 45.7513 24.9562 50.1358C20.7191 50.7008 16.4805 51.2659 12.2433 51.831ZM51.8779 29.6954C51.8613 30.0278 51.8447 30.3602 51.8281 30.6925C51.6999 31.2623 51.3984 31.8354 51.0802 32.238C50.7226 32.6904 50.0475 33.1024 49.435 33.2849C49.1473 33.3708 48.8253 33.3116 48.6374 33.4844C47.9728 34.4149 47.3079 35.3457 46.6432 36.2762C46.8208 36.9667 48.2596 36.454 48.9365 36.5755C49.0362 36.6752 49.136 36.7749 49.2356 36.8745C49.231 37.7456 47.2299 39.8666 46.6432 40.3145C46.7096 40.4142 46.7761 40.5139 46.8426 40.6136C47.7022 40.6727 48.5893 40.4561 49.136 40.8629C49.1692 41.029 49.2024 41.1953 49.2357 41.3614C48.7377 42.4138 47.9815 43.2446 47.3411 44.1532C46.7429 45.1835 46.1446 46.2141 45.5464 47.2443C43.4115 47.5439 39.586 48.9108 38.0183 47.6929C37.0812 46.965 37.4636 46.3714 37.0212 45.2002C36.6888 46.3467 36.3565 47.4936 36.0241 48.6402C34.7115 48.8728 33.3982 49.1055 32.0855 49.3381C32.0855 49.3215 32.0855 49.3049 32.0855 49.2882C32.2683 48.6236 32.4512 47.9588 32.634 47.2941C31.0259 48.3239 29.7203 49.573 27.2995 49.8367C27.2995 49.8201 27.2995 49.8035 27.2995 49.7868C27.7813 48.4243 28.2634 47.0613 28.7453 45.6988C29.6405 46.2284 31.96 44.4924 32.4843 43.9039C31.3212 44.1532 30.1577 44.4027 28.9945 44.6518C28.9945 44.6353 28.9945 44.6187 28.9945 44.602C29.277 43.7878 29.5596 42.9734 29.842 42.1592C31.4206 41.7936 32.9997 41.4279 34.5782 41.0622C34.6281 40.8463 34.6779 40.6303 34.7278 40.4142C33.9081 40.596 31.304 42.219 30.6895 40.9127C30.4339 40.3577 30.9324 39.181 31.0883 38.5696C32.0687 38.3868 33.0494 38.204 34.0298 38.0213C34.0089 38.3017 33.8318 38.724 33.9799 38.8189C34.1881 38.9909 34.5815 39.1996 34.8275 39.1679C35.0934 38.553 35.3593 37.938 35.6251 37.3233C35.6251 37.3067 35.6251 37.2901 35.6251 37.2734C34.0798 37.5559 32.534 37.8385 30.9887 38.121C30.9887 38.1044 30.9887 38.0879 30.9887 38.0711C31.2712 37.2902 31.5537 36.509 31.8362 35.7281C36.0567 34.9471 40.2788 34.1658 44.4993 33.385C44.1565 35.5486 41.8755 36.0733 39.6634 36.3762C39.5969 36.5423 39.5304 36.7086 39.464 36.8748C41.0174 36.4914 42.4357 35.5478 43.3526 37.2238C43.4213 35.6801 46.104 34.1256 46.9421 33.0359C46.9421 33.0193 46.9421 33.0027 46.9421 32.9862C44.4804 32.0537 44.7826 28.3599 46.7926 27.1531C48.6 26.0681 51.2712 27.1687 51.6285 28.8981C52.5425 28.3165 53.4567 27.7347 54.3706 27.1531C53.5398 28.0003 52.7087 28.848 51.8779 29.6954Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1,7 @@
<svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="64.000000" fill="none" customFrame="#000000">
<g id="组合 19">
<path id="矢量 50" d="M38.0183 28.4988C37.8854 28.4822 37.7524 28.4656 37.6194 28.449C37.2422 28.7113 36.6771 29.3268 37.0212 30.0942C37.6132 29.8404 38.2761 29.551 38.1678 28.748C38.118 28.6651 38.0681 28.582 38.0183 28.4988Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 51" d="M43.253 41.5609C43.2198 41.3449 43.1865 41.1289 43.1534 40.9127C43.8655 40.3423 45.3483 38.6984 45.7457 37.8716C45.7291 37.8385 45.7125 37.8051 45.696 37.7719C44.8483 37.9193 44.0981 38.0624 43.4525 37.6223C43.4026 37.506 43.3527 37.3896 43.3028 37.2733C43.2986 38.0187 42.9553 38.3395 42.7545 38.8688C41.7077 39.1013 40.6605 39.334 39.6136 39.5666C39.6967 39.2344 39.7798 38.9019 39.8629 38.5696C39.6469 38.5031 39.4308 38.4366 39.2148 38.3702C38.9324 39.0182 38.6498 39.6664 38.3673 40.3145C39.9624 39.9987 41.5581 39.683 43.1534 39.3672C42.4227 41.8907 40.4358 42.2557 37.769 42.8072C37.6195 43.3224 37.4699 43.8376 37.3203 44.3528C37.3369 44.3528 37.3535 44.3528 37.3701 44.3528C37.3701 44.3195 37.3701 44.2862 37.3701 44.2531C39.4835 42.1773 41.0645 42.4143 42.4054 45.0507C42.6713 44.7848 42.9373 44.5188 43.2031 44.2531C44.0671 43.4554 44.9315 42.6576 45.7955 41.8599C45.7955 41.8101 45.7955 41.7602 45.7955 41.7103C45.7623 41.6773 45.729 41.6439 45.6958 41.6107C44.6542 41.6318 44.0192 42.0217 43.253 41.5609Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 52" d="M32.0001 0C14.327 0 0 14.3269 0 32C0 49.6731 14.327 64 32.0001 64C49.6731 64 64 49.6731 64 32C63.9999 14.3269 49.6731 0 32.0001 0ZM52.9746 16.5337C52.6756 17.2649 52.3764 17.9962 52.0773 18.7274C51.1994 19.7145 47.1946 19.5488 45.4964 19.874C42.1244 20.5198 39.9534 21.2417 39.4142 24.71C39.4973 24.71 39.5803 24.71 39.6634 24.71C40.5607 24.5936 41.4583 24.4773 42.3556 24.3609C42.6713 23.2643 42.987 22.1672 43.3027 21.0705C44.6488 20.8046 45.9951 20.5387 47.341 20.2728C47.0586 21.4194 46.7759 22.5663 46.4935 23.7128C48.205 23.4469 49.917 23.181 51.6285 22.9151C51.6285 22.9318 51.6285 22.9484 51.6285 22.965C51.3294 23.7791 51.0302 24.5936 50.731 25.4079C49.0694 25.6571 47.4073 25.9064 45.7456 26.1557C45.4466 27.2357 45.1474 28.3162 44.8483 29.3962C44.0136 32.1402 43.3776 34.6959 39.4141 33.4843C38.8158 33.2517 38.2175 33.019 37.6193 32.7863C36.2625 33.7702 34.5113 34.7079 32.1353 34.3817C32.667 32.8532 33.1988 31.3239 33.7306 29.7951C34.8589 30.0452 35.0517 30.2694 36.3231 29.9945C35.7405 27.7268 38.2097 26.4735 39.5138 27.9504C40.4855 29.0511 39.3013 30.3223 39.2147 31.1412C39.3808 31.1578 39.5471 31.1744 39.7133 31.1911C40.8362 30.4825 41.3541 28.2227 41.6077 26.7041C39.2149 27.0696 36.8214 27.4353 34.4287 27.8009C34.7776 27.0199 35.1266 26.2386 35.4756 25.4577C36.6667 22.7403 37.6389 20.0061 40.3614 18.827C44.2905 17.1253 50.4798 17.3788 53.6227 14.9383C53.7043 15.3733 53.1544 16.1221 52.9746 16.5337ZM12.2433 51.831C12.8581 49.7041 13.4731 47.5765 14.0879 45.4496C14.9643 42.9914 16.2414 40.7002 17.3783 38.4699C18.3255 36.6255 19.2729 34.7805 20.22 32.936C22.0178 30.1368 24.3002 27.551 26.3522 24.9592C27.753 23.1899 29.6255 21.7209 30.8889 19.8242C29.4233 20.7224 28.614 20.7901 26.4519 21.1204C25.6875 21.1537 24.9229 21.1869 24.1586 21.2201C20.5085 22.0271 18.6903 23.9875 17.7772 27.5018C16.1154 27.7677 14.4533 28.0337 12.7917 28.2996C12.7917 28.2829 12.7917 28.2663 12.7917 28.2497C13.8385 24.8931 14.8857 21.5355 15.9325 18.179C17.1954 18.046 18.4586 17.9131 19.7215 17.7802C19.7048 18.0958 19.6883 18.4117 19.6716 18.7274C23.2753 17.1819 26.3396 15.3956 30.6397 14.4897C34.6711 13.6404 36.9813 15.362 39.0154 12.0967C39.6965 12.0302 40.3781 11.9637 41.0593 11.8972C41.1591 11.8972 41.2588 11.8972 41.3584 11.8972C40.6273 13.3761 39.896 14.8554 39.1649 16.3343C37.1111 19.6083 34.4669 22.4572 32.4345 25.8067C31.7864 27.1693 31.1381 28.5322 30.4901 29.8948C29.3875 32.3979 28.1812 35.1502 27.2994 37.8716C26.0723 41.6581 25.5411 45.7513 24.9562 50.1358C20.7191 50.7008 16.4805 51.2659 12.2433 51.831ZM51.8779 29.6954C51.8613 30.0278 51.8447 30.3602 51.8281 30.6925C51.6999 31.2623 51.3984 31.8354 51.0802 32.238C50.7226 32.6904 50.0475 33.1024 49.435 33.2849C49.1473 33.3708 48.8253 33.3116 48.6374 33.4844C47.9728 34.4149 47.3079 35.3457 46.6432 36.2762C46.8208 36.9667 48.2596 36.454 48.9365 36.5755C49.0362 36.6752 49.136 36.7749 49.2356 36.8745C49.231 37.7456 47.2299 39.8666 46.6432 40.3145C46.7096 40.4142 46.7761 40.5139 46.8426 40.6136C47.7022 40.6727 48.5893 40.4561 49.136 40.8629C49.1692 41.029 49.2024 41.1953 49.2357 41.3614C48.7377 42.4138 47.9815 43.2446 47.3411 44.1532C46.7429 45.1835 46.1446 46.2141 45.5464 47.2443C43.4115 47.5439 39.586 48.9108 38.0183 47.6929C37.0812 46.965 37.4636 46.3714 37.0212 45.2002C36.6888 46.3467 36.3565 47.4936 36.0241 48.6402C34.7115 48.8728 33.3982 49.1055 32.0855 49.3381C32.0855 49.3215 32.0855 49.3049 32.0855 49.2882C32.2683 48.6236 32.4512 47.9588 32.634 47.2941C31.0259 48.3239 29.7203 49.573 27.2995 49.8367C27.2995 49.8201 27.2995 49.8035 27.2995 49.7868C27.7813 48.4243 28.2634 47.0613 28.7453 45.6988C29.6405 46.2284 31.96 44.4924 32.4843 43.9039C31.3212 44.1532 30.1577 44.4027 28.9945 44.6518C28.9945 44.6353 28.9945 44.6187 28.9945 44.602C29.277 43.7878 29.5596 42.9734 29.842 42.1592C31.4206 41.7936 32.9997 41.4279 34.5782 41.0622C34.6281 40.8463 34.6779 40.6303 34.7278 40.4142C33.9081 40.596 31.304 42.219 30.6895 40.9127C30.4339 40.3577 30.9324 39.181 31.0883 38.5696C32.0687 38.3868 33.0494 38.204 34.0298 38.0213C34.0089 38.3017 33.8318 38.724 33.9799 38.8189C34.1881 38.9909 34.5815 39.1996 34.8275 39.1679C35.0934 38.553 35.3593 37.938 35.6251 37.3233C35.6251 37.3067 35.6251 37.2901 35.6251 37.2734C34.0798 37.5559 32.534 37.8385 30.9887 38.121C30.9887 38.1044 30.9887 38.0879 30.9887 38.0711C31.2712 37.2902 31.5537 36.509 31.8362 35.7281C36.0567 34.9471 40.2788 34.1658 44.4993 33.385C44.1565 35.5486 41.8755 36.0733 39.6634 36.3762C39.5969 36.5423 39.5304 36.7086 39.464 36.8748C41.0174 36.4914 42.4357 35.5478 43.3526 37.2238C43.4213 35.6801 46.104 34.1256 46.9421 33.0359C46.9421 33.0193 46.9421 33.0027 46.9421 32.9862C44.4804 32.0537 44.7826 28.3599 46.7926 27.1531C48.6 26.0681 51.2712 27.1687 51.6285 28.8981C52.5425 28.3165 53.4567 27.7347 54.3706 27.1531C53.5398 28.0003 52.7087 28.848 51.8779 29.6954Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 143 117" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="143.000000" height="117.000000" fill="none" customFrame="#000000">
<g id="组合 91">
<path id="矢量 94" d="M97.5001 71.4999L117 71.4999L117 97.5L97.5001 97.5L97.5001 71.4999ZM64.9999 45.5L84.5 45.5L84.5 97.5L64.9999 97.5L64.9999 45.5ZM25.9999 32.4999L45.4999 32.4999L45.4999 97.5L25.9999 97.5L25.9999 32.4999ZM13 10.4C12.8292 10.4 12.6602 10.4167 12.4927 10.45C12.3253 10.4833 12.1627 10.5326 12.005 10.598C11.8473 10.6633 11.6974 10.7434 11.5555 10.8382C11.4135 10.933 11.2822 11.0408 11.1615 11.1615C11.0408 11.2822 10.933 11.4136 10.8381 11.5555C10.7433 11.6974 10.6632 11.8473 10.5979 12.005C10.5325 12.1627 10.4832 12.3253 10.4499 12.4927C10.4166 12.6602 10.3999 12.8292 10.3999 12.9999L10.3999 104C10.3999 104.171 10.4166 104.34 10.4499 104.507C10.4832 104.675 10.5325 104.837 10.5979 104.995C10.6632 105.153 10.7433 105.303 10.8381 105.444C10.933 105.586 11.0408 105.718 11.1615 105.838C11.2822 105.959 11.4135 106.067 11.5555 106.162C11.6974 106.257 11.8473 106.337 12.005 106.402C12.1627 106.467 12.3253 106.517 12.4927 106.55C12.6602 106.583 12.8292 106.6 13 106.6L130 106.6C130.171 106.6 130.34 106.583 130.507 106.55C130.675 106.517 130.837 106.467 130.995 106.402C131.153 106.337 131.303 106.257 131.445 106.162C131.586 106.067 131.718 105.959 131.839 105.838C131.959 105.718 132.067 105.586 132.162 105.444C132.257 105.303 132.337 105.153 132.402 104.995C132.467 104.837 132.517 104.675 132.55 104.507C132.583 104.34 132.6 104.171 132.6 104L132.6 12.9999C132.6 12.8292 132.583 12.6602 132.55 12.4927C132.517 12.3253 132.467 12.1627 132.402 12.005C132.337 11.8473 132.257 11.6975 132.162 11.5555C132.067 11.4136 131.959 11.2822 131.839 11.1615C131.718 11.0408 131.586 10.933 131.445 10.8382C131.303 10.7434 131.153 10.6633 130.995 10.598C130.837 10.5326 130.675 10.4833 130.507 10.45C130.34 10.4167 130.171 10.4 130 10.4L13 10.4ZM13 0L130 0C130.426 7.61329e-08 130.851 0.0208662 131.274 0.0625985C131.698 0.104331 132.119 0.166728 132.536 0.249791C132.954 0.332853 133.366 0.436181 133.774 0.559774C134.181 0.683367 134.582 0.82663 134.975 0.989563C135.368 1.1525 135.753 1.33431 136.128 1.53502C136.504 1.73572 136.868 1.95434 137.222 2.19089C137.576 2.42743 137.918 2.68075 138.247 2.95085C138.576 3.22096 138.891 3.50654 139.192 3.8076C139.493 4.10866 139.779 4.42375 140.049 4.75287C140.319 5.08199 140.573 5.42355 140.809 5.77756C141.046 6.13158 141.264 6.49633 141.465 6.87182C141.666 7.24731 141.847 7.63173 142.01 8.02508C142.173 8.41844 142.317 8.81883 142.44 9.22626C142.564 9.63369 142.667 10.0462 142.75 10.4638C142.833 10.8814 142.896 11.302 142.937 11.7257C142.979 12.1494 143 12.5742 143 12.9999L143 104C143 104.426 142.979 104.851 142.937 105.274C142.896 105.698 142.833 106.119 142.75 106.536C142.667 106.954 142.564 107.366 142.44 107.774C142.317 108.181 142.173 108.582 142.01 108.975C141.847 109.368 141.666 109.753 141.465 110.128C141.264 110.504 141.046 110.868 140.809 111.222C140.573 111.576 140.319 111.918 140.049 112.247C139.779 112.576 139.493 112.891 139.192 113.192C138.891 113.493 138.576 113.779 138.247 114.049C137.918 114.319 137.576 114.573 137.222 114.809C136.868 115.046 136.504 115.264 136.128 115.465C135.753 115.666 135.368 115.847 134.975 116.01C134.582 116.173 134.181 116.317 133.774 116.44C133.366 116.564 132.954 116.667 132.536 116.75C132.119 116.833 131.698 116.896 131.274 116.937C130.851 116.979 130.426 117 130 117L13 117C12.5742 117 12.1495 116.979 11.7257 116.937C11.302 116.896 10.8814 116.833 10.4638 116.75C10.0462 116.667 9.6337 116.564 9.22627 116.44C8.81884 116.317 8.41844 116.173 8.02509 116.01C7.63173 115.847 7.24731 115.666 6.87182 115.465C6.49633 115.264 6.13158 115.046 5.77757 114.809C5.42356 114.573 5.08199 114.319 4.75287 114.049C4.42375 113.779 4.10866 113.493 3.8076 113.192C3.50654 112.891 3.22096 112.576 2.95085 112.247C2.68075 111.918 2.42743 111.576 2.19089 111.222C1.95435 110.868 1.73572 110.504 1.53502 110.128C1.33431 109.753 1.1525 109.368 0.989563 108.975C0.82663 108.582 0.683367 108.181 0.559774 107.774C0.436181 107.366 0.332853 106.954 0.249791 106.536C0.166728 106.119 0.104331 105.698 0.0625983 105.274C0.0208661 104.851 0 104.426 0 104L0 12.9999C-5.70997e-08 12.5742 0.020866 12.1494 0.0625982 11.7257C0.10433 11.302 0.166728 10.8814 0.24979 10.4638C0.332853 10.0462 0.436181 9.63369 0.559773 9.22626C0.683366 8.81883 0.826629 8.41844 0.989562 8.02508C1.1525 7.63173 1.33431 7.2473 1.53502 6.87181C1.73572 6.49632 1.95435 6.13157 2.19089 5.77756C2.42743 5.42355 2.68075 5.08199 2.95085 4.75287C3.22096 4.42375 3.50654 4.10866 3.8076 3.8076C4.10866 3.50653 4.42375 3.22095 4.75287 2.95085C5.08199 2.68075 5.42356 2.42743 5.77757 2.19089C6.13158 1.95434 6.49633 1.73572 6.87182 1.53502C7.24731 1.33431 7.63173 1.15249 8.02509 0.989561C8.41844 0.826629 8.81884 0.683366 9.22627 0.559773C9.6337 0.43618 10.0462 0.332852 10.4638 0.24979C10.8814 0.166728 11.302 0.10433 11.7257 0.0625981C12.1495 0.0208659 12.5742 -7.61329e-08 13 0Z" fill="rgb(255,255,255)" fill-opacity="0.379999995" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 117 117" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="117.000000" height="117.000000" fill="none" customFrame="#000000">
<g id="组合 95">
<path id="矢量 99" d="M108.643 0L8.35714 0C3.74175 0 0 3.74175 0 8.35714L0 108.643C0 113.258 3.74175 117 8.35714 117L108.643 117C113.258 117 117 113.258 117 108.643L117 8.35714C117 3.74175 113.258 0 108.643 0ZM108.643 104.465C108.643 106.772 106.773 108.643 104.465 108.643L12.6659 108.643C10.3583 108.643 8.48793 106.773 8.48793 104.465L8.48793 12.6657C8.48793 10.3582 10.3579 8.48778 12.6659 8.48778L104.465 8.48778C106.772 8.48778 108.643 10.3577 108.643 12.6657L108.643 104.465ZM91.9292 44.6454L72.4072 44.6454L72.4072 25.2011C72.4072 20.5874 68.6658 16.8451 64.0508 16.8451L25.2971 16.8451C20.6824 16.8451 16.9408 20.5864 16.9408 25.2011L16.9408 64.1289C16.9408 68.7426 20.6822 72.485 25.2971 72.485L44.8191 72.485L44.8191 91.9292C44.8191 96.5429 48.5606 100.285 53.1755 100.285L91.9292 100.285C96.544 100.285 100.286 96.544 100.286 91.9292L100.286 53.0015C100.286 48.3878 96.5441 44.6454 91.9292 44.6454L91.9292 44.6454ZM29.5767 64.0407C27.2692 64.0407 25.3985 62.1691 25.3985 59.8611L25.3985 29.5496C25.3985 27.2413 27.2692 25.37 29.5767 25.37L59.7708 25.37C62.0785 25.37 63.949 27.2416 63.949 29.5496L63.949 44.6457L53.1753 44.6457C48.5605 44.6457 44.8189 48.387 44.8189 53.0018L44.8189 64.0409L29.5767 64.0409L29.5767 64.0407ZM63.949 53.1704L63.949 59.8612C63.949 62.1695 62.0782 64.0409 59.7708 64.0409L53.277 64.0409L53.277 57.3501C53.277 55.0418 55.1479 53.1704 57.4552 53.1704L63.949 53.1704L63.949 53.1704ZM91.8275 87.6614C91.8275 89.9697 89.9568 91.841 87.6493 91.841L57.4552 91.841C55.1477 91.841 53.277 89.9694 53.277 87.6614L53.277 72.4851L64.0507 72.4851C68.6655 72.4851 72.4071 68.7438 72.4071 64.129L72.4071 53.1703L87.6493 53.1703C89.9568 53.1703 91.8275 55.0419 91.8275 57.3499L91.8275 87.6612L91.8275 87.6614Z" fill="rgb(255,255,255)" fill-opacity="0.370000005" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,11 @@
<svg viewBox="0 0 64 63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="63.000000" fill="none" customFrame="#000000">
<g id="组合 21">
<path id="矢量 40" d="M18.2537 31.5L16.4316 31.5C16.5594 31.311 16.7193 31.122 16.8791 30.87L18.6054 30.87L18.957 30.0195L14.7692 30.0195L14.4176 30.87L15.4725 30.87C15.025 31.689 14.3856 32.4135 13.5864 32.9175L13.2028 33.831L13.4585 33.7365L14.002 33.4845L13.7782 34.02C14.1938 34.083 14.5774 34.209 14.961 34.3665C14.2258 35.028 13.4266 35.595 12.5315 36.036L12.1798 36.918C14.6413 36.225 16.6873 34.587 17.9021 32.382L18.2537 31.5L18.2537 31.5ZM15.8561 33.39C15.4725 33.264 15.0889 33.201 14.6733 33.138C15.025 32.9175 15.3446 32.6655 15.6324 32.382L16.4955 32.382C16.3357 32.76 16.1119 33.075 15.8561 33.39L15.8561 33.39ZM20.2997 30.303L19.0849 30.303L17.0709 35.3745L18.3177 35.3745L20.2997 30.303Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 41" d="M20.971 29.799L18.6373 35.721C18.6054 35.91 18.4455 36.0045 18.2537 36.0045L17.6783 36.0045L17.3586 36.8235L18.4136 36.8235C19.0529 36.855 19.6283 36.477 19.8521 35.91L22.3137 29.8305L20.971 29.8305L20.971 29.799ZM7.35262 33.579L7.6723 32.697L7.41656 32.76L7.09688 32.8545L7.60837 31.5L7.99198 31.5L8.31166 30.618L7.92805 30.618L8.27969 29.736L7.03294 29.736L6.71326 30.618L6.20177 30.618L5.88209 31.5L6.32964 31.5L5.72225 33.075L5.40257 33.075L5.05092 33.138L4.63534 34.1775L5.05092 34.1145C5.14683 34.083 5.24273 34.0515 5.33864 34.0515L4.69928 35.721C4.66731 35.9415 4.4755 36.0675 4.25172 36.036L4.05991 36.036L3.74023 36.8865L4.4755 36.8865C5.1788 36.918 5.81816 36.477 6.00996 35.8155L6.80917 33.705L7.35262 33.579L7.35262 33.579ZM12.2757 34.524L11.0609 34.524L11.5404 33.3585L12.4995 33.3585L12.8511 32.445L11.8921 32.445L12.2437 31.5L13.2987 31.5L13.6823 30.555L12.5954 30.555L12.947 29.673L11.6363 29.673L8.85512 36.918L10.1658 36.918L10.7732 35.3745L11.9241 35.3745L12.2757 34.524Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 42" d="M9.87815 29.7045L9.52651 30.618L8.59943 30.618L8.24779 31.5315L9.17486 31.5315L8.79124 32.508L7.96007 32.508L7.60843 33.39L8.47156 33.39L8.02401 34.524L6.90513 34.524L6.58545 35.3745L7.70433 35.3745L7.09694 36.918L8.40763 36.9495L11.1569 29.7045L9.87815 29.7045Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 43" d="M32 0C14.3217 0 0 14.112 0 31.5C0 48.888 14.3217 63 32 63C49.6783 63 64 48.888 64 31.5C64 14.112 49.6783 0 32 0ZM54.8252 16.128L56.967 17.388L47.025 24.885L54.8252 16.128L54.8252 16.128ZM43.3486 11.9385L43.4765 11.9385C46.7373 11.9385 48.3676 13.545 48.3676 16.758C48.3676 19.971 46.7373 21.5775 43.4765 21.5775L43.3486 21.5775C40.0879 21.5775 38.4575 19.971 38.4575 16.758C38.4256 13.5135 40.0559 11.9385 43.3486 11.9385ZM32.2238 6.3L32.2238 20.3175L28.3237 6.3L32.2238 6.3ZM26.8212 14.1435L29.0589 21.3255L24.6154 15.0255L26.8212 14.1435ZM17.5824 14.3955L25.6703 23.9085L14.6094 16.8525L17.5824 14.3955L17.5824 14.3955ZM14.1618 45.7065L24.7432 42.4935L15.9201 48.9195L14.1618 45.7065L14.1618 45.7065ZM26.1179 55.818L23.8801 55.818L28.3237 47.502L26.1179 55.818L26.1179 55.818ZM35.7083 47.3445L35.4206 47.3445C29.7622 47.3445 24.9351 43.911 22.9211 39.06L1.37463 39.06L4.15584 28.2555L23.7203 27.405C26.0539 23.436 30.4016 20.7585 35.3886 20.7585L35.6763 20.7585C43.1249 20.7585 49.1668 26.712 49.1668 34.0515C49.1668 41.391 43.1568 47.3445 35.7083 47.3445L35.7083 47.3445ZM55.4965 24.255L56.6473 25.956L50.6374 27.6885L55.4965 24.255ZM50.8931 30.744L63.4885 29.2005L63.4885 32.0985L50.8931 30.744Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<g id="5">
<path id="矢量 54" d="M32.803 42.6712C33.5155 42.8781 34.3198 42.9816 35.2161 42.9816C35.9088 42.9816 36.5689 42.8819 37.1963 42.6824C37.5199 42.5796 37.8348 42.4502 38.141 42.2943C38.4746 42.1238 38.7847 41.9246 39.0713 41.6967C39.5611 41.3072 39.9822 40.834 40.3347 40.2769C40.8934 39.3937 41.1728 38.3314 41.1728 37.0899C41.1728 35.8632 40.9347 34.8581 40.4584 34.0748C40.1572 33.573 39.7897 33.1546 39.3558 32.8195C39.1092 32.629 38.8411 32.4655 38.5516 32.3289C38.4559 32.2837 38.3591 32.2413 38.2611 32.2015C37.5415 31.9095 36.7608 31.7635 35.9192 31.7635C35.5329 31.7635 35.1786 31.8023 34.8561 31.8799C34.5336 31.9575 34.2055 32.0702 33.8717 32.218L34.1867 28.6542L40.3909 28.6542L40.3909 25.8552L31.273 25.8552L30.8005 34.0138L32.353 35.0059C32.8517 34.6881 33.2755 34.4628 33.6242 34.3297C33.9767 34.1967 34.4061 34.1302 34.9123 34.1302C35.5091 34.1302 36.0267 34.2601 36.4649 34.5198C36.6518 34.6305 36.8242 34.7648 36.9823 34.9228C37.0286 34.9687 37.0728 35.0163 37.1151 35.0656C37.559 35.5832 37.781 36.2857 37.781 37.173C37.781 37.8271 37.6516 38.3869 37.3929 38.8524C37.2279 39.1494 37.0232 39.4005 36.7788 39.6057C36.64 39.7223 36.4885 39.8241 36.3242 39.911C35.8742 40.1512 35.3529 40.2713 34.7605 40.2713C34.243 40.2713 33.7574 40.1937 33.3036 40.0385C32.8536 39.8796 32.4393 39.6727 32.0605 39.4178C31.7354 39.1967 31.43 38.9548 31.1444 38.6921C31.1006 38.6518 31.0572 38.611 31.0143 38.5698L29.4393 40.6925C29.8743 41.1064 30.3656 41.4888 30.913 41.8398C31.4605 42.1872 32.0905 42.4643 32.803 42.6712Z" fill="rgb(241,49,68)" fill-rule="evenodd" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1,9 @@
<svg viewBox="0 0 64 63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="63.000000" fill="none" customFrame="#000000">
<g id="组合 16">
<path id="矢量 40" d="M18.2537 31.5L16.4316 31.5C16.5594 31.311 16.7193 31.122 16.8791 30.87L18.6054 30.87L18.957 30.0195L14.7692 30.0195L14.4176 30.87L15.4725 30.87C15.025 31.689 14.3856 32.4135 13.5864 32.9175L13.2028 33.831L13.4585 33.7365L14.002 33.4845L13.7782 34.02C14.1938 34.083 14.5774 34.209 14.961 34.3665C14.2258 35.028 13.4266 35.595 12.5315 36.036L12.1798 36.918C14.6413 36.225 16.6873 34.587 17.9021 32.382L18.2537 31.5L18.2537 31.5ZM15.8561 33.39C15.4725 33.264 15.0889 33.201 14.6733 33.138C15.025 32.9175 15.3446 32.6655 15.6324 32.382L16.4955 32.382C16.3357 32.76 16.1119 33.075 15.8561 33.39L15.8561 33.39ZM20.2997 30.303L19.0849 30.303L17.0709 35.3745L18.3177 35.3745L20.2997 30.303Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 41" d="M20.971 29.799L18.6373 35.721C18.6054 35.91 18.4455 36.0045 18.2537 36.0045L17.6783 36.0045L17.3586 36.8235L18.4136 36.8235C19.0529 36.855 19.6283 36.477 19.8521 35.91L22.3137 29.8305L20.971 29.8305L20.971 29.799ZM7.35262 33.579L7.6723 32.697L7.41656 32.76L7.09688 32.8545L7.60837 31.5L7.99198 31.5L8.31166 30.618L7.92805 30.618L8.27969 29.736L7.03294 29.736L6.71326 30.618L6.20177 30.618L5.88209 31.5L6.32964 31.5L5.72225 33.075L5.40257 33.075L5.05092 33.138L4.63534 34.1775L5.05092 34.1145C5.14683 34.083 5.24273 34.0515 5.33864 34.0515L4.69928 35.721C4.66731 35.9415 4.4755 36.0675 4.25172 36.036L4.05991 36.036L3.74023 36.8865L4.4755 36.8865C5.1788 36.918 5.81816 36.477 6.00996 35.8155L6.80916 33.705L7.35262 33.579L7.35262 33.579ZM12.2757 34.524L11.0609 34.524L11.5404 33.3585L12.4995 33.3585L12.8511 32.445L11.8921 32.445L12.2437 31.5L13.2987 31.5L13.6823 30.555L12.5954 30.555L12.947 29.673L11.6363 29.673L8.85512 36.918L10.1658 36.918L10.7732 35.3745L11.924 35.3745L12.2757 34.524Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 42" d="M9.87815 29.7045L9.52651 30.618L8.59943 30.618L8.24779 31.5315L9.17486 31.5315L8.79124 32.508L7.96007 32.508L7.60843 33.39L8.47156 33.39L8.02401 34.524L6.90513 34.524L6.58545 35.3745L7.70433 35.3745L7.09694 36.918L8.40763 36.9495L11.1569 29.7045L9.87815 29.7045Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 43" d="M32 0C14.3217 0 0 14.112 0 31.5C0 48.888 14.3217 63 32 63C49.6783 63 64 48.888 64 31.5C64 14.112 49.6783 0 32 0ZM54.8252 16.128L56.967 17.388L47.025 24.885L54.8252 16.128L54.8252 16.128ZM43.3486 11.9385L43.4765 11.9385C46.7373 11.9385 48.3676 13.545 48.3676 16.758C48.3676 19.971 46.7373 21.5775 43.4765 21.5775L43.3486 21.5775C40.0879 21.5775 38.4575 19.971 38.4575 16.758C38.4256 13.5135 40.0559 11.9385 43.3486 11.9385ZM32.2238 6.3L32.2238 20.3175L28.3237 6.3L32.2238 6.3ZM26.8212 14.1435L29.0589 21.3255L24.6154 15.0255L26.8212 14.1435ZM17.5824 14.3955L25.6703 23.9085L14.6094 16.8525L17.5824 14.3955L17.5824 14.3955ZM14.1618 45.7065L24.7432 42.4935L15.9201 48.9195L14.1618 45.7065L14.1618 45.7065ZM26.1179 55.818L23.8801 55.818L28.3237 47.502L26.1179 55.818L26.1179 55.818ZM35.7083 47.3445L35.4206 47.3445C29.7622 47.3445 24.9351 43.911 22.9211 39.06L1.37463 39.06L4.15584 28.2555L23.7203 27.405C26.0539 23.436 30.4016 20.7585 35.3886 20.7585L35.6763 20.7585C43.1249 20.7585 49.1668 26.712 49.1668 34.0515C49.1668 41.391 43.1568 47.3445 35.7083 47.3445L35.7083 47.3445ZM55.4965 24.255L56.6473 25.956L50.6374 27.6885L55.4965 24.255ZM50.8931 30.744L63.4885 29.2005L63.4885 32.0985L50.8931 30.744Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 44" d="M40.7912 33.39C42.1019 32.823 42.9011 31.5 42.7412 30.114C42.7732 28.917 42.3256 27.783 41.4945 26.901C40.4715 25.956 38.969 25.641 35.7083 25.641C30.1139 25.641 28.6114 26.6175 28.5155 31.0905L32.1918 31.0905C32.1918 29.736 32.1918 28.98 35.4525 28.98C37.8501 28.98 39.0969 29.0745 39.0969 30.618C39.0969 32.1615 38.01 32.1615 37.1148 32.1615L33.918 32.1615L33.918 35.028L37.1148 35.028C38.0419 35.028 39.3526 34.902 39.3526 36.729C39.3526 38.556 37.6903 38.5245 36.0279 38.5245C32.1278 38.5245 31.9041 38.3355 31.9041 36.036L28.1318 36.036C28.1318 40.4775 29.0269 41.8635 35.932 41.8635C39.8641 41.8635 43.0609 41.328 43.0609 37.107C43.0609 34.272 41.4945 33.642 40.7912 33.39Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,9 @@
<svg viewBox="0 0 64 63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="63.000000" fill="none" customFrame="#000000">
<g id="组合 16">
<path id="矢量 40" d="M18.2537 31.5L16.4316 31.5C16.5594 31.311 16.7193 31.122 16.8791 30.87L18.6054 30.87L18.957 30.0195L14.7692 30.0195L14.4176 30.87L15.4725 30.87C15.025 31.689 14.3856 32.4135 13.5864 32.9175L13.2028 33.831L13.4585 33.7365L14.002 33.4845L13.7782 34.02C14.1938 34.083 14.5774 34.209 14.961 34.3665C14.2258 35.028 13.4266 35.595 12.5315 36.036L12.1798 36.918C14.6413 36.225 16.6873 34.587 17.9021 32.382L18.2537 31.5L18.2537 31.5ZM15.8561 33.39C15.4725 33.264 15.0889 33.201 14.6733 33.138C15.025 32.9175 15.3446 32.6655 15.6324 32.382L16.4955 32.382C16.3357 32.76 16.1119 33.075 15.8561 33.39L15.8561 33.39ZM20.2997 30.303L19.0849 30.303L17.0709 35.3745L18.3177 35.3745L20.2997 30.303Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 41" d="M20.971 29.799L18.6373 35.721C18.6054 35.91 18.4455 36.0045 18.2537 36.0045L17.6783 36.0045L17.3586 36.8235L18.4136 36.8235C19.0529 36.855 19.6283 36.477 19.8521 35.91L22.3137 29.8305L20.971 29.8305L20.971 29.799ZM7.35262 33.579L7.6723 32.697L7.41656 32.76L7.09688 32.8545L7.60837 31.5L7.99198 31.5L8.31166 30.618L7.92805 30.618L8.27969 29.736L7.03294 29.736L6.71326 30.618L6.20177 30.618L5.88209 31.5L6.32964 31.5L5.72225 33.075L5.40257 33.075L5.05092 33.138L4.63534 34.1775L5.05092 34.1145C5.14683 34.083 5.24273 34.0515 5.33864 34.0515L4.69928 35.721C4.66731 35.9415 4.4755 36.0675 4.25172 36.036L4.05991 36.036L3.74023 36.8865L4.4755 36.8865C5.1788 36.918 5.81816 36.477 6.00996 35.8155L6.80916 33.705L7.35262 33.579L7.35262 33.579ZM12.2757 34.524L11.0609 34.524L11.5404 33.3585L12.4995 33.3585L12.8511 32.445L11.8921 32.445L12.2437 31.5L13.2987 31.5L13.6823 30.555L12.5954 30.555L12.947 29.673L11.6363 29.673L8.85512 36.918L10.1658 36.918L10.7732 35.3745L11.924 35.3745L12.2757 34.524Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 42" d="M9.87815 29.7045L9.52651 30.618L8.59943 30.618L8.24779 31.5315L9.17486 31.5315L8.79124 32.508L7.96007 32.508L7.60843 33.39L8.47156 33.39L8.02401 34.524L6.90513 34.524L6.58545 35.3745L7.70433 35.3745L7.09694 36.918L8.40763 36.9495L11.1569 29.7045L9.87815 29.7045Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 43" d="M32 0C14.3217 0 0 14.112 0 31.5C0 48.888 14.3217 63 32 63C49.6783 63 64 48.888 64 31.5C64 14.112 49.6783 0 32 0ZM54.8252 16.128L56.967 17.388L47.025 24.885L54.8252 16.128L54.8252 16.128ZM43.3486 11.9385L43.4765 11.9385C46.7373 11.9385 48.3676 13.545 48.3676 16.758C48.3676 19.971 46.7373 21.5775 43.4765 21.5775L43.3486 21.5775C40.0879 21.5775 38.4575 19.971 38.4575 16.758C38.4256 13.5135 40.0559 11.9385 43.3486 11.9385ZM32.2238 6.3L32.2238 20.3175L28.3237 6.3L32.2238 6.3ZM26.8212 14.1435L29.0589 21.3255L24.6154 15.0255L26.8212 14.1435ZM17.5824 14.3955L25.6703 23.9085L14.6094 16.8525L17.5824 14.3955L17.5824 14.3955ZM14.1618 45.7065L24.7432 42.4935L15.9201 48.9195L14.1618 45.7065L14.1618 45.7065ZM26.1179 55.818L23.8801 55.818L28.3237 47.502L26.1179 55.818L26.1179 55.818ZM35.7083 47.3445L35.4206 47.3445C29.7622 47.3445 24.9351 43.911 22.9211 39.06L1.37463 39.06L4.15584 28.2555L23.7203 27.405C26.0539 23.436 30.4016 20.7585 35.3886 20.7585L35.6763 20.7585C43.1249 20.7585 49.1668 26.712 49.1668 34.0515C49.1668 41.391 43.1568 47.3445 35.7083 47.3445L35.7083 47.3445ZM55.4965 24.255L56.6473 25.956L50.6374 27.6885L55.4965 24.255ZM50.8931 30.744L63.4885 29.2005L63.4885 32.0985L50.8931 30.744Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 44" d="M40.7912 33.39C42.1019 32.823 42.9011 31.5 42.7412 30.114C42.7732 28.917 42.3256 27.783 41.4945 26.901C40.4715 25.956 38.969 25.641 35.7083 25.641C30.1139 25.641 28.6114 26.6175 28.5155 31.0905L32.1918 31.0905C32.1918 29.736 32.1918 28.98 35.4525 28.98C37.8501 28.98 39.0969 29.0745 39.0969 30.618C39.0969 32.1615 38.01 32.1615 37.1148 32.1615L33.918 32.1615L33.918 35.028L37.1148 35.028C38.0419 35.028 39.3526 34.902 39.3526 36.729C39.3526 38.556 37.6903 38.5245 36.0279 38.5245C32.1278 38.5245 31.9041 38.3355 31.9041 36.036L28.1318 36.036C28.1318 40.4775 29.0269 41.8635 35.932 41.8635C39.8641 41.8635 43.0609 41.328 43.0609 37.107C43.0609 34.272 41.4945 33.642 40.7912 33.39Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,11 @@
<svg viewBox="0 0 64 63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="63.000000" fill="none" customFrame="#000000">
<g id="组合 21">
<path id="矢量 40" d="M18.2537 31.5L16.4316 31.5C16.5594 31.311 16.7193 31.122 16.8791 30.87L18.6054 30.87L18.957 30.0195L14.7692 30.0195L14.4176 30.87L15.4725 30.87C15.025 31.689 14.3856 32.4135 13.5864 32.9175L13.2028 33.831L13.4585 33.7365L14.002 33.4845L13.7782 34.02C14.1938 34.083 14.5774 34.209 14.961 34.3665C14.2258 35.028 13.4266 35.595 12.5315 36.036L12.1798 36.918C14.6413 36.225 16.6873 34.587 17.9021 32.382L18.2537 31.5L18.2537 31.5ZM15.8561 33.39C15.4725 33.264 15.0889 33.201 14.6733 33.138C15.025 32.9175 15.3446 32.6655 15.6324 32.382L16.4955 32.382C16.3357 32.76 16.1119 33.075 15.8561 33.39L15.8561 33.39ZM20.2997 30.303L19.0849 30.303L17.0709 35.3745L18.3177 35.3745L20.2997 30.303Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 41" d="M20.971 29.799L18.6373 35.721C18.6054 35.91 18.4455 36.0045 18.2537 36.0045L17.6783 36.0045L17.3586 36.8235L18.4136 36.8235C19.0529 36.855 19.6283 36.477 19.8521 35.91L22.3137 29.8305L20.971 29.8305L20.971 29.799ZM7.35262 33.579L7.6723 32.697L7.41656 32.76L7.09688 32.8545L7.60837 31.5L7.99198 31.5L8.31166 30.618L7.92805 30.618L8.27969 29.736L7.03294 29.736L6.71326 30.618L6.20177 30.618L5.88209 31.5L6.32964 31.5L5.72225 33.075L5.40257 33.075L5.05092 33.138L4.63534 34.1775L5.05092 34.1145C5.14683 34.083 5.24273 34.0515 5.33864 34.0515L4.69928 35.721C4.66731 35.9415 4.4755 36.0675 4.25172 36.036L4.05991 36.036L3.74023 36.8865L4.4755 36.8865C5.1788 36.918 5.81816 36.477 6.00996 35.8155L6.80917 33.705L7.35262 33.579L7.35262 33.579ZM12.2757 34.524L11.0609 34.524L11.5404 33.3585L12.4995 33.3585L12.8511 32.445L11.8921 32.445L12.2437 31.5L13.2987 31.5L13.6823 30.555L12.5954 30.555L12.947 29.673L11.6363 29.673L8.85512 36.918L10.1658 36.918L10.7732 35.3745L11.9241 35.3745L12.2757 34.524Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 42" d="M9.87815 29.7045L9.52651 30.618L8.59943 30.618L8.24779 31.5315L9.17486 31.5315L8.79124 32.508L7.96007 32.508L7.60843 33.39L8.47156 33.39L8.02401 34.524L6.90513 34.524L6.58545 35.3745L7.70433 35.3745L7.09694 36.918L8.40763 36.9495L11.1569 29.7045L9.87815 29.7045Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<path id="矢量 43" d="M32 0C14.3217 0 0 14.112 0 31.5C0 48.888 14.3217 63 32 63C49.6783 63 64 48.888 64 31.5C64 14.112 49.6783 0 32 0ZM54.8252 16.128L56.967 17.388L47.025 24.885L54.8252 16.128L54.8252 16.128ZM43.3486 11.9385L43.4765 11.9385C46.7373 11.9385 48.3676 13.545 48.3676 16.758C48.3676 19.971 46.7373 21.5775 43.4765 21.5775L43.3486 21.5775C40.0879 21.5775 38.4575 19.971 38.4575 16.758C38.4256 13.5135 40.0559 11.9385 43.3486 11.9385ZM32.2238 6.3L32.2238 20.3175L28.3237 6.3L32.2238 6.3ZM26.8212 14.1435L29.0589 21.3255L24.6154 15.0255L26.8212 14.1435ZM17.5824 14.3955L25.6703 23.9085L14.6094 16.8525L17.5824 14.3955L17.5824 14.3955ZM14.1618 45.7065L24.7432 42.4935L15.9201 48.9195L14.1618 45.7065L14.1618 45.7065ZM26.1179 55.818L23.8801 55.818L28.3237 47.502L26.1179 55.818L26.1179 55.818ZM35.7083 47.3445L35.4206 47.3445C29.7622 47.3445 24.9351 43.911 22.9211 39.06L1.37463 39.06L4.15584 28.2555L23.7203 27.405C26.0539 23.436 30.4016 20.7585 35.3886 20.7585L35.6763 20.7585C43.1249 20.7585 49.1668 26.712 49.1668 34.0515C49.1668 41.391 43.1568 47.3445 35.7083 47.3445L35.7083 47.3445ZM55.4965 24.255L56.6473 25.956L50.6374 27.6885L55.4965 24.255ZM50.8931 30.744L63.4885 29.2005L63.4885 32.0985L50.8931 30.744Z" fill="rgb(200,200,200)" fill-rule="nonzero" />
<g id="5">
<path id="矢量 54" d="M32.803 42.6712C33.5155 42.8781 34.3198 42.9816 35.2161 42.9816C35.9088 42.9816 36.5689 42.8819 37.1963 42.6824C37.5199 42.5796 37.8348 42.4502 38.141 42.2943C38.4746 42.1238 38.7847 41.9246 39.0713 41.6967C39.5611 41.3072 39.9822 40.834 40.3347 40.2769C40.8934 39.3937 41.1728 38.3314 41.1728 37.0899C41.1728 35.8632 40.9347 34.8581 40.4584 34.0748C40.1572 33.573 39.7897 33.1546 39.3558 32.8195C39.1092 32.629 38.8411 32.4655 38.5516 32.3289C38.4559 32.2837 38.3591 32.2413 38.2611 32.2015C37.5415 31.9095 36.7608 31.7635 35.9192 31.7635C35.5329 31.7635 35.1786 31.8023 34.8561 31.8799C34.5336 31.9575 34.2055 32.0702 33.8717 32.218L34.1867 28.6542L40.3909 28.6542L40.3909 25.8552L31.273 25.8552L30.8005 34.0138L32.353 35.0059C32.8517 34.6881 33.2755 34.4628 33.6242 34.3297C33.9767 34.1967 34.4061 34.1302 34.9123 34.1302C35.5091 34.1302 36.0267 34.2601 36.4649 34.5198C36.6518 34.6305 36.8242 34.7648 36.9823 34.9228C37.0286 34.9687 37.0728 35.0163 37.1151 35.0656C37.559 35.5832 37.781 36.2857 37.781 37.173C37.781 37.8271 37.6516 38.3869 37.3929 38.8524C37.2279 39.1494 37.0232 39.4005 36.7788 39.6057C36.64 39.7223 36.4885 39.8241 36.3242 39.911C35.8742 40.1512 35.3529 40.2713 34.7605 40.2713C34.243 40.2713 33.7574 40.1937 33.3036 40.0385C32.8536 39.8796 32.4393 39.6727 32.0605 39.4178C31.7354 39.1967 31.43 38.9548 31.1444 38.6921C31.1006 38.6518 31.0572 38.611 31.0143 38.5698L29.4393 40.6925C29.8743 41.1064 30.3656 41.4888 30.913 41.8398C31.4605 42.1872 32.0905 42.4643 32.803 42.6712Z" fill="rgb(200,200,200)" fill-rule="evenodd" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,6 @@
<svg viewBox="0 0 29.1501 37.4263" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="29.150146" height="37.426270" fill="none" customFrame="#000000">
<g id="组合 67">
<path id="矢量 71" d="M21.8732 6.50801C23.1272 6.50801 24.147 5.53829 24.147 4.33867L24.147 2.16934C24.147 0.969723 23.1272 0 21.8732 0C20.6151 0 19.5994 0.969723 19.5994 2.16934L19.5994 4.33867C19.5994 5.53829 20.6193 6.50801 21.8732 6.50801ZM7.24795 6.50801C8.50191 6.50801 9.52179 5.53829 9.52179 4.33867L9.52179 2.16934C9.52179 0.969723 8.50191 0 7.24795 0C5.98982 0 4.97412 0.969723 4.97412 2.16934L4.97412 4.33867C4.97412 5.53829 5.98982 6.50801 7.24795 6.50801Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 72" d="M25.6391 3.43583L25.6391 4.7692C25.6391 6.4495 23.9421 7.81631 21.8522 7.81631C19.7581 7.81631 18.0611 6.45368 18.0611 4.7692L18.0611 3.24774L11.0055 3.24774L11.0055 4.7692C11.0055 6.4495 9.3085 7.81631 7.21858 7.81631C5.12448 7.81631 3.42747 6.45368 3.42747 4.7692L3.42747 3.46091C1.44204 4.07535 0 5.9312 0 8.12979L0 32.5442C0 35.2402 2.17352 37.4263 4.85697 37.4263L24.2932 37.4263C26.9767 37.4263 29.1502 35.2402 29.1502 32.5442L29.1502 8.12979C29.1544 5.90194 27.6705 4.02101 25.6391 3.43583L25.6391 3.43583ZM23.8376 31.3906L5.32094 31.3906C4.55185 31.3906 3.93323 30.7469 3.93323 29.9486C3.93323 29.1544 4.55602 28.5065 5.32094 28.5065L23.8418 28.5065C24.6109 28.5065 25.2295 29.1502 25.2295 29.9486C25.2295 30.7469 24.6067 31.3906 23.8376 31.3906ZM23.8376 23.7415L5.32094 23.7415C4.55185 23.7415 3.93323 23.0978 3.93323 22.2994C3.93323 21.5053 4.55602 20.8574 5.32094 20.8574L23.8418 20.8574C24.6109 20.8574 25.2295 21.5011 25.2295 22.2994C25.2295 23.0978 24.6067 23.7415 23.8376 23.7415ZM23.8376 16.0924L5.32094 16.0924C4.55185 16.0924 3.93323 15.4487 3.93323 14.6503C3.93323 13.8562 4.55602 13.2083 5.32094 13.2083L23.8418 13.2083C24.6109 13.2083 25.2295 13.852 25.2295 14.6503C25.2295 15.4487 24.6067 16.0924 23.8376 16.0924Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 42.3735 34.2413" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="42.373535" height="34.241272" fill="none" customFrame="#000000">
<path id="矢量 78" d="M42.2381 11.4137L42.1965 11.2585L35.5879 1.54254C35.1563 0.615989 34.1632 0 33.0401 0L9.33021 0C8.20713 0 7.21401 0.615989 6.78245 1.54254L0.173809 11.2585L0.129615 11.4137C0.0889032 11.5297 0.05767 11.6482 0.0360295 11.7692C0.0143319 11.8901 0.00245526 12.012 0.000342594 12.1348C-0.00177007 12.2577 0.0059954 12.3799 0.0235248 12.5015C0.0410542 12.6231 0.0682333 12.7426 0.104948 12.8599C0.14172 12.9771 0.187627 13.0908 0.242614 13.2008C0.297657 13.3107 0.361094 13.4157 0.432982 13.5155C0.50487 13.6154 0.584237 13.709 0.671142 13.7962C0.758104 13.8834 0.851404 13.9632 0.951156 14.0355L19.3913 33.6589L19.5655 33.7754C20.0412 34.0859 20.6028 34.2412 21.2033 34.2412C21.7857 34.2361 22.3524 34.0756 22.8464 33.7754L23.0206 33.6589L41.4607 14.0355C42.2407 13.3781 42.5838 12.3377 42.2407 11.4112L42.2381 11.4137L42.2381 11.4137ZM21.1618 31.1924L3.23894 12.1436L9.58761 2.8159L32.7775 2.8159L39.1288 12.1462L21.1643 31.195L21.1618 31.195L21.1618 31.1924Z" fill="rgb(241,49,68)" fill-rule="evenodd" />
<path id="矢量 78" d="M28.9039 12.1125C28.9039 12.0867 28.9039 12.053 28.8701 12.053C28.8701 11.9909 28.8363 11.9624 28.8363 11.9003C28.8363 11.8912 28.833 11.8836 28.8262 11.8774C28.8195 11.8712 28.8116 11.8685 28.8025 11.8693C28.7408 11.7542 28.6611 11.6532 28.5633 11.5665L23.7589 7.24424C23.6988 7.1928 23.6346 7.14707 23.5663 7.10702C23.498 7.06697 23.4267 7.03321 23.3524 7.00581C23.2781 6.97838 23.2019 6.95769 23.1239 6.94376C23.0459 6.92984 22.9673 6.92287 22.888 6.92287C22.8087 6.92287 22.7301 6.92984 22.6521 6.94376C22.5741 6.95769 22.4979 6.97838 22.4236 7.00581C22.3492 7.03321 22.278 7.06697 22.2097 7.10702C22.1414 7.14707 22.0772 7.1928 22.0171 7.24424C21.9608 7.29222 21.9103 7.34565 21.8657 7.40451C21.821 7.46337 21.7832 7.5263 21.7522 7.59332C21.7212 7.66034 21.6978 7.72989 21.682 7.80194C21.6661 7.87399 21.6582 7.94692 21.6582 8.02067C21.6582 8.09445 21.6661 8.16736 21.682 8.23944C21.6978 8.31149 21.7212 8.38101 21.7522 8.44802C21.7832 8.51504 21.821 8.578 21.8657 8.63686C21.9103 8.69572 21.9608 8.74912 22.0171 8.79713L24.713 11.2041L14.6935 11.2041C14.0124 11.2041 13.4665 11.6881 13.4665 12.2963C13.4665 12.9045 14.0124 13.3911 14.6935 13.3911L27.6768 13.3911C27.7444 13.3911 27.8483 13.3911 27.9159 13.36L27.9497 13.36C28.0617 13.3414 28.1687 13.3077 28.271 13.2587C28.3732 13.2098 28.4666 13.1476 28.5511 13.0722C28.6355 12.9968 28.7077 12.9112 28.7677 12.8154C28.8278 12.7195 28.8731 12.6172 28.9039 12.5085L28.9039 12.4775C28.9039 12.4154 28.9377 12.3248 28.9377 12.2653L28.9377 12.2342C28.9039 12.2342 28.9039 12.1721 28.9039 12.1125ZM27.6768 15.1562L14.6935 15.1562C14.6259 15.1562 14.5246 15.1562 14.4543 15.1873L14.4205 15.1873C14.3089 15.2061 14.2021 15.24 14.1001 15.2891C13.9981 15.3381 13.905 15.4003 13.8208 15.4757C13.7366 15.5511 13.6645 15.6366 13.6048 15.7324C13.5449 15.8281 13.4997 15.9302 13.469 16.0388L13.469 16.0672C13.469 16.1294 13.4327 16.2225 13.4327 16.282L13.4327 16.3105C13.427 16.3749 13.4383 16.4361 13.4665 16.4943C13.4665 16.5253 13.4665 16.5538 13.5002 16.5538C13.5002 16.6159 13.534 16.647 13.534 16.7091C13.5347 16.7183 13.5386 16.7257 13.5459 16.7314C13.5531 16.7371 13.5613 16.7391 13.5704 16.7376C13.6306 16.8522 13.7086 16.9531 13.8044 17.0404L18.614 21.3315C18.6741 21.3828 18.7382 21.4284 18.8064 21.4683C18.8746 21.5082 18.9458 21.5418 19.02 21.5692C19.0942 21.5965 19.1703 21.6171 19.2481 21.631C19.326 21.6448 19.4045 21.6518 19.4836 21.6518C19.5627 21.6518 19.6412 21.6448 19.7191 21.631C19.797 21.6171 19.873 21.5965 19.9472 21.5692C20.0214 21.5418 20.0926 21.5082 20.1608 21.4683C20.229 21.4284 20.2932 21.3828 20.3532 21.3315C20.4095 21.2835 20.46 21.2301 20.5047 21.1713C20.5493 21.1124 20.5871 21.0495 20.6181 20.9824C20.6491 20.9154 20.6725 20.8459 20.6883 20.7739C20.7042 20.7018 20.7121 20.6289 20.7121 20.5551C20.7121 20.4813 20.7042 20.4084 20.6883 20.3364C20.6725 20.2643 20.6491 20.1948 20.6181 20.1277C20.5871 20.0607 20.5493 19.9978 20.5047 19.9389C20.46 19.8801 20.4095 19.8266 20.3532 19.7787L17.6599 17.3768L27.6794 17.3768C28.3605 17.3768 28.9064 16.8903 28.9064 16.282C28.9064 15.6713 28.3605 15.1562 27.6794 15.1562L27.6768 15.1562Z" fill="rgb(241,49,68)" fill-rule="evenodd" />
<path id="矢量 78" d="M28.9039 12.1125C28.9039 12.0867 28.9039 12.053 28.8701 12.053C28.8701 11.9909 28.8363 11.9624 28.8363 11.9003C28.8363 11.8912 28.833 11.8836 28.8262 11.8774C28.8195 11.8712 28.8116 11.8685 28.8025 11.8693C28.7408 11.7542 28.6611 11.6532 28.5633 11.5665L23.7589 7.24424C23.6988 7.1928 23.6346 7.14707 23.5663 7.10702C23.498 7.06697 23.4267 7.03321 23.3524 7.00581C23.2781 6.97838 23.2019 6.95769 23.1239 6.94376C23.0459 6.92984 22.9673 6.92287 22.888 6.92287C22.8087 6.92287 22.7301 6.92984 22.6521 6.94376C22.5741 6.95769 22.4979 6.97838 22.4236 7.00581C22.3492 7.03321 22.278 7.06697 22.2097 7.10702C22.1414 7.14707 22.0772 7.1928 22.0171 7.24424C21.9608 7.29222 21.9103 7.34565 21.8657 7.40451C21.821 7.46337 21.7832 7.5263 21.7522 7.59332C21.7212 7.66034 21.6978 7.72989 21.682 7.80194C21.6661 7.87399 21.6582 7.94692 21.6582 8.02067C21.6582 8.09445 21.6661 8.16736 21.682 8.23944C21.6978 8.31149 21.7212 8.38101 21.7522 8.44802C21.7832 8.51504 21.821 8.578 21.8657 8.63686C21.9103 8.69572 21.9608 8.74912 22.0171 8.79713L24.713 11.2041L14.6935 11.2041C14.0124 11.2041 13.4665 11.6881 13.4665 12.2963C13.4665 12.9045 14.0124 13.3911 14.6935 13.3911L27.6768 13.3911C27.7444 13.3911 27.8483 13.3911 27.9159 13.36L27.9497 13.36C28.0617 13.3414 28.1687 13.3077 28.271 13.2587C28.3732 13.2098 28.4666 13.1476 28.5511 13.0722C28.6355 12.9968 28.7077 12.9112 28.7677 12.8154C28.8278 12.7195 28.8731 12.6172 28.9039 12.5085L28.9039 12.4775C28.9039 12.4154 28.9377 12.3248 28.9377 12.2653L28.9377 12.2342C28.9039 12.2342 28.9039 12.1721 28.9039 12.1125ZM27.6768 15.1562L14.6935 15.1562C14.6259 15.1562 14.5246 15.1562 14.4543 15.1873L14.4205 15.1873C14.3089 15.2061 14.2021 15.24 14.1001 15.2891C13.9981 15.3381 13.905 15.4003 13.8208 15.4757C13.7366 15.5511 13.6645 15.6366 13.6048 15.7324C13.5449 15.8281 13.4997 15.9302 13.469 16.0388L13.469 16.0672C13.469 16.1294 13.4327 16.2225 13.4327 16.282L13.4327 16.3105C13.427 16.3749 13.4383 16.4361 13.4665 16.4943C13.4665 16.5253 13.4665 16.5538 13.5002 16.5538C13.5002 16.6159 13.534 16.647 13.534 16.7091C13.5347 16.7183 13.5386 16.7257 13.5459 16.7314C13.5531 16.7371 13.5613 16.7391 13.5704 16.7376C13.6306 16.8522 13.7086 16.9531 13.8044 17.0404L18.614 21.3315C18.6741 21.3828 18.7382 21.4284 18.8064 21.4683C18.8746 21.5082 18.9458 21.5418 19.02 21.5692C19.0942 21.5965 19.1703 21.6171 19.2481 21.631C19.326 21.6448 19.4045 21.6518 19.4836 21.6518C19.5627 21.6518 19.6412 21.6448 19.7191 21.631C19.797 21.6171 19.873 21.5965 19.9472 21.5692C20.0214 21.5418 20.0926 21.5082 20.1608 21.4683C20.229 21.4284 20.2932 21.3828 20.3532 21.3315C20.4095 21.2835 20.46 21.2301 20.5047 21.1713C20.5493 21.1124 20.5871 21.0495 20.6181 20.9824C20.6491 20.9154 20.6725 20.8459 20.6883 20.7739C20.7042 20.7018 20.7121 20.6289 20.7121 20.5551C20.7121 20.4813 20.7042 20.4084 20.6883 20.3364C20.6725 20.2643 20.6491 20.1948 20.6181 20.1277C20.5871 20.0607 20.5493 19.9978 20.5047 19.9389C20.46 19.8801 20.4095 19.8266 20.3532 19.7787L17.6599 17.3768L27.6794 17.3768C28.3605 17.3768 28.9064 16.8903 28.9064 16.282C28.9064 15.6713 28.3605 15.1562 27.6794 15.1562L27.6768 15.1562Z" fill="rgb(241,49,68)" fill-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24.000000" height="24.000000" fill="none" customFrame="#000000">
<g id="组合 82">
<path id="矢量 90" d="M12 0C5.37259 0 0 5.37259 0 12C0 18.6274 5.37259 24 12 24C18.6274 24 24 18.6274 24 12C24 5.37259 18.6274 0 12 0ZM12.0967 20.9183C12.0215 20.9183 11.947 20.911 11.8732 20.8964C11.7994 20.8818 11.7278 20.8601 11.6583 20.8314C11.5888 20.8026 11.5227 20.7674 11.4601 20.7256C11.3976 20.6839 11.3397 20.6364 11.2865 20.5832C11.2332 20.5301 11.1857 20.4722 11.1439 20.4097C11.1021 20.3472 11.0668 20.2812 11.0379 20.2117C11.0091 20.1422 10.9873 20.0706 10.9726 19.9968C10.9579 19.9231 10.9506 19.8486 10.9505 19.7734C10.9505 19.6981 10.9578 19.6236 10.9724 19.5499C10.9871 19.4761 11.0088 19.4044 11.0375 19.3349C11.0663 19.2654 11.1016 19.1994 11.1433 19.1368C11.1851 19.0743 11.2326 19.0164 11.2857 18.9632C11.3389 18.91 11.3968 18.8625 11.4593 18.8207C11.5218 18.7788 11.5878 18.7435 11.6573 18.7147C11.7268 18.6859 11.7984 18.6642 11.8722 18.6495C11.946 18.6348 12.0205 18.6274 12.0957 18.6274C12.1709 18.6274 12.2454 18.6347 12.3192 18.6494C12.393 18.664 12.4646 18.6858 12.5341 18.7145C12.6036 18.7433 12.6696 18.7786 12.7322 18.8204C12.7947 18.8621 12.8526 18.9096 12.9058 18.9628C12.959 19.016 13.0065 19.0739 13.0483 19.1364C13.0901 19.1989 13.1254 19.265 13.1542 19.3345C13.183 19.4039 13.2047 19.4756 13.2194 19.5494C13.234 19.6231 13.2414 19.6976 13.2414 19.7728C13.2414 19.848 13.234 19.9225 13.2194 19.9962C13.2047 20.0699 13.183 20.1415 13.1543 20.211C13.1255 20.2805 13.0903 20.3464 13.0485 20.409C13.0067 20.4715 12.9593 20.5293 12.9062 20.5825C12.853 20.6357 12.7952 20.6832 12.7327 20.725C12.6702 20.7668 12.6043 20.8021 12.5348 20.8309C12.4654 20.8597 12.3938 20.8814 12.3201 20.8961C12.2464 20.9108 12.1719 20.9182 12.0967 20.9183L12.0967 20.9183ZM16.8597 9.53897C16.6122 10.2476 16.2057 10.9534 15.6838 11.58C15.345 11.9868 14.9855 12.3636 14.639 12.728C14.1887 13.2005 13.7635 13.6469 13.4017 14.1328C12.9375 14.7559 12.7603 15.4451 12.8586 16.2403C12.8671 16.3078 12.8688 16.3753 12.864 16.4431C12.8591 16.5109 12.8476 16.5775 12.8296 16.643C12.8116 16.7085 12.7874 16.7716 12.757 16.8324C12.7265 16.8931 12.6905 16.9503 12.6488 17.0039C12.6071 17.0575 12.5605 17.1066 12.5092 17.151C12.4578 17.1955 12.4026 17.2345 12.3435 17.2681C12.2845 17.3017 12.2227 17.3292 12.1582 17.3506C12.0938 17.372 12.0278 17.3869 11.9604 17.3953C11.9175 17.4007 11.8744 17.4034 11.8311 17.4034C11.7687 17.4033 11.7068 17.3976 11.6454 17.3863C11.584 17.3751 11.5241 17.3584 11.4657 17.3362C11.4074 17.3141 11.3514 17.2869 11.298 17.2547C11.2445 17.2224 11.1944 17.1857 11.1476 17.1443C11.1008 17.103 11.0581 17.0578 11.0195 17.0088C10.9809 16.9598 10.947 16.9076 10.9178 16.8524C10.8886 16.7973 10.8646 16.7399 10.8458 16.6804C10.827 16.6209 10.8137 16.5601 10.8059 16.4982C10.6394 15.1663 10.9541 13.9549 11.7416 12.8977C12.1784 12.3114 12.6672 11.7983 13.14 11.302C13.4785 10.9466 13.7984 10.6109 14.093 10.2569C14.8611 9.33439 15.2113 8.28957 15.0295 7.46198C14.9002 6.87129 14.4559 6.29819 13.8422 5.92784C13.5105 5.7303 13.1551 5.59496 12.776 5.52184C12.3969 5.44872 12.0167 5.44216 11.6353 5.50215C9.89896 5.78483 8.69664 7.49845 8.955 9.32198C8.96453 9.38924 8.96742 9.45677 8.96365 9.5246C8.95988 9.59242 8.94953 9.65922 8.9326 9.72501C8.91567 9.79079 8.89249 9.85429 8.86305 9.91551C8.83362 9.97672 8.79849 10.0345 8.75768 10.0888C8.71687 10.1431 8.67115 10.1929 8.62053 10.2382C8.5699 10.2835 8.51535 10.3234 8.45686 10.3579C8.39838 10.3925 8.33708 10.421 8.27298 10.4435C8.20888 10.4659 8.1432 10.4819 8.07595 10.4915C8.00869 10.501 7.94115 10.5039 7.87333 10.5001C7.80551 10.4963 7.73871 10.486 7.67292 10.4691C7.60714 10.4521 7.54364 10.429 7.48242 10.3995C7.4212 10.3701 7.36345 10.335 7.30915 10.2941C7.25485 10.2533 7.20505 10.2076 7.15976 10.157C7.11447 10.1064 7.07455 10.0518 7.04 9.99333C7.00546 9.93484 6.97695 9.87355 6.95447 9.80945C6.932 9.74534 6.916 9.67967 6.90646 9.61241C6.85706 9.26805 6.84022 8.9221 6.85595 8.57456C6.87167 8.22703 6.91968 7.88401 6.99997 7.54551C7.08026 7.20701 7.19143 6.87898 7.33347 6.56141C7.47551 6.24383 7.64594 5.9423 7.84474 5.65681C8.67077 4.46871 9.8987 3.68845 11.3028 3.45983C11.6121 3.40959 11.9234 3.38678 12.2367 3.3914C12.55 3.39602 12.8605 3.428 13.1682 3.48734C13.4758 3.54668 13.776 3.63246 14.0685 3.74469C14.3611 3.85692 14.6416 3.99386 14.91 4.15552C16.0172 4.82302 16.7979 5.86603 17.0501 7.01767C17.2278 7.82172 17.1634 8.67026 16.8595 9.53974L16.8597 9.53897Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,6 @@
<svg viewBox="0 0 33.8132 34.0272" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="33.813232" height="34.027222" fill="none" customFrame="#000000">
<g id="组合 68">
<path id="矢量 69" d="M27.9877 5.9865C27.9649 5.90294 27.9649 5.81937 27.9269 5.7358L27.1479 4.06445C26.3536 2.36651 24.9438 1.07501 23.1692 0.429257C21.3983 -0.212695 19.4869 -0.132925 17.7844 0.657168L8.35641 5.05586C7.9992 5.223 7.74839 5.51928 7.62679 5.86115L7.04537 5.86115C3.16168 5.86115 0 9.02152 0 12.9036L0 26.9848C0 30.8669 3.16168 34.0272 7.04537 34.0272L26.7679 34.0272C30.6516 34.0272 33.8132 30.8669 33.8132 26.9848L33.8132 12.8998C33.8094 9.43936 31.29 6.56768 27.9877 5.9865L27.9877 5.9865ZM18.9777 3.21358C19.9961 2.73876 21.1399 2.69318 22.2077 3.08063C23.2718 3.46808 24.1192 4.24298 24.5942 5.25718L24.8754 5.86115L13.2965 5.86115L18.9777 3.21358ZM30.9936 24.1701L24.9134 24.1701C22.584 24.1701 20.6877 22.2746 20.6877 19.9461C20.6877 17.6176 22.584 15.7221 24.9134 15.7221L30.9936 15.7221L30.9936 24.1701ZM24.9134 12.9036C21.0297 12.9036 17.868 16.064 17.868 19.9461C17.868 23.8282 21.0297 26.9886 24.9134 26.9886L30.9936 26.9886C30.9936 29.3171 29.0973 31.2125 26.7679 31.2125L7.04537 31.2125C4.71592 31.2125 2.81967 29.3171 2.81967 26.9886L2.81967 12.9036C2.81967 10.5751 4.71592 8.67966 7.04537 8.67966L26.7679 8.67966C29.0973 8.67966 30.9936 10.5751 30.9936 12.9036L24.9134 12.9036L24.9134 12.9036Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 70" d="M22.4243 19.9461C22.4243 20.0383 22.4288 20.1303 22.4379 20.222C22.4469 20.3137 22.4604 20.4048 22.4784 20.4952C22.4964 20.5857 22.5188 20.675 22.5456 20.7632C22.5723 20.8514 22.6034 20.9381 22.6387 21.0233C22.674 21.1084 22.7133 21.1917 22.7568 21.273C22.8003 21.3543 22.8476 21.4332 22.8989 21.5099C22.9501 21.5865 23.005 21.6605 23.0635 21.7318C23.122 21.803 23.1839 21.8712 23.2491 21.9364C23.3143 22.0016 23.3825 22.0634 23.4538 22.1219C23.5251 22.1804 23.5991 22.2352 23.6758 22.2865C23.7525 22.3377 23.8315 22.385 23.9128 22.4285C23.9941 22.4719 24.0774 22.5113 24.1626 22.5466C24.2478 22.5818 24.3345 22.6129 24.4228 22.6396C24.511 22.6664 24.6004 22.6888 24.6908 22.7067C24.7813 22.7247 24.8724 22.7382 24.9642 22.7473C25.056 22.7563 25.148 22.7608 25.2402 22.7608C25.3324 22.7608 25.4244 22.7563 25.5162 22.7473C25.608 22.7382 25.6991 22.7247 25.7895 22.7067C25.88 22.6888 25.9693 22.6664 26.0576 22.6396C26.1458 22.6129 26.2326 22.5818 26.3178 22.5466C26.403 22.5113 26.4862 22.4719 26.5676 22.4285C26.6489 22.385 26.7279 22.3377 26.8046 22.2865C26.8813 22.2352 26.9553 22.1804 27.0266 22.1219C27.0978 22.0634 27.1661 22.0016 27.2313 21.9364C27.2965 21.8712 27.3584 21.803 27.4169 21.7318C27.4754 21.6605 27.5303 21.5865 27.5815 21.5099C27.6327 21.4332 27.6801 21.3543 27.7236 21.273C27.767 21.1917 27.8064 21.1084 27.8417 21.0233C27.877 20.9381 27.908 20.8514 27.9348 20.7632C27.9616 20.675 27.984 20.5857 28.0019 20.4952C28.0199 20.4048 28.0335 20.3138 28.0425 20.222C28.0515 20.1303 28.0561 20.0383 28.0561 19.9461C28.0561 19.8539 28.0515 19.762 28.0425 19.6702C28.0335 19.5785 28.0199 19.4874 28.0019 19.397C27.984 19.3066 27.9616 19.2173 27.9348 19.1291C27.908 19.0408 27.877 18.9541 27.8417 18.869C27.8064 18.7838 27.767 18.7006 27.7236 18.6193C27.6801 18.538 27.6327 18.459 27.5815 18.3823C27.5303 18.3057 27.4754 18.2317 27.4169 18.1605C27.3584 18.0892 27.2965 18.021 27.2313 17.9558C27.1661 17.8906 27.0978 17.8288 27.0266 17.7703C26.9553 17.7118 26.8813 17.657 26.8046 17.6058C26.7279 17.5546 26.6489 17.5072 26.5676 17.4638C26.4862 17.4203 26.403 17.3809 26.3178 17.3457C26.2326 17.3104 26.1458 17.2794 26.0576 17.2526C25.9693 17.2258 25.88 17.2035 25.7895 17.1855C25.6991 17.1675 25.608 17.154 25.5162 17.145C25.4244 17.1359 25.3324 17.1314 25.2402 17.1314C25.148 17.1314 25.056 17.1359 24.9642 17.145C24.8724 17.154 24.7813 17.1675 24.6908 17.1855C24.6004 17.2035 24.511 17.2258 24.4228 17.2526C24.3345 17.2794 24.2478 17.3104 24.1626 17.3457C24.0774 17.3809 23.9941 17.4203 23.9128 17.4638C23.8315 17.5072 23.7525 17.5546 23.6758 17.6058C23.5991 17.657 23.5251 17.7118 23.4538 17.7703C23.3825 17.8288 23.3143 17.8906 23.2491 17.9558C23.1839 18.021 23.122 18.0892 23.0635 18.1605C23.005 18.2317 22.9501 18.3057 22.8989 18.3823C22.8476 18.459 22.8003 18.538 22.7568 18.6193C22.7133 18.7006 22.674 18.7838 22.6387 18.869C22.6034 18.9541 22.5723 19.0408 22.5456 19.1291C22.5188 19.2173 22.4964 19.3066 22.4784 19.397C22.4604 19.4874 22.4469 19.5785 22.4379 19.6702C22.4288 19.762 22.4243 19.8539 22.4243 19.9461Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -0,0 +1,6 @@
<svg viewBox="0 0 22 25" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="22.000000" height="25.000000" fill="none" customFrame="#000000">
<g id="组合 78">
<path id="矢量 80" d="M3.47368 0L18.5263 0C18.6401 0 18.7536 0.0054719 18.8668 0.0164157C18.98 0.0273595 19.0924 0.0437225 19.204 0.0655047C19.3156 0.0872869 19.4258 0.114383 19.5347 0.146794C19.6435 0.179205 19.7505 0.216774 19.8556 0.259502C19.9607 0.302229 20.0635 0.349909 20.1638 0.402541C20.2641 0.455173 20.3616 0.512505 20.4562 0.574535C20.5508 0.636566 20.6421 0.702997 20.73 0.773828C20.8179 0.844659 20.9021 0.91955 20.9826 0.998499C21.063 1.07745 21.1393 1.16008 21.2115 1.24639C21.2837 1.33269 21.3514 1.42227 21.4146 1.5151C21.4778 1.60794 21.5362 1.70359 21.5898 1.80206C21.6435 1.90052 21.692 2.00134 21.7356 2.10449C21.7791 2.20764 21.8174 2.31264 21.8504 2.41948C21.8834 2.52633 21.9111 2.6345 21.9333 2.74401C21.9555 2.85352 21.9721 2.96383 21.9833 3.07494C21.9944 3.18606 22 3.29744 22 3.40909L22 21.5909C22 21.7026 21.9944 21.8139 21.9833 21.9251C21.9721 22.0362 21.9554 22.1465 21.9333 22.256C21.9111 22.3655 21.8834 22.4737 21.8504 22.5805C21.8174 22.6874 21.7791 22.7924 21.7356 22.8955C21.692 22.9987 21.6435 23.0995 21.5898 23.1979C21.5362 23.2964 21.4778 23.3921 21.4146 23.4849C21.3514 23.5777 21.2837 23.6673 21.2115 23.7536C21.1393 23.8399 21.063 23.9226 20.9826 24.0015C20.9021 24.0805 20.8179 24.1553 20.73 24.2262C20.6421 24.297 20.5508 24.3634 20.4562 24.4255C20.3616 24.4875 20.2641 24.5448 20.1638 24.5975C20.0635 24.6501 19.9607 24.6978 19.8556 24.7405C19.7505 24.7832 19.6435 24.8208 19.5347 24.8532C19.4258 24.8856 19.3156 24.9127 19.204 24.9345C19.0924 24.9563 18.98 24.9726 18.8668 24.9836C18.7536 24.9945 18.6401 25 18.5263 25L3.47368 25C3.35992 25 3.24642 24.9945 3.1332 24.9836C3.01998 24.9726 2.90758 24.9563 2.796 24.9345C2.68442 24.9127 2.5742 24.8856 2.46533 24.8532C2.35646 24.8208 2.24947 24.7832 2.14436 24.7405C2.03926 24.6978 1.93653 24.6501 1.8362 24.5975C1.73587 24.5448 1.6384 24.4875 1.54381 24.4255C1.44921 24.3634 1.35795 24.297 1.27 24.2262C1.18206 24.1553 1.09786 24.0805 1.01742 24.0015C0.936973 23.9226 0.860663 23.8399 0.78849 23.7536C0.716317 23.6673 0.648627 23.5777 0.585421 23.4849C0.522216 23.3921 0.463798 23.2964 0.410168 23.1979C0.356539 23.0995 0.307955 22.9987 0.264418 22.8955C0.220882 22.7924 0.182601 22.6874 0.149576 22.5805C0.116551 22.4737 0.0889408 22.3655 0.0667459 22.256C0.0445509 22.1465 0.0278779 22.0362 0.0167267 21.9251C0.00557558 21.8139 0 21.7026 0 21.5909L0 3.40909C-1.41272e-08 3.29744 0.00557555 3.18606 0.0167267 3.07494C0.0278778 2.96383 0.0445509 2.85352 0.0667458 2.74401C0.0889407 2.6345 0.116551 2.52633 0.149576 2.41948C0.182601 2.31264 0.220881 2.20764 0.264418 2.10449C0.307955 2.00134 0.356539 1.90053 0.410168 1.80206C0.463798 1.70359 0.522215 1.60794 0.585421 1.5151C0.648627 1.42227 0.716317 1.3327 0.78849 1.24639C0.860663 1.16008 0.936973 1.07745 1.01742 0.9985C1.09786 0.91955 1.18206 0.84466 1.27 0.773828C1.35795 0.702997 1.44921 0.636566 1.54381 0.574536C1.6384 0.512505 1.73587 0.455174 1.8362 0.402542C1.93653 0.349909 2.03926 0.302229 2.14436 0.259502C2.24947 0.216775 2.35646 0.179206 2.46533 0.146795C2.5742 0.114384 2.68442 0.0872873 2.796 0.0655051C2.90758 0.0437228 3.01998 0.0273598 3.1332 0.016416C3.24642 0.00547223 3.35992 3.20962e-07 3.47368 3.17496e-07L3.47368 0Z" fill="rgb(241,49,68)" fill-rule="nonzero" />
<path id="矢量 81" d="M17.6578 17.0455C17.7149 17.0455 17.7713 17.0509 17.8273 17.0618C17.8832 17.0728 17.9375 17.0889 17.9902 17.1103C18.0429 17.1317 18.0929 17.158 18.1403 17.1891C18.1877 17.2202 18.2316 17.2555 18.2719 17.2951C18.3122 17.3347 18.3482 17.3777 18.3799 17.4242C18.4116 17.4708 18.4383 17.5199 18.4602 17.5716C18.482 17.6233 18.4985 17.6766 18.5096 17.7315C18.5207 17.7863 18.5263 17.8418 18.5263 17.8977C18.5263 17.9537 18.5207 18.0091 18.5096 18.064C18.4985 18.1189 18.482 18.1722 18.4602 18.2239C18.4383 18.2756 18.4116 18.3247 18.3799 18.3712C18.3482 18.4178 18.3122 18.4608 18.2719 18.5004C18.2316 18.5399 18.1877 18.5753 18.1403 18.6064C18.0929 18.6375 18.0429 18.6637 17.9902 18.6851C17.9375 18.7065 17.8832 18.7227 17.8273 18.7336C17.7713 18.7445 17.7149 18.75 17.6578 18.75L4.34205 18.75C4.28503 18.75 4.22856 18.7445 4.17263 18.7336C4.11671 18.7227 4.0624 18.7065 4.00972 18.6851C3.95704 18.6637 3.907 18.6375 3.85958 18.6064C3.81217 18.5753 3.76831 18.5399 3.72799 18.5004C3.68767 18.4608 3.65167 18.4178 3.61999 18.3712C3.58831 18.3247 3.56156 18.2756 3.53974 18.2239C3.51792 18.1722 3.50144 18.1189 3.49032 18.064C3.47919 18.0091 3.47363 17.9537 3.47363 17.8977C3.47363 17.8418 3.47919 17.7863 3.49032 17.7315C3.50144 17.6766 3.51792 17.6233 3.53974 17.5716C3.56156 17.5199 3.58831 17.4708 3.61999 17.4242C3.65167 17.3777 3.68767 17.3347 3.72799 17.2951C3.76831 17.2555 3.81217 17.2202 3.85958 17.1891C3.907 17.158 3.95704 17.1317 4.00972 17.1103C4.0624 17.0889 4.11671 17.0728 4.17263 17.0618C4.22856 17.0509 4.28503 17.0455 4.34205 17.0455L17.6578 17.0455ZM17.6578 11.3636C17.7149 11.3636 17.7713 11.3691 17.8273 11.38C17.8832 11.3909 17.9375 11.4071 17.9902 11.4285C18.0429 11.4499 18.0929 11.4762 18.1403 11.5073C18.1877 11.5384 18.2316 11.5737 18.2719 11.6133C18.3122 11.6528 18.3482 11.6959 18.3799 11.7424C18.4116 11.7889 18.4383 11.8381 18.4602 11.8898C18.482 11.9415 18.4985 11.9948 18.5096 12.0496C18.5207 12.1045 18.5263 12.16 18.5263 12.2159C18.5263 12.2719 18.5207 12.3273 18.5096 12.3822C18.4985 12.4371 18.482 12.4904 18.4602 12.5421C18.4383 12.5938 18.4116 12.6429 18.3799 12.6894C18.3482 12.7359 18.3122 12.779 18.2719 12.8186C18.2316 12.8581 18.1877 12.8935 18.1403 12.9246C18.0929 12.9556 18.0429 12.9819 17.9902 13.0033C17.9375 13.0247 17.8832 13.0409 17.8273 13.0518C17.7713 13.0627 17.7149 13.0682 17.6578 13.0682L4.34205 13.0682C4.28503 13.0682 4.22856 13.0627 4.17263 13.0518C4.11671 13.0409 4.0624 13.0247 4.00972 13.0033C3.95704 12.9819 3.907 12.9556 3.85958 12.9246C3.81217 12.8935 3.76831 12.8581 3.72799 12.8186C3.68767 12.779 3.65167 12.7359 3.61999 12.6894C3.58831 12.6429 3.56156 12.5938 3.53974 12.5421C3.51792 12.4904 3.50144 12.4371 3.49032 12.3822C3.47919 12.3273 3.47363 12.2719 3.47363 12.2159C3.47363 12.16 3.47919 12.1045 3.49032 12.0496C3.50144 11.9948 3.51792 11.9415 3.53974 11.8898C3.56156 11.8381 3.58831 11.7889 3.61999 11.7424C3.65167 11.6959 3.68767 11.6528 3.72799 11.6133C3.76831 11.5737 3.81217 11.5384 3.85958 11.5073C3.907 11.4762 3.95704 11.4499 4.00972 11.4285C4.0624 11.4071 4.11671 11.3909 4.17263 11.38C4.22856 11.3691 4.28503 11.3636 4.34205 11.3636L17.6578 11.3636ZM11.8684 5.68182C11.9254 5.68182 11.9819 5.68728 12.0378 5.6982C12.0937 5.70912 12.148 5.72528 12.2007 5.7467C12.2534 5.76811 12.3034 5.79437 12.3508 5.82546C12.3982 5.85655 12.4421 5.89188 12.4824 5.93145C12.5228 5.97102 12.5588 6.01407 12.5904 6.0606C12.6221 6.10713 12.6489 6.15624 12.6707 6.20795C12.6925 6.25965 12.709 6.31294 12.7201 6.36783C12.7312 6.42271 12.7368 6.47814 12.7368 6.5341C12.7368 6.59006 12.7312 6.64548 12.7201 6.70037C12.709 6.75525 12.6925 6.80855 12.6707 6.86025C12.6489 6.91195 12.6221 6.96106 12.5904 7.00759C12.5588 7.05412 12.5228 7.09717 12.4824 7.13674C12.4421 7.17631 12.3982 7.21165 12.3508 7.24274C12.3034 7.27383 12.2534 7.30008 12.2007 7.32149C12.148 7.34291 12.0937 7.35908 12.0378 7.36999C11.9819 7.38091 11.9254 7.38637 11.8684 7.38637L4.34205 7.38637C4.28503 7.38637 4.22856 7.38091 4.17263 7.36999C4.11671 7.35908 4.0624 7.34291 4.00972 7.32149C3.95704 7.30008 3.907 7.27383 3.85959 7.24274C3.81217 7.21165 3.76831 7.17631 3.72799 7.13674C3.68767 7.09717 3.65167 7.05412 3.61999 7.00759C3.58831 6.96106 3.56156 6.91195 3.53974 6.86025C3.51792 6.80855 3.50144 6.75525 3.49032 6.70037C3.4792 6.64548 3.47363 6.59006 3.47363 6.5341C3.47363 6.47814 3.4792 6.42271 3.49032 6.36783C3.50144 6.31294 3.51792 6.25965 3.53974 6.20795C3.56156 6.15624 3.58831 6.10713 3.61999 6.0606C3.65167 6.01407 3.68767 5.97102 3.72799 5.93145C3.76831 5.89188 3.81217 5.85655 3.85959 5.82546C3.907 5.79437 3.95704 5.76811 4.00972 5.7467C4.0624 5.72528 4.11671 5.70912 4.17263 5.6982C4.22856 5.68728 4.28503 5.68182 4.34205 5.68182L11.8684 5.68182Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -0,0 +1,5 @@
<svg viewBox="0 0 65 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="65.000000" height="64.000000" fill="none" customFrame="#000000">
<g id="组合 34">
<path id="矢量 53" d="M28.414 37.709L28.7398 37.8194L29.0111 34.3554C29.0111 34.3554 27.6723 35.2355 26.6232 36.1695C27.7084 36.8298 28.414 37.709 28.414 37.709ZM36.3555 17.1854C36.7805 16.377 36.365 15.8579 35.6229 15.7416C35.4428 16.3616 35.2627 16.981 35.0831 17.6005C35.3636 17.6084 35.6417 17.6181 35.9161 17.6307C36.0872 17.5351 36.2373 17.3866 36.3555 17.1854ZM32.5 0C14.5507 0 0 14.3268 0 32C0 49.673 14.5508 64 32.5 64C50.4491 64 65 49.673 65 32C64.9998 14.3267 50.4491 0 32.5 0ZM26.1686 16.0343C26.817 14.2698 28.5399 13.8174 30.6398 13.8088C30.4077 14.5715 30.1746 15.3345 29.9417 16.0973C28.5678 15.8506 28.1141 17.2746 29.0891 17.8153C29.3231 17.7945 29.5604 17.7753 29.7998 17.7568L31.9331 11.3055L34.5558 11.1725L34.1983 12.0959L32.6481 12.2462L30.7429 17.6912C30.8422 17.685 30.9412 17.6787 31.0413 17.6729L32.8492 12.4621L35.4495 12.34L35.0856 13.339L33.4855 13.4144L32.0487 17.6224C32.1447 17.6183 32.2399 17.6138 32.3368 17.6101L33.6747 13.6472L36.5778 13.5299C38.5093 13.8963 39.5396 16.182 38.7289 17.8492C48.3578 18.9089 53.4342 22.7555 53.4342 22.7555C53.4342 22.7555 46.5929 20.1611 34.1649 19.7649L33.1432 22.3482L30.7239 22.3874L31.6248 19.7191C31.5271 19.719 31.4298 19.7191 31.3327 19.7195L30.913 20.9488L29.8892 20.9938L30.3273 19.7311C30.227 19.7331 30.1267 19.735 30.027 19.7373L30.0191 19.7598L29.1197 19.8134L29.1358 19.7649C29.0159 19.7694 28.8968 19.7744 28.7778 19.7796L28.7773 19.7812C28.7753 19.7808 28.7734 19.7802 28.7713 19.7799C18.9205 20.208 12.2957 22.7555 12.2957 22.7555C12.2957 22.7555 16.4311 19.4819 26.2946 18.1296C25.9424 17.524 25.8484 16.8029 26.1686 16.0343ZM52.1853 45.6806C49.8224 48.2598 45.338 50.5487 42.2572 51.5406C38.3322 52.8049 35.3067 52.8273 35.3067 52.8273L37.6401 40.6231L36.5 39.4137L35.0891 46.3957L26.7315 46.3957C26.7315 46.3957 25.4023 48.2232 21.6347 49.1304C19.1078 49.8072 15.4474 50.1921 11.264 48.4843C10.4294 48.0384 9.80655 47.4829 9.34453 46.8774C7.43412 44.3711 8.27905 41.0082 8.27905 41.0082C8.27905 41.0082 12.8742 40.9712 14.9001 41.0082C14.4747 42.7925 15.0352 43.9666 16.2027 44.4711C18.2617 44.9328 20.9247 44.026 21.5755 42.4372C23.4029 38.4788 18.5906 36.5543 18.5906 36.5543C25.4472 33.9525 23.855 30.8003 23.0409 30.1772C19.3684 27.8867 17.7765 32.1564 17.7765 32.1564L10.9383 32.1564C11.5716 28.4546 15.4249 24.6796 22.0098 24.6796C28.5951 24.6065 30.5301 28.0882 30.5301 28.0882L31.5615 23.5251L43.4473 23.5251C49.7056 23.4706 52.9062 28.196 52.9439 28.2519C51.5959 28.6141 50.6019 29.8575 50.6019 31.3366C50.6019 33.0992 52.0138 34.5283 53.7546 34.5283C54.3755 34.5283 54.9539 34.3457 55.4419 34.032C55.4656 34.2591 56.1715 41.2999 52.1853 45.6806ZM42.7456 28.9709C39.1791 28.9709 36.2878 31.9014 36.2878 35.5171C36.2878 39.1328 39.179 42.0633 42.7456 42.0633C46.3121 42.0633 49.2034 39.1328 49.2034 35.5171C49.2034 31.9013 46.3121 28.9709 42.7456 28.9709Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,3 @@
<svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="64.000000" fill="none" customFrame="#000000">
<path id="矢量 52" d="M32.0001 0C14.327 0 0 14.3269 0 32C0 49.6731 14.327 64 32.0001 64C49.6731 64 64 49.6731 64 32C63.9999 14.3269 49.6731 0 32.0001 0ZM52.9746 16.5337C52.6756 17.2649 52.3764 17.9962 52.0773 18.7274C51.1994 19.7145 47.1946 19.5488 45.4964 19.874C42.1244 20.5198 39.9534 21.2417 39.4142 24.71C39.4973 24.71 39.5803 24.71 39.6634 24.71C40.5607 24.5936 41.4583 24.4773 42.3556 24.3609C42.6713 23.2643 42.987 22.1672 43.3027 21.0705C44.6488 20.8046 45.9951 20.5387 47.341 20.2728C47.0586 21.4194 46.7759 22.5663 46.4935 23.7128C48.205 23.4469 49.917 23.181 51.6285 22.9151C51.6285 22.9318 51.6285 22.9484 51.6285 22.965C51.3294 23.7791 51.0302 24.5936 50.731 25.4079C49.0694 25.6571 47.4073 25.9064 45.7456 26.1557C45.4466 27.2357 45.1474 28.3162 44.8483 29.3962C44.0136 32.1402 43.3776 34.6959 39.4141 33.4843C38.8158 33.2517 38.2175 33.019 37.6193 32.7863C36.2625 33.7702 34.5113 34.7079 32.1353 34.3817C32.667 32.8532 33.1988 31.3239 33.7306 29.7951C34.8589 30.0452 35.0517 30.2694 36.3231 29.9945C35.7405 27.7268 38.2097 26.4735 39.5138 27.9504C40.4855 29.0511 39.3013 30.3223 39.2147 31.1412C39.3808 31.1578 39.5471 31.1744 39.7133 31.1911C40.8362 30.4825 41.3541 28.2227 41.6077 26.7041C39.2149 27.0696 36.8214 27.4353 34.4287 27.8009C34.7776 27.0199 35.1266 26.2386 35.4756 25.4577C36.6667 22.7403 37.6389 20.0061 40.3614 18.827C44.2905 17.1253 50.4798 17.3788 53.6227 14.9383C53.7043 15.3733 53.1544 16.1221 52.9746 16.5337ZM12.2433 51.831C12.8581 49.7041 13.4731 47.5765 14.0879 45.4496C14.9643 42.9914 16.2414 40.7002 17.3783 38.4699C18.3255 36.6255 19.2729 34.7805 20.22 32.936C22.0178 30.1368 24.3002 27.551 26.3522 24.9592C27.753 23.1899 29.6255 21.7209 30.8889 19.8242C29.4233 20.7224 28.614 20.7901 26.4519 21.1204C25.6875 21.1537 24.9229 21.1869 24.1586 21.2201C20.5085 22.0271 18.6903 23.9875 17.7772 27.5018C16.1154 27.7677 14.4533 28.0337 12.7917 28.2996C12.7917 28.2829 12.7917 28.2663 12.7917 28.2497C13.8385 24.8931 14.8857 21.5355 15.9325 18.179C17.1954 18.046 18.4586 17.9131 19.7215 17.7802C19.7048 18.0958 19.6883 18.4117 19.6716 18.7274C23.2753 17.1819 26.3396 15.3956 30.6397 14.4897C34.6711 13.6404 36.9813 15.362 39.0154 12.0967C39.6965 12.0302 40.3781 11.9637 41.0593 11.8972C41.1591 11.8972 41.2588 11.8972 41.3584 11.8972C40.6273 13.3761 39.896 14.8554 39.1649 16.3343C37.1111 19.6083 34.4669 22.4572 32.4345 25.8067C31.7864 27.1693 31.1381 28.5322 30.4901 29.8948C29.3875 32.3979 28.1812 35.1502 27.2994 37.8716C26.0723 41.6581 25.5411 45.7513 24.9562 50.1358C20.7191 50.7008 16.4805 51.2659 12.2433 51.831ZM51.8779 29.6954C51.8613 30.0278 51.8447 30.3602 51.8281 30.6925C51.6999 31.2623 51.3984 31.8354 51.0802 32.238C50.7226 32.6904 50.0475 33.1024 49.435 33.2849C49.1473 33.3708 48.8253 33.3116 48.6374 33.4844C47.9728 34.4149 47.3079 35.3457 46.6432 36.2762C46.8208 36.9667 48.2596 36.454 48.9365 36.5755C49.0362 36.6752 49.136 36.7749 49.2356 36.8745C49.231 37.7456 47.2299 39.8666 46.6432 40.3145C46.7096 40.4142 46.7761 40.5139 46.8426 40.6136C47.7022 40.6727 48.5893 40.4561 49.136 40.8629C49.1692 41.029 49.2024 41.1953 49.2357 41.3614C48.7377 42.4138 47.9815 43.2446 47.3411 44.1532C46.7429 45.1835 46.1446 46.2141 45.5464 47.2443C43.4115 47.5439 39.586 48.9108 38.0183 47.6929C37.0812 46.965 37.4636 46.3714 37.0212 45.2002C36.6888 46.3467 36.3565 47.4936 36.0241 48.6402C34.7115 48.8728 33.3982 49.1055 32.0855 49.3381C32.0855 49.3215 32.0855 49.3049 32.0855 49.2882C32.2683 48.6236 32.4512 47.9588 32.634 47.2941C31.0259 48.3239 29.7203 49.573 27.2995 49.8367C27.2995 49.8201 27.2995 49.8035 27.2995 49.7868C27.7813 48.4243 28.2634 47.0613 28.7453 45.6988C29.6405 46.2284 31.96 44.4924 32.4843 43.9039C31.3212 44.1532 30.1577 44.4027 28.9945 44.6518C28.9945 44.6353 28.9945 44.6187 28.9945 44.602C29.277 43.7878 29.5596 42.9734 29.842 42.1592C31.4206 41.7936 32.9997 41.4279 34.5782 41.0622C34.6281 40.8463 34.6779 40.6303 34.7278 40.4142C33.9081 40.596 31.304 42.219 30.6895 40.9127C30.4339 40.3577 30.9324 39.181 31.0883 38.5696C32.0687 38.3868 33.0494 38.204 34.0298 38.0213C34.0089 38.3017 33.8318 38.724 33.9799 38.8189C34.1881 38.9909 34.5815 39.1996 34.8275 39.1679C35.0934 38.553 35.3593 37.938 35.6251 37.3233C35.6251 37.3067 35.6251 37.2901 35.6251 37.2734C34.0798 37.5559 32.534 37.8385 30.9887 38.121C30.9887 38.1044 30.9887 38.0879 30.9887 38.0711C31.2712 37.2902 31.5537 36.509 31.8362 35.7281C36.0567 34.9471 40.2788 34.1658 44.4993 33.385C44.1565 35.5486 41.8755 36.0733 39.6634 36.3762C39.5969 36.5423 39.5304 36.7086 39.464 36.8748C41.0174 36.4914 42.4357 35.5478 43.3526 37.2238C43.4213 35.6801 46.104 34.1256 46.9421 33.0359C46.9421 33.0193 46.9421 33.0027 46.9421 32.9862C44.4804 32.0537 44.7826 28.3599 46.7926 27.1531C48.6 26.0681 51.2712 27.1687 51.6285 28.8981C52.5425 28.3165 53.4567 27.7347 54.3706 27.1531C53.5398 28.0003 52.7087 28.848 51.8779 29.6954Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,9 @@
<svg viewBox="0 0 64 63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="63.000000" fill="none" customFrame="#000000">
<g id="组合 27">
<path id="矢量 40" d="M18.2537 31.5L16.4316 31.5C16.5594 31.311 16.7193 31.122 16.8791 30.87L18.6054 30.87L18.957 30.0195L14.7692 30.0195L14.4176 30.87L15.4725 30.87C15.025 31.689 14.3856 32.4135 13.5864 32.9175L13.2028 33.831L13.4585 33.7365L14.002 33.4845L13.7782 34.02C14.1938 34.083 14.5774 34.209 14.961 34.3665C14.2258 35.028 13.4266 35.595 12.5315 36.036L12.1798 36.918C14.6413 36.225 16.6873 34.587 17.9021 32.382L18.2537 31.5L18.2537 31.5ZM15.8561 33.39C15.4725 33.264 15.0889 33.201 14.6733 33.138C15.025 32.9175 15.3446 32.6655 15.6324 32.382L16.4955 32.382C16.3357 32.76 16.1119 33.075 15.8561 33.39L15.8561 33.39ZM20.2997 30.303L19.0849 30.303L17.0709 35.3745L18.3177 35.3745L20.2997 30.303Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 41" d="M20.971 29.799L18.6374 35.721C18.6054 35.91 18.4456 36.0045 18.2537 36.0045L17.6783 36.0045L17.3586 36.8235L18.4136 36.8235C19.0529 36.855 19.6284 36.477 19.8521 35.91L22.3137 29.8305L20.971 29.8305L20.971 29.799ZM7.35265 33.579L7.67233 32.697L7.41659 32.76L7.09691 32.8545L7.6084 31.5L7.99201 31.5L8.31169 30.618L7.92808 30.618L8.27972 29.736L7.03297 29.736L6.71329 30.618L6.2018 30.618L5.88212 31.5L6.32967 31.5L5.72228 33.075L5.4026 33.075L5.05095 33.138L4.63537 34.1775L5.05095 34.1145C5.14686 34.083 5.24276 34.0515 5.33867 34.0515L4.69931 35.721C4.66734 35.9415 4.47553 36.0675 4.25175 36.036L4.05995 36.036L3.74026 36.8865L4.47553 36.8865C5.17883 36.918 5.81819 36.477 6.00999 35.8155L6.8092 33.705L7.35265 33.579L7.35265 33.579ZM12.2757 34.524L11.0609 34.524L11.5405 33.3585L12.4995 33.3585L12.8512 32.445L11.8921 32.445L12.2438 31.5L13.2987 31.5L13.6823 30.555L12.5954 30.555L12.9471 29.673L11.6364 29.673L8.85515 36.918L10.1658 36.918L10.7732 35.3745L11.9241 35.3745L12.2757 34.524Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 42" d="M9.87815 29.7045L9.52651 30.618L8.59943 30.618L8.24779 31.5315L9.17486 31.5315L8.79124 32.508L7.96007 32.508L7.60843 33.39L8.47156 33.39L8.02401 34.524L6.90513 34.524L6.58545 35.3745L7.70433 35.3745L7.09694 36.918L8.40763 36.9495L11.1569 29.7045L9.87815 29.7045Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 43" d="M32 0C14.3217 0 0 14.112 0 31.5C0 48.888 14.3217 63 32 63C49.6783 63 64 48.888 64 31.5C64 14.112 49.6783 0 32 0ZM54.8252 16.128L56.967 17.388L47.025 24.885L54.8252 16.128L54.8252 16.128ZM43.3486 11.9385L43.4765 11.9385C46.7373 11.9385 48.3676 13.545 48.3676 16.758C48.3676 19.971 46.7373 21.5775 43.4765 21.5775L43.3486 21.5775C40.0879 21.5775 38.4575 19.971 38.4575 16.758C38.4256 13.5135 40.0559 11.9385 43.3486 11.9385ZM32.2238 6.3L32.2238 20.3175L28.3237 6.3L32.2238 6.3ZM26.8212 14.1435L29.0589 21.3255L24.6154 15.0255L26.8212 14.1435ZM17.5824 14.3955L25.6703 23.9085L14.6094 16.8525L17.5824 14.3955L17.5824 14.3955ZM14.1618 45.7065L24.7432 42.4935L15.9201 48.9195L14.1618 45.7065L14.1618 45.7065ZM26.1179 55.818L23.8801 55.818L28.3237 47.502L26.1179 55.818L26.1179 55.818ZM35.7083 47.3445L35.4206 47.3445C29.7622 47.3445 24.9351 43.911 22.9211 39.06L1.37463 39.06L4.15584 28.2555L23.7203 27.405C26.0539 23.436 30.4016 20.7585 35.3886 20.7585L35.6763 20.7585C43.1249 20.7585 49.1668 26.712 49.1668 34.0515C49.1668 41.391 43.1568 47.3445 35.7083 47.3445L35.7083 47.3445ZM55.4965 24.255L56.6473 25.956L50.6374 27.6885L55.4965 24.255ZM50.8931 30.744L63.4885 29.2005L63.4885 32.0985L50.8931 30.744Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 44" d="M40.7912 33.39C42.1019 32.823 42.9011 31.5 42.7413 30.114C42.7732 28.917 42.3257 27.783 41.4945 26.901C40.4715 25.956 38.969 25.641 35.7083 25.641C30.1139 25.641 28.6114 26.6175 28.5155 31.0905L32.1918 31.0905C32.1918 29.736 32.1918 28.98 35.4525 28.98C37.8501 28.98 39.0969 29.0745 39.0969 30.618C39.0969 32.1615 38.01 32.1615 37.1149 32.1615L33.9181 32.1615L33.9181 35.028L37.1149 35.028C38.042 35.028 39.3526 34.902 39.3526 36.729C39.3526 38.556 37.6903 38.5245 36.028 38.5245C32.1279 38.5245 31.9041 38.3355 31.9041 36.036L28.1319 36.036C28.1319 40.4775 29.027 41.8635 35.9321 41.8635C39.8641 41.8635 43.0609 41.328 43.0609 37.107C43.0609 34.272 41.4945 33.642 40.7912 33.39Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,11 @@
<svg viewBox="0 0 64 63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.000000" height="63.000000" fill="none" customFrame="#000000">
<g id="组合 29">
<path id="矢量 40" d="M18.2537 31.5L16.4316 31.5C16.5594 31.311 16.7193 31.122 16.8791 30.87L18.6054 30.87L18.957 30.0195L14.7692 30.0195L14.4176 30.87L15.4725 30.87C15.025 31.689 14.3856 32.4135 13.5864 32.9175L13.2028 33.831L13.4585 33.7365L14.002 33.4845L13.7782 34.02C14.1938 34.083 14.5774 34.209 14.961 34.3665C14.2258 35.028 13.4266 35.595 12.5315 36.036L12.1798 36.918C14.6413 36.225 16.6873 34.587 17.9021 32.382L18.2537 31.5L18.2537 31.5ZM15.8561 33.39C15.4725 33.264 15.0889 33.201 14.6733 33.138C15.025 32.9175 15.3446 32.6655 15.6324 32.382L16.4955 32.382C16.3357 32.76 16.1119 33.075 15.8561 33.39L15.8561 33.39ZM20.2997 30.303L19.0849 30.303L17.0709 35.3745L18.3177 35.3745L20.2997 30.303Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 41" d="M20.971 29.799L18.6374 35.721C18.6054 35.91 18.4456 36.0045 18.2537 36.0045L17.6783 36.0045L17.3586 36.8235L18.4136 36.8235C19.0529 36.855 19.6284 36.477 19.8522 35.91L22.3137 29.8305L20.971 29.8305L20.971 29.799ZM7.35265 33.579L7.67233 32.697L7.41659 32.76L7.09691 32.8545L7.6084 31.5L7.99201 31.5L8.31169 30.618L7.92808 30.618L8.27972 29.736L7.03297 29.736L6.71329 30.618L6.2018 30.618L5.88212 31.5L6.32967 31.5L5.72228 33.075L5.4026 33.075L5.05095 33.138L4.63537 34.1775L5.05095 34.1145C5.14686 34.083 5.24276 34.0515 5.33867 34.0515L4.69931 35.721C4.66734 35.9415 4.47553 36.0675 4.25175 36.036L4.05995 36.036L3.74026 36.8865L4.47553 36.8865C5.17883 36.918 5.81819 36.477 6.00999 35.8155L6.8092 33.705L7.35265 33.579L7.35265 33.579ZM12.2757 34.524L11.0609 34.524L11.5405 33.3585L12.4995 33.3585L12.8512 32.445L11.8921 32.445L12.2438 31.5L13.2987 31.5L13.6823 30.555L12.5954 30.555L12.9471 29.673L11.6364 29.673L8.85515 36.918L10.1658 36.918L10.7732 35.3745L11.9241 35.3745L12.2757 34.524Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 42" d="M9.87815 29.7045L9.52651 30.618L8.59943 30.618L8.24779 31.5315L9.17486 31.5315L8.79124 32.508L7.96007 32.508L7.60843 33.39L8.47156 33.39L8.02401 34.524L6.90513 34.524L6.58545 35.3745L7.70433 35.3745L7.09694 36.918L8.40763 36.9495L11.1569 29.7045L9.87815 29.7045Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<path id="矢量 43" d="M32 0C14.3217 0 0 14.112 0 31.5C0 48.888 14.3217 63 32 63C49.6783 63 64 48.888 64 31.5C64 14.112 49.6783 0 32 0ZM54.8252 16.128L56.967 17.388L47.025 24.885L54.8252 16.128L54.8252 16.128ZM43.3486 11.9385L43.4765 11.9385C46.7373 11.9385 48.3676 13.545 48.3676 16.758C48.3676 19.971 46.7373 21.5775 43.4765 21.5775L43.3486 21.5775C40.0879 21.5775 38.4575 19.971 38.4575 16.758C38.4256 13.5135 40.0559 11.9385 43.3486 11.9385ZM32.2238 6.3L32.2238 20.3175L28.3237 6.3L32.2238 6.3ZM26.8212 14.1435L29.0589 21.3255L24.6154 15.0255L26.8212 14.1435ZM17.5824 14.3955L25.6703 23.9085L14.6094 16.8525L17.5824 14.3955L17.5824 14.3955ZM14.1618 45.7065L24.7432 42.4935L15.9201 48.9195L14.1618 45.7065L14.1618 45.7065ZM26.1179 55.818L23.8801 55.818L28.3237 47.502L26.1179 55.818L26.1179 55.818ZM35.7083 47.3445L35.4206 47.3445C29.7622 47.3445 24.9351 43.911 22.9211 39.06L1.37463 39.06L4.15584 28.2555L23.7203 27.405C26.0539 23.436 30.4016 20.7585 35.3886 20.7585L35.6763 20.7585C43.1249 20.7585 49.1668 26.712 49.1668 34.0515C49.1668 41.391 43.1568 47.3445 35.7083 47.3445L35.7083 47.3445ZM55.4965 24.255L56.6473 25.956L50.6374 27.6885L55.4965 24.255ZM50.8931 30.744L63.4885 29.2005L63.4885 32.0985L50.8931 30.744Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
<g id="5">
<path id="矢量 54" d="M32.803 42.6712C33.5155 42.8781 34.3198 42.9816 35.216 42.9816C35.9088 42.9816 36.5688 42.8819 37.1963 42.6824C37.5199 42.5796 37.8348 42.4502 38.141 42.2943C38.4746 42.1238 38.7847 41.9246 39.0713 41.6967C39.5611 41.3072 39.9822 40.834 40.3347 40.2769C40.8934 39.3937 41.1728 38.3314 41.1728 37.0899C41.1728 35.8632 40.9347 34.8581 40.4584 34.0748C40.1572 33.573 39.7896 33.1546 39.3558 32.8195C39.1091 32.629 38.8411 32.4655 38.5516 32.3289C38.4559 32.2837 38.359 32.2413 38.2611 32.2015C37.5414 31.9095 36.7608 31.7635 35.9191 31.7635C35.5329 31.7635 35.1785 31.8023 34.856 31.8799C34.5336 31.9575 34.2054 32.0702 33.8717 32.218L34.1867 28.6542L40.3909 28.6542L40.3909 25.8552L31.273 25.8552L30.8005 34.0138L32.353 35.0059C32.8517 34.6881 33.2755 34.4628 33.6242 34.3297C33.9767 34.1967 34.4061 34.1302 34.9123 34.1302C35.5091 34.1302 36.0266 34.2601 36.4649 34.5198C36.6518 34.6305 36.8242 34.7648 36.9822 34.9228C37.0285 34.9687 37.0728 35.0163 37.1151 35.0656C37.559 35.5832 37.781 36.2857 37.781 37.173C37.781 37.8271 37.6516 38.3869 37.3929 38.8524C37.2278 39.1494 37.0231 39.4005 36.7788 39.6057C36.64 39.7223 36.4885 39.8241 36.3241 39.911C35.8741 40.1512 35.3529 40.2713 34.7604 40.2713C34.2429 40.2713 33.7573 40.1937 33.3036 40.0385C32.8536 39.8796 32.4392 39.6727 32.0605 39.4178C31.7354 39.1967 31.43 38.9548 31.1443 38.6921C31.1005 38.6518 31.0572 38.611 31.0143 38.5698L29.4393 40.6925C29.8743 41.1064 30.3655 41.4888 30.913 41.8398C31.4605 42.1872 32.0905 42.4643 32.803 42.6712Z" fill="rgb(255,255,255)" fill-rule="evenodd" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -4,6 +4,8 @@ import { useRoute } from 'vue-router'
import { userStore } from './store/user'
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
import BottomNavigation from './components/BottomNavigation.vue'
import CozeChat from './components/CozeChat.vue'
// 获取当前路由
const route = useRoute()
@@ -13,6 +15,12 @@ const isAdminRoute = computed(() => {
return route.path.startsWith('/admin')
})
// 处理发现按钮点击事件
const handleDiscoveryClick = () => {
// 触发全局事件让CozeChat组件处理
window.dispatchEvent(new CustomEvent('showAIAssistant'))
}
// 应用启动时获取用户信息
onMounted(async () => {
// 如果用户已登录但没有完整的用户信息,则从后端获取
@@ -22,8 +30,9 @@ onMounted(async () => {
await userStore.fetchLoginUser()
console.log('用户信息获取成功:', userStore.user)
} catch (error) {
console.error('获取用户信息失败:', error)
// 如果获取失败可能是token过期清除登录状态
console.warn('获取用户信息失败,可能是后端服务不可用:', error)
// 不强制清除登录状态,让用户可以继续浏览页面
// 如果是401错误才清除登录状态
if (error.response?.status === 401) {
userStore.logout()
}
@@ -47,33 +56,24 @@ onMounted(async () => {
<!-- 前台用户路由显示应用容器和底部导航 -->
<div v-else class="app-container">
<!-- 全局顶部导航栏 -->
<header class="global-header">
<div class="header-content">
<div class="app-logo">
<span class="logo-text">精彩猪手</span>
</div>
</div>
</header>
<main class="main-content">
<router-view />
</main>
<!-- 底部导航栏 -->
<nav class="bottom-nav">
<router-link to="/" class="nav-item" :class="{ active: $route.path === '/' }">
<div class="nav-icon">
<img src="@/assets/banner/home.png" alt="首页" class="nav-icon-img" />
</div>
<div class="nav-text">首页</div>
</router-link>
<router-link to="/lottery-info" class="nav-item" :class="{ active: $route.path === '/lottery-info' }">
<div class="nav-icon">
<img src="@/assets/banner/kaijiang.png" alt="开奖" class="nav-icon-img" />
</div>
<div class="nav-text">开奖</div>
</router-link>
<BottomNavigation @discovery-click="handleDiscoveryClick" />
<router-link to="/profile" class="nav-item" :class="{ active: $route.path === '/profile' }">
<div class="nav-icon">
<img src="@/assets/banner/wode.png" alt="我的" class="nav-icon-img" />
</div>
<div class="nav-text">我的</div>
</router-link>
</nav>
<!-- Coze AI 聊天助手组件 -->
<CozeChat />
</div>
</template>
@@ -97,11 +97,11 @@ body {
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: #f0f2f5 !important;
background: #f5f5f5 !important;
line-height: 1.5;
min-height: 100vh;
margin: 0 !important;
padding: 30px !important;
padding: 0 !important;
width: 100%;
display: flex;
flex-direction: column;
@@ -111,136 +111,109 @@ body {
/* 应用容器 - 包含主内容和底部导航 */
.app-container {
min-height: calc(100vh - 60px);
min-height: 100vh;
display: flex;
flex-direction: column;
position: relative;
max-width: 900px;
max-width: 850px;
width: 100%;
margin: 0 auto;
background: white;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.08);
border-radius: 12px;
border-radius: 0;
overflow: hidden;
}
/* 全局顶部导航栏 */
.global-header {
height: 60px;
background: linear-gradient(135deg, #ff7b7b 0%, #ff6363 50%, #f85555 100%);
position: sticky;
top: 0;
z-index: 999;
box-shadow: 0 2px 12px rgba(248, 85, 85, 0.3);
position: relative;
overflow: hidden;
}
/* 装饰性波浪背景 */
.global-header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 60' preserveAspectRatio='none'%3E%3Cpath d='M0,30 Q100,10 200,30 T400,30 T600,30 T800,30 L800,60 L0,60 Z' fill='rgba(255,255,255,0.08)'/%3E%3Cpath d='M0,40 Q150,20 300,40 T600,40 T800,35 L800,60 L0,60 Z' fill='rgba(255,255,255,0.05)'/%3E%3Ccircle cx='50' cy='15' r='3' fill='rgba(255,255,255,0.15)'/%3E%3Ccircle cx='150' cy='45' r='2' fill='rgba(255,255,255,0.12)'/%3E%3Ccircle cx='300' cy='12' r='2.5' fill='rgba(255,255,255,0.1)'/%3E%3Ccircle cx='500' cy='48' r='2' fill='rgba(255,255,255,0.15)'/%3E%3Ccircle cx='650' cy='18' r='3' fill='rgba(255,255,255,0.1)'/%3E%3Ccircle cx='750' cy='40' r='2' fill='rgba(255,255,255,0.12)'/%3E%3C/svg%3E");
background-size: cover;
background-position: center;
opacity: 1;
z-index: 0;
}
.header-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 0 20px;
max-width: 1200px;
margin: 0 auto;
position: relative;
z-index: 2;
}
.app-logo {
display: flex;
align-items: center;
justify-content: center;
transform: translateY(0);
transition: all 0.3s ease;
}
.app-logo:hover {
transform: translateY(-1px) scale(1.02);
}
.logo-text {
font-size: 22px;
font-weight: 700;
color: white;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3),
0 1px 2px rgba(0, 0, 0, 0.5);
letter-spacing: 2px;
position: relative;
display: inline-block;
}
.logo-text::after {
content: '';
position: absolute;
bottom: -2px;
left: 50%;
width: 0;
height: 2px;
background: rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
transform: translateX(-50%);
}
.app-logo:hover .logo-text::after {
width: 100%;
}
/* 主要内容区域 */
.main-content {
flex: 1;
background: #f0f2f5;
position: relative;
padding-bottom: 65px;
min-height: calc(100vh - 130px);
}
/* 底部导航栏 */
.bottom-nav {
height: 75px;
background: white;
display: flex;
align-items: center;
justify-content: space-around;
border-top: 1px solid #f0f0f0;
z-index: 1000;
padding: 5px 0;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
}
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-decoration: none;
color: #9ca3af;
transition: all 0.3s ease;
padding: 0;
min-width: 65px;
position: relative;
}
.nav-item:hover {
color: #e53e3e;
}
.nav-item:hover .nav-icon-img {
transform: scale(1.05);
}
.nav-item.active {
color: #e53e3e;
}
.nav-item.active .nav-icon {
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border-radius: 50%;
box-shadow: 0 4px 12px rgba(229, 62, 62, 0.3);
}
.nav-item.active .nav-icon-img {
filter: brightness(0) invert(1);
transform: scale(1.1);
}
.nav-item.active .nav-text {
color: #e53e3e;
font-weight: 700;
}
.nav-icon {
margin-bottom: 5px;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: 50%;
}
.nav-icon-img {
width: 26px;
height: 26px;
object-fit: contain;
transition: all 0.3s ease;
}
.nav-icon svg {
width: 24px;
height: 24px;
}
.nav-text {
font-size: 12px;
font-weight: 500;
text-align: center;
transition: all 0.3s ease;
}
/* 移动端适配 */
@media (max-width: 768px) {
.bottom-nav {
height: 70px;
padding: 3px 0;
}
.nav-item {
padding: 0;
min-width: 60px;
}
.nav-icon-img {
width: 28px;
height: 28px;
}
.nav-text {
font-size: 11px;
}
.nav-item.active::before {
width: 30px;
height: 3px;
}
}
/* 通用容器样式 */
.container {
@@ -437,30 +410,66 @@ body {
/* 响应式设计 */
@media (max-width: 1024px) {
.app-container {
max-width: 800px;
max-width: 850px;
}
}
@media (max-width: 768px) {
body {
padding: 15px !important;
padding: 0 !important;
}
.app-container {
max-width: 100%;
min-height: calc(100vh - 30px);
border-radius: 8px;
min-height: 100vh;
border-radius: 0;
}
.global-header {
height: 55px;
}
.header-content {
padding: 0 16px;
}
.logo-text {
font-size: 20px;
}
.main-content {
padding-bottom: 55px;
min-height: calc(100vh - 120px);
}
}
@media (max-width: 480px) {
body {
padding: 10px !important;
padding: 0 !important;
margin: 0 !important;
}
.app-container {
border-radius: 0;
min-height: 100vh;
box-shadow: none;
}
.global-header {
height: 50px;
}
.header-content {
padding: 0 12px;
}
.logo-text {
font-size: 18px;
}
.main-content {
padding-bottom: 55px;
min-height: calc(100vh - 110px);
}
.page-header {
@@ -497,4 +506,6 @@ html {
background: rgba(229, 62, 62, 0.2);
color: #e53e3e;
}
</style>

View File

@@ -0,0 +1,380 @@
import axios from 'axios'
// 创建大乐透专用的axios实例
const dltApi = axios.create({
// baseURL: 'http://localhost:8123/api',
baseURL: 'https://www.yicaishuzhi.com/api',
timeout: 300000, // 5分钟超时时间
withCredentials: true, // 关键支持跨域携带cookie和session
headers: {
'Content-Type': 'application/json'
}
})
// 响应拦截器
dltApi.interceptors.response.use(
response => {
const data = response.data
// 检查是否是session过期的响应
if (data && data.success === false) {
const message = data.message || ''
if (message.includes('未登录') || message.includes('登录过期') || message.includes('无权限') || message.includes('Invalid session')) {
console.log('检测到session过期清除本地登录状态')
// 动态导入userStore避免循环依赖
import('../../store/user.js').then(({ userStore }) => {
userStore.logout()
})
}
}
return data
},
error => {
console.error('大乐透API请求错误:', error)
// 检查HTTP状态码401/403通常表示未授权/session过期
if (error.response && (error.response.status === 401 || error.response.status === 403)) {
console.log('检测到401/403错误可能是session过期或无权限')
// 动态导入userStore避免循环依赖
import('../../store/user.js').then(({ userStore }) => {
userStore.logout()
})
}
return Promise.reject(error)
}
)
// 大乐透API接口方法
export const dltLotteryApi = {
// 获取近10期大乐透开奖期号
getRecent10DrawIds() {
return dltApi.get('/dlt-draw/recent-10-draw-ids')
},
// 根据期号获取大乐透开奖号码
getDrawNumbersById(drawId) {
return dltApi.get(`/dlt-draw/draw/${drawId}/numbers`)
},
// 大乐透前区首球分析
analyzeFrontBalls(level, frontBalls, backBalls) {
return dltApi.post('/dlt/ball-analysis/predict-first-ball', {
level,
redBalls: frontBalls, // 前区球
blueBalls: backBalls // 后区球
})
},
// 大乐透前区随球分析
analyzeFollowFrontBalls(level, wellRegardedBalls, previousFrontBalls, previousBackBalls) {
return dltApi.post('/dlt/ball-analysis/predict-follower-ball', {
level,
wellRegardedBalls,
previousFrontBalls,
previousBackBalls
})
},
// 大乐透后区球分析
analyzeBackBalls(level, nextFrontBalls, previousFrontBalls, previousBackBalls, nextBackBalls) {
return dltApi.post('/dlt/ball-analysis/predict-back-ball', {
level,
nextFrontBalls,
previousFrontBalls,
previousBackBalls,
nextBackBalls
})
},
// 大乐透后区随球分析
analyzeFollowBackBalls(level, backFirstBall, nextFrontBalls, previousFrontBalls, previousBackBalls) {
return dltApi.post('/dlt/ball-analysis/predict-follow-back-ball', {
level,
backFirstBall,
nextFrontBalls,
previousFrontBalls,
previousBackBalls
})
},
// 创建大乐透推测记录
createPredictRecord(userId, drawId, drawDate, frontBalls, backBalls) {
return dltApi.post('/dlt/ball-analysis/create-predict', {
userId,
drawId,
drawDate,
frontBalls: frontBalls.join(','),
backBalls: backBalls.join(',')
})
},
// 获取大乐透推测记录
getPredictRecordsByUserId(userId, page = 1) {
return dltApi.get(`/dlt/ball-analysis/predict-records/${userId}?page=${page}`)
},
// 获取近期大乐透开奖记录
getRecentDraws(limit = 10) {
return dltApi.get(`/dlt-draw/recent-draws?limit=${limit}`)
},
// 根据期号获取大乐透开奖记录
getDrawById(drawId) {
return dltApi.get(`/dlt-draw/draw/${drawId}`)
},
// 根据日期范围查询大乐透开奖记录
queryDraws(startDate, endDate) {
return dltApi.get(`/dlt-draw/query-draws?startDate=${startDate}&endDate=${endDate}`)
},
// 获取近100期大乐透开奖记录用于表相查询
getRecent100Draws() {
return dltApi.get('/dlt-draw/recent-100-draws')
},
// 创建大乐透预测记录(新接口)
createDltPredictRecord(userId, drawId, frontBalls, backBalls, drawDate = null) {
const params = new URLSearchParams({
userId: userId,
drawId: drawId,
frontBalls: frontBalls,
backBalls: backBalls
})
if (drawDate) {
params.append('drawDate', drawDate)
}
return dltApi.post(`/dlt/ball-analysis/create-dlt-predict?${params.toString()}`)
},
// 前区与前区的组合性分析
frontFrontCombinationAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/front-front-combination-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 前区与后区的组合性分析
frontBackCombinationAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/front-back-combination-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 后区与后区的组合性分析
backBackCombinationAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/back-back-combination-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 后区与前区的组合性分析
backFrontCombinationAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/back-front-combination-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 前区与前区的持续性分析
frontFrontPersistenceAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/front-front-persistence-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 后区与后区的持续性分析
backBackPersistenceAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/back-back-persistence-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 前区与后区的持续性分析
frontBackPersistenceAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/front-back-persistence-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 后区与前区的持续性分析
backFrontPersistenceAnalysis(masterBall, slaveBall) {
return dltApi.get(`/dlt/ball-analysis/back-front-persistence-analysis?masterBall=${masterBall}&slaveBall=${slaveBall}`)
},
// 根据用户ID获取大乐透预测记录新接口
getDltPredictRecordsByUserId(userId, page = 1, pageSize = 10) {
return dltApi.get(`/dlt-predict/predict-records/${userId}?page=${page}&pageSize=${pageSize}`)
},
// 条件查询大乐透预测记录
queryDltPredictRecords(userId, predictStatus, page = 1, pageSize = 10) {
return dltApi.post('/dlt-predict/query-predict-records', {
userId: userId,
predictStatus: predictStatus,
current: page,
pageSize: pageSize
})
},
// 前区历史数据查询
getFrontendHistoryAll() {
return dltApi.get('/dlt/ball-active-analysis/frontend-history-all')
},
getFrontendHistory100() {
return dltApi.get('/dlt/ball-active-analysis/frontend-history-100')
},
getFrontendHistoryTop() {
return dltApi.get('/dlt/ball-active-analysis/frontend-history-top')
},
getFrontendHistoryTop100() {
return dltApi.get('/dlt/ball-active-analysis/frontend-history-top-100')
},
// 后区历史数据查询
getBackendHistoryAll() {
return dltApi.get('/dlt/ball-active-analysis/backend-history-all')
},
getBackendHistory100() {
return dltApi.get('/dlt/ball-active-analysis/backend-history-100')
},
getBackendHistoryTop() {
return dltApi.get('/dlt/ball-active-analysis/backend-history-top')
},
getBackendHistoryTop100() {
return dltApi.get('/dlt/ball-active-analysis/backend-history-top-100')
},
// Excel数据导入相关API
// 上传Excel文件完整导入大乐透数据D3-D12工作表
uploadDltExcelFile(file) {
const formData = new FormData()
formData.append('file', file)
return dltApi.post('/dlt/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
},
// 上传Excel文件导入大乐透开奖数据覆盖D1工作表
uploadDltDrawsFile(file) {
const formData = new FormData()
formData.append('file', file)
return dltApi.post('/dlt/upload-draw-data', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
},
// 追加导入大乐透开奖数据D1工作表
appendDltDrawsFile(file) {
const formData = new FormData()
formData.append('file', file)
return dltApi.post('/dlt/append-draw-data', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
},
// 手动处理待开奖记录(双色球+大乐透)
processPendingPredictions() {
return dltApi.post('/dlt-predict/process-pending')
},
// 获取用户大乐透预测统计
getUserPredictStats(userId) {
return dltApi.get(`/dlt-predict/user-predict-stat/${userId}`)
},
// 获取用户大乐透奖金统计
getPrizeStatistics(userId) {
return dltApi.get('/dlt-predict/prize-statistics', {
params: {
userId: userId
}
})
},
// 大乐透命中率分析接口
// 前区首球命中率分析
getFrontFirstBallHitRate() {
return dltApi.get('/dlt-predict/front-first-ball-hit-rate')
},
// 前区球号命中率分析
getFrontBallHitRate() {
return dltApi.get('/dlt-predict/front-ball-hit-rate')
},
// 后区首球命中率分析
getBackFirstBallHitRate() {
return dltApi.get('/dlt-predict/back-first-ball-hit-rate')
},
// 后区球号命中率分析
getBackBallHitRate() {
return dltApi.get('/dlt-predict/back-ball-hit-rate')
},
// 精推版大乐透第一步分析
jtdltFirstStepAnalysis(level, frontBalls, backBalls) {
const params = new URLSearchParams()
params.append('level', level)
params.append('frontBalls', frontBalls)
params.append('backBalls', backBalls)
return dltApi.post('/jtdlt/analysis/first-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
// 精推版大乐透第二步分析
jtdltSecondStepAnalysis(level, previousFrontBalls, previousBackBalls, currentFirstBall) {
const params = new URLSearchParams()
params.append('level', level)
params.append('previousFrontBalls', previousFrontBalls)
params.append('previousBackBalls', previousBackBalls)
params.append('currentFirstBall', currentFirstBall)
return dltApi.post('/jtdlt/analysis/second-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
// 精推版大乐透第三步分析
jtdltThirdStepAnalysis(level, previousFrontBalls, previousBackBalls, currentFrontBalls) {
const params = new URLSearchParams()
params.append('level', level)
params.append('previousFrontBalls', previousFrontBalls)
params.append('previousBackBalls', previousBackBalls)
params.append('currentFrontBalls', currentFrontBalls)
return dltApi.post('/jtdlt/analysis/third-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
// 精推版大乐透第四步分析
jtdltFourthStepAnalysis(level, previousFrontBalls, previousBackBalls, currentFrontBalls, currentBackFirstBall) {
const params = new URLSearchParams()
params.append('level', level)
params.append('previousFrontBalls', previousFrontBalls)
params.append('previousBackBalls', previousBackBalls)
params.append('currentFrontBalls', currentFrontBalls)
params.append('currentBackFirstBall', currentBackFirstBall)
return dltApi.post('/jtdlt/analysis/fourth-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
}
}
export default dltLotteryApi

View File

@@ -3,7 +3,7 @@ import axios from 'axios'
// 创建axios实例
const api = axios.create({
// baseURL: 'http://localhost:8123/api',
baseURL: 'https://www.jingcaishuju.com/api',
baseURL: 'https://www.yicaishuzhi.com/api',
timeout: 300000, // 5分钟超时时间300秒
withCredentials: true, // 关键支持跨域携带cookie和session
headers: {
@@ -11,6 +11,9 @@ const api = axios.create({
}
})
// 防止重复提示的标志
let isKickedOut = false
// 响应拦截器
api.interceptors.response.use(
response => {
@@ -20,16 +23,56 @@ api.interceptors.response.use(
if (data && data.success === false) {
// 可以根据后端返回的错误码或消息判断是否是session过期
const message = data.message || ''
// 专门处理账号在其他设备登录的情况
if (message.includes('其他设备登录') || message.includes('当前会话已失效')) {
if (!isKickedOut) {
isKickedOut = true
console.log('检测到账号在其他设备登录,正在踢出当前会话...')
// 动态导入 Element Plus 的消息组件
import('element-plus').then(({ ElMessage }) => {
ElMessage.warning({
message: '您的账号已在其他设备登录,请重新登录',
duration: 3000,
showClose: true
})
})
// 检查当前路径是否为后台管理路径
if (window.location.pathname.startsWith('/cpzsadmin') && window.location.pathname !== '/cpzsadmin/login') {
// 后台管理会话
import('../store/user.js').then(({ userStore }) => {
userStore.adminLogout(true) // 标记为被踢出
setTimeout(() => {
window.location.href = '/cpzsadmin/login'
isKickedOut = false // 重置标志
}, 1500)
})
} else {
// 前台用户会话
import('../store/user.js').then(({ userStore }) => {
userStore.logout(true) // 标记为被踢出
setTimeout(() => {
isKickedOut = false // 重置标志
}, 3000)
})
}
}
return data
}
// 处理其他登录/权限相关的错误
if (message.includes('未登录') || message.includes('登录过期') || message.includes('无权限') || message.includes('Invalid session')) {
console.log('检测到session过期清除本地登录状态')
// 检查当前路径是否为后台管理路径
if (window.location.pathname.startsWith('/admin') && window.location.pathname !== '/admin/login') {
if (window.location.pathname.startsWith('/cpzsadmin') && window.location.pathname !== '/cpzsadmin/login') {
console.log('后台管理会话过期,正在注销...')
// 动态导入userStore避免循环依赖
import('../store/user.js').then(({ userStore }) => {
userStore.adminLogout()
window.location.href = '/admin/login'
window.location.href = '/cpzsadmin/login'
})
} else {
// 前台用户会话过期处理
@@ -50,12 +93,12 @@ api.interceptors.response.use(
console.log('检测到401/403错误可能是session过期或无权限')
// 检查当前路径是否为后台管理路径
if (window.location.pathname.startsWith('/admin') && window.location.pathname !== '/admin/login') {
if (window.location.pathname.startsWith('/cpzsadmin') && window.location.pathname !== '/cpzsadmin/login') {
console.log('后台管理会话过期,正在注销...')
// 动态导入userStore避免循环依赖
import('../store/user.js').then(({ userStore }) => {
userStore.adminLogout()
window.location.href = '/admin/login'
window.location.href = '/cpzsadmin/login'
})
} else {
// 前台用户会话过期处理
@@ -99,11 +142,42 @@ export const lotteryApi = {
return api.get('/user/get/login')
},
// 获取用户信息(用于编辑)
getUserInfo() {
return api.get('/user/get/login')
},
// 更新用户信息
updateUserInfo(userInfo) {
console.log('调用更新用户信息接口:', userInfo)
return api.post('/user/update', userInfo, {
headers: {
'Content-Type': 'application/json'
}
})
},
// 上传文件
uploadFile(file) {
const formData = new FormData()
formData.append('file', file)
return api.post('/file/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
},
// 获取用户统计信息总用户数和VIP用户数
getUserCount() {
return api.get('/user/count')
},
// 检查当前用户VIP是否过期
checkVipExpire() {
return api.get('/user/check-vip-expire')
},
// 获取用户推测记录(支持分页)
getPredictRecordsByUserId(userId, page = 1) {
return api.get(`/ball-analysis/predict-records/${userId}?page=${page}`)
@@ -112,7 +186,7 @@ export const lotteryApi = {
// 按条件查询推测记录(支持分页和状态筛选)
queryPredictRecords(userId, predictStatus, page = 1, pageSize = 10) {
return api.post('/data-analysis/query-predict-records', {
userId: Number(userId),
userId: userId,
predictStatus,
current: page,
pageSize
@@ -124,7 +198,7 @@ export const lotteryApi = {
return api.get(`/ball-analysis/recent-draws?limit=${limit}`)
},
// 获取最新100条开奖信息表相性分析
// 获取最新100条开奖信息表相查询
getRecent100Draws() {
return api.get('/ball-analysis/recent-100-draws')
},
@@ -173,6 +247,50 @@ export const lotteryApi = {
})
},
// 精推版双色球第一步分析
jtssqFirstStepAnalysis(level, redBalls, blueBall) {
const params = new URLSearchParams()
params.append('level', level)
params.append('redBalls', redBalls)
params.append('blueBall', blueBall)
return api.post('/jtssq/analysis/first-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
// 精推版双色球第二步分析
jtssqSecondStepAnalysis(level, redBalls, blueBall, nextFirstBall) {
const params = new URLSearchParams()
params.append('level', level)
params.append('redBalls', redBalls)
params.append('blueBall', blueBall)
params.append('nextFirstBall', nextFirstBall)
return api.post('/jtssq/analysis/second-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
// 精推版双色球第三步分析
jtssqThirdStepAnalysis(level, redBalls, blueBall, nextRedBalls) {
const params = new URLSearchParams()
params.append('level', level)
params.append('redBalls', redBalls)
params.append('blueBall', blueBall)
params.append('nextRedBalls', nextRedBalls)
return api.post('/jtssq/analysis/third-step', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
// 跟随球号分析算法
fallowBallAnalysis(userId, level, firstThreeRedBalls, lastSixRedBalls, blueBall) {
const params = new URLSearchParams()
@@ -207,23 +325,31 @@ export const lotteryApi = {
},
// 获取用户推测统计数据
getUserPredictStat(userId) {
return api.get(`/data-analysis/user-predict-stat/${userId}`)
getUserPredictStat(userId, lotteryType) {
return api.get(`/data-analysis/user-predict-stat/${userId}`, {
params: { lotteryType }
})
},
// 获取首球命中率统计
getFirstBallHitRate() {
return api.get('/ball-analysis/first-ball-hit-rate')
getFirstBallHitRate(lotteryType) {
return api.get('/ball-analysis/first-ball-hit-rate', {
params: { lotteryType }
})
},
// 获取蓝球命中率统计
getBlueBallHitRate() {
return api.get('/ball-analysis/blue-ball-hit-rate')
getBlueBallHitRate(lotteryType) {
return api.get('/ball-analysis/blue-ball-hit-rate', {
params: { lotteryType }
})
},
// 获取红球命中率统计
getRedBallHitRate() {
return api.get('/ball-analysis/red-ball-hit-rate')
getRedBallHitRate(lotteryType) {
return api.get('/ball-analysis/red-ball-hit-rate', {
params: { lotteryType }
})
},
// 获取奖金统计
@@ -657,6 +783,134 @@ export const lotteryApi = {
}
return api.get(`/operation-history/list${queryParams.toString() ? '?' + queryParams.toString() : ''}`)
},
// ==================== 公告管理接口 ====================
// 添加公告
addAnnouncement(data) {
console.log('调用添加公告接口:', data)
return api.post('/announcement/add', data)
},
// 查询公告列表(分页)
getAnnouncementList(params) {
console.log('调用查询公告列表接口:', params)
const queryParams = new URLSearchParams()
if (params?.current) queryParams.append('current', params.current)
if (params?.pageSize) queryParams.append('pageSize', params.pageSize)
if (params?.title) queryParams.append('title', params.title)
if (params?.status !== undefined && params?.status !== null && params?.status !== '') {
queryParams.append('status', params.status)
}
if (params?.priority !== undefined && params?.priority !== null && params?.priority !== '') {
queryParams.append('priority', params.priority)
}
if (params?.publisherId) queryParams.append('publisherId', params.publisherId)
if (params?.publisherName) queryParams.append('publisherName', params.publisherName)
if (params?.startTime) queryParams.append('startTime', params.startTime)
if (params?.endTime) queryParams.append('endTime', params.endTime)
return api.get(`/announcement/list/page${queryParams.toString() ? '?' + queryParams.toString() : ''}`)
},
// 根据ID查询公告详情
getAnnouncementById(id) {
console.log('调用根据ID查询公告接口:', id)
return api.get(`/announcement/${id}`)
},
// 更新公告
updateAnnouncement(data) {
console.log('调用更新公告接口:', data)
return api.post('/announcement/update', data)
},
// 删除公告
deleteAnnouncement(id) {
console.log('调用删除公告接口:', id)
return api.delete(`/announcement/delete/${id}`)
},
// 获取置顶公告
getTopAnnouncements() {
console.log('调用获取置顶公告接口')
return api.get('/announcement/top')
},
// 获取所有已发布公告
getPublishedAnnouncements() {
console.log('调用获取所有已发布公告接口')
return api.get('/announcement/published')
},
// ==================== 推测管理接口 ====================
// 管理员获取所有双色球推测记录
getAllSsqPredictRecords(params) {
const queryParams = new URLSearchParams()
if (params?.userId) queryParams.append('userId', params.userId)
if (params?.predictResult) queryParams.append('predictResult', params.predictResult)
if (params?.current) queryParams.append('current', params.current)
if (params?.pageSize) queryParams.append('pageSize', params.pageSize)
return api.get(`/ball-analysis/admin/all-records?${queryParams.toString()}`)
},
// 管理员获取所有大乐透推测记录
getAllDltPredictRecords(params) {
const queryParams = new URLSearchParams()
if (params?.userId) queryParams.append('userId', params.userId)
if (params?.predictResult) queryParams.append('predictResult', params.predictResult)
if (params?.current) queryParams.append('current', params.current)
if (params?.pageSize) queryParams.append('pageSize', params.pageSize)
return api.get(`/dlt-predict/admin/all-records?${queryParams.toString()}`)
},
// ==================== 奖金统计接口 ====================
// 管理员获取双色球中奖记录明细
getAdminPrizeStatistics(params) {
const queryParams = new URLSearchParams()
if (params?.userId) queryParams.append('userId', params.userId)
if (params?.prizeGrade) queryParams.append('prizeGrade', params.prizeGrade)
if (params?.current) queryParams.append('current', params.current)
if (params?.pageSize) queryParams.append('pageSize', params.pageSize)
return api.get(`/ball-analysis/admin/prize-statistics?${queryParams.toString()}`)
},
// 管理员获取大乐透中奖记录明细
getAdminDltPrizeStatistics(params) {
const queryParams = new URLSearchParams()
if (params?.userId) queryParams.append('userId', params.userId)
if (params?.prizeGrade) queryParams.append('prizeGrade', params.prizeGrade)
if (params?.current) queryParams.append('current', params.current)
if (params?.pageSize) queryParams.append('pageSize', params.pageSize)
return api.get(`/dlt-predict/admin/prize-statistics?${queryParams.toString()}`)
},
// 记录页面访问PV
recordPageView(pagePath) {
return api.post(`/pv/record?pagePath=${encodeURIComponent(pagePath)}`)
},
// 获取总PV
getTotalPageViews() {
return api.get('/pv/total')
},
// 获取今日PV
getTodayPageViews() {
return api.get('/pv/today')
},
// 获取近N天PV统计
getPageViewsByDays(days = 7) {
return api.get(`/pv/stats?days=${days}`)
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -5,6 +5,7 @@
font-weight: normal;
width: 100%;
min-height: 100vh;
background-color: rgb(240, 242, 245);
}
a,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,440 @@
<template>
<Transition name="modal-fade">
<div v-if="visible" class="custom-modal-overlay" @click.self="handleOverlayClick">
<div class="custom-modal el-dialog--center" :class="themeClass">
<div class="custom-modal-header">
<h3 class="custom-modal-title">{{ title }}</h3>
<button class="custom-modal-close" @click="handleClose">
<svg viewBox="0 0 1024 1024" width="16" height="16">
<path d="M810.666667 273.493333L750.506667 213.333333 512 451.84 273.493333 213.333333 213.333333 273.493333 451.84 512 213.333333 750.506667 273.493333 810.666667 512 572.16 750.506667 810.666667 810.666667 750.506667 572.16 512z" fill="currentColor"></path>
</svg>
</button>
</div>
<div class="custom-modal-body">
<div class="algorithm-process-content">
<p v-if="introText" class="process-intro">{{ introText }}</p>
<div class="process-text">
{{ formattedProcessText }}
</div>
</div>
</div>
<div class="custom-modal-footer">
<button class="custom-modal-button" @click="handleClose">{{ confirmText }}</button>
</div>
</div>
</div>
</Transition>
</template>
<script>
export default {
name: 'AlgorithmProcessModal',
props: {
// 弹窗显示状态
modelValue: {
type: Boolean,
default: false
},
// 弹窗标题
title: {
type: String,
default: '猪手专业算法筛选过程'
},
// 介绍文本
introText: {
type: String,
default: ''
},
// 确认按钮文本
confirmText: {
type: String,
default: '我知道了'
},
// 筛选过程原始文本
processText: {
type: String,
default: ''
},
// 是否启用文本格式化(大乐透需要,双色球不需要)
enableFormatting: {
type: Boolean,
default: false
},
// 主题类型ssq: 双色球, dlt: 大乐透)
theme: {
type: String,
default: 'ssq',
validator: (value) => ['ssq', 'dlt'].includes(value)
}
},
emits: ['update:modelValue', 'close'],
computed: {
visible: {
get() {
return this.modelValue
},
set(value) {
this.$emit('update:modelValue', value)
}
},
formattedProcessText() {
if (!this.processText) {
return '暂无筛选过程说明'
}
if (this.enableFormatting) {
return this.formatFilteringText(this.processText)
}
return this.processText
},
themeClass() {
return `${this.theme}-theme`
}
},
methods: {
handleVisibilityChange(value) {
this.$emit('update:modelValue', value)
},
handleClose() {
this.visible = false
this.$emit('close')
},
handleOverlayClick() {
// 点击遮罩层关闭弹窗
this.handleClose()
},
// 格式化筛选过程文本(只在关键步骤处换行)
formatFilteringText(text) {
if (!text) return '暂无筛选过程说明'
return text
// 先清理可能的重复词汇(只处理字母单词,不处理数字)
.replace(/\b([a-zA-Z\u4e00-\u9fa5]+)\1+\b/g, '$1') // 清理连续重复的单词,但不处理数字
.replace(/通过通过/g, '通过') // 特别处理"通过"重复
.replace(/+/g, '') // 清理连续逗号
.replace(/。。+/g, '。') // 清理连续句号
// 在步骤分隔处换行(如:第一步、第二步等关键词后)
.replace(/(第[一二三四五六七八九十\d]+步[:,])/g, '\n$1\n')
// 在预测结果开始处换行
.replace(/(最终推荐[:,])/g, '\n$1')
.replace(/(推荐结果[:,])/g, '\n$1')
.replace(/(筛选结果[:,])/g, '\n$1')
// 在重要的算法说明开始处换行
.replace(/(算法说明[:,])/g, '\n$1')
.replace(/(分析过程[:,])/g, '\n$1')
// 在筛选步骤说明处换行
.replace(/(筛选步骤[:,])/g, '\n$1\n')
// 在分号后面如果是重要内容开始则换行
.replace(/(\s*直接)/g, '\n$1')
.replace(/(\s*筛选)/g, '\n$1')
.replace(/(\s*推荐)/g, '\n$1')
// 在"其中"这种重要分段处适当换行(但要更谨慎)
.replace(/([。;])(\s*其中)/g, '$1\n$2')
// 在包含多个数字的长列表后换行(但保持在一行内的短序列不变)
.replace(/(\d+(?:\s*,\s*\d+){4,}[\d\s,]*?)([,。])/g, '$1$2\n')
// 清理开头和结尾的换行
.replace(/^\n+/, '')
.replace(/\n+$/, '')
// 清理多余的连续换行
.replace(/\n{3,}/g, '\n\n')
// 最后再清理一次可能的重复
.replace(/通过通过/g, '通过')
.trim()
}
}
}
</script>
<style scoped>
/* 弹窗过渡动画 */
.modal-fade-enter-active,
.modal-fade-leave-active {
transition: opacity 0.3s ease;
}
.modal-fade-enter-from,
.modal-fade-leave-to {
opacity: 0;
}
.modal-fade-enter-active .custom-modal,
.modal-fade-leave-active .custom-modal {
transition: transform 0.3s ease;
}
.modal-fade-enter-from .custom-modal,
.modal-fade-leave-to .custom-modal {
transform: scale(0.9);
}
/* 遮罩层 */
.custom-modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 2000;
padding: 20px;
}
/* 弹窗容器 */
.custom-modal {
background: #ffffff;
border-radius: 12px;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);
width: 90%;
max-width: 600px;
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 弹窗头部 */
.custom-modal-header {
padding: 20px 20px 10px;
border-bottom: 1px solid #ebeef5;
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
.custom-modal-title {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0;
flex: 1;
text-align: center;
}
.custom-modal-close {
background: none;
border: none;
cursor: pointer;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
color: #909399;
transition: color 0.3s ease;
position: absolute;
right: 18px;
top: 18px;
}
.custom-modal-close:hover {
color: #409eff;
}
/* 弹窗主体 */
.custom-modal-body {
padding: 20px;
overflow-y: auto;
flex: 1;
}
/* 筛选过程内容样式 */
.algorithm-process-content {
padding: 0;
}
.process-intro {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 15px;
text-align: center;
}
.process-text {
font-size: 16px;
color: #555;
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
word-break: break-word;
word-wrap: break-word;
overflow-wrap: break-word;
max-width: 100%;
text-align: left;
line-height: 2.2;
white-space: pre-line;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
/* 双色球主题 */
.custom-modal.ssq-theme .process-text {
background: linear-gradient(135deg, #f8f9fa 0%, #fff5f5 100%);
}
.custom-modal.ssq-theme .process-text:hover {
box-shadow: 0 4px 12px rgba(229, 62, 62, 0.15);
}
.custom-modal.ssq-theme .custom-modal-button {
background: linear-gradient(135deg, #e53e3e 0%, #ff6b6b 100%);
box-shadow: 0 2px 8px rgba(229, 62, 62, 0.3);
}
.custom-modal.ssq-theme .custom-modal-button:hover {
background: linear-gradient(135deg, #ff6b6b 0%, #e53e3e 100%);
box-shadow: 0 4px 12px rgba(229, 62, 62, 0.4);
}
/* 大乐透主题 */
.custom-modal.dlt-theme .process-text {
background: linear-gradient(135deg, #f8f9fa 0%, #f7fcf7 100%);
}
.custom-modal.dlt-theme .process-text:hover {
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.15);
}
.custom-modal.dlt-theme .custom-modal-button {
background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%);
box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3);
}
.custom-modal.dlt-theme .custom-modal-button:hover {
background: linear-gradient(135deg, #66bb6a 0%, #4caf50 100%);
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
}
/* 弹窗底部 */
.custom-modal-footer {
padding: 10px 20px 20px;
text-align: center;
flex-shrink: 0;
border-top: 1px solid #ebeef5;
}
.custom-modal-button {
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
border: none;
padding: 12px 24px;
font-size: 14px;
font-weight: 500;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
transition: all 0.3s ease;
color: #ffffff;
cursor: pointer;
min-width: 100px;
}
.custom-modal-button:hover {
background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
}
.custom-modal-button:active {
transform: translateY(0);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}
/* 移动端优化 */
@media (max-width: 768px) {
.custom-modal-overlay {
padding: 15px;
}
.custom-modal-header {
padding: 15px 15px 8px;
}
.custom-modal-title {
font-size: 16px;
}
.custom-modal-close {
right: 15px;
top: 15px;
}
.custom-modal-body {
padding: 15px;
}
.process-intro {
font-size: 15px;
margin-bottom: 12px;
}
.process-text {
font-size: 15px;
line-height: 2.0;
padding: 15px;
border-radius: 6px;
}
.custom-modal-button {
padding: 10px 20px;
font-size: 13px;
}
}
@media (max-width: 480px) {
.custom-modal-overlay {
padding: 10px;
}
.custom-modal {
width: 95%;
max-height: 85vh;
}
.custom-modal-header {
padding: 12px 12px 6px;
}
.custom-modal-title {
font-size: 15px;
}
.custom-modal-close {
right: 12px;
top: 12px;
}
.custom-modal-body {
padding: 12px;
}
.process-intro {
font-size: 14px;
margin-bottom: 10px;
}
.process-text {
font-size: 14px;
line-height: 1.8;
padding: 12px;
border-radius: 4px;
}
.custom-modal-footer {
padding: 8px 12px 12px;
}
.custom-modal-button {
padding: 8px 16px;
font-size: 12px;
min-width: 80px;
}
}
</style>

View File

@@ -0,0 +1,190 @@
<template>
<nav class="bottom-nav">
<router-link to="/" class="nav-item" :class="{ active: $route.path === '/' }">
<div class="nav-icon">
<img :src="$route.path === '/' ? '/assets/bottom/home-1.svg' : '/assets/bottom/home-0.svg'" alt="首页" class="nav-icon-img" />
</div>
<div class="nav-text">首页</div>
</router-link>
<div class="nav-item" @click="handleDiscoveryClick">
<div class="nav-icon">
<img src="/assets/bottom/faxian-0.svg" alt="交流" class="nav-icon-img" />
</div>
<div class="nav-text">交流</div>
</div>
<router-link to="/lottery-info" class="nav-item" :class="{ active: $route.path === '/lottery-info' }">
<div class="nav-icon">
<img :src="$route.path === '/lottery-info' ? '/assets/bottom/kaijiang-1.svg' : '/assets/bottom/kaijiang-0.svg'" alt="开奖" class="nav-icon-img" />
</div>
<div class="nav-text">开奖</div>
</router-link>
<router-link to="/data-analysis" class="nav-item" :class="{ active: $route.path === '/data-analysis' }">
<div class="nav-icon">
<img :src="$route.path === '/data-analysis' ? '/assets/bottom/tuice-1.svg' : '/assets/bottom/tuice-0.svg'" alt="分析" class="nav-icon-img" />
</div>
<div class="nav-text">分析</div>
</router-link>
<router-link to="/profile" class="nav-item" :class="{ active: $route.path === '/profile' }">
<div class="nav-icon">
<img :src="$route.path === '/profile' ? '/assets/bottom/wode-1.svg' : '/assets/bottom/wode-0.svg'" alt="我的" class="nav-icon-img" />
</div>
<div class="nav-text">我的</div>
</router-link>
</nav>
</template>
<script>
export default {
name: 'BottomNavigation',
methods: {
handleDiscoveryClick() {
// 触发自定义事件通知父组件
this.$emit('discovery-click')
}
}
}
</script>
<style scoped>
/* 底部导航栏 */
.bottom-nav {
height: 70px;
background: white;
display: flex;
align-items: center;
justify-content: space-around;
border-top: 1px solid #f0f0f0;
z-index: 1000;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
position: fixed;
bottom: 0;
left: 0;
right: 0;
max-width: 850px;
margin: 0 auto;
}
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-decoration: none;
color: #8a8a8a;
transition: all 0.3s ease;
padding: 4px 8px;
min-width: 60px;
position: relative;
border-radius: 8px;
cursor: pointer;
}
.nav-item:hover {
color: #ff6b35;
background: rgba(255, 107, 53, 0.05);
}
.nav-item:hover .nav-icon-img {
transform: scale(1.05);
}
.nav-item.active {
color: #ff6b35;
background: rgba(255, 107, 53, 0.1);
}
.nav-item.active .nav-text {
color: #ff6b35;
font-weight: 600;
}
.nav-icon {
margin-bottom: 4px;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
}
.nav-icon-img {
width: 24px;
height: 24px;
object-fit: contain;
transition: all 0.3s ease;
}
.nav-text {
font-size: 11px;
font-weight: 500;
text-align: center;
transition: all 0.3s ease;
line-height: 1;
}
/* 移动端适配 */
@media (max-width: 768px) {
.bottom-nav {
height: 65px;
max-width: 100%;
left: 15px;
right: 15px;
border-radius: 0 0 8px 8px;
}
.nav-item {
padding: 3px 6px;
min-width: 55px;
}
.nav-icon {
width: 28px;
height: 28px;
margin-bottom: 3px;
}
.nav-icon-img {
width: 22px;
height: 22px;
}
.nav-text {
font-size: 10px;
}
}
@media (max-width: 480px) {
.bottom-nav {
height: 60px;
max-width: 100%;
left: 0;
right: 0;
border-radius: 0;
}
.nav-item {
padding: 2px 4px;
min-width: 50px;
}
.nav-icon {
width: 26px;
height: 26px;
margin-bottom: 2px;
}
.nav-icon-img {
width: 20px;
height: 20px;
}
.nav-text {
font-size: 9px;
}
}
</style>

View File

@@ -0,0 +1,526 @@
<template>
<!-- Coze AI 聊天助手容器 -->
<div id="coze-chat-container"></div>
<!-- 登录提示弹窗 -->
<div v-if="showLoginModal" class="modal-overlay" @click="hideLoginModal">
<div class="modal-content login-prompt-modal" @click.stop>
<div class="modal-icon">
<svg class="login-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="8" r="3" stroke="currentColor" stroke-width="2"/>
<path d="M12 14c-4 0-7 2-7 4v2h14v-2c0-2-3-4-7-4z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
</svg>
</div>
<h3>需要登录</h3>
<p>使用AI助手功能需要先登录您的账号</p>
<div class="modal-actions">
<button class="btn btn-secondary" @click="hideLoginModal">取消</button>
<button class="btn btn-primary" @click="goToLogin">立即登录</button>
</div>
</div>
</div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { useRouter } from 'vue-router'
import { userStore } from '../store/user'
export default {
name: 'CozeChat',
setup() {
// 响应式数据
const cozeWebSDK = ref(null)
const showLoginModal = ref(false)
const router = useRouter()
// 加载Coze Chat SDK
const loadCozeChatSDK = () => {
// 检查是否已经存在script标签
const existingScript = document.querySelector('script[src*="coze"]')
if (existingScript) {
console.log('Coze SDK已存在直接初始化')
if (window.CozeWebSDK) {
initCozeChatClient()
}
return
}
// 创建script标签
const script = document.createElement('script')
script.src = 'https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.2.0-beta.10/libs/cn/index.js'
script.async = true
script.onload = () => {
console.log('Coze SDK 加载完成')
initCozeChatClient()
.then(() => {
console.log('Coze客户端初始化成功')
})
.catch(error => {
console.error('Failed to initialize Coze chat client:', error)
})
}
script.onerror = (error) => {
console.error('加载Coze SDK失败:', error)
}
document.body.appendChild(script)
}
// 初始化Coze聊天客户端
const initCozeChatClient = async () => {
if (!window.CozeWebSDK) {
console.error('Coze SDK not loaded')
throw new Error('Coze SDK未加载')
}
try {
console.log('Initializing Coze chat client...')
// 获取token
const tokenData = await fetchCozeToken()
console.log('Token data received:', tokenData)
if (!tokenData || !tokenData.access_token) {
console.error('Failed to get valid Coze token')
throw new Error('无法获取有效的Coze token')
}
console.log('Creating Coze chat client with token...')
// 检测设备类型
const isMobile = checkDeviceType()
console.log('设备类型:', isMobile ? '移动设备' : 'PC设备')
// 保存Coze SDK配置
const config = {
config: {
bot_id: '7524958762676305971',
},
componentProps: {
title: '精彩猪手',
},
auth: {
type: 'token',
token: tokenData.access_token,
onRefreshToken: async () => {
try {
console.log('Refreshing token...')
const refreshedData = await fetchCozeToken()
if (refreshedData && refreshedData.access_token) {
console.log('Token refreshed successfully')
return refreshedData.access_token
} else {
throw new Error('Failed to refresh token')
}
} catch (error) {
console.error('Error refreshing token:', error)
return ''
}
}
},
userInfo: {
id: userStore.user?.id?.toString() || 'guest',
url: 'https://wanlvzhisong-1387432270.cos.ap-guangzhou.myqcloud.com/2026/01/14/99595bd6-455b-43d9-857c-c5e6a485d94a.png',
nickname: userStore.user?.username || '游客',
},
ui: {
base: {
icon: 'https://wanlvzhisong-1387432270.cos.ap-guangzhou.myqcloud.com/2026/01/14/fb2fb9fb-7b71-4fc0-81f9-9eb7215d0fc3.jpeg',
layout: isMobile ? 'mobile' : 'pc',
zIndex: 1000,
lang:'zh-CN'
},
asstBtn: {
isNeed: false, // 不展示默认悬浮球
},
footer: {
isShow: false // 隐藏底部版权信息
}
}
}
// 创建聊天客户端实例
cozeWebSDK.value = new window.CozeWebSDK.WebChatClient(config)
console.log('Coze chat client initialized successfully')
return cozeWebSDK.value
} catch (error) {
console.error('Error initializing Coze chat:', error)
throw error
}
}
// 从API获取Coze token
const fetchCozeToken = async () => {
try {
// 确保获取最新的用户信息
let userId = 'guest'
if (userStore.isLoggedIn && userStore.user?.id) {
userId = userStore.user.id
console.log('使用已登录用户ID:', userId)
} else if (userStore.isLoggedIn) {
// 如果用户已登录但没有用户信息,尝试获取
try {
await userStore.fetchLoginUser()
userId = userStore.user?.id || 'guest'
console.log('重新获取用户信息后的ID:', userId)
} catch (error) {
console.warn('获取用户信息失败使用guest模式:', error)
}
}
const jwtExpireSeconds = 3600 // 1小时
const tokenDurationSeconds = 86400 // 24小时
// 根据环境确定API基础URL
let baseUrl = ''
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
baseUrl = 'http://localhost:8123'
} else {
baseUrl = 'https://www.yicaishuzhi.com'
}
const url = `${baseUrl}/api/jwt/one-step-token?jwtExpireSeconds=${jwtExpireSeconds}&sessionName=${userId}&tokenDurationSeconds=${tokenDurationSeconds}`
console.log('Fetching Coze token, URL:', url)
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
})
if (!response.ok) {
console.error(`API error: ${response.status}`, await response.text())
throw new Error(`API error: ${response.status}`)
}
const data = await response.json()
console.log('Token API response:', data)
if (!data.success || !data.data) {
throw new Error('API返回错误: ' + (data.message || '未知错误'))
}
if (data.data.access_token) {
console.log('Token received successfully:', data.data.access_token.substring(0, 10) + '...')
return data.data
} else if (typeof data.data === 'string') {
console.log('Token string received:', data.data.substring(0, 10) + '...')
return { access_token: data.data }
} else {
console.error('Invalid token format:', data.data)
throw new Error('Invalid token format')
}
} catch (error) {
console.error('Error fetching Coze token:', error)
return null
}
}
// 检查是否为移动设备
const checkDeviceType = () => {
const isMobile = window.innerWidth <= 768
console.log('设备类型检测:', isMobile ? '移动设备' : 'PC设备', '屏幕宽度:', window.innerWidth)
return isMobile
}
// 显示AI助手聊天窗口
const showAIAssistant = async () => {
// 检查用户是否已登录
if (!userStore.isLoggedIn) {
console.log('用户未登录,提示先登录')
// 显示登录提示
showLoginPrompt()
return
}
// 如果用户已登录但Coze SDK未初始化强制重新初始化
if (!cozeWebSDK.value) {
console.log('用户已登录但Coze SDK未初始化强制重新初始化')
try {
await forceReinitializeCozeSDK()
// 重新初始化后直接显示聊天窗口
if (cozeWebSDK.value) {
cozeWebSDK.value.showChatBot()
}
} catch (error) {
console.error('强制重新初始化失败:', error)
}
return
}
// 如果SDK已初始化直接显示聊天窗口
if (cozeWebSDK.value) {
console.log('显示聊天窗口')
try {
cozeWebSDK.value.showChatBot()
} catch (error) {
console.error('显示聊天窗口失败:', error)
// 重新初始化并显示
await forceReinitializeCozeSDK()
if (cozeWebSDK.value) {
cozeWebSDK.value.showChatBot()
}
}
}
}
// 显示登录提示
const showLoginPrompt = () => {
showLoginModal.value = true
}
// 隐藏登录提示
const hideLoginModal = () => {
showLoginModal.value = false
}
// 跳转到登录页
const goToLogin = () => {
hideLoginModal()
router.push('/login')
}
// 强制重新初始化Coze SDK用于用户登录后
const forceReinitializeCozeSDK = async () => {
try {
console.log('用户登录状态变化强制重新初始化Coze SDK')
// 清理现有的Coze实例
cozeWebSDK.value = null
// 移除已有的script标签
const existingScripts = document.querySelectorAll('script[src*="coze"]')
existingScripts.forEach(script => {
try {
document.body.removeChild(script)
} catch (e) {
console.warn('移除script标签失败:', e)
}
})
// 清除window上的CozeWebSDK
if (window.CozeWebSDK) {
delete window.CozeWebSDK
}
// 重新加载并初始化SDK
await loadCozeChatSDK()
console.log('Coze SDK 重新初始化完成')
} catch (error) {
console.error('强制重新初始化Coze SDK失败:', error)
}
}
// 组件挂载时初始化
onMounted(() => {
// 加载Coze Chat SDK
loadCozeChatSDK()
// 监听来自其他组件的AI助手调用事件
window.addEventListener('showAIAssistant', showAIAssistant)
// 监听来自其他组件的Coze SDK重新初始化事件
window.addEventListener('reinitializeCozeSDK', forceReinitializeCozeSDK)
})
// 监听用户登录状态变化重新初始化Coze SDK
watch(() => userStore.isLoggedIn, async (newValue, oldValue) => {
console.log('用户登录状态变化:', { oldValue, newValue })
// 只有从未登录变为已登录时才重新初始化
if (!oldValue && newValue) {
console.log('用户刚刚登录需要重新初始化Coze SDK')
// 延迟一下确保用户信息已经更新
setTimeout(async () => {
await forceReinitializeCozeSDK()
}, 1000)
}
// 如果用户退出登录清理Coze实例
if (oldValue && !newValue) {
console.log('用户退出登录清理Coze SDK')
cozeWebSDK.value = null
}
})
// 组件卸载时清理
onBeforeUnmount(() => {
// 移除事件监听器
window.removeEventListener('showAIAssistant', showAIAssistant)
window.removeEventListener('reinitializeCozeSDK', forceReinitializeCozeSDK)
// 清理Coze SDK实例
cozeWebSDK.value = null
})
return {
showLoginModal,
hideLoginModal,
goToLogin
}
}
}
</script>
<style scoped>
/* Coze AI 聊天助手样式 */
#coze-chat-container {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
}
/* 登录提示弹窗样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
backdrop-filter: blur(4px);
}
.modal-content {
background: white;
border-radius: 16px;
padding: 30px;
max-width: 380px;
width: 90%;
text-align: center;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
animation: modalSlideIn 0.3s ease-out;
}
.login-prompt-modal {
border: 2px solid rgba(255, 107, 53, 0.1);
}
.modal-icon {
width: 64px;
height: 64px;
margin: 0 auto 20px auto;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #ff6b35, #f7931e);
border-radius: 50%;
box-shadow: 0 8px 24px rgba(255, 107, 53, 0.3);
}
.login-icon {
width: 32px;
height: 32px;
color: white;
}
.modal-content h3 {
color: #333;
font-size: 20px;
font-weight: 700;
margin-bottom: 15px;
}
.modal-content p {
color: #666;
font-size: 16px;
line-height: 1.5;
margin-bottom: 25px;
}
.modal-actions {
display: flex;
gap: 15px;
justify-content: center;
}
.btn {
padding: 12px 24px;
border-radius: 8px;
font-weight: 600;
font-size: 14px;
cursor: pointer;
border: none;
transition: all 0.3s ease;
min-width: 100px;
}
.btn-primary {
background: linear-gradient(135deg, #ff6b35, #f7931e);
color: white;
box-shadow: 0 4px 15px rgba(255, 107, 53, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(255, 107, 53, 0.4);
}
.btn-secondary {
background: #f8f9fa;
color: #666;
border: 1px solid #e0e0e0;
}
.btn-secondary:hover {
background: #e9ecef;
border-color: #ccc;
}
@keyframes modalSlideIn {
from {
opacity: 0;
transform: translateY(-30px) scale(0.9);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
/* 移动端适配 */
@media (max-width: 480px) {
.modal-content {
padding: 25px 20px;
margin: 0 15px;
}
.modal-icon {
width: 56px;
height: 56px;
margin-bottom: 15px;
}
.login-icon {
width: 28px;
height: 28px;
}
.modal-content h3 {
font-size: 18px;
}
.modal-content p {
font-size: 14px;
}
.modal-actions {
flex-direction: column;
gap: 10px;
}
.btn {
width: 100%;
padding: 14px 20px;
}
}
</style>

View File

@@ -0,0 +1,189 @@
<template>
<div class="custom-select-wrapper">
<div class="custom-select" :class="{ 'open': isOpen }">
<div class="select-trigger" @click="toggleOpen">
<span class="select-value">{{ selectedLabel || placeholder }}</span>
<svg class="select-arrow" viewBox="0 0 24 24">
<path d="M7 10l5 5 5-5z" fill="currentColor"/>
</svg>
</div>
<div v-if="isOpen" class="select-dropdown">
<div
v-for="option in options"
:key="option.value"
class="select-option"
:class="{ 'selected': String(modelValue) === String(option.value) }"
@click="selectOption(option)"
>
{{ option.label }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CustomSelect',
props: {
modelValue: {
type: [String, Number],
default: ''
},
options: {
type: Array,
required: true,
validator: (arr) => arr.every(item => 'value' in item && 'label' in item)
},
placeholder: {
type: String,
default: '请选择'
}
},
emits: ['update:modelValue'],
data() {
return {
isOpen: false
}
},
computed: {
selectedLabel() {
const option = this.options.find(opt => String(opt.value) === String(this.modelValue))
return option ? option.label : ''
}
},
methods: {
toggleOpen() {
this.isOpen = !this.isOpen
},
selectOption(option) {
this.$emit('update:modelValue', option.value)
this.isOpen = false
},
closeDropdown() {
this.isOpen = false
},
handleClickOutside(event) {
if (this.$el && !this.$el.contains(event.target)) {
this.isOpen = false
}
}
},
mounted() {
document.addEventListener('click', this.handleClickOutside)
},
beforeUnmount() {
document.removeEventListener('click', this.handleClickOutside)
}
}
</script>
<style scoped>
.custom-select-wrapper {
width: 100%;
}
.custom-select {
position: relative;
width: 100%;
}
.select-trigger {
width: 100%;
padding: 10px 14px;
border: 2px solid #e8eef5;
border-radius: 10px;
background: white;
color: #2d3748;
font-size: 13px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: border-color 0.2s ease;
user-select: none;
}
.select-trigger:hover {
border-color: #d0d8e8;
}
.custom-select.open .select-trigger {
border-color: #4a90e2;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select-value {
flex: 1;
text-align: left;
}
.select-arrow {
width: 14px;
height: 14px;
color: #999;
transition: transform 0.2s ease;
flex-shrink: 0;
margin-left: 8px;
}
.custom-select.open .select-arrow {
transform: rotate(180deg);
color: #4a90e2;
}
.select-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 2px solid #4a90e2;
border-top: none;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
z-index: 1000;
max-height: 180px;
overflow-y: auto;
}
.select-option {
padding: 10px 14px;
color: #2d3748;
cursor: pointer;
transition: background-color 0.15s ease;
font-size: 13px;
line-height: 1.4;
}
.select-option:hover {
background: #f5f7fa;
}
.select-option.selected {
background: #f0f4f8;
color: #4a90e2;
font-weight: 500;
}
/* 滚动条美化 */
.select-dropdown::-webkit-scrollbar {
width: 5px;
}
.select-dropdown::-webkit-scrollbar-track {
background: transparent;
}
.select-dropdown::-webkit-scrollbar-thumb {
background: #d0d8e8;
border-radius: 2px;
}
.select-dropdown::-webkit-scrollbar-thumb:hover {
background: #b0b8d8;
}
</style>

View File

@@ -11,6 +11,8 @@ import './store/user'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// 导入 Element Plus 中文语言包
import zhCn from 'element-plus/es/locale/lang/zh-cn'
// 导入 Toast 通知组件
import Toast from 'vue-toastification'
@@ -41,6 +43,8 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.use(router)
app.use(Toast, toastOptions)
app.use(ElementPlus)
app.use(ElementPlus, {
locale: zhCn,
})
app.mount('#app')

View File

@@ -1,31 +1,64 @@
import { createRouter, createWebHistory } from 'vue-router'
import { ElMessage } from 'element-plus'
import LotterySelection from '../views/LotterySelection.vue'
import Home from '../views/Home.vue'
import LotteryPremium from '../views/LotteryPremium.vue'
import Home from '../views/ssq/Home.vue'
import DltHome from '../views/dlt/Home.vue'
import LotteryInfo from '../views/LotteryInfo.vue'
import Profile from '../views/Profile.vue'
import Login from '../views/Login.vue'
import Register from '../views/Register.vue'
import ResetPassword from '../views/ResetPassword.vue'
import PredictRecords from '../views/PredictRecords.vue'
import VipCodeManagement from '../views/VipCodeManagement.vue'
import DltPredictRecords from '../views/dlt/PredictRecords.vue'
import ExcelImportManagement from '../views/ExcelImportManagement.vue'
import ExchangeRecords from '../views/ExchangeRecords.vue'
import TrendAnalysis from '../views/TrendAnalysis.vue'
import SurfaceAnalysis from '../views/SurfaceAnalysis.vue'
import LineAnalysis from '../views/LineAnalysis.vue'
import TableAnalysis from '../views/TableAnalysis.vue'
import TrendAnalysis from '../views/ssq/TrendAnalysis.vue'
import SurfaceAnalysis from '../views/ssq/SurfaceAnalysis.vue'
import LineAnalysis from '../views/ssq/LineAnalysis.vue'
import SsqTableAnalysis from '../views/ssq/SsqTableAnalysis.vue'
import DataAnalysis from '../views/DataAnalysis.vue'
import HelpCenter from '../views/HelpCenter.vue'
import AboutUs from '../views/AboutUs.vue'
import UserAgreement from '../views/UserAgreement.vue'
import AIAssistant from '../views/AIAssistant.vue'
import UserGuide from '../views/UserGuide.vue'
import MemberAgreement from '../views/MemberAgreement.vue'
import PrivacyPolicy from '../views/PrivacyPolicy.vue'
import HitAnalysis from '../views/ssq/HitAnalysis.vue'
import DltHitAnalysis from '../views/dlt/HitAnalysis.vue'
import UsageStats from '../views/ssq/UsageStats.vue'
import DltUsageStats from '../views/dlt/UsageStats.vue'
import PrizeStatistics from '../views/ssq/PrizeStatistics.vue'
import DltPrizeStatistics from '../views/dlt/PrizeStatistics.vue'
// 双色球相关页面
import SsqLottery from '../views/ssq/Lottery.vue'
// 大乐透相关页面
import DltLottery from '../views/dlt/Lottery.vue'
import DltTableAnalysis from '../views/dlt/DltTableAnalysis.vue'
import DltSurfaceAnalysis from '../views/dlt/SurfaceAnalysis.vue'
import DltLineAnalysis from '../views/dlt/LineAnalysis.vue'
import DltTrendAnalysis from '../views/dlt/TrendAnalysis.vue'
// 精推版页面
import JtSsqHome from '../views/jt/SsqHome.vue'
import JtDltHome from '../views/jt/DltHome.vue'
// 后台管理相关组件
import AdminLogin from '../views/admin/AdminLogin.vue'
import AdminLayout from '../views/admin/layout/AdminLayout.vue'
import AdminVipCodeManagement from '../views/admin/VipCodeManagement.vue'
import AdminExcelImportManagement from '../views/admin/ExcelImportManagement.vue'
import AdminDltExcelImportManagement from '../views/admin/DltExcelImportManagement.vue'
import AdminPredictionManagement from '../views/admin/PredictionManagement.vue'
import AdminDltPredictionManagement from '../views/admin/DltPredictionManagement.vue'
import AdminPrizeStatistics from '../views/admin/PrizeStatistics.vue'
import AdminDltPrizeStatistics from '../views/admin/DltPrizeStatistics.vue'
import AdminUsageStats from '../views/ssq/UsageStats.vue'
import AdminDltUsageStats from '../views/dlt/UsageStats.vue'
const routes = [
// 前台用户路由
@@ -34,16 +67,70 @@ const routes = [
name: 'LotterySelection',
component: LotterySelection
},
{
path: '/lottery-premium',
name: 'LotteryPremium',
component: LotteryPremium
},
{
path: '/shuangseqiu',
name: 'Shuangseqiu',
component: Home
},
{
path: '/daletou',
name: 'DaLeTou',
component: DltHome
},
{
path: '/jt/shuangseqiu',
name: 'JtShuangseqiu',
component: JtSsqHome
},
{
path: '/jt/daletou',
name: 'JtDaLeTou',
component: JtDltHome
},
{
path: '/lottery-info',
name: 'LotteryInfo',
component: LotteryInfo
},
{
path: '/lottery-info/ssq',
name: 'SsqLottery',
component: SsqLottery
},
{
path: '/lottery-info/dlt',
name: 'DltLottery',
component: DltLottery
},
{
path: '/dlt-table-analysis',
name: 'DltTableAnalysis',
component: DltTableAnalysis,
meta: { requiresAuth: true }
},
{
path: '/dlt-surface-analysis',
name: 'DltSurfaceAnalysis',
component: DltSurfaceAnalysis,
meta: { requiresAuth: true }
},
{
path: '/dlt-line-analysis',
name: 'DltLineAnalysis',
component: DltLineAnalysis,
meta: { requiresAuth: true }
},
{
path: '/dlt-trend-analysis',
name: 'DltTrendAnalysis',
component: DltTrendAnalysis,
meta: { requiresAuth: true }
},
{
path: '/profile',
name: 'Profile',
@@ -70,10 +157,12 @@ const routes = [
component: PredictRecords
},
{
path: '/vip-management',
name: 'VipCodeManagement',
component: VipCodeManagement
path: '/dlt/predict-records',
name: 'DltPredictRecords',
component: DltPredictRecords,
meta: { requiresAuth: true }
},
{
path: '/excel-import',
name: 'ExcelImportManagement',
@@ -106,6 +195,42 @@ const routes = [
component: DataAnalysis,
meta: { requiresAuth: true }
},
{
path: '/hit-analysis',
name: 'HitAnalysis',
component: HitAnalysis,
meta: { requiresAuth: true }
},
{
path: '/daletou/hit-analysis',
name: 'DltHitAnalysis',
component: DltHitAnalysis,
meta: { requiresAuth: true }
},
{
path: '/usage-stats',
name: 'UsageStats',
component: UsageStats,
meta: { requiresAuth: true }
},
{
path: '/daletou/usage-stats',
name: 'DltUsageStats',
component: DltUsageStats,
meta: { requiresAuth: true }
},
{
path: '/prize-statistics',
name: 'PrizeStatistics',
component: PrizeStatistics,
meta: { requiresAuth: true }
},
{
path: '/daletou/prize-statistics',
name: 'DltPrizeStatistics',
component: DltPrizeStatistics,
meta: { requiresAuth: true }
},
{
path: '/help-center',
name: 'HelpCenter',
@@ -125,19 +250,33 @@ const routes = [
meta: { requiresAuth: true }
},
{
path: '/table-analysis',
name: 'TableAnalysis',
component: TableAnalysis
path: '/user-guide',
name: 'UserGuide',
component: UserGuide,
meta: { requiresAuth: true }
},
{
path: '/ai-assistant',
name: 'AIAssistant',
component: AIAssistant
path: '/member-agreement',
name: 'MemberAgreement',
component: MemberAgreement,
meta: { requiresAuth: false }
},
{
path: '/privacy-policy',
name: 'PrivacyPolicy',
component: PrivacyPolicy,
meta: { requiresAuth: false }
},
{
path: '/table-analysis',
name: 'SsqTableAnalysis',
component: SsqTableAnalysis
},
// 后台管理路由 - 完全隔离
{
path: '/admin/login',
path: '/cpzsadmin/login',
name: 'AdminLogin',
component: AdminLogin,
meta: {
@@ -147,7 +286,7 @@ const routes = [
}
},
{
path: '/admin',
path: '/cpzsadmin',
component: AdminLayout,
meta: {
requiresAuth: true,
@@ -156,7 +295,7 @@ const routes = [
children: [
{
path: '',
redirect: '/admin/dashboard'
redirect: '/cpzsadmin/dashboard'
},
{
path: 'dashboard',
@@ -180,13 +319,133 @@ const routes = [
},
{
path: 'excel-import',
name: 'AdminExcelImportManagement',
component: AdminExcelImportManagement,
meta: {
title: '数据导入',
requiresAuth: true,
isAdmin: true
}
},
children: [
{
path: '',
name: 'AdminExcelImportManagement',
component: AdminExcelImportManagement,
meta: {
title: '数据导入',
requiresAuth: true,
isAdmin: true
}
},
{
path: 'ssq',
name: 'AdminExcelImportSSQ',
component: AdminExcelImportManagement,
meta: {
title: '双色球数据导入',
requiresAuth: true,
isAdmin: true
}
},
{
path: 'dlt',
name: 'AdminExcelImportDLT',
component: AdminDltExcelImportManagement,
meta: {
title: '大乐透数据导入',
requiresAuth: true,
isAdmin: true
}
}
]
},
{
path: 'prediction',
meta: {
title: '推测管理',
requiresAuth: true,
isAdmin: true
},
children: [
{
path: 'ssq',
name: 'AdminPredictionSSQ',
component: AdminPredictionManagement,
meta: {
title: '双色球推测管理',
requiresAuth: true,
isAdmin: true
}
},
{
path: 'dlt',
name: 'AdminPredictionDLT',
component: AdminDltPredictionManagement,
meta: {
title: '大乐透推测管理',
requiresAuth: true,
isAdmin: true
}
}
]
},
{
path: 'prize-statistics',
meta: {
title: '奖金统计',
requiresAuth: true,
isAdmin: true
},
children: [
{
path: 'ssq',
name: 'AdminPrizeStatisticsSSQ',
component: AdminPrizeStatistics,
meta: {
title: '双色球奖金统计',
requiresAuth: true,
isAdmin: true
}
},
{
path: 'dlt',
name: 'AdminPrizeStatisticsDLT',
component: AdminDltPrizeStatistics,
meta: {
title: '大乐透奖金统计',
requiresAuth: true,
isAdmin: true
}
}
]
},
{
path: 'usage-stats',
meta: {
title: '使用统计',
requiresAuth: true,
isAdmin: true
},
children: [
{
path: 'ssq',
name: 'AdminUsageStatsSSQ',
component: AdminUsageStats,
meta: {
title: '双色球使用统计',
requiresAuth: true,
isAdmin: true
}
},
{
path: 'dlt',
name: 'AdminUsageStatsDLT',
component: AdminDltUsageStats,
meta: {
title: '大乐透使用统计',
requiresAuth: true,
isAdmin: true
}
}
]
},
{
path: 'user-list',
@@ -207,6 +466,16 @@ const routes = [
requiresAuth: true,
isAdmin: true
}
},
{
path: 'announcement',
name: 'AdminAnnouncementManagement',
component: () => import('../views/admin/AnnouncementManagement.vue'),
meta: {
title: '公告管理',
requiresAuth: true,
isAdmin: true
}
}
]
},
@@ -221,7 +490,16 @@ const routes = [
const router = createRouter({
history: createWebHistory(),
routes
routes,
scrollBehavior(to, from, savedPosition) {
// 如果有保存的位置(比如浏览器后退),使用保存的位置
if (savedPosition) {
return savedPosition
} else {
// 否则滚动到页面顶部
return { top: 0, behavior: 'smooth' }
}
}
})
// 路由守卫 - 权限控制
@@ -244,7 +522,7 @@ router.beforeEach((to, from, next) => {
// 检查是否已登录使用session存储
if (!userStore.isAdminLoggedIn()) {
ElMessage.error('请先登录后台管理系统')
next('/admin/login')
next('/cpzsadmin/login')
return
}
@@ -252,14 +530,14 @@ router.beforeEach((to, from, next) => {
const adminInfo = JSON.parse(sessionStorage.getItem('adminInfo') || '{}')
if (adminInfo.userRole === 'user') {
ElMessage.error('您没有权限访问后台管理系统')
next('/admin/login')
next('/cpzsadmin/login')
return
}
next()
}).catch(error => {
console.error('加载用户状态出错:', error)
next('/admin/login')
next('/cpzsadmin/login')
})
} else {
next()

View File

@@ -6,6 +6,8 @@ export const userStore = reactive({
// 用户信息
user: null,
isLoggedIn: false,
isKickedOut: false, // 标记是否被其他设备踢出
lastCheckTime: null, // 最后一次检查登录状态的时间
// 获取登录用户信息
async fetchLoginUser() {
@@ -15,7 +17,7 @@ export const userStore = reactive({
const userData = response.data
// 更新用户信息,保留现有的本地数据结构
this.user = {
id: userData.id,
id: String(userData.id), // 确保ID始终为字符串避免精度丢失
username: userData.userName || userData.userAccount || userData.username || userData.name,
email: userData.email,
phone: userData.phone,
@@ -70,6 +72,8 @@ export const userStore = reactive({
}
}
this.isLoggedIn = true
this.isKickedOut = false // 重置被踢出状态
this.lastCheckTime = Date.now() // 记录登录时间
// 保存到本地存储
localStorage.setItem('user', JSON.stringify(this.user))
@@ -77,9 +81,16 @@ export const userStore = reactive({
},
// 登出
logout() {
logout(isKickedOut = false) {
// 如果是被踢出,标记状态
if (isKickedOut) {
this.isKickedOut = true
console.log('[安全] 账号在其他设备登录,当前会话已被踢出')
}
this.user = null;
this.isLoggedIn = false;
this.lastCheckTime = null;
// 清除所有本地存储的用户信息
localStorage.removeItem('user');
@@ -106,7 +117,12 @@ export const userStore = reactive({
const savedLoginState = localStorage.getItem('isLoggedIn')
if (savedUser && savedLoginState === 'true') {
this.user = JSON.parse(savedUser)
const user = JSON.parse(savedUser)
// 确保ID始终为字符串避免精度丢失
if (user.id) {
user.id = String(user.id)
}
this.user = user
this.isLoggedIn = true
}
},
@@ -132,7 +148,7 @@ export const userStore = reactive({
// 设置用户信息(用于管理员登录)
setUserInfo(userInfo) {
this.user = {
id: userInfo.id,
id: String(userInfo.id), // 确保ID始终为字符串避免精度丢失
username: userInfo.userAccount || userInfo.userName,
nickname: userInfo.userName || userInfo.userAccount,
avatar: userInfo.avatar || null,
@@ -187,13 +203,65 @@ export const userStore = reactive({
},
// 管理员登出
adminLogout() {
adminLogout(isKickedOut = false) {
// 如果是被踢出,标记状态
if (isKickedOut) {
this.isKickedOut = true
console.log('[安全] 管理员账号在其他设备登录,当前会话已被踢出')
}
this.user = null;
this.isLoggedIn = false;
this.lastCheckTime = null;
// 清除所有session存储的管理员信息
sessionStorage.removeItem('adminInfo');
sessionStorage.removeItem('adminLoggedIn');
},
// 主动检查登录状态是否有效
async checkLoginStatus() {
// 如果没有登录,直接返回
if (!this.isLoggedIn) {
return { valid: false, reason: 'not_logged_in' }
}
// 避免频繁检查10秒内只检查一次
const now = Date.now()
if (this.lastCheckTime && (now - this.lastCheckTime) < 10000) {
return { valid: true, reason: 'recently_checked' }
}
try {
// 调用后端接口验证登录状态
const response = await lotteryApi.getLoginUser()
if (response.success === true) {
// 登录状态有效,更新检查时间
this.lastCheckTime = now
this.isKickedOut = false
return { valid: true, reason: 'verified' }
} else {
// 检查是否是被踢出
const message = response.message || ''
if (message.includes('其他设备登录') || message.includes('当前会话已失效')) {
this.logout(true) // 标记为被踢出
return { valid: false, reason: 'kicked_out', message }
} else {
this.logout(false)
return { valid: false, reason: 'session_expired', message }
}
}
} catch (error) {
console.error('[Store] 检查登录状态失败:', error)
// 网络错误等情况,不清除登录状态,让用户继续使用
return { valid: true, reason: 'check_failed', error }
}
},
// 重置被踢出状态(用于重新登录后)
resetKickedOutStatus() {
this.isKickedOut = false
}
})

View File

@@ -250,4 +250,43 @@ body.admin-body {
font-size: 14px;
margin-bottom: 15px;
border-left: 4px solid #4caf50;
}
/* 隐藏子页面顶部背景图的浮动元素 */
.page-header-modern::before {
display: none !important;
}
/* 移除所有链接的选中效果 */
a, a:link, a:visited, a:hover, a:active, a:focus {
-webkit-tap-highlight-color: transparent !important;
-webkit-touch-callout: none !important;
-webkit-user-select: none !important;
-khtml-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
outline: none !important;
}
/* 移除所有元素的tap高亮效果 */
* {
-webkit-tap-highlight-color: transparent !important;
-webkit-touch-callout: none !important;
}
/* 特别针对协议链接 */
.terms-link,
.terms-link:link,
.terms-link:visited,
.terms-link:hover,
.terms-link:active,
.terms-link:focus {
-webkit-tap-highlight-color: transparent !important;
-webkit-touch-callout: none !important;
-webkit-user-select: none !important;
user-select: none !important;
outline: none !important;
background: transparent !important;
background-color: transparent !important;
}

View File

@@ -1,636 +0,0 @@
<template>
<div class="ai-assistant-container">
<!-- 顶部导航栏 -->
<div class="top-nav">
<div class="back-btn" @click="$router.push('/profile')">
<span class="back-icon"></span>
<span class="back-text">返回</span>
</div>
<div class="session-info">
<div class="info-item">
<span class="info-label">会话ID:</span>
<span class="info-value">{{ conversationId }}</span>
</div>
</div>
</div>
<!-- 聊天主体区域 -->
<div class="chat-container">
<div class="chat-messages" ref="chatMessages">
<!-- 聊天消息列表 -->
<div v-if="messages.length === 0" class="empty-chat">
<div class="welcome-message">
<h3>欢迎使用AI智能助手</h3>
<p>您可以向我咨询彩票相关的任何问题我将尽力为您解答</p>
</div>
</div>
<div v-for="(msg, index) in messages" :key="index" class="message-wrapper" :class="{ 'user-message': msg.type === 'USER', 'ai-message': msg.type === 'AI' }">
<div class="message-avatar">
<div v-if="msg.type === 'USER'" class="user-avatar">用户</div>
<div v-else class="ai-avatar">AI</div>
</div>
<div class="message-content">
<div class="message-bubble" :class="{ 'user-bubble': msg.type === 'USER', 'ai-bubble': msg.type === 'AI' }">
<div class="message-text" v-html="formatMessage(msg.content)"></div>
<div v-if="msg.type === 'USER'" class="message-time">{{ msg.time }}</div>
<div v-else class="message-time">{{ msg.time }}</div>
</div>
</div>
</div>
<!-- 正在输入指示器 -->
<div v-if="isAITyping" class="message-wrapper ai-message">
<div class="message-avatar">
<div class="ai-avatar">AI</div>
</div>
<div class="message-content">
<div class="message-bubble ai-bubble">
<div class="typing-indicator">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
</div>
<!-- 输入区域 -->
<div class="chat-input-container">
<div class="input-wrapper">
<textarea
v-model="userInput"
class="chat-input"
placeholder="请输入您的问题..."
@keydown.enter.prevent="sendMessage"
:disabled="isAITyping"
ref="chatInput"
></textarea>
<button
class="send-btn"
@click="sendMessage"
:disabled="!userInput.trim() || isAITyping"
>
发送
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { userStore } from '../store/user'
export default {
name: 'AIAssistant',
data() {
return {
userInput: '',
messages: [],
conversationId: '',
isAITyping: false,
eventSource: null
}
},
mounted() {
// 生成会话ID
this.generateConversationId()
// 添加欢迎消息
this.addAIMessage('您好!我是彩票智能助手,请问有什么可以帮助您的?')
// 自动聚焦输入框
this.$nextTick(() => {
this.$refs.chatInput.focus()
})
},
beforeUnmount() {
// 组件销毁前关闭SSE连接
this.closeEventSource()
},
methods: {
// 生成10位随机会话ID
generateConversationId() {
const min = 1000000000 // 10位数的最小值
const max = 9999999999 // 10位数的最大值
this.conversationId = Math.floor(Math.random() * (max - min + 1) + min).toString()
},
// 发送消息
sendMessage() {
if (!this.userInput.trim() || this.isAITyping) return
// 获取用户ID
const userId = userStore.user?.id
if (!userId) {
this.$router.push('/login')
return
}
// 添加用户消息到列表
this.addUserMessage(this.userInput)
// 保存用户输入并清空输入框
const message = this.userInput
this.userInput = ''
// 显示AI正在输入状态
this.isAITyping = true
// 滚动到底部
this.scrollToBottom()
// 关闭之前的SSE连接
this.closeEventSource()
// 创建新的SSE连接
const url = `http://47.117.22.239:8123/api/chat/sse?message=${encodeURIComponent(message)}&conversationId=${this.conversationId}&userId=${userId}`
this.eventSource = new EventSource(url)
let aiResponse = ''
this.eventSource.onmessage = (event) => {
// 将收到的文本添加到响应中
aiResponse += event.data
// 更新最后一条AI消息或添加新消息
if (this.messages.length > 0 && this.messages[this.messages.length - 1].type === 'AI') {
this.messages[this.messages.length - 1].content = aiResponse
} else {
this.addAIMessage(aiResponse)
}
// 滚动到底部
this.scrollToBottom()
}
this.eventSource.onerror = (error) => {
console.error('SSE错误:', error)
this.isAITyping = false
this.closeEventSource()
// 如果没有收到任何响应,添加错误消息
if (!aiResponse) {
this.addAIMessage('抱歉,服务器连接出现问题,请稍后再试。')
}
}
this.eventSource.onopen = () => {
console.log('SSE连接已打开')
}
// 添加完成事件处理
this.eventSource.addEventListener('complete', () => {
console.log('流式响应完成')
this.isAITyping = false
this.closeEventSource()
})
},
// 关闭SSE连接
closeEventSource() {
if (this.eventSource) {
this.eventSource.close()
this.eventSource = null
}
this.isAITyping = false
},
// 添加用户消息
addUserMessage(content) {
this.messages.push({
type: 'USER',
content: content,
time: this.getCurrentTime()
})
},
// 添加AI消息
addAIMessage(content) {
this.messages.push({
type: 'AI',
content: content,
time: this.getCurrentTime()
})
},
// 获取当前时间
getCurrentTime() {
const now = new Date()
const hours = String(now.getHours()).padStart(2, '0')
const minutes = String(now.getMinutes()).padStart(2, '0')
return `${hours}:${minutes}`
},
// 滚动到底部
scrollToBottom() {
this.$nextTick(() => {
if (this.$refs.chatMessages) {
this.$refs.chatMessages.scrollTop = this.$refs.chatMessages.scrollHeight
}
})
},
// 格式化消息内容(处理换行符等)
formatMessage(text) {
if (!text) return ''
return text.replace(/\n/g, '<br>')
}
}
}
</script>
<style scoped>
/* 整体容器样式 */
.ai-assistant-container {
min-height: 100vh;
height: 100vh;
width: 100%;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
background: #f8f9fa;
overflow: hidden;
}
/* 顶部导航栏 */
.top-nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
background-color: #f44336;
color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
z-index: 10;
}
.back-btn {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
transition: all 0.2s ease;
}
.back-btn:hover {
opacity: 0.8;
}
.back-icon {
font-size: 16px;
font-weight: bold;
}
.back-text {
font-size: 14px;
font-weight: 500;
}
.session-info {
font-size: 12px;
}
.info-item {
display: flex;
align-items: center;
gap: 5px;
}
.info-label {
font-weight: 600;
}
.info-value {
font-family: monospace;
}
/* 聊天区域样式 */
.chat-container {
flex: 1;
display: flex;
flex-direction: column;
background: white;
width: 100%;
height: calc(100vh - 50px); /* 减去顶部导航栏高度 */
position: relative;
overflow: hidden;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 20px;
display: flex;
flex-direction: column;
gap: 15px;
height: calc(100vh - 130px); /* 减去顶部导航栏和输入区域的高度 */
}
/* 空聊天时的欢迎消息 */
.empty-chat {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 20px;
}
.welcome-message {
text-align: center;
padding: 30px;
background: #f0f7ff;
border-radius: 12px;
max-width: 80%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.welcome-message h3 {
color: #4a6fff;
margin-bottom: 15px;
font-size: 22px;
}
.welcome-message p {
color: #666;
line-height: 1.6;
font-size: 16px;
}
/* 消息样式 */
.message-wrapper {
display: flex;
margin-bottom: 15px;
animation: fadeIn 0.3s ease;
}
.user-message {
justify-content: flex-end;
}
.ai-message {
justify-content: flex-start;
}
.message-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
margin: 0 10px;
}
.user-avatar {
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.ai-avatar {
background: linear-gradient(135deg, #4a6fff, #6c4aff);
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.message-content {
max-width: 70%;
}
.message-bubble {
padding: 12px 16px;
border-radius: 18px;
position: relative;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.user-bubble {
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
color: white;
border-top-right-radius: 4px;
}
.ai-bubble {
background: #f0f7ff;
color: #333;
border-top-left-radius: 4px;
}
.message-text {
line-height: 1.5;
word-break: break-word;
font-size: 15px;
}
.message-time {
font-size: 11px;
opacity: 0.7;
text-align: right;
margin-top: 5px;
}
/* 输入区域样式 */
.chat-input-container {
padding: 15px 20px;
background: #f8f9fa;
border-top: 1px solid #e9ecef;
width: 100%;
box-sizing: border-box;
}
.input-wrapper {
display: flex;
gap: 10px;
position: relative;
}
.chat-input {
flex: 1;
border: 1px solid #ced4da;
border-radius: 24px;
padding: 12px 20px;
font-size: 15px;
resize: none;
height: 50px;
max-height: 100px;
overflow-y: auto;
background: white;
transition: all 0.3s ease;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.chat-input:focus {
outline: none;
border-color: #4a6fff;
box-shadow: 0 0 0 3px rgba(74, 111, 255, 0.1);
}
.chat-input:disabled {
background: #e9ecef;
cursor: not-allowed;
}
.send-btn {
background: linear-gradient(135deg, #4a6fff, #6c4aff);
color: white;
border: none;
border-radius: 24px;
padding: 0 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
min-width: 80px;
}
.send-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(74, 111, 255, 0.3);
}
.send-btn:disabled {
background: #cbd3ff;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
/* 正在输入指示器 */
.typing-indicator {
display: flex;
align-items: center;
gap: 4px;
padding: 5px 0;
}
.typing-indicator span {
display: block;
width: 8px;
height: 8px;
border-radius: 50%;
background: #6c4aff;
opacity: 0.7;
animation: typing 1s infinite ease-in-out;
}
.typing-indicator span:nth-child(1) {
animation-delay: 0s;
}
.typing-indicator span:nth-child(2) {
animation-delay: 0.2s;
}
.typing-indicator span:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes typing {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
100% {
transform: translateY(0);
}
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 响应式样式 */
@media (max-width: 768px) {
.message-content {
max-width: 80%;
}
}
@media (max-width: 480px) {
.chat-messages {
padding: 15px 10px;
}
.message-avatar {
width: 35px;
height: 35px;
font-size: 12px;
margin: 0 5px;
}
.message-content {
max-width: 90%;
}
.message-bubble {
padding: 10px 12px;
}
.message-text {
font-size: 14px;
}
.welcome-message {
padding: 20px;
}
.welcome-message h3 {
font-size: 18px;
}
.welcome-message p {
font-size: 14px;
}
.chat-input {
padding: 10px 15px;
font-size: 14px;
height: 45px;
}
.send-btn {
min-width: 70px;
padding: 0 15px;
height: 45px;
font-size: 13px;
}
.top-nav {
padding: 8px 10px;
}
.back-text {
font-size: 12px;
}
.session-info {
font-size: 11px;
}
}
</style>

View File

@@ -1,91 +1,69 @@
<template>
<div class="about-us-page">
<el-page-header @back="goBack" content="关于我们">
<template #title>
<span>返回</span>
</template>
</el-page-header>
<el-card class="about-content-card">
<div class="company-info">
<h4>彩票猪手</h4>
<div class="intro-content">
<p>彩票猪手的宗旨是脚踏实地做一个对用户有价值的专属彩票数据助理</p>
<p>彩票猪手的靓点是其独有的彩票数据活跃性组合性接续性分析和开奖辅助推测简称为"三性一推"</p>
<p>彩票猪手摒弃现行的彩票数据"和值""区比""奇偶"等观察统计方法开创数据姿态逻辑研究新领域</p>
<p>彩票猪手以个人用户为目标努力探索"数据戏彩"的新途径开启"数据变现"的新典范</p>
<p>彩票猪手契合AI智能体犹如镶嵌了时代的印记目的和意义不仅仅是渲染和炫耀</p>
<p>彩票猪手只专注于对号球"交叉现隐"规律的研究有关具体投注的方法与技巧不在其列</p>
<p>彩票猪手的三项基本服务可以归纳为开奖信息查询开奖数据分析开奖号码推测</p>
<p>彩票猪手可以同时满足用户自行研判选号和程序辅助推号的需求</p>
</div>
</div>
<div class="contact-section">
<h4>联系我们</h4>
<div class="contact-item">
<div class="contact-icon">
<el-icon :size="20"><Phone /></el-icon>
</div>
<div class="contact-info">
<span class="contact-label">客服热线</span>
<span class="contact-value">400-888-9999</span>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">
<el-icon :size="20"><Message /></el-icon>
</div>
<div class="contact-info">
<span class="contact-label">邮箱地址</span>
<span class="contact-value">service@lottery-ai.com</span>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">
<el-icon :size="20"><ChatDotRound /></el-icon>
</div>
<div class="contact-info">
<span class="contact-label">在线客服</span>
<span class="contact-value">右上角悬浮弹窗</span>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">
<el-icon :size="20"><Clock /></el-icon>
</div>
<div class="contact-info">
<span class="contact-label">服务时间</span>
<span class="contact-value">周一至周日 9:00-21:00</span>
<!-- 现代化页面头部 -->
<div class="page-header-modern">
<div class="header-content">
<button class="back-btn" @click="goBack">
<svg viewBox="0 0 24 24" class="back-icon">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
</svg>
</button>
<div class="header-info">
<div class="header-text">
<h1 class="header-title">关于我们</h1>
<p class="header-subtitle">了解精彩猪手的产品理念与服务</p>
</div>
</div>
</div>
<div class="version-info">
<div class="version-row">
<span>版本号v1.0.0</span>
<div class="user-agreement-link" @click="$router.push('/user-agreement')">
用户协议
</div>
<!-- 主要内容 - 通篇文章 -->
<div class="about-content">
<div class="article-container">
<!-- 文章正文 -->
<div class="article-body">
<p class="opening-title">精彩猪手不仅仅是一款彩票数据分析工具</p>
<div class="tight-paragraphs">
<p class="paragraph">庖丁解牛且看彩票数据姿态逻辑分析法</p>
<p class="paragraph">游刃有余且用彩票号组分段逻辑推测法</p>
<p class="paragraph">彩票下注是最懵懂的彷徨和最无奈的焦虑但我们让"老虎吃天"不再"无从下口"</p>
</div>
<p class="paragraph">我们是彩票数据姿态逻辑分析法的原创者从婀娜多姿的彩票数据中模型化活跃性接续性组合性逻辑让彩票号球尽显动态灵性在四方交错中不再冰冷呆滞和虚幻想得到看得清抓得住彩票数据之海任尔纵横捭阖</p>
<p class="paragraph">我们还是彩票号组分段推测逻辑的开路人正是基于彩票姿态逻辑数据集彩票号组分段式推测逻辑方得跃然而出这是一股彩票下注方法论的清流也是一种数据引领逻辑导向的突破车到山前必有"路"有路先有"开路人"</p>
<p class="paragraph">我们致力于"精彩"本色扮演好"猪手"角色花独放香尽散提供精品优质的彩票数据服务便是我们的本色做好彩民的彩票数据助手更是我们的角色我们用一首数据加逻辑的彩票推测神曲唤醒和造福一方追梦的彩民</p>
<p class="paragraph"><strong>我们的宗旨</strong>助力再助力直至彩民们梦想成真科技给出了腾飞的翅膀我们却把它插上彩民的臂膀在彩票追梦大戏中我们永远都甘当配角能够创造神奇的主角只属于那些智慧和运气并驾的彩民</p>
<p class="blessing">愿好花常开祝好运常在</p>
</div>
<!-- 联系方式 -->
<div class="contact-section">
<p class="section-text">公司微信客服二维码</p>
<div class="qrcode-wrapper">
<img src="/assets/home/erweima.png" alt="客服二维码" class="qrcode-img" />
</div>
<p class="section-text">公司微信公众号<strong>精彩猪手</strong></p>
</div>
<!-- 公司信息 -->
<div class="company-footer">
<p class="company-name">西安溢彩数智科技有限公司</p>
<p class="company-date">2026年2月</p>
</div>
<p>© 2025 彩票智能推测系统. 保留所有权利.</p>
</div>
</el-card>
</div>
</div>
</template>
<script>
import { ElPageHeader, ElCard, ElIcon } from 'element-plus'
import { Phone, Message, ChatDotRound, Clock } from '@element-plus/icons-vue'
export default {
name: 'AboutUs',
components: {
ElPageHeader,
ElCard,
ElIcon,
Phone,
Message,
ChatDotRound,
Clock
},
methods: {
goBack() {
this.$router.go(-1)
@@ -96,162 +74,300 @@ export default {
<style scoped>
.about-us-page {
padding: 20px;
background-color: #f0f2f5;
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 0;
padding-bottom: 80px;
}
/* 自定义返回按钮样式 */
:deep(.el-page-header__header) {
background: white;
padding: 15px 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
:deep(.el-page-header__back) {
color: #409EFF !important;
font-weight: 600;
font-size: 16px;
}
:deep(.el-page-header__back:hover) {
color: #66b1ff !important;
}
:deep(.el-page-header__content) {
color: #333 !important;
font-weight: 600;
font-size: 18px;
}
.about-content-card {
margin-top: 20px;
border-radius: 8px;
/* 页面头部 */
.page-header-modern {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
padding: 20px 0;
position: relative;
overflow: hidden;
}
.company-info {
margin-bottom: 25px;
text-align: center;
.page-header-modern::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 200' preserveAspectRatio='none'%3E%3Cpath d='M0,100 Q200,60 400,100 T800,100 L800,200 L0,200 Z' fill='rgba(255,255,255,0.08)'/%3E%3Cpath d='M0,120 Q200,80 400,120 T800,120 L800,200 L0,200 Z' fill='rgba(255,255,255,0.05)'/%3E%3C/svg%3E");
background-size: cover;
background-position: center;
opacity: 1;
z-index: 0;
}
.company-info h4 {
color: #e53e3e;
font-size: 18px;
font-weight: 600;
margin-bottom: 10px;
}
.intro-content {
text-align: left;
margin-top: 15px;
}
.intro-content p {
color: #666;
line-height: 1.8;
margin: 0 0 12px 0;
font-size: 14px;
text-align: justify;
}
.intro-content p:last-child {
margin-bottom: 0;
}
.contact-section h4 {
color: #333;
font-size: 16px;
font-weight: 600;
margin-bottom: 15px;
padding-bottom: 8px;
border-bottom: 1px solid #f0f0f0;
}
.contact-item {
.header-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
align-items: center;
margin-bottom: 15px;
padding: 12px;
background: #f8f9fa;
border-radius: 8px;
transition: all 0.3s ease;
padding: 0 20px;
position: relative;
z-index: 1;
}
.contact-item:hover {
background: #e9ecef;
transform: translateY(-1px);
}
.contact-icon {
font-size: 20px;
margin-right: 12px;
width: 32px;
height: 32px;
text-align: center;
.back-btn {
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
color: #409EFF;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
color: white;
margin-right: 16px;
}
.contact-info {
.back-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
.back-icon {
width: 24px;
height: 24px;
fill: currentColor;
}
.header-info {
flex: 1;
display: flex;
flex-direction: column;
}
.contact-label {
font-size: 12px;
color: #999;
margin-bottom: 2px;
font-weight: 500;
.header-title {
font-size: 24px;
font-weight: 700;
margin: 0 0 4px 0;
color: white;
}
.contact-value {
.header-subtitle {
font-size: 14px;
opacity: 0.8;
margin: 0;
}
/* 主要内容 */
.about-content {
max-width: 900px;
margin: 0 auto;
padding: 24px 20px;
}
/* 文章容器 */
.article-container {
background: white;
border-radius: 20px;
padding: 40px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
line-height: 2;
}
/* 文章正文 */
.article-body {
font-size: 15px;
color: #555;
line-height: 2;
}
.opening-title {
font-size: 18px;
font-weight: 600;
color: #333;
text-align: center;
margin: 0 0 32px 0;
line-height: 2;
}
.paragraph {
margin: 0;
text-align: justify;
line-height: 2;
text-indent: 2em;
}
.tight-paragraphs {
margin-bottom: 16px;
}
.tight-paragraphs .paragraph {
margin: 0;
line-height: 1.8;
}
.paragraph strong {
color: #333;
font-weight: 600;
}
.version-info {
.blessing {
text-align: center;
margin-top: 20px;
padding-top: 15px;
font-size: 16px;
color: #e53e3e;
font-weight: 600;
margin: 32px 0;
font-style: italic;
letter-spacing: 2px;
}
/* 联系方式 */
.contact-section {
margin-top: 32px;
padding-top: 24px;
border-top: 1px solid #f0f0f0;
}
.version-row {
.section-text {
font-size: 15px;
color: #555;
line-height: 2;
margin: 0 0 16px 0;
text-align: center;
}
.section-text strong {
color: #4facfe;
font-weight: 600;
}
.qrcode-wrapper {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 8px;
gap: 20px;
margin: 20px 0;
}
.version-row span {
font-size: 12px;
.qrcode-img {
width: 180px;
height: 180px;
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
border: 2px solid #f0f0f0;
}
/* 公司信息 */
.company-footer {
margin-top: 40px;
padding-top: 24px;
border-top: 1px solid #f0f0f0;
text-align: right;
}
.company-name {
font-size: 15px;
color: #333;
font-weight: 600;
margin: 0 0 8px 0;
}
.company-date {
font-size: 13px;
color: #999;
line-height: 1.4;
margin: 0;
padding-right: 60px;
}
.version-info p {
font-size: 12px;
color: #999;
margin: 4px 0;
line-height: 1.4;
/* 响应式设计 */
@media (max-width: 768px) {
.page-header-modern {
padding: 16px 0;
}
.header-content {
padding: 0 12px;
}
.back-btn {
width: 40px;
height: 40px;
margin-right: 10px;
}
.back-icon {
width: 20px;
height: 20px;
}
.header-title {
font-size: 18px;
}
.header-subtitle {
font-size: 12px;
}
.about-content {
padding: 16px 12px;
}
.article-container {
padding: 24px 20px;
border-radius: 16px;
}
.opening-title {
font-size: 16px;
}
.article-body {
font-size: 14px;
}
.paragraph {
margin-bottom: 16px;
}
.blessing {
font-size: 15px;
}
.qrcode-img {
width: 160px;
height: 160px;
}
.company-date {
padding-right: 40px;
}
}
.user-agreement-link {
color: #409EFF;
font-size: 12px;
cursor: pointer;
text-decoration: underline;
transition: color 0.3s ease;
@media (max-width: 480px) {
.about-content {
padding: 12px 10px;
}
.article-container {
padding: 20px 16px;
}
.opening-title {
font-size: 15px;
}
.article-body {
font-size: 13px;
}
.blessing {
font-size: 14px;
}
.qrcode-img {
width: 140px;
height: 140px;
}
.company-date {
padding-right: 20px;
}
}
.user-agreement-link:hover {
color: #66b1ff;
}
</style>
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -18,136 +18,168 @@
<!-- 主要内容 - 只有有权限时才显示 -->
<div v-else-if="hasPermission" class="import-container">
<!-- 完整数据导入 -->
<div class="import-card">
<div class="card-header">
<div>
<h2>📋 完整数据导入</h2>
<p>上传包含T1-T7工作表的Excel文件导入红球蓝球接续系数和组合系数数据</p>
</div>
</div>
<div class="upload-section">
<div class="file-input-container">
<input
type="file"
ref="fullDataFileInput"
@change="handleFileSelect($event, 'fullData')"
accept=".xlsx,.xls"
class="file-input"
id="fullDataFile"
/>
<label for="fullDataFile" class="file-label">
<span class="file-icon">📁</span>
<span class="file-text">
{{ fullDataFile ? fullDataFile.name : '选择Excel文件包含T1-T7工作表' }}
</span>
</label>
</div>
<button
@click="uploadFullData"
:disabled="!fullDataFile || fullDataUploading"
class="btn btn-primary"
>
{{ fullDataUploading ? '导入中...' : '开始导入' }}
</button>
<div v-if="fullDataResult" class="result-message" :class="fullDataResult.type">
{{ fullDataResult.message }}
</div>
</div>
</div>
<!-- 功能区域 -->
<div class="function-area">
<el-row :gutter="20">
<!-- 完整数据导入 -->
<el-col :span="8">
<el-card class="function-card">
<template #header>
<div class="card-header">
<el-icon><Document /></el-icon>
<span>完整数据导入</span>
</div>
</template>
<div class="card-desc">
<p>上传包含T1-T7工作表的Excel文件导入红球蓝球接续系数和组合系数数据</p>
</div>
<div class="upload-section">
<div class="file-input-container">
<input
type="file"
ref="fullDataFileInput"
@change="handleFileSelect($event, 'fullData')"
accept=".xlsx,.xls"
class="file-input"
id="fullDataFile"
/>
<label for="fullDataFile" class="file-label">
<el-icon class="file-icon"><FolderOpened /></el-icon>
<span class="file-text">
{{ fullDataFile ? fullDataFile.name : '选择Excel文件包含T1-T7工作表' }}
</span>
</label>
</div>
<el-button
type="primary"
@click="uploadFullData"
:disabled="!fullDataFile || fullDataUploading"
:loading="fullDataUploading"
style="width: 100%; margin-top: 16px"
>
{{ fullDataUploading ? '导入中...' : '开始导入' }}
</el-button>
<div v-if="fullDataResult" class="result-message" :class="fullDataResult.type">
{{ fullDataResult.message }}
</div>
</div>
</el-card>
</el-col>
<!-- 开奖数据导入覆盖 -->
<div class="import-card">
<div class="card-header">
<div>
<h2>🎯 开奖数据导入覆盖</h2>
<p>上传包含T10工作表的Excel文件清空并重新导入开奖数据</p>
</div>
</div>
<div class="upload-section">
<div class="file-input-container">
<input
type="file"
ref="lotteryFileInput"
@change="handleFileSelect($event, 'lottery')"
accept=".xlsx,.xls"
class="file-input"
id="lotteryFile"
/>
<label for="lotteryFile" class="file-label">
<span class="file-icon">📁</span>
<span class="file-text">
{{ lotteryFile ? lotteryFile.name : '选择Excel文件包含T10工作表' }}
</span>
</label>
</div>
<button
@click="uploadLotteryData"
:disabled="!lotteryFile || lotteryUploading"
class="btn btn-warning"
>
{{ lotteryUploading ? '导入中...' : '覆盖导入' }}
</button>
<div v-if="lotteryResult" class="result-message" :class="lotteryResult.type">
{{ lotteryResult.message }}
</div>
</div>
</div>
<!-- 开奖数据导入覆盖 -->
<el-col :span="8">
<el-card class="function-card">
<template #header>
<div class="card-header">
<el-icon><Warning /></el-icon>
<span>开奖数据导入覆盖</span>
</div>
</template>
<div class="card-desc">
<p>上传包含T10工作表的Excel文件清空并重新导入开奖数据</p>
</div>
<div class="upload-section">
<div class="file-input-container">
<input
type="file"
ref="lotteryFileInput"
@change="handleFileSelect($event, 'lottery')"
accept=".xlsx,.xls"
class="file-input"
id="lotteryFile"
/>
<label for="lotteryFile" class="file-label">
<el-icon class="file-icon"><FolderOpened /></el-icon>
<span class="file-text">
{{ lotteryFile ? lotteryFile.name : '选择Excel文件包含T10工作表' }}
</span>
</label>
</div>
<el-button
type="warning"
@click="uploadLotteryData"
:disabled="!lotteryFile || lotteryUploading"
:loading="lotteryUploading"
style="width: 100%; margin-top: 16px"
>
{{ lotteryUploading ? '导入中...' : '覆盖导入' }}
</el-button>
<div v-if="lotteryResult" class="result-message" :class="lotteryResult.type">
{{ lotteryResult.message }}
</div>
</div>
</el-card>
</el-col>
<!-- 开奖数据追加 -->
<div class="import-card">
<div class="card-header">
<div>
<h2> 开奖数据追加</h2>
<p>上传包含T10工作表的Excel文件追加导入开奖数据跳过重复期号</p>
</div>
</div>
<div class="upload-section">
<div class="file-input-container">
<input
type="file"
ref="appendFileInput"
@change="handleFileSelect($event, 'append')"
accept=".xlsx,.xls"
class="file-input"
id="appendFile"
/>
<label for="appendFile" class="file-label">
<span class="file-icon">📁</span>
<span class="file-text">
{{ appendFile ? appendFile.name : '选择Excel文件包含T10工作表' }}
</span>
</label>
</div>
<button
@click="appendLotteryData"
:disabled="!appendFile || appendUploading"
class="btn btn-success"
>
{{ appendUploading ? '追加中...' : '追加导入' }}
</button>
<div v-if="appendResult" class="result-message" :class="appendResult.type">
{{ appendResult.message }}
</div>
</div>
<!-- 开奖数据追加 -->
<el-col :span="8">
<el-card class="function-card">
<template #header>
<div class="card-header">
<el-icon><Plus /></el-icon>
<span>开奖数据追加</span>
</div>
</template>
<div class="card-desc">
<p>上传包含T10工作表的Excel文件追加导入开奖数据跳过重复期号</p>
</div>
<div class="upload-section">
<div class="file-input-container">
<input
type="file"
ref="appendFileInput"
@change="handleFileSelect($event, 'append')"
accept=".xlsx,.xls"
class="file-input"
id="appendFile"
/>
<label for="appendFile" class="file-label">
<el-icon class="file-icon"><FolderOpened /></el-icon>
<span class="file-text">
{{ appendFile ? appendFile.name : '选择Excel文件包含T10工作表' }}
</span>
</label>
</div>
<el-button
type="success"
@click="appendLotteryData"
:disabled="!appendFile || appendUploading"
:loading="appendUploading"
style="width: 100%; margin-top: 16px"
>
{{ appendUploading ? '追加中...' : '追加导入' }}
</el-button>
<div v-if="appendResult" class="result-message" :class="appendResult.type">
{{ appendResult.message }}
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<!-- 导入说明 -->
<div class="info-card">
<div class="card-header">
<h2> 导入说明</h2>
</div>
<el-card class="info-card">
<template #header>
<div class="card-header">
<el-icon><InfoFilled /></el-icon>
<span>导入说明</span>
</div>
</template>
<div class="info-content">
<div class="info-item">
<h4>📋 完整数据导入</h4>
@@ -170,7 +202,7 @@
<p> 自动跳过重复的期号适用于增量更新</p>
</div>
</div>
</div>
</el-card>
</div>
@@ -188,9 +220,35 @@
<script>
import { lotteryApi } from '../api/index.js'
import { userStore } from '../store/user.js'
import {
ElCard,
ElRow,
ElCol,
ElButton,
ElIcon
} from 'element-plus'
import {
Document,
Warning,
Plus,
InfoFilled,
FolderOpened
} from '@element-plus/icons-vue'
export default {
name: 'ExcelImportManagement',
components: {
ElCard,
ElRow,
ElCol,
ElButton,
ElIcon,
Document,
Warning,
Plus,
InfoFilled,
FolderOpened
},
data() {
return {
// 权限验证
@@ -470,52 +528,49 @@ export default {
/* 主容器 */
.import-container {
max-width: 1400px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 25px;
margin-bottom: 30px;
padding: 20px;
}
/* 导入卡片 */
.import-card,
.info-card {
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
/* 功能区域 */
.function-area {
margin-bottom: 24px;
}
.import-card:hover {
transform: translateY(-5px);
.function-card {
border: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
height: 100%;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 25px;
}
.card-header h2 {
align-items: center;
gap: 8px;
font-weight: 600;
color: #333;
margin: 0 0 5px 0;
font-size: 20px;
}
.card-header p {
.card-header .el-icon {
font-size: 18px;
color: #409EFF;
}
.card-desc {
margin-bottom: 20px;
}
.card-desc p {
color: #666;
margin: 0;
font-size: 14px;
line-height: 1.5;
}
/* 上传区域 */
.upload-section {
display: flex;
flex-direction: column;
gap: 20px;
gap: 16px;
}
.file-input-container {
@@ -529,73 +584,38 @@ export default {
.file-label {
display: flex;
align-items: center;
padding: 15px 20px;
border: 2px dashed #ddd;
border-radius: 12px;
padding: 12px 16px;
border: 2px dashed #dcdfe6;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
background: #f8f9fa;
background: #fafafa;
min-height: 60px;
}
.file-label:hover {
border-color: #74b9ff;
background: #e3f2fd;
border-color: #409eff;
background: #ecf5ff;
}
.file-icon {
font-size: 24px;
font-size: 20px;
margin-right: 12px;
color: #409eff;
}
.file-text {
color: #555;
color: #606266;
font-size: 14px;
flex: 1;
word-break: break-all;
}
/* 按钮样式 */
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
font-size: 16px;
}
/* Element Plus 按钮样式已由组件提供 */
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.btn-primary {
background: linear-gradient(135deg, #74b9ff, #0984e3);
color: white;
}
.btn-warning {
background: linear-gradient(135deg, #fdcb6e, #e17055);
color: white;
}
.btn-success {
background: linear-gradient(135deg, #00b894, #00cec9);
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-small {
padding: 8px 16px;
font-size: 12px;
}
.btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
/* 减少卡片内边距 */
:deep(.el-card__body) {
padding: 10px !important;
}
/* 结果消息 */
@@ -620,6 +640,13 @@ export default {
/* 信息卡片 */
.info-card {
border: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-top: 24px;
}
/* 信息说明 */
.info-content {
display: flex;
@@ -631,6 +658,7 @@ export default {
color: #333;
margin-bottom: 8px;
font-size: 16px;
font-weight: 600;
}
.info-item p {
@@ -677,12 +705,21 @@ export default {
/* 响应式设计 */
@media (max-width: 768px) {
.import-container {
grid-template-columns: 1fr;
gap: 20px;
padding: 15px;
}
.import-card,
.info-card {
.function-area .el-row {
flex-wrap: wrap;
}
.function-area .el-col {
flex: 0 0 33.333333%;
max-width: 33.333333%;
padding: 0 5px;
margin-bottom: 16px;
}
.page-header {
padding: 20px;
}
@@ -690,10 +727,43 @@ export default {
font-size: 24px;
}
.card-header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
.card-header span {
font-size: 14px;
}
.card-desc {
margin-bottom: 12px;
}
.card-desc p {
font-size: 12px;
line-height: 1.4;
}
.file-label {
padding: 8px 10px;
min-height: 45px;
}
.file-text {
font-size: 12px;
}
.file-icon {
font-size: 16px;
margin-right: 8px;
}
.upload-section {
gap: 12px;
}
.info-item h4 {
font-size: 14px;
}
.info-item p {
font-size: 12px;
}
}
</style>

View File

@@ -1,84 +1,140 @@
<template>
<div class="exchange-records-page">
<!-- 页面头部 -->
<el-page-header @back="goBack" class="page-header">
<template #title>
返回
</template>
<template #content>
<div class="header-content">
<el-icon :size="24" style="margin-right: 8px;"><ShoppingBag /></el-icon>
<span class="header-title">兑换记录</span>
<div class="page-header-modern">
<div class="header-content">
<button class="back-btn" @click="goBack">
<svg viewBox="0 0 24 24" class="back-icon">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
</svg>
</button>
<div class="header-info">
<div class="header-text">
<h1 class="header-title">兑换记录</h1>
<p class="header-subtitle">查看您的会员兑换历史</p>
</div>
</div>
</template>
</el-page-header>
</div>
</div>
<!-- 主要内容 -->
<div class="records-container" v-loading="loading" element-loading-text="正在加载兑换记录...">
<div class="records-container">
<!-- 加载状态 -->
<div v-if="loading" class="loading-container">
<div class="loading-spinner">
<div class="spinner"></div>
<p class="loading-text">正在加载兑换记录...</p>
</div>
</div>
<!-- 错误提示 -->
<el-result
v-if="errorMessage"
status="error"
title="加载失败"
:sub-title="errorMessage"
>
<template #extra>
<el-button type="primary" @click="loadExchangeRecords" :loading="loading">重新加载</el-button>
</template>
</el-result>
<div v-else-if="errorMessage" class="error-container">
<div class="error-content">
<div class="error-icon"></div>
<h3 class="error-title">加载失败</h3>
<p class="error-message">{{ errorMessage }}</p>
<button class="retry-btn" @click="loadExchangeRecords">
<span>重新加载</span>
</button>
</div>
</div>
<!-- 空状态 -->
<el-empty v-else-if="records.length === 0 && !loading" description="暂无兑换记录">
<el-button type="primary" @click="goToProfile">去兑换会员码</el-button>
</el-empty>
<div v-else-if="records.length === 0" class="empty-container">
<div class="empty-content">
<div class="empty-icon">📋</div>
<h3 class="empty-title">暂无兑换记录</h3>
<p class="empty-message">您还没有任何兑换记录快去兑换会员码吧</p>
<button class="action-btn primary" @click="goToProfile">
<span>去兑换会员码</span>
</button>
</div>
</div>
<!-- 兑换记录列表 -->
<el-card v-else class="records-list-card" shadow="never">
<template #header>
<div class="card-header">
<span>兑换记录 ({{ records.length }})</span>
<el-button :icon="Refresh" circle @click="loadExchangeRecords" :loading="loading" />
</div>
</template>
<div v-else class="records-list">
<div class="list-header">
<span class="record-count">{{ records.length }}条记录</span>
</div>
<div class="records-grid">
<el-card
<div
v-for="record in paginatedRecords"
:key="record.id"
class="record-card"
shadow="hover"
class="record-card-modern"
>
<template #header>
<div class="record-card-header">
<el-tag :type="getStatusClass(record.isUse)" effect="dark" size="large">
{{ getStatusText(record.isUse) }}
</el-tag>
<span class="record-date">{{ formatDate(record.exchangeTime) }}</span>
<div class="record-header">
<div class="status-badge" :class="getStatusClass(record.isUse)">
<!-- <span class="status-icon">{{ getStatusIcon(record.isUse) }}</span> -->
<span class="status-text">{{ getStatusText(record.isUse) }}</span>
</div>
</template>
<el-descriptions :column="1" border>
<el-descriptions-item label-class-name="record-label" label="订单号">{{ record.orderNo || '-' }}</el-descriptions-item>
<el-descriptions-item label-class-name="record-label" label="兑换类型">{{ getExchangeTypeText(record.type) }}</el-descriptions-item>
<el-descriptions-item label-class-name="record-label" label="兑换模式">{{ getExchangeModeText(record.exchangeMode) }}</el-descriptions-item>
<el-descriptions-item v-if="record.orderAmount" label-class-name="record-label" label="订单金额">
<span class="amount-value">¥{{ record.orderAmount }}</span>
</el-descriptions-item>
</el-descriptions>
</el-card>
<div class="record-date">{{ formatDate(record.exchangeTime) }}</div>
</div>
<div class="record-body">
<div class="record-info-grid">
<div class="info-item">
<label class="info-label">订单号</label>
<span class="info-value">{{ record.orderNo || '-' }}</span>
</div>
<div class="info-item">
<label class="info-label">兑换类型</label>
<span class="info-value type-value">{{ getExchangeTypeText(record.type) }}</span>
</div>
<div class="info-item">
<label class="info-label">兑换模式</label>
<span class="info-value">{{ getExchangeModeText(record.exchangeMode) }}</span>
</div>
<div v-if="record.orderAmount" class="info-item">
<label class="info-label">订单金额</label>
<span class="info-value amount-value">¥{{ record.orderAmount }}</span>
</div>
</div>
<!-- 移动端紧凑布局 -->
<div class="record-info-compact">
<div class="compact-left">
<div class="compact-item">
<span class="compact-label">订单号</span>
<span class="compact-value">{{ record.orderNo || '-' }}</span>
</div>
<div class="compact-item">
<span class="compact-label">兑换模式</span>
<span class="compact-value">{{ getExchangeModeText(record.exchangeMode) }}</span>
</div>
</div>
<div class="compact-right">
<div class="compact-item">
<span class="compact-label">兑换类型</span>
<span class="compact-value type-value">{{ getExchangeTypeText(record.type) }}</span>
</div>
<div v-if="record.orderAmount" class="compact-item">
<span class="compact-label">订单金额</span>
<span class="compact-value amount-value">¥{{ record.orderAmount }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 分页组件 -->
<div v-if="totalPages > 1" class="pagination-container">
<el-pagination
background
layout="prev, pager, next"
:total="records.length"
:page-size="pageSize"
v-model:current-page="currentPage"
@current-change="goToPage"
/>
<div class="pagination-wrapper">
<el-pagination
background
layout="prev, pager, next"
:total="records.length"
:page-size="pageSize"
v-model:current-page="currentPage"
@current-change="goToPage"
:pager-count="5"
small
/>
</div>
</div>
</el-card>
</div>
</div>
</div>
</template>
@@ -180,8 +236,10 @@ export default {
switch (isUse) {
case 1:
return 'success'
case 0:
return 'failure'
default:
return 'info'
return 'pending'
}
},
@@ -190,8 +248,22 @@ export default {
switch (isUse) {
case 1:
return '成功'
case 0:
return '失败'
default:
return '未知'
return '处理中'
}
},
// 获取状态图标
getStatusIcon(isUse) {
switch (isUse) {
case 1:
return '✅'
case 0:
return '❌'
default:
return '⏳'
}
},
@@ -256,86 +328,597 @@ export default {
</script>
<style scoped>
/* 页面容器 */
.exchange-records-page {
background-color: #f0f2f5;
padding: 20px;
min-height: calc(100vh - 70px);
background: linear-gradient(135deg, #f0f9ff 0%, #e0f7fa 100%);
min-height: 100vh;
padding: 0;
}
.page-header {
background: linear-gradient(135deg, #3a7bd5, #00d2ff);
padding: 30px 24px;
border-radius: 8px;
margin-bottom: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
/* 现代化页面头部 */
.page-header-modern {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
box-shadow: 0 8px 32px rgba(79, 172, 254, 0.3);
position: relative;
overflow: hidden;
}
:deep(.el-page-header__back .el-icon),
:deep(.el-page-header__back .el-page-header__title) {
color: white;
}
:deep(.el-divider) {
border-color: rgba(255, 255, 255, 0.5);
.page-header-modern::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none"><defs><linearGradient id="waveGrad" x1="0%25" y1="0%25" x2="100%25" y2="0%25"><stop offset="0%25" style="stop-color:rgba(255,255,255,0.1);stop-opacity:1" /><stop offset="50%25" style="stop-color:rgba(255,255,255,0.2);stop-opacity:1" /><stop offset="100%25" style="stop-color:rgba(255,255,255,0.1);stop-opacity:1" /></linearGradient></defs><path fill="url(%23waveGrad)" fill-opacity="1" d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,112C672,96,768,96,864,112C960,128,1056,160,1152,165.3C1248,171,1344,149,1392,138.7L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path><circle cx="200" cy="60" r="4" fill="rgba(255,255,255,0.3)"><animate attributeName="cy" values="60;80;60" dur="3s" repeatCount="indefinite"/></circle><circle cx="400" cy="100" r="3" fill="rgba(255,255,255,0.25)"><animate attributeName="cy" values="100;120;100" dur="4s" repeatCount="indefinite"/></circle><circle cx="600" cy="70" r="5" fill="rgba(255,255,255,0.2)"><animate attributeName="cy" values="70;90;70" dur="3.5s" repeatCount="indefinite"/></circle><circle cx="800" cy="90" r="3.5" fill="rgba(255,255,255,0.3)"><animate attributeName="cy" values="90;110;90" dur="4.5s" repeatCount="indefinite"/></circle><circle cx="1000" cy="80" r="4" fill="rgba(255,255,255,0.25)"><animate attributeName="cy" values="80;100;80" dur="3.8s" repeatCount="indefinite"/></circle><circle cx="1200" cy="95" r="3" fill="rgba(255,255,255,0.2)"><animate attributeName="cy" values="95;115;95" dur="4.2s" repeatCount="indefinite"/></circle><g opacity="0.15"><rect x="100" y="40" width="60" height="60" fill="none" stroke="white" stroke-width="2" rx="8"><animateTransform attributeName="transform" type="rotate" from="0 130 70" to="360 130 70" dur="20s" repeatCount="indefinite"/></rect><circle cx="900" cy="50" r="25" fill="none" stroke="white" stroke-width="2"><animate attributeName="r" values="25;30;25" dur="3s" repeatCount="indefinite"/></circle><polygon points="1300,60 1320,100 1280,100" fill="none" stroke="white" stroke-width="2"><animateTransform attributeName="transform" type="rotate" from="0 1300 80" to="360 1300 80" dur="15s" repeatCount="indefinite"/></polygon></g></svg>') no-repeat center center;
background-size: cover;
pointer-events: none;
opacity: 0.8;
}
.header-content {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
max-width: 1200px;
margin: 0 auto;
position: relative;
z-index: 1;
}
.back-btn {
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 10px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
}
.back-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateX(-2px);
}
.back-icon {
width: 20px;
height: 20px;
fill: white;
}
.header-info {
display: flex;
align-items: center;
flex: 1;
margin-left: 20px;
gap: 16px;
}
.header-text {
color: white;
}
.header-title {
font-size: 20px;
font-weight: 600;
font-weight: 700;
margin: 0 0 2px 0;
letter-spacing: -0.5px;
}
.header-subtitle {
font-size: 12px;
opacity: 0.8;
margin: 0;
}
/* 内容容器 */
.records-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px 20px;
}
.records-list-card {
border-radius: 8px;
}
.card-header {
/* 加载状态 */
.loading-container {
display: flex;
justify-content: space-between;
justify-content: center;
align-items: center;
width: 100%;
min-height: 400px;
}
.loading-spinner {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.spinner {
width: 50px;
height: 50px;
border: 4px solid #e1e8ed;
border-left: 4px solid #4facfe;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
color: #666;
font-size: 16px;
margin: 0;
}
/* 错误状态 */
.error-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 400px;
}
.error-content {
text-align: center;
max-width: 400px;
}
.error-icon {
font-size: 64px;
margin-bottom: 16px;
}
.error-title {
font-size: 24px;
color: #333;
margin: 0 0 12px 0;
font-weight: 600;
}
.error-message {
color: #666;
font-size: 16px;
line-height: 1.5;
margin: 0 0 24px 0;
}
.retry-btn {
background: linear-gradient(135deg, #4facfe, #00f2fe);
color: white;
border: none;
border-radius: 12px;
padding: 12px 24px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 16px rgba(79, 172, 254, 0.3);
}
.retry-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(79, 172, 254, 0.4);
}
/* 空状态 */
.empty-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 400px;
}
.empty-content {
text-align: center;
max-width: 400px;
}
.empty-icon {
font-size: 64px;
margin-bottom: 16px;
}
.empty-title {
font-size: 24px;
color: #333;
margin: 0 0 12px 0;
font-weight: 600;
}
.empty-message {
color: #666;
font-size: 16px;
line-height: 1.5;
margin: 0 0 24px 0;
}
.action-btn {
border: none;
border-radius: 12px;
padding: 12px 24px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.action-btn.primary {
background: linear-gradient(135deg, #4facfe, #00f2fe);
color: white;
box-shadow: 0 4px 16px rgba(79, 172, 254, 0.3);
}
.action-btn.primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(79, 172, 254, 0.4);
}
/* 记录列表 */
.records-list {
background: white;
border-radius: 16px;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.list-header {
display: flex;
justify-content: flex-end;
align-items: center;
padding: 12px 24px 12px 24px;
border-bottom: 1px solid #f0f0f0;
}
.record-count {
background: linear-gradient(135deg, #4facfe, #00f2fe);
color: white;
padding: 4px 10px;
border-radius: 16px;
font-size: 11px;
font-weight: 600;
flex-shrink: 0;
}
/* 记录网格 */
.records-grid {
padding: 16px 24px 24px 24px;
display: grid;
gap: 16px;
gap: 12px;
}
.record-card-header {
/* 现代化记录卡片 */
.record-card-modern {
background: #fafbfc;
border: 2px solid #f0f0f0;
border-radius: 12px;
padding: 14px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.record-card-modern::before {
display: none;
}
.record-card-modern:hover {
border-color: #e0e0e0;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
transform: translateY(-2px);
}
/* 记录头部 */
.record-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.status-badge {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 10px;
border-radius: 16px;
font-size: 12px;
font-weight: 600;
}
.status-badge.success {
background: linear-gradient(135deg, #10ac84, #00d2d3);
color: white;
}
.status-badge.failure {
background: linear-gradient(135deg, #ee5a24, #ff3742);
color: white;
}
.status-badge.pending {
background: linear-gradient(135deg, #ffeaa7, #fab1a0);
color: #333;
}
.status-icon {
font-size: 16px;
}
.record-date {
font-size: 14px;
color: #909399;
font-size: 11px;
color: #666;
font-weight: 500;
}
/* 记录信息网格 */
.record-info-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.info-item {
display: flex;
flex-direction: column;
gap: 3px;
}
.info-label {
font-size: 11px;
color: #888;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.info-value {
font-size: 13px;
color: #333;
font-weight: 500;
}
.type-value {
color: #4facfe;
font-weight: 600;
}
.amount-value {
color: #F56C6C;
font-weight: 600;
color: #e74c3c;
font-weight: 700;
font-size: 14px;
}
/* 移动端紧凑布局 */
.record-info-compact {
display: none; /* 默认隐藏,仅在移动端显示 */
}
.compact-left, .compact-right {
flex: 1;
min-width: 0; /* 允许flex项目收缩 */
}
.compact-item {
display: flex;
flex-direction: column;
gap: 4px;
padding: 8px 0;
border-bottom: 1px solid #f5f5f5;
min-width: 0; /* 防止溢出 */
}
.compact-item:last-child {
border-bottom: none;
}
.compact-label {
font-size: 12px;
color: #666;
font-weight: 500;
line-height: 1.2;
}
.compact-value {
font-size: 13px;
color: #333;
font-weight: 600;
line-height: 1.3;
word-break: break-all; /* 长文本换行 */
overflow-wrap: break-word;
}
.compact-value.type-value {
color: #4facfe;
}
.compact-value.amount-value {
color: #e74c3c;
font-weight: 700;
}
/* 分页容器 */
.pagination-container {
padding: 16px 24px;
border-top: 1px solid #f0f0f0;
background: #fafbfc;
}
.pagination-wrapper {
display: flex;
justify-content: center;
margin-top: 24px;
}
:deep(.record-label) {
width: 100px;
font-weight: 600;
color: #606266;
/* Element Plus 覆盖样式 */
:deep(.el-pagination.is-background .el-pager li:not(.is-disabled).is-active) {
background: linear-gradient(135deg, #4facfe, #00f2fe);
border-color: #4facfe;
}
:deep(.el-pagination.is-background .el-pager li:not(.is-disabled):hover) {
background: linear-gradient(135deg, #4facfe, #00f2fe);
color: white;
}
/* 响应式设计 */
@media (max-width: 768px) {
.header-content {
padding: 20px 16px;
}
.header-info {
margin-left: 12px;
gap: 12px;
}
.header-title {
font-size: 20px;
}
.header-subtitle {
font-size: 13px;
}
.records-container {
padding: 24px 16px;
}
.list-header {
padding: 10px 20px 10px 20px;
flex-direction: row;
}
.records-grid {
padding: 20px 20px 24px 20px;
gap: 16px;
}
.record-info-grid {
display: none; /* 移动端隐藏原始网格布局 */
}
/* 移动端显示紧凑布局 */
.record-info-compact {
display: flex !important;
gap: 24px;
margin-top: 12px;
}
.pagination-container {
padding: 20px 16px;
}
}
/* 中等屏幕尺寸额外优化 */
@media (max-width: 600px) {
.record-info-grid {
display: none; /* 在600px以下也隐藏原始网格 */
}
.record-info-compact {
display: flex !important;
gap: 20px;
margin-top: 10px;
}
}
@media (max-width: 480px) {
.header-content {
padding: 16px 12px;
}
.header-title {
font-size: 18px;
}
.back-btn {
width: 40px;
height: 40px;
}
.back-icon {
width: 20px;
height: 20px;
}
.records-container {
padding: 20px 12px;
}
.records-list {
border-radius: 16px;
}
.list-header {
padding: 8px 16px 8px 16px;
flex-direction: row;
}
.record-count {
font-size: 11px;
padding: 4px 8px;
}
.records-grid {
padding: 16px 16px 20px 16px;
}
.record-card-modern {
padding: 14px;
}
/* 小屏幕进一步优化紧凑布局 */
.record-info-compact {
gap: 18px;
}
.compact-item {
padding: 6px 0;
}
.compact-label {
font-size: 11px;
}
.compact-value {
font-size: 12px;
line-height: 1.4;
}
/* 状态徽章和日期在小屏幕上调整 */
.record-header {
margin-bottom: 8px;
}
.status-badge {
padding: 4px 10px;
font-size: 12px;
}
.record-date {
font-size: 12px;
}
.pagination-container {
padding: 16px 12px;
}
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -3,13 +3,25 @@
<!-- 页面头部 -->
<div class="page-header">
<div class="page-title">
<h1 class="main-title">彩票猪手</h1>
<h1 class="main-title">用户登录</h1>
<p class="subtitle">您的专属彩票数据助理</p>
</div>
</div>
<!-- 登录表单 -->
<el-card class="login-form-container" shadow="never">
<!-- 被踢出提示 -->
<el-alert
v-if="showKickedOutAlert"
title="账号已在其他设备登录"
type="warning"
description="为保障账号安全,您的账号已在其他设备登录,当前会话已失效。请重新登录。"
show-icon
:closable="true"
@close="showKickedOutAlert = false"
style="margin-bottom: 20px"
/>
<div class="login-tabs">
<div
class="login-tab"
@@ -67,19 +79,31 @@
<!-- 手机号登录表单 -->
<div v-else>
<!-- 手机号 -->
<!-- 手机号和发送验证码按钮 -->
<div class="form-group">
<el-input
v-model="formData.phone"
type="tel"
placeholder="请输入手机号"
prefix-icon="Iphone"
size="large"
maxlength="11"
@input="validatePhoneInput"
@blur="validatePhoneOnBlur"
clearable
/>
<div class="phone-code-row">
<el-input
v-model="formData.phone"
type="tel"
placeholder="请输入手机号"
prefix-icon="Iphone"
size="large"
maxlength="11"
@input="validatePhoneInput"
@blur="validatePhoneOnBlur"
clearable
class="phone-input"
/>
<el-button
type="primary"
:disabled="codeBtnDisabled"
@click="sendVerificationCode"
class="send-code-btn-inline"
size="large"
>
{{ codeButtonText }}
</el-button>
</div>
<div v-if="errors.phone" class="error-text">{{ errors.phone }}</div>
<div v-else-if="formData.phone && formData.phone.length > 0 && formData.phone.length < 11" class="tip-text">请输入11位手机号码</div>
</div>
@@ -92,17 +116,7 @@
prefix-icon="Key"
size="large"
maxlength="6"
>
<template #append>
<el-button
type="primary"
:disabled="codeBtnDisabled"
@click="sendVerificationCode"
>
{{ codeButtonText }}
</el-button>
</template>
</el-input>
/>
<div v-if="errors.code" class="error-text">{{ errors.code }}</div>
</div>
</div>
@@ -126,24 +140,6 @@
</form>
</el-card>
<!-- 登录成功弹窗 -->
<div v-if="showSuccessModal" class="modal-overlay" @click="closeSuccessModal">
<div class="modal-content success-modal" @click.stop>
<h3>登录成功</h3>
<p>欢迎回来正在跳转到个人中心...</p>
<button class="modal-btn" @click="closeSuccessModal">确定</button>
</div>
</div>
<!-- 错误提示弹窗 -->
<div v-if="showErrorModal" class="modal-overlay" @click="closeErrorModal">
<div class="modal-content error-modal" @click.stop>
<div class="error-icon"></div>
<h3>登录失败</h3>
<p>{{ errorMessage }}</p>
<button class="modal-btn error-btn" @click="closeErrorModal">确定</button>
</div>
</div>
</div>
</template>
@@ -152,7 +148,7 @@ import { userStore } from '../store/user'
import { lotteryApi } from '../api/index.js'
import { useToast } from 'vue-toastification'
import { useRouter } from 'vue-router'
import { ElCard, ElInput, ElButton, ElCheckbox } from 'element-plus'
import { ElCard, ElInput, ElButton, ElCheckbox, ElAlert } from 'element-plus'
import { User, Lock, Iphone, Key } from '@element-plus/icons-vue'
export default {
@@ -162,6 +158,7 @@ export default {
ElInput,
ElButton,
ElCheckbox,
ElAlert,
User,
Lock,
Iphone,
@@ -177,13 +174,11 @@ export default {
loginType: 'account', // 默认使用账号登录方式
showPassword: false,
loading: false,
showSuccessModal: false,
showErrorModal: false,
errorMessage: '',
codeCountdown: 0,
timer: null,
showPhoneError: false,
phoneValid: false,
showKickedOutAlert: false, // 是否显示被踢出提示
formData: {
username: '',
@@ -204,6 +199,16 @@ export default {
return this.codeCountdown > 0 || !this.isValidPhone(this.formData.phone);
}
},
mounted() {
// 检查是否因为被踢出而跳转到登录页
if (userStore.isKickedOut) {
this.showKickedOutAlert = true
// 显示提示后重置状态
setTimeout(() => {
userStore.resetKickedOutStatus()
}, 500)
}
},
methods: {
// 切换登录方式
switchLoginType(type) {
@@ -386,50 +391,37 @@ export default {
try {
const userInfo = await userStore.fetchLoginUser();
if (userInfo) {
// 显示成功提示
this.showSuccessModal = true;
// 触发Coze SDK重新初始化事件
setTimeout(() => {
window.dispatchEvent(new CustomEvent('reinitializeCozeSDK'));
console.log('已触发Coze SDK重新初始化事件');
}, 200);
// 直接跳转到个人中心
setTimeout(() => {
this.router.push('/profile');
}, 300);
} else {
this.showError('获取用户信息失败,请重新登录');
this.toast.error('获取用户信息失败,请重新登录');
}
} catch (error) {
console.error('获取用户信息失败:', error);
this.showError('获取用户信息失败,请重新登录');
this.toast.error('获取用户信息失败,请重新登录');
}
} else {
// 登录失败
this.showError(response.message || '登录失败,请检查账号密码');
this.toast.error(response.message || '登录失败,请检查账号密码');
}
} catch (error) {
console.error('登录失败:', error);
if (error.response && error.response.data) {
this.showError(error.response.data.message || '登录失败,请检查账号密码');
this.toast.error(error.response.data.message || '登录失败,请检查账号密码');
} else {
this.showError('网络错误,请重试');
this.toast.error('网络错误,请重试');
}
} finally {
this.loading = false;
}
},
// 关闭成功弹窗
closeSuccessModal() {
this.showSuccessModal = false;
// 延迟跳转,让用户看到弹窗
setTimeout(() => {
this.router.push('/profile');
}, 500);
},
// 显示错误弹窗
showError(message) {
this.errorMessage = message;
this.showErrorModal = true;
},
// 关闭错误弹窗
closeErrorModal() {
this.showErrorModal = false;
this.errorMessage = '';
}
},
// 组件销毁时清除定时器
@@ -447,18 +439,19 @@ export default {
.login-page-container {
min-height: calc(100vh - 70px);
background: #f0f2f5;
padding: 20px 20px 0px 20px;
padding: 20px 20px 8px 20px;
}
/* 页面头部 */
.page-header {
background: url('@/assets/banner/backend1.png') center/cover no-repeat, linear-gradient(135deg, #ff6b6b, #ee5a52);
background: linear-gradient(135deg, #ff6b6b, #ee5a52);
color: white;
padding: 45px 20px 25px;
padding: 35px 20px 25px;
text-align: center;
position: relative;
margin-bottom: 20px;
border-radius: 8px;
margin-bottom: 15px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(238, 90, 82, 0.3);
}
.page-title {
@@ -467,31 +460,31 @@ export default {
}
.main-title {
font-size: 38px;
margin: 0 auto 10px;
font-size: 32px;
margin: 0 auto 4px;
font-weight: 700;
color: white;
text-shadow: 0 2px 6px rgba(0,0,0,0.7), 0 0 15px rgba(0,0,0,0.4);
letter-spacing: 2px;
text-shadow: 0 2px 8px rgba(0,0,0,0.5), 0 0 20px rgba(0,0,0,0.3);
letter-spacing: 1px;
text-align: center;
width: 100%;
}
.subtitle {
font-size: 22px;
font-size: 16px;
margin: 0;
color: white;
opacity: 0.9;
text-shadow: 0 2px 6px rgba(0,0,0,0.7), 0 0 15px rgba(0,0,0,0.4);
opacity: 0.95;
text-shadow: 0 2px 4px rgba(0,0,0,0.4);
text-align: center;
width: 100%;
font-weight: 500;
font-weight: 400;
}
/* 桌面端样式 */
@media (min-width: 1024px) {
.page-header {
padding: 40px 20px 30px;
padding: 30px 20px 25px;
}
}
@@ -499,59 +492,52 @@ export default {
padding: 0;
background: white;
margin: 0 0 20px 0;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
/* 登录方式切换标签 */
.login-tabs {
display: flex;
border-bottom: 1px solid #eee;
border-bottom: 1px solid #f0f0f0;
background: #fafafa;
}
.login-tab {
flex: 1;
text-align: center;
padding: 15px 0;
font-size: 16px;
color: #666;
padding: 18px 0;
font-size: 15px;
color: #888;
cursor: pointer;
transition: all 0.3s;
transition: all 0.3s ease;
position: relative;
font-weight: 500;
}
.login-tab.active {
color: #e53e3e;
font-weight: 500;
background: white;
font-weight: 600;
}
.login-tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: 3px;
background: #e53e3e;
border-radius: 2px;
}
.login-tab:hover:not(.active) {
color: #333;
color: #666;
background: #f8f8f8;
}
.login-form {
background: white;
border-radius: 0;
padding: 30px 25px;
padding: 28px 24px 20px;
box-shadow: none;
min-height: calc(100vh - 400px);
}
/* 表单组 */
.form-group {
margin-bottom: 24px;
margin-bottom: 16px;
}
.input-wrapper {
@@ -634,7 +620,49 @@ input:-webkit-autofill:active {
outline: none !important;
}
/* Element Plus验证码按钮已在组件中实现移除原来的样式以避免冲突 */
/* 手机号和验证码按钮同行布局 */
.phone-code-row {
display: flex;
gap: 12px;
align-items: stretch;
}
.phone-input {
flex: 1;
}
/* 内联发送验证码按钮样式 */
.send-code-btn-inline {
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border: none;
border-radius: 12px;
font-weight: 500;
transition: all 0.3s ease;
min-width: 120px;
flex-shrink: 0;
height: auto;
display: flex;
align-items: center;
justify-content: center;
}
.send-code-btn-inline:hover:not(.is-disabled) {
background: linear-gradient(135deg, #d43030, #ff5a5a);
transform: translateY(-1px);
box-shadow: 0 4px 15px rgba(229, 62, 62, 0.3);
}
.send-code-btn-inline:active:not(.is-disabled) {
transform: translateY(0);
}
.send-code-btn-inline.is-disabled {
background: #cccccc !important;
border-color: #cccccc !important;
color: #888 !important;
transform: none !important;
box-shadow: none !important;
}
/* 提示文本 */
.error-text {
@@ -686,7 +714,6 @@ input::-webkit-credentials-auto-fill-button {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
}
.checkbox-wrapper {
@@ -736,42 +763,57 @@ input::-webkit-credentials-auto-fill-button {
/* 登录按钮 */
.login-btn {
width: 100%;
margin: 30px 0 25px 0;
padding: 12px;
font-size: 18px;
height: auto;
margin: 24px 0 24px 0;
padding: 14px;
font-size: 16px;
font-weight: 600;
height: 52px;
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border: none;
box-shadow: 0 4px 15px rgba(229, 62, 62, 0.3);
border-radius: 12px;
box-shadow: 0 4px 20px rgba(229, 62, 62, 0.25);
transition: all 0.3s ease;
}
.login-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(229, 62, 62, 0.4);
transform: translateY(-1px);
box-shadow: 0 6px 30px rgba(229, 62, 62, 0.35);
background: linear-gradient(135deg, #d43030, #ff5a5a);
border: none;
}
.login-btn:active:not(:disabled) {
transform: translateY(0);
box-shadow: 0 2px 10px rgba(229, 62, 62, 0.3);
}
/* Element UI 组件自定义样式 */
:deep(.el-input__wrapper) {
padding: 4px 11px;
padding: 6px 16px;
box-shadow: none !important;
background-color: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 12px;
transition: all 0.3s ease;
}
:deep(.el-input__wrapper.is-focus) {
background-color: #fff;
border-color: #e53e3e;
box-shadow: 0 0 0 4px rgba(229, 62, 62, 0.1);
}
:deep(.el-input__prefix) {
margin-right: 8px;
margin-right: 12px;
color: #999;
}
:deep(.el-input__inner) {
height: 40px;
font-size: 16px;
height: 44px;
font-size: 15px;
color: #333;
}
:deep(.el-checkbox__label) {
@@ -788,35 +830,6 @@ input::-webkit-credentials-auto-fill-button {
border-color: #e53e3e;
}
:deep(.el-input-group__append) {
padding: 0;
border: none;
}
:deep(.el-input-group__append .el-button) {
background-color: #ECF5FF;
border: 1px solid #DCDFE6;
margin: 0;
height: 100%;
border-radius: 0 4px 4px 0;
padding: 0 15px;
font-size: 14px;
font-weight: normal;
color: #e53e3e;
min-width: 105px;
box-shadow: none;
}
:deep(.el-input-group__append .el-button:hover) {
background-color: #e6f1ff;
color: #e53e3e;
}
:deep(.el-input-group__append .el-button.is-disabled) {
background-color: #F5F7FA;
color: #C0C4CC;
border-color: #E4E7ED;
}
:deep(.el-button.is-disabled) {
background: #cccccc;
@@ -840,175 +853,72 @@ input::-webkit-credentials-auto-fill-button {
text-decoration: underline;
}
/* 成功弹窗样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
padding: 20px;
}
.modal-content {
background: white;
border-radius: 20px;
padding: 40px 30px;
text-align: center;
max-width: 350px;
width: 100%;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
animation: modalSlideIn 0.3s ease-out;
}
@keyframes modalSlideIn {
from {
opacity: 0;
transform: translateY(-30px) scale(0.9);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.success-modal h3 {
margin-bottom: 15px;
color: #4caf50;
font-size: 22px;
font-weight: bold;
}
.success-modal p {
margin-bottom: 25px;
color: #666;
line-height: 1.5;
font-size: 16px;
}
.modal-btn {
background: linear-gradient(135deg, #4caf50, #66bb6a);
color: white;
border: none;
padding: 12px 30px;
border-radius: 25px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
min-width: 120px;
}
.modal-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(76, 175, 80, 0.3);
}
.modal-btn:active {
transform: translateY(0);
}
.error-icon {
font-size: 48px;
margin-bottom: 20px;
animation: shake 0.6s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.error-modal h3 {
margin-bottom: 15px;
color: #f44336;
font-size: 22px;
font-weight: bold;
}
.error-modal p {
margin-bottom: 25px;
color: #666;
line-height: 1.5;
font-size: 16px;
}
.error-btn {
background: linear-gradient(135deg, #f44336, #e57373) !important;
}
.error-btn:hover {
box-shadow: 0 8px 25px rgba(244, 67, 54, 0.3) !important;
}
/* 响应式设计 */
@media (max-width: 768px) {
.login-page-container {
padding: 10px;
padding: 10px 10px 5px 10px;
}
.login-form {
padding: 25px 20px;
padding: 22px 20px 18px;
}
.send-code-btn {
font-size: 12px;
min-width: 90px;
padding: 0 10px;
}
}
@media (max-width: 480px) {
.login-page-container {
padding: 5px 5px 3px 5px;
}
.page-header {
padding: 40px 12px 30px;
padding: 30px 20px 25px;
margin-bottom: 12px;
}
.page-title {
margin: 0 0 6px 0;
margin: 0;
}
.main-title {
font-size: 28px;
margin-bottom: 3px;
letter-spacing: 0.5px;
}
.subtitle {
font-size: 18px;
font-size: 14px;
}
.login-form {
padding: 20px 15px;
padding: 28px 20px 20px;
}
.input-icon {
padding: 12px 25px;
.login-tab {
padding: 16px 0;
font-size: 14px;
}
.icon-img {
width: 22px;
height: 22px;
:deep(.el-input__inner) {
height: 42px;
font-size: 14px;
}
.toggle-icon-img {
width: 20px;
height: 20px;
.login-btn {
height: 48px;
font-size: 15px;
margin: 20px 0 20px 0;
}
.password-toggle {
padding: 0 12px;
}
.send-code-btn {
.send-code-btn-inline {
font-size: 12px;
min-width: 85px;
padding: 0 8px;
min-width: 90px;
padding: 0 10px;
}
.phone-code-row {
gap: 8px;
}
}
/* 桌面端样式 - 这部分已在上面定义,这里移除重复定义 */
</style>
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,541 @@
<template>
<div class="member-agreement-page">
<!-- 页面头部 -->
<div class="page-header-modern">
<div class="header-content">
<button class="back-btn" @click="goBack">
<svg viewBox="0 0 24 24" class="back-icon">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
</svg>
</button>
<div class="header-info">
<div class="header-text">
<h1 class="header-title">会员服务协议</h1>
<p class="header-subtitle">精彩猪手会员服务条款</p>
</div>
</div>
</div>
</div>
<!-- 主要内容 -->
<div class="agreement-content">
<!-- 标题 -->
<div class="agreement-title-section">
</div>
<!-- 第一章 -->
<div class="agreement-section">
<h3 class="section-title">定义</h3>
<div class="section-content">
<div class="definition-item">
<span class="def-num">1</span>
<div class="def-content">
<strong>本服务</strong>指我们通过网站应用程序或其他相关平台向会员提供的精彩猪手数据服务包括但不限于彩票开奖信息查询姿态逻辑数据分析报告个性化推导推测辅助以及会员行为统计经验技巧交流等
</div>
</div>
<div class="definition-item">
<span class="def-num">2</span>
<div class="def-content">
<strong>会员</strong>指承认本协议接受本服务的自然人具体包括一般会员和付费会员
</div>
</div>
<div class="definition-item">
<span class="def-num">3</span>
<div class="def-content">
<strong>个人信息</strong>指以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息不包括匿名化处理后的信息
</div>
</div>
<div class="definition-item">
<span class="def-num">4</span>
<div class="def-content">
<strong>知识产权</strong>包括但不限于著作权专利权商标权商业秘密等
</div>
</div>
</div>
</div>
<!-- 第二章 -->
<div class="agreement-section">
<h3 class="section-title">服务内容及门槛</h3>
<div class="section-content">
<p>1. 我们将尽力为会员提供稳定高效的服务服务内容包括但不限于</p>
<ul class="service-list">
<li>1.1 既定彩票开奖信息查询浏览</li>
<li>1.2 既定彩票开奖数据姿态逻辑分析及报告</li>
<li>1.3 按期次更新的号球动态数据以及通过"本期"已出的开奖号球进行"下期"开奖号球的个性化推测逻辑辅助</li>
<li>1.4 根据首球与随球的关联线索启发复式/胆拖的投注参考</li>
<li>1.5 推测行为统计分析备份</li>
<li>1.6 进行规律总结技巧探索经验交流</li>
</ul>
<p>2. 我们会根据实际情况对服务内容进行调整更新如有重大变更我们将通过企业公众号企业微信短信等方式通知会员</p>
<p>3. 会员理解并同意使用本服务可能需要会员具备相应的设备软件网络环境和一定的专业知识相关费用由会员自行承担</p>
</div>
</div>
<!-- 第三章 -->
<div class="agreement-section">
<h3 class="section-title">会员账号</h3>
<div class="section-content">
<p>1. 会员可以通过免费注册的方式获取本服务账号在注册过程中会员需提供真实准确完整的信息并确保信息的及时更新</p>
<p>2. 会员应妥善保管账号及密码不将账号出借转让赠予或共享给他人使用因会员自身原因导致账号泄露或被他人使用的后果由会员自行承担</p>
<p>3. 若会员发现账号存在异常或安全问题请立即通知我们我们将尽力协助处理但对于非因我们原因导致的损失我们不承担责任</p>
<p>4. 会员在使用账号过程中应遵守法律法规及本协议约定不得利用账号从事违法违规或损害他人权益的行为否则我们有权暂停或终止会员的账号使用</p>
</div>
</div>
<!-- 第四章 -->
<div class="agreement-section">
<h3 class="section-title">会员权利与义务</h3>
<div class="section-content">
<h4 class="sub-title">1. 权利</h4>
<ul class="rights-list">
<li>1.1 有权在遵守本协议的前提下按照我们提供的方式使用服务</li>
<li>1.2 对我们提供的服务质量有权提出合理的意见和建议</li>
</ul>
<h4 class="sub-title">2. 义务</h4>
<ul class="duties-list">
<li>2.1 遵守国家法律法规及互联网相关规定不得利用本服务从事违法犯罪活动</li>
<li>2.2 不得干扰破坏本服务的正常运行不得对服务进行反向工程反编译反汇编等行为</li>
<li>2.3 不得发布传播任何侵犯他人知识产权隐私或其他合法权益的信息</li>
<li>2.4 不得恶意注册账号发送垃圾信息或进行其他滥用服务的行为</li>
<li>2.5 如因会员的行为导致我们或第三方遭受损失责任方会员应承担相应的赔偿责任</li>
</ul>
</div>
</div>
<!-- 第五章 -->
<div class="agreement-section">
<h3 class="section-title">隐私政策</h3>
<div class="section-content">
<p>1. 我们十分重视对会员个人信息保护将谨慎收集安全存储妥善使用会员的个人信息</p>
<p>2. 会员同意我们为提供服务改进服务包括遵守法律法规的需要对会员的个人信息进行合理的调用过程中我们将采取合理措施确保信息安全</p>
</div>
</div>
<!-- 第六章 -->
<div class="agreement-section">
<h3 class="section-title">知识产权</h3>
<div class="section-content">
<p>我们对本服务及相关内容包括但不限于软件数据文字图片音频视频等享有知识产权未经我们书面许可会员不得擅自复制改编或创造基于本服务的衍生品</p>
</div>
</div>
<!-- 第七章 -->
<div class="agreement-section">
<h3 class="section-title">责任限制与免责</h3>
<div class="section-content">
<div class="warning-box">
<p><strong>重要提示</strong>会员应当理解并知晓彩票本身就是概率游戏彩票开奖也是纯粹的随机事件因此本服务仅具备参考和辅助功效会员必须对自己的判断和选择结果承担最终责任</p>
</div>
<p>1. 本服务所提供的各项数据分析报告均为根据彩票历史数据统计学数学和数据科学原理通过计算机技术进行建模分析而得出我们仅对数据的及时性客观性承担责任</p>
<p>2. 我们将尽力确保服务的正常运行但由于互联网的复杂性和不确定性可能会出现服务中断延迟错误等情况对于因不可抗力技术故障网络攻击等不可预见不可避免的原因导致的服务问题我们不承担责任</p>
<p>3. 我们对会员通过本服务获取的第三方信息的准确性完整性可靠性不承担保证责任会员应自行判断并承担使用风险</p>
<p>4. 在任何情况下我们对会员因使用本服务而产生的直接间接偶然特殊或后果性损失均不承担超过会员实际支付的服务费用的赔偿责任</p>
</div>
</div>
<!-- 第八章 -->
<div class="agreement-section">
<h3 class="section-title">收费及其规则</h3>
<div class="section-content">
<div class="price-box">
<h4>会员类型与收费标准</h4>
<div class="price-grid">
<div class="price-item">
<span class="price-label">包月付费</span>
<span class="price-value">10/</span>
</div>
<div class="price-item">
<span class="price-label">包年付费</span>
<span class="price-value">100/</span>
</div>
</div>
</div>
<p>1. 本服务采用会员制运营模式所有会员分为普通会员与VIP会员两种类型</p>
<p>2. 本服务对普通会员仅提供一般的基础数据服务</p>
<p>3. 本服务对VIP会员在提供一般基础数据服务的基础上还提供个性化的智推精推特色辅助服务</p>
<p>4. 包月付费每月10元不足一个月时按一个月计算</p>
<p>5. 包年付费每年100元若因会员原因中途提出终止协议需要发生退款时所退款项均按包月付费标准进行折算</p>
<p>6. 出现业务退款情形时所退款项只限原路退回付款账号</p>
<p>7. 所有会员在服务有效期内使用本服务额定内容的时段和频次均不受限</p>
</div>
</div>
<!-- 第九章 -->
<div class="agreement-section">
<h3 class="section-title">协议变更与终止</h3>
<div class="section-content">
<p>1. 我们有权根据法律法规变化业务发展需要等对本协议进行变更变更后的协议将在相关平台以显著方式公布自公布之日起生效</p>
<p>2. 出现以下情况下我们有权终止本协议及停止会员继续使用服务</p>
<ul>
<li>2.1 会员严重违反本协议约定</li>
<li>2.2 法律法规要求我们终止服务</li>
<li>2.3 因不可抗力等不可预见不可避免的原因导致服务无法继续提供</li>
</ul>
<p>3. 协议终止后我们有权根据法律法规要求对会员的相关信息进行封存处理</p>
</div>
</div>
<!-- 第十章 -->
<div class="agreement-section">
<h3 class="section-title">争议解决</h3>
<div class="section-content">
<p>1. 本协议的签订履行解释及争议解决均适用中华人民共和国民法典</p>
<p>2. 如双方在本协议履行过程中发生争议应首先通过友好协商解决协商不成的任何一方均有权向有管辖权的人民法院提起诉讼</p>
</div>
</div>
<!-- 第十一章 -->
<div class="agreement-section">
<h3 class="section-title">十一其他条款</h3>
<div class="section-content">
<p>1. 本协议构成会员与我们之间关于本服务的完整协议未经我们书面同意会员不得转让本协议项下的任何权利利益和义务</p>
<p>2. 本协议各条款的标题仅为方便阅读而设不影响条款的具体含义及解释</p>
<p>3. 若本协议任何条款被认定为无效或不可执行不影响其他条款的效力及执行</p>
<p>4. 我们未行使或执行本协议任何权利或条款不构成对该权利或条款的放弃</p>
<p>5. 本协议自会员成功注册精彩猪手服务相关账号之日即刻生效</p>
<p>6. 任何有关本协议项下服务的问题会员可通过本公司企业微信进行咨询</p>
</div>
</div>
<!-- 重要提示 -->
<div class="notice-box">
在开始使用我们的服务之前请会员仔细阅读并充分理解本会员服务协议的全部内容
本协议是会员与我们西安溢彩数智科技有限公司之间关于使用本服务的法律协议
一旦会员使用本服务即表示会员已同意接受本协议的约束
</div>
<!-- 底部信息 -->
<div class="footer-info">
<p class="company-name">西安溢彩数智科技有限公司</p>
<p class="date">2025年12月31日</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'MemberAgreement',
methods: {
goBack() {
this.$router.go(-1)
}
}
}
</script>
<style scoped>
.member-agreement-page {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 0;
}
/* 页面头部 */
.page-header-modern {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
padding: 20px 0;
position: relative;
}
.header-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
align-items: center;
padding: 0 20px;
position: relative;
z-index: 1;
}
.back-btn {
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
color: white;
margin-right: 16px;
}
.back-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
.back-icon {
width: 24px;
height: 24px;
fill: currentColor;
}
.header-info {
flex: 1;
}
.header-title {
font-size: 24px;
font-weight: 700;
margin: 0 0 4px 0;
color: white;
}
.header-subtitle {
font-size: 14px;
opacity: 0.8;
margin: 0;
}
/* 主要内容 */
.agreement-content {
max-width: 850px;
margin: 0 auto;
padding: 24px 20px;
}
/* 标题区域 */
.agreement-title-section {
text-align: center;
margin-bottom: 10px;
}
.main-title {
font-size: 28px;
font-weight: 700;
color: #333;
margin-bottom: 16px;
}
.intro-text {
font-size: 16px;
color: #666;
line-height: 1.8;
margin-bottom: 20px;
}
.notice-box {
background: linear-gradient(135deg, rgba(255, 193, 7, 0.1) 0%, rgba(255, 152, 0, 0.1) 100%);
padding: 16px 20px;
border-radius: 12px;
border-left: 4px solid #ffc107;
text-align: left;
font-size: 14px;
color: #666;
line-height: 1.6;
margin-bottom: 20px;
}
/* 章节样式 */
.agreement-section {
background: white;
border-radius: 16px;
padding: 24px;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 18px;
font-weight: 700;
color: #333;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 2px solid #4facfe;
}
.section-content {
font-size: 14px;
color: #555;
line-height: 1.8;
}
.section-content p {
margin-bottom: 12px;
}
.sub-title {
font-size: 15px;
font-weight: 600;
color: #333;
margin: 16px 0 12px 0;
}
/* 定义项 */
.definition-item {
display: flex;
align-items: flex-start;
margin-bottom: 14px;
padding: 14px;
background: #fafbfc;
border-radius: 10px;
}
.def-num {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 600;
flex-shrink: 0;
margin-right: 12px;
}
.def-content {
flex: 1;
line-height: 1.6;
}
/* 列表样式 */
.service-list,
.rights-list,
.duties-list {
padding-left: 20px;
margin: 12px 0;
}
.service-list li,
.rights-list li,
.duties-list li {
margin-bottom: 8px;
line-height: 1.6;
}
/* 警告框 */
.warning-box {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, rgba(220, 38, 38, 0.1) 100%);
padding: 16px 20px;
border-radius: 12px;
border-left: 4px solid #ef4444;
margin-bottom: 16px;
}
.warning-box p {
margin: 0;
color: #b91c1c;
}
/* 价格框 */
.price-box {
background: linear-gradient(135deg, rgba(79, 172, 254, 0.1) 0%, rgba(0, 242, 254, 0.1) 100%);
padding: 20px;
border-radius: 12px;
margin-bottom: 20px;
}
.price-box h4 {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 16px;
text-align: center;
}
.price-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.price-item {
background: white;
padding: 16px;
border-radius: 10px;
text-align: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.price-label {
display: block;
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.price-value {
display: block;
font-size: 24px;
font-weight: 700;
color: #4facfe;
}
/* 底部信息 */
.footer-info {
text-align: center;
color: #666;
}
.company-name {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.date {
font-size: 14px;
color: #999;
}
/* 响应式设计 */
@media (max-width: 768px) {
.page-header-modern {
padding: 16px 0;
}
.header-content {
padding: 0 16px;
}
.back-btn {
width: 40px;
height: 40px;
margin-right: 12px;
}
.header-title {
font-size: 20px;
}
.agreement-content {
padding: 16px;
}
.main-title {
font-size: 22px;
}
.section-title {
font-size: 16px;
}
.definition-item {
flex-direction: column;
}
.def-num {
margin-bottom: 8px;
margin-right: 0;
}
.price-grid {
grid-template-columns: 1fr;
}
.price-value {
font-size: 20px;
}
}
</style>

View File

@@ -1,98 +1,361 @@
<template>
<div class="not-found">
<!-- 背景装饰 -->
<div class="background-decoration">
<div class="floating-shape shape-1"></div>
<div class="floating-shape shape-2"></div>
<div class="floating-shape shape-3"></div>
<div class="floating-shape shape-4"></div>
</div>
<div class="not-found-content">
<div class="error-code">404</div>
<h1>页面未找到</h1>
<p>抱歉您访问的页面不存在或已被移除</p>
<!-- 404图标区域 -->
<div class="error-illustration">
<div class="error-code">
<span class="digit">4</span>
<div class="zero-container">
<div class="zero-outer">
<div class="zero-inner">
<div class="sad-face">
<div class="eye left-eye"></div>
<div class="eye right-eye"></div>
<div class="mouth"></div>
</div>
</div>
</div>
</div>
<span class="digit">4</span>
</div>
</div>
<!-- 文字信息 -->
<div class="error-info">
<h1 class="error-title">页面未找到</h1>
<p class="error-description">抱歉您访问的页面不存在或已被移除</p>
</div>
<!-- 操作按钮 -->
<div class="actions">
<el-button type="primary" @click="goHome">
<el-icon><House /></el-icon>
<button class="action-btn primary-btn" @click="goHome">
<svg class="btn-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 12L5 10M5 10L12 3L19 10M5 10V20C5 20.5523 5.44772 21 6 21H9M19 10L21 12M19 10V20C19 20.5523 18.5523 21 18 21H15M9 21C9.55228 21 10 20.5523 10 20V16C10 15.4477 10.4477 15 11 15H13C13.5523 15 14 15.4477 14 16V20C14 20.5523 14.4477 21 15 21M9 21H15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
返回首页
</el-button>
<el-button @click="goBack">
<el-icon><Back /></el-icon>
</button>
<button class="action-btn secondary-btn" @click="goBack">
<svg class="btn-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 12H5M12 19L5 12L12 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
返回上页
</el-button>
</button>
</div>
</div>
</div>
</template>
<script>
import { useRouter } from 'vue-router'
import { House, Back } from '@element-plus/icons-vue'
export default {
name: 'NotFound',
components: {
House,
Back
},
setup() {
const router = useRouter()
const goHome = () => {
router.push('/')
}
const goBack = () => {
router.go(-1)
}
return {
goHome,
goBack
methods: {
goHome() {
this.$router.push('/')
},
goBack() {
this.$router.go(-1)
}
}
}
</script>
<style scoped>
/* 主容器 */
.not-found {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
padding: 20px;
position: relative;
overflow: hidden;
}
/* 背景装饰动画 */
.background-decoration {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
.floating-shape {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
animation: float 6s ease-in-out infinite;
}
.shape-1 {
width: 80px;
height: 80px;
top: 20%;
left: 10%;
animation-delay: 0s;
}
.shape-2 {
width: 120px;
height: 120px;
top: 60%;
right: 10%;
animation-delay: 2s;
}
.shape-3 {
width: 60px;
height: 60px;
top: 30%;
right: 25%;
animation-delay: 4s;
}
.shape-4 {
width: 100px;
height: 100px;
bottom: 20%;
left: 20%;
animation-delay: 1s;
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
opacity: 0.7;
}
50% {
transform: translateY(-20px) rotate(180deg);
opacity: 1;
}
}
/* 内容容器 */
.not-found-content {
text-align: center;
color: white;
max-width: 500px;
max-width: 600px;
position: relative;
z-index: 2;
animation: fadeInUp 1s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 404错误图标设计 */
.error-illustration {
margin-bottom: 40px;
}
.error-code {
display: flex;
align-items: center;
justify-content: center;
font-size: 120px;
font-weight: 800;
font-family: 'Arial', sans-serif;
text-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
margin-bottom: 0;
}
.digit {
color: #fff;
animation: bounce 2s infinite;
}
.digit:first-child {
animation-delay: 0.1s;
}
.digit:last-child {
animation-delay: 0.3s;
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
/* 0字符设计圆形带表情 */
.zero-container {
margin: 0 20px;
animation: bounce 2s infinite;
animation-delay: 0.2s;
}
.zero-outer {
width: 120px;
height: 120px;
border: 8px solid #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
position: relative;
}
.zero-inner {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
}
/* 表情设计 */
.sad-face {
position: relative;
width: 60px;
height: 60px;
}
.eye {
position: absolute;
width: 8px;
height: 8px;
background: #fff;
border-radius: 50%;
animation: blink 3s infinite;
}
.left-eye {
top: 18px;
left: 15px;
}
.right-eye {
top: 18px;
right: 15px;
}
.mouth {
position: absolute;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
width: 20px;
height: 10px;
border: 2px solid #fff;
border-top: none;
border-radius: 0 0 20px 20px;
}
@keyframes blink {
0%, 90%, 100% {
transform: scaleY(1);
}
95% {
transform: scaleY(0.1);
}
}
/* 文字信息 */
.error-info {
margin-bottom: 40px;
}
.error-title {
font-size: 36px;
font-weight: 700;
line-height: 1;
margin-bottom: 20px;
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.not-found-content h1 {
font-size: 32px;
font-weight: 600;
margin-bottom: 16px;
color: #fff;
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
letter-spacing: -0.5px;
}
.not-found-content p {
font-size: 16px;
.error-description {
font-size: 18px;
opacity: 0.9;
margin-bottom: 32px;
line-height: 1.5;
margin-bottom: 0;
line-height: 1.6;
color: #f8f9fa;
}
/* 按钮设计 */
.actions {
display: flex;
gap: 16px;
gap: 20px;
justify-content: center;
flex-wrap: wrap;
}
.actions .el-button {
min-width: 120px;
.action-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 14px 28px;
border: none;
border-radius: 50px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
min-width: 160px;
justify-content: center;
backdrop-filter: blur(10px);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
.btn-icon {
width: 20px;
height: 20px;
}
.primary-btn {
background: rgba(255, 255, 255, 0.2);
color: #fff;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.primary-btn:hover {
background: rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.5);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}
.secondary-btn {
background: rgba(255, 255, 255, 0.1);
color: #fff;
border: 2px solid rgba(255, 255, 255, 0.2);
}
.secondary-btn:hover {
background: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.4);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
/* 响应式设计 */
@@ -101,21 +364,124 @@ export default {
font-size: 80px;
}
.not-found-content h1 {
font-size: 24px;
.zero-outer {
width: 80px;
height: 80px;
}
.not-found-content p {
font-size: 14px;
.zero-inner {
width: 60px;
height: 60px;
}
.sad-face {
width: 40px;
height: 40px;
}
.eye {
width: 6px;
height: 6px;
}
.left-eye {
top: 12px;
left: 10px;
}
.right-eye {
top: 12px;
right: 10px;
}
.mouth {
bottom: 10px;
width: 15px;
height: 8px;
}
.error-title {
font-size: 28px;
}
.error-description {
font-size: 16px;
}
.actions {
flex-direction: column;
align-items: center;
gap: 12px;
}
.actions .el-button {
.action-btn {
width: 200px;
padding: 12px 24px;
font-size: 15px;
}
.floating-shape {
display: none;
}
}
@media (max-width: 480px) {
.not-found {
padding: 16px;
}
.error-code {
font-size: 60px;
margin-bottom: 20px;
}
.zero-outer {
width: 60px;
height: 60px;
border-width: 4px;
}
.zero-inner {
width: 40px;
height: 40px;
}
.sad-face {
width: 30px;
height: 30px;
}
.eye {
width: 4px;
height: 4px;
}
.left-eye {
top: 8px;
left: 7px;
}
.right-eye {
top: 8px;
right: 7px;
}
.mouth {
bottom: 6px;
width: 12px;
height: 6px;
}
.error-title {
font-size: 24px;
}
.error-description {
font-size: 14px;
}
.error-info {
margin-bottom: 30px;
}
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,411 @@
<template>
<div class="privacy-policy-page">
<!-- 页面头部 -->
<div class="page-header-modern">
<div class="header-content">
<button class="back-btn" @click="goBack">
<svg viewBox="0 0 24 24" class="back-icon">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
</svg>
</button>
<div class="header-info">
<div class="header-text">
<h1 class="header-title">个人信息收集与处理规则</h1>
<p class="header-subtitle">精彩猪手网站个人信息保护政策</p>
</div>
</div>
</div>
</div>
<!-- 主要内容 -->
<div class="policy-content">
<!-- 标题区域 -->
<div class="policy-title-section">
</div>
<!-- 引言 -->
<div class="policy-section">
<div class="section-content">
<p>尊敬的会员欢迎来到精彩猪手网站以下简称"本网站"为了更好地保障您的个人权益我们依据国家法律法规监管要求和标准规范结合业务开展的实际情况制定了精彩猪手网站个人信息保护政策旨在明确本网站收集存储使用传输删除等个人信息处理活动的具体规则保障您的个人信息权益与隐私安全</p>
<p>本规则适用于所有访问注册使用本网站服务的会员以下简称"您"以及本网站运营团队参与网站运营的相关人员和第三方服务提供商对个人信息的处理行为当您访问注册或使用本网站服务时即表示您已充分阅读理解并同意本政策的全部内容</p>
</div>
</div>
<!-- 第一章 -->
<div class="policy-section">
<h3 class="section-title">1核心处理原则</h3>
<div class="section-content">
<p><strong>1合法正当诚信原则</strong>本网站仅在法律法规允许的范围内出于合法正当的目的处理您的个人信息不通过误导欺诈胁迫等方式收集或使用个人信息</p>
<p><strong>2最小必要原则</strong>仅收集与本网站服务功能直接相关的个人信息限于实现处理目的的最小范围不过度收集信息</p>
<p><strong>3公开透明原则</strong>以显著方式清晰易懂的语言公开个人信息处理规则明确告知您处理目的方式和范围</p>
<p><strong>4安全保障原则</strong>采取必要的技术和管理措施保障您的个人信息在收集存储使用等全生命周期的安全防止未经授权的访问泄露篡改或丢失</p>
<p><strong>5会员权利保障原则</strong>充分保障您对个人信息享有的知情权访问权更正权删除权撤回同意权等合法权益并提供便捷的行使渠道</p>
</div>
</div>
<!-- 第二章 -->
<div class="policy-section">
<h3 class="section-title">2个人信息收集范围与方式</h3>
<div class="section-content">
<p>本网站仅在实现特定服务功能的必要范围内通过以下方式收集您的个人信息具体收集类型将根据您使用的服务场景动态调整</p>
<h4 class="sub-title">1必要收集的个人信息</h4>
<p><strong>账户注册信息</strong>当您注册本网站账户时需提供自设账号自设昵称手机号码经验证以及自设密码将采用强加密算法存储不保留明文此类信息用于身份验证账户登录密码找回及重要通知推送是保障账户安全和正常使用的基础</p>
<h4 class="sub-title">2可选收集的个人信息</h4>
<p>为提升服务质量本网站可能在特定服务场景下如个性化推荐活动参与客户咨询收集以下信息您可自主选择是否提供</p>
<ul>
<li>1个人资料信息如姓名性别头像等用于完善会员信息标记</li>
<li>2彩票偏好信息用于提供个性化内容和服务推荐</li>
<li>3联系方式信息如微信通讯地址等仅用于日常必要时的沟通交流或活动奖品寄送线上支付线下服务对接等特定目的</li>
<li>4获客渠道信息用于掌握触达潜在用户完成用户转化的核心通路</li>
<li>5所属省市级地域信息用于一般性的会员群属统计</li>
</ul>
<h4 class="sub-title">3敏感个人信息的特殊收集</h4>
<p>本网站当前服务业务无需对敏感个人信息的特殊收集故不会主动收集此类信息</p>
<h4 class="sub-title">4收集方式说明</h4>
<ul>
<li>1主动提交您通过注册表单留言表单咨询窗口等主动填写并提交的信息</li>
<li>2系统自动采集通过网站服务器日志Cookie等技术手段自动收集的访问数据您可通过浏览器设置管理Cookie权限</li>
<li>3第三方获取若您通过社交账号等第三方平台登录本网站将仅获取您授权公开的昵称头像等信息具体以第三方平台的授权协议为准</li>
<li>4问卷调查本网站客服可能会向您发出有关网站服务的问卷调查其中所有问题您均有权选答或据答</li>
</ul>
</div>
</div>
<!-- 第三章 -->
<div class="policy-section">
<h3 class="section-title">3个人信息使用规则</h3>
<div class="section-content">
<p>1本网站仅在以下合法目的范围内使用收集的个人信息</p>
<ul>
<li> 保障网站服务的正常运行如账户管理身份验证安全防护</li>
<li> 履行服务承诺如提供内容浏览个性化推荐会员支持</li>
<li> 优化服务质量如分析会员行为改进功能设计修复系统漏洞</li>
<li> 开展合法营销活动如推送活动通知优惠信息您可随时拒绝此类推送</li>
<li> 遵守法律法规要求如配合监管检查履行信息留存义务</li>
</ul>
<p>2若需将个人信息用于本规则未明确的其他目的本网站将提前向您告知并重新取得您的同意</p>
<p>3本网站利用个人信息进行自动化决策如个性化推荐将保证决策的透明度和结果公平公正不实行不合理的差别待遇</p>
<p>4未经您的单独同意本网站不会将个人信息用于广告推送或与其他第三方共享</p>
</div>
</div>
<!-- 第四章 -->
<div class="policy-section">
<h3 class="section-title">4个人信息存储与安全保障</h3>
<div class="section-content">
<h4 class="sub-title">1存储规范</h4>
<ul>
<li> 您的个人信息将存储于中国大陆境内的服务器符合数据本地化存储要求</li>
<li> 存储期限遵循"必要最短时间"原则超出实现服务目的所需的存储期限后将自动删除或进行匿名化处理</li>
<li> 您注销账户后本网站将在30日内完成个人信息的删除或匿名化处理法律法规另有规定的除外</li>
</ul>
<h4 class="sub-title">2安全措施</h4>
<ul>
<li> 技术防护采用HTTPS传输加密AES256存储加密访问权限分级管理等技术防止数据泄露篡改</li>
<li> 运维保障定期开展安全审计漏洞扫描建立数据备份机制保留最近90天历史数据及时修复安全隐患</li>
<li> 人员管理对接触个人信息的运营人员进行严格资质审核和保密培训签订保密协议明确岗位职责</li>
</ul>
<p>3若发生个人信息泄露篡改丢失等安全事件本网站将立即启动应急响应机制采取补救措施并在事件发生后72小时内告知您事件相关情况及处理措施法律法规另有规定的除外</p>
</div>
</div>
<!-- 第五章 -->
<div class="policy-section">
<h3 class="section-title">5个人信息共享与第三方合作</h3>
<div class="section-content">
<p>1本网站原则上不向第三方共享您的个人信息仅在以下特殊情形下经您单独同意或法律法规允许时共享</p>
<ul>
<li> 为履行服务必需如委托第三方服务商提供云存储CDN加速支付结算等服务将与第三方签订保密协议明确数据处理范围和安全义务</li>
<li> 为遵守法律规定如配合司法机关监管部门的合法调查取证要求</li>
<li> 为保护合法权益如为保护您或他人的人身财产安全或维护本网站的合法权益</li>
</ul>
<p>2向第三方共享个人信息时将严格限制共享范围仅提供实现服务目的所必需的信息且要求第三方采取与本网站同等的安全保护措施第三方不得超出约定范围处理个人信息</p>
<p>3若第三方服务提供商发生合并分立解散等情形本网站将要求其及时返还或删除所持有您的个人信息并向您告知接收方信息如涉及信息转移</p>
</div>
</div>
<!-- 第六章 -->
<div class="policy-section">
<h3 class="section-title">6您的权利及行使方式</h3>
<div class="section-content">
<p>您可依法行使以下个人信息相关权利本网站将提供便捷的行使渠道不设置不合理条件限制您的权利行使</p>
<ul>
<li><strong>1知情权</strong>您可通过查阅本规则了解个人信息的收集使用共享等具体情况</li>
<li><strong>2访问权与复制权</strong>您可登录个人账户"我的"页面查看您的个人信息副本</li>
<li><strong>3更正权</strong>若您发现个人信息不准确或不完整可通过直接修改或联系客服协助更正</li>
<li><strong>4删除权</strong>在符合法律法规规定的情形下如信息收集目的已实现您撤回同意您可要求删除个人信息联系客服后将及时处理</li>
<li><strong>5撤回同意权</strong>您可通过联系客服撤回对个人信息处理的同意撤回同意后本网站将停止相关信息处理活动但不影响撤回前基于同意已进行的合法处理行为的效力</li>
<li><strong>6投诉举报权</strong>若您认为本网站的个人信息处理行为侵害了您的权益可通过客服联系方式投诉举报我们将在15个工作日内予以答复</li>
</ul>
<p><strong>权利行使方式</strong>通过微信客服渠道申请时需完成身份验证如短信验证码以保障信息安全</p>
</div>
</div>
<!-- 第七章 -->
<div class="policy-section">
<h3 class="section-title">7规则更新与通知</h3>
<div class="section-content">
<p>1本规则将根据法律法规更新服务功能调整等情况适时修订修订后将在网站显著位置公示更新内容及生效时间公示期不少于30日</p>
<p>2若修订内容涉及您的核心权益如收集范围扩大使用目的变更将通过微信等方式向您单独通知您继续使用本网站服务即表示同意修订后的规则</p>
<p>3您可随时访问网站查看本规则的最新版本</p>
</div>
</div>
<!-- 第八章 -->
<div class="policy-section">
<h3 class="section-title">8附则</h3>
<div class="section-content">
<p>1本规则的解释权归本网站运营主体所有</p>
<p>2若您与本网站就个人信息处理产生争议可先通过客服渠道协商解决协商不成的可向有管辖权的人民法院提起诉讼</p>
<p>3本政策自2026年1月26日起生效</p>
</div>
</div>
<!-- 第九章 -->
<div class="policy-section">
<h3 class="section-title">9联系方式</h3>
<div class="section-content">
<p><strong>运营主体</strong>西安溢彩数智科技有限公司</p>
<p><strong>注册地址</strong>陕西省西安市高新区</p>
<p><strong>微信客服二维码</strong></p>
<div class="qrcode-placeholder">
<img src="/assets/home/erweima.png" alt="客服二维码" class="qrcode-img" />
</div>
</div>
</div>
<!-- 底部信息 -->
<div class="footer-info">
<p class="company-name">西安溢彩数智科技有限公司</p>
<p class="date">2026年2月1日</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'PrivacyPolicy',
methods: {
goBack() {
this.$router.go(-1)
}
}
}
</script>
<style scoped>
.privacy-policy-page {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 0;
}
/* 页面头部 */
.page-header-modern {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
padding: 20px 0;
position: relative;
}
.header-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
align-items: center;
padding: 0 20px;
position: relative;
z-index: 1;
}
.back-btn {
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
color: white;
margin-right: 16px;
}
.back-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
.back-icon {
width: 24px;
height: 24px;
fill: currentColor;
}
.header-info {
flex: 1;
}
.header-title {
font-size: 24px;
font-weight: 700;
margin: 0 0 4px 0;
color: white;
}
.header-subtitle {
font-size: 14px;
opacity: 0.8;
margin: 0;
}
/* 主要内容 */
.policy-content {
max-width: 850px;
margin: 0 auto;
padding: 24px 20px;
}
/* 标题区域 */
.policy-title-section {
text-align: center;
margin-bottom: 10px;
}
/* 章节样式 */
.policy-section {
background: white;
border-radius: 16px;
padding: 24px;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 18px;
font-weight: 700;
color: #333;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 2px solid #4facfe;
}
.section-content {
font-size: 14px;
color: #555;
line-height: 1.8;
}
.section-content p {
margin-bottom: 12px;
}
.section-content p:last-child {
margin-bottom: 0;
}
.sub-title {
font-size: 15px;
font-weight: 600;
color: #333;
margin: 16px 0 12px 0;
}
/* 列表样式 */
.section-content ul {
padding-left: 20px;
margin: 12px 0;
}
.section-content ul li {
margin-bottom: 8px;
line-height: 1.6;
}
/* 二维码 */
.qrcode-placeholder {
text-align: center;
margin-top: 16px;
}
.qrcode-img {
max-width: 200px;
height: auto;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
/* 提示框 */
.notice-box {
background: linear-gradient(135deg, rgba(255, 193, 7, 0.1) 0%, rgba(255, 152, 0, 0.1) 100%);
padding: 16px 20px;
border-radius: 12px;
border-left: 4px solid #ffc107;
text-align: left;
font-size: 14px;
color: #666;
line-height: 1.6;
margin-bottom: 20px;
}
/* 底部信息 */
.footer-info {
text-align: center;
color: #666;
}
.company-name {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.date {
font-size: 14px;
color: #999;
}
/* 响应式设计 */
@media (max-width: 768px) {
.page-header-modern {
padding: 16px 0;
}
.header-content {
padding: 0 16px;
}
.back-btn {
width: 40px;
height: 40px;
margin-right: 12px;
}
.header-title {
font-size: 18px;
}
.policy-content {
padding: 16px;
}
.section-title {
font-size: 16px;
}
.qrcode-img {
max-width: 160px;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
<!-- 页面头部 -->
<div class="page-header">
<div class="page-title">
<h1 class="main-title">彩票猪手</h1>
<h1 class="main-title">用户注册</h1>
<p class="subtitle">您的专属彩票数据助理</p>
</div>
</div>
@@ -39,20 +39,32 @@
<div v-if="errors.nickname" class="error-text">{{ errors.nickname }}</div>
</div>
<!-- 手机号 -->
<!-- 手机号和发送验证码按钮 -->
<div class="form-group">
<el-input
v-model="formData.phone"
type="tel"
placeholder="请输入手机号"
:error="errors.phone"
prefix-icon="Iphone"
size="large"
maxlength="11"
@input="validatePhoneInput"
@blur="validatePhoneOnBlur"
clearable
/>
<div class="phone-code-row">
<el-input
v-model="formData.phone"
type="tel"
placeholder="请输入手机号"
:error="errors.phone"
prefix-icon="Iphone"
size="large"
maxlength="11"
@input="validatePhoneInput"
@blur="validatePhoneOnBlur"
clearable
class="phone-input"
/>
<el-button
type="primary"
:disabled="codeBtnDisabled"
@click="sendVerificationCode"
class="send-code-btn-inline"
size="large"
>
{{ codeButtonText }}
</el-button>
</div>
<div v-if="errors.phone" class="error-text">{{ errors.phone }}</div>
<div v-else-if="formData.phone && formData.phone.length > 0 && formData.phone.length < 11" class="tip-text">请输入11位手机号码</div>
</div>
@@ -64,18 +76,9 @@
placeholder="请输入验证码"
prefix-icon="Key"
size="large"
maxlength="6"
@blur="validateCode"
>
<template #append>
<el-button
type="primary"
:disabled="codeBtnDisabled"
@click="sendVerificationCode"
>
{{ codeButtonText }}
</el-button>
</template>
</el-input>
/>
<div v-if="errors.code" class="error-text">{{ errors.code }}</div>
</div>
@@ -115,7 +118,8 @@
<div class="form-group">
<el-checkbox v-model="formData.agreeTerms" class="checkbox-custom">
我已阅读并同意
<a href="#" class="terms-link" @click.prevent="showTerms">用户服务协议</a>
<span class="terms-link" @click.stop="showTerms">会员服务协议</span>
<span class="terms-link" @click.stop="showPrivacyPolicy">个人信息收集与处理规则</span>
</el-checkbox>
<div v-if="errors.agreeTerms" class="error-text">{{ errors.agreeTerms }}</div>
</div>
@@ -175,6 +179,7 @@ export default {
codeCountdown: 0,
timer: null,
saveTimer: null, // 用于防抖保存的定时器
showPhoneError: false,
phoneValid: false,
@@ -274,9 +279,7 @@ export default {
const response = await lotteryApi.sendSmsCode(this.formData.phone);
if (response.success) {
this.toast.success('验证码已发送,请注意查收');
} else {
if (!response.success) {
// 如果发送失败,停止倒计时
this.codeCountdown = 0;
clearInterval(this.timer);
@@ -381,7 +384,7 @@ export default {
// 服务条款验证
if (!this.formData.agreeTerms) {
this.errors.agreeTerms = '请同意用户服务协议';
this.errors.agreeTerms = '请同意会员服务协议';
}
return Object.keys(this.errors).length === 0;
@@ -408,6 +411,7 @@ export default {
if (response.success === true) {
// 注册成功
this.clearSavedFormData(); // 清除保存的表单数据
this.toast.success('注册成功!请登录您的账号');
this.router.push('/login');
} else {
@@ -427,17 +431,101 @@ export default {
}
},
// 保存表单数据到临时存储(带防抖)
saveFormData(immediate = false) {
// 如果不是立即保存,使用防抖
if (!immediate) {
if (this.saveTimer) {
clearTimeout(this.saveTimer);
}
this.saveTimer = setTimeout(() => {
this.doSaveFormData();
}, 1000); // 1秒防抖
} else {
this.doSaveFormData();
}
},
// 实际执行保存操作
doSaveFormData() {
const formData = {
username: this.formData.username,
nickname: this.formData.nickname,
password: this.formData.password,
confirmPassword: this.formData.confirmPassword,
phone: this.formData.phone,
code: this.formData.code,
agreeTerms: this.formData.agreeTerms
};
sessionStorage.setItem('register_form_data', JSON.stringify(formData));
},
// 从临时存储恢复表单数据
restoreFormData() {
const savedData = sessionStorage.getItem('register_form_data');
if (savedData) {
try {
const formData = JSON.parse(savedData);
this.formData = { ...this.formData, ...formData };
// 恢复手机号验证状态
if (formData.phone && this.isValidPhone(formData.phone)) {
this.phoneValid = true;
}
} catch (error) {
console.warn('恢复表单数据失败:', error);
}
}
},
// 清除临时存储的表单数据
clearSavedFormData() {
sessionStorage.removeItem('register_form_data');
},
// 显示服务条款
showTerms() {
this.$router.push('/user-agreement');
// 跳转前立即保存当前表单数据
this.saveFormData(true);
this.$router.push('/member-agreement');
},
// 显示隐私政策
showPrivacyPolicy() {
// 跳转前立即保存当前表单数据
this.saveFormData(true);
this.$router.push('/privacy-policy');
}
},
// 监听表单数据变化,自动保存
watch: {
'formData': {
handler(newFormData) {
// 只有当表单有实际内容时才保存,避免保存空数据
if (newFormData.username || newFormData.nickname || newFormData.phone ||
newFormData.password || newFormData.code) {
this.saveFormData();
}
},
deep: true,
// 延迟保存,避免频繁操作
immediate: false
}
},
// 组件挂载时恢复表单数据
mounted() {
this.restoreFormData();
},
// 组件销毁时清除定时器
beforeUnmount() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
// 清除保存定时器
if (this.saveTimer) {
clearTimeout(this.saveTimer);
this.saveTimer = null;
}
}
}
</script>
@@ -447,18 +535,19 @@ export default {
.register-page-container {
min-height: calc(100vh - 70px);
background: #f0f2f5;
padding: 20px 20px 0px 20px;
padding: 20px 20px 8px 20px;
}
/* 页面头部 */
.page-header {
background: url('@/assets/banner/backend1.png') center/cover no-repeat, linear-gradient(135deg, #ff6b6b, #ee5a52);
background: linear-gradient(135deg, #ff6b6b, #ee5a52);
color: white;
padding: 45px 20px 25px;
padding: 35px 20px 25px;
text-align: center;
position: relative;
margin-bottom: 20px;
border-radius: 8px;
margin-bottom: 15px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(238, 90, 82, 0.3);
}
.page-title {
@@ -467,31 +556,31 @@ export default {
}
.main-title {
font-size: 38px;
margin: 0 auto 10px;
font-size: 32px;
margin: 0 auto 4px;
font-weight: 700;
color: white;
text-shadow: 0 2px 6px rgba(0,0,0,0.7), 0 0 15px rgba(0,0,0,0.4);
letter-spacing: 2px;
text-shadow: 0 2px 8px rgba(0,0,0,0.5), 0 0 20px rgba(0,0,0,0.3);
letter-spacing: 1px;
text-align: center;
width: 100%;
}
.subtitle {
font-size: 22px;
font-size: 16px;
margin: 0;
color: white;
opacity: 0.9;
text-shadow: 0 2px 6px rgba(0,0,0,0.7), 0 0 15px rgba(0,0,0,0.4);
opacity: 0.95;
text-shadow: 0 2px 4px rgba(0,0,0,0.4);
text-align: center;
width: 100%;
font-weight: 500;
font-weight: 400;
}
/* 桌面端样式 */
@media (min-width: 1024px) {
.page-header {
padding: 40px 20px 30px;
padding: 30px 20px 25px;
}
}
@@ -499,20 +588,21 @@ export default {
padding: 0;
background: white;
margin: 0 0 20px 0;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.register-form {
background: white;
border-radius: 0;
padding: 30px 25px;
padding: 28px 24px 20px;
box-shadow: none;
}
/* 表单组 */
.form-group {
margin-bottom: 24px;
margin-bottom: 16px;
}
.input-wrapper {
@@ -598,7 +688,49 @@ input:-webkit-autofill:active {
outline: none !important;
}
/* Element Plus验证码按钮已在组件中实现移除原来的样式以避免冲突 */
/* 手机号和验证码按钮同行布局 */
.phone-code-row {
display: flex;
gap: 12px;
align-items: stretch;
}
.phone-input {
flex: 1;
}
/* 内联发送验证码按钮样式 */
.send-code-btn-inline {
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border: none;
border-radius: 12px;
font-weight: 500;
transition: all 0.3s ease;
min-width: 120px;
flex-shrink: 0;
height: auto;
display: flex;
align-items: center;
justify-content: center;
}
.send-code-btn-inline:hover:not(.is-disabled) {
background: linear-gradient(135deg, #d43030, #ff5a5a);
transform: translateY(-1px);
box-shadow: 0 4px 15px rgba(229, 62, 62, 0.3);
}
.send-code-btn-inline:active:not(.is-disabled) {
transform: translateY(0);
}
.send-code-btn-inline.is-disabled {
background: #cccccc !important;
border-color: #cccccc !important;
color: #888 !important;
transform: none !important;
box-shadow: none !important;
}
/* 隐藏浏览器自带的密码控件 */
input::-ms-reveal,
@@ -682,51 +814,81 @@ input::-webkit-credentials-auto-fill-button {
color: #e53e3e;
text-decoration: none;
margin-left: 4px;
cursor: pointer;
-webkit-tap-highlight-color: transparent !important;
-webkit-touch-callout: none !important;
-webkit-user-select: none !important;
-khtml-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
outline: none !important;
background-color: transparent !important;
display: inline;
}
.terms-link:hover {
text-decoration: underline;
}
.terms-link:active {
background-color: transparent !important;
outline: none !important;
-webkit-tap-highlight-color: transparent !important;
}
/* 注册按钮 */
.register-btn {
width: 100%;
margin: 30px 0 25px 0;
padding: 12px;
font-size: 18px;
height: auto;
margin: 8px 0 24px 0;
padding: 14px;
font-size: 16px;
font-weight: 600;
height: 52px;
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border: none;
box-shadow: 0 4px 15px rgba(229, 62, 62, 0.3);
border-radius: 12px;
box-shadow: 0 4px 20px rgba(229, 62, 62, 0.25);
transition: all 0.3s ease;
}
.register-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(229, 62, 62, 0.4);
transform: translateY(-1px);
box-shadow: 0 6px 30px rgba(229, 62, 62, 0.35);
background: linear-gradient(135deg, #d43030, #ff5a5a);
border: none;
}
.register-btn:active:not(:disabled) {
transform: translateY(0);
box-shadow: 0 2px 10px rgba(229, 62, 62, 0.3);
}
/* Element UI 组件自定义样式 */
:deep(.el-input__wrapper) {
padding: 4px 11px;
padding: 6px 16px;
box-shadow: none !important;
background-color: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 12px;
transition: all 0.3s ease;
}
:deep(.el-input__wrapper.is-focus) {
background-color: #fff;
border-color: #e53e3e;
box-shadow: 0 0 0 4px rgba(229, 62, 62, 0.1);
}
:deep(.el-input__prefix) {
margin-right: 8px;
margin-right: 12px;
color: #999;
}
:deep(.el-input__inner) {
height: 40px;
font-size: 16px;
height: 44px;
font-size: 15px;
color: #333;
}
:deep(.el-checkbox__label) {
@@ -743,35 +905,6 @@ input::-webkit-credentials-auto-fill-button {
border-color: #e53e3e;
}
:deep(.el-input-group__append) {
padding: 0;
border: none;
}
:deep(.el-input-group__append .el-button) {
background-color: #ECF5FF;
border: 1px solid #DCDFE6;
margin: 0;
height: 100%;
border-radius: 0 4px 4px 0;
padding: 0 15px;
font-size: 14px;
font-weight: normal;
color: #e53e3e;
min-width: 105px;
box-shadow: none;
}
:deep(.el-input-group__append .el-button:hover) {
background-color: #e6f1ff;
color: #e53e3e;
}
:deep(.el-input-group__append .el-button.is-disabled) {
background-color: #F5F7FA;
color: #C0C4CC;
border-color: #E4E7ED;
}
:deep(.el-button.is-disabled) {
background: #cccccc;
@@ -779,9 +912,36 @@ input::-webkit-credentials-auto-fill-button {
}
/* 处理用户协议链接 */
.checkbox-custom {
align-items: flex-start !important;
}
.checkbox-custom :deep(.el-checkbox__input) {
margin-top: 4px;
}
.checkbox-custom :deep(.el-checkbox__label) {
display: flex;
align-items: center;
display: block;
line-height: 1.8;
white-space: normal;
word-break: break-word;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
padding-top: 0;
}
.checkbox-custom :deep(.el-checkbox__label) * {
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-tap-highlight-color: transparent !important;
-webkit-touch-callout: none;
background-color: transparent !important;
}
/* 登录链接 */
@@ -806,70 +966,78 @@ input::-webkit-credentials-auto-fill-button {
/* 响应式设计 */
@media (max-width: 768px) {
.register-page-container {
padding: 10px;
padding: 10px 10px 5px 10px;
}
.page-header {
padding: 45px 15px 35px;
padding: 30px 15px 25px;
}
.page-title {
margin: 0 0 8px 0;
margin: 0;
}
.send-code-btn {
font-size: 12px;
min-width: 90px;
padding: 0 10px;
}
}
@media (max-width: 480px) {
.register-page-container {
padding: 5px 5px 3px 5px;
}
.page-header {
padding: 40px 12px 30px;
padding: 30px 20px 25px;
margin-bottom: 12px;
}
.page-title {
margin: 0 0 6px 0;
margin: 0;
}
.main-title {
font-size: 28px;
margin-bottom: 3px;
letter-spacing: 0.5px;
}
.subtitle {
font-size: 18px;
font-size: 14px;
}
.register-form {
padding: 20px 15px;
padding: 24px 20px 18px;
}
.input-icon {
padding: 12px 25px;
:deep(.el-input__inner) {
height: 42px;
font-size: 14px;
}
.icon-img {
width: 22px;
height: 22px;
.register-btn {
height: 48px;
font-size: 15px;
margin: 8px 0 20px 0;
}
.toggle-icon-img {
width: 20px;
height: 20px;
}
.password-toggle {
padding: 0 12px;
}
.send-code-btn {
.send-code-btn-inline {
font-size: 12px;
min-width: 85px;
padding: 0 8px;
height: 42px;
min-width: 90px;
padding: 0 10px;
}
.phone-code-row {
gap: 8px;
}
.checkbox-custom :deep(.el-checkbox__label) {
font-size: 13px;
}
.terms-link {
display: inline;
margin: 0 2px;
}
}
/* 桌面端样式 - 这部分已在上面定义,这里移除重复定义 */
</style>
</style>

View File

@@ -3,7 +3,8 @@
<!-- 页面头部 -->
<div class="page-header">
<div class="page-title">
<h1>找回密码</h1>
<h1 class="main-title">找回密码</h1>
<p class="subtitle">重置您的登录密码</p>
</div>
</div>
@@ -12,118 +13,81 @@
<form @submit.prevent="handleResetPassword" class="reset-password-form">
<!-- 手机号 -->
<div class="form-group">
<div class="input-wrapper" :class="{ error: errors.phone }">
<div class="input-icon">
<img src="@/assets/icon/login/shouji.png" alt="手机号" class="icon-img" />
</div>
<input
v-model="formData.phone"
type="tel"
class="form-input"
placeholder="请输入手机号"
maxlength="11"
@input="validatePhoneInput"
@blur="validatePhoneOnBlur"
/>
</div>
<el-input
v-model="formData.phone"
type="tel"
placeholder="请输入手机号"
prefix-icon="Iphone"
size="large"
maxlength="11"
@input="validatePhoneInput"
@blur="validatePhoneOnBlur"
clearable
/>
<div v-if="errors.phone" class="error-text">{{ errors.phone }}</div>
<div v-else-if="formData.phone && formData.phone.length > 0 && formData.phone.length < 11" class="tip-text">请输入11位手机号码</div>
</div>
<!-- 验证码 -->
<div class="form-group">
<div class="input-wrapper code-input-wrapper" :class="{ error: errors.code }">
<div class="input-icon">
<img src="@/assets/icon/login/mima.png" alt="验证码" class="icon-img" />
</div>
<input
v-model="formData.code"
type="text"
class="form-input"
placeholder="请输入验证码"
/>
<button
type="button"
class="send-code-btn"
@click="sendVerificationCode"
:disabled="codeBtnDisabled"
>
{{ codeButtonText }}
</button>
</div>
<el-input
v-model="formData.code"
placeholder="请输入验证码"
prefix-icon="Key"
size="large"
maxlength="6"
>
<template #append>
<el-button
type="primary"
:disabled="codeBtnDisabled"
@click="sendVerificationCode"
>
{{ codeButtonText }}
</el-button>
</template>
</el-input>
<div v-if="errors.code" class="error-text">{{ errors.code }}</div>
</div>
<!-- 新密码 -->
<div class="form-group">
<div class="input-wrapper" :class="{ error: errors.newPassword }">
<div class="input-icon">
<img src="@/assets/icon/login/mima.png" alt="新密码" class="icon-img" />
</div>
<input
v-model="formData.newPassword"
:type="showNewPassword ? 'text' : 'password'"
class="form-input"
placeholder="请输入新密码"
autocomplete="new-password"
/>
<div class="password-toggle" @click="showNewPassword = !showNewPassword">
<img
v-if="showNewPassword"
src="@/assets/icon/login/zhanshi.png"
alt="隐藏密码"
class="toggle-icon-img"
/>
<img
v-else
src="@/assets/icon/login/yingcang.png"
alt="显示密码"
class="toggle-icon-img"
/>
</div>
</div>
<el-input
v-model="formData.newPassword"
placeholder="请输入新密码"
prefix-icon="Lock"
size="large"
:type="showNewPassword ? 'text' : 'password'"
:show-password="true"
autocomplete="new-password"
/>
<div v-if="errors.newPassword" class="error-text">{{ errors.newPassword }}</div>
</div>
<!-- 确认新密码 -->
<div class="form-group">
<div class="input-wrapper" :class="{ error: errors.confirmPassword }">
<div class="input-icon">
<img src="@/assets/icon/login/mima.png" alt="确认新密码" class="icon-img" />
</div>
<input
v-model="formData.confirmPassword"
:type="showConfirmPassword ? 'text' : 'password'"
class="form-input"
placeholder="请再次输入新密码"
autocomplete="new-password"
/>
<div class="password-toggle" @click="showConfirmPassword = !showConfirmPassword">
<img
v-if="showConfirmPassword"
src="@/assets/icon/login/zhanshi.png"
alt="隐藏密码"
class="toggle-icon-img"
/>
<img
v-else
src="@/assets/icon/login/yingcang.png"
alt="显示密码"
class="toggle-icon-img"
/>
</div>
</div>
<el-input
v-model="formData.confirmPassword"
placeholder="请再次输入新密码"
prefix-icon="Lock"
size="large"
:type="showConfirmPassword ? 'text' : 'password'"
:show-password="true"
autocomplete="new-password"
/>
<div v-if="errors.confirmPassword" class="error-text">{{ errors.confirmPassword }}</div>
</div>
<!-- 重置密码按钮 -->
<button
type="submit"
<el-button
type="primary"
native-type="submit"
:loading="loading"
class="reset-password-btn"
:disabled="loading"
size="large"
>
{{ loading ? '重置中...' : '重置密码' }}
</button>
</el-button>
<!-- 返回登录链接 -->
<div class="login-link">
@@ -148,9 +112,18 @@
import { lotteryApi } from '../api/index.js'
import { useToast } from 'vue-toastification'
import { useRouter } from 'vue-router'
import { ElInput, ElButton } from 'element-plus'
import { Lock, Iphone, Key } from '@element-plus/icons-vue'
export default {
name: 'ResetPassword',
components: {
ElInput,
ElButton,
Lock,
Iphone,
Key
},
setup() {
const toast = useToast()
const router = useRouter()
@@ -380,43 +353,63 @@ export default {
/* 页面容器 */
.reset-password-page-container {
min-height: calc(100vh - 70px);
background: #f8f9fa;
padding: 0;
background: #f0f2f5;
padding: 20px 20px 8px 20px;
}
/* 页面头部 */
.page-header {
background: url('@/assets/banner/backend1.png') center/cover no-repeat, linear-gradient(135deg, #ff6b6b, #ee5a52);
background: linear-gradient(135deg, #ff6b6b, #ee5a52);
color: white;
padding: 50px 20px 40px;
padding: 35px 20px 25px;
text-align: center;
position: relative;
margin-bottom: 15px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(238, 90, 82, 0.3);
}
.page-title {
margin: 0 0 8px 0;
margin: 0;
text-align: center;
}
.page-title h1 {
font-size: 36px;
.main-title {
font-size: 32px;
margin: 0 auto 4px;
font-weight: 700;
color: white;
text-shadow: 0 2px 8px rgba(0,0,0,0.5), 0 0 20px rgba(0,0,0,0.3);
letter-spacing: 1px;
text-align: center;
width: 100%;
}
.subtitle {
font-size: 16px;
margin: 0;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
color: white;
opacity: 0.95;
text-shadow: 0 2px 4px rgba(0,0,0,0.4);
text-align: center;
width: 100%;
font-weight: 400;
}
.reset-password-form-container {
padding: 0;
background: white;
margin: 0 20px;
margin: 0 0 20px 0;
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.reset-password-form {
background: white;
border-radius: 0;
padding: 30px 25px;
padding: 32px 24px 24px;
box-shadow: none;
min-height: calc(100vh - 320px);
}
/* 表单组 */
@@ -424,123 +417,87 @@ export default {
margin-bottom: 24px;
}
.input-wrapper {
position: relative;
display: flex;
align-items: center;
/* Element UI 组件自定义样式 */
:deep(.el-input__wrapper) {
padding: 6px 16px;
box-shadow: none !important;
background-color: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 6px;
background: #f8f9fa;
border-radius: 12px;
transition: all 0.3s ease;
min-height: 56px;
overflow: hidden;
}
.input-wrapper:focus-within {
border-color: #e9ecef;
background: white;
box-shadow: none;
outline: none;
/* 带有 append 按钮的输入框样式优化 */
:deep(.el-input-group .el-input__wrapper) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: none;
}
input:focus {
outline: none;
box-shadow: none;
}
.input-wrapper.error {
border-color: #dc3545;
background: #fff5f5;
}
.input-wrapper.success {
border-color: #4caf50;
background: #f8fff8;
}
.input-icon {
padding: 12px 25px;
color: #6c757d;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
}
.icon-img {
width: 22px;
height: 22px;
object-fit: contain;
}
.form-input {
flex: 1;
padding: 16px 8px;
:deep(.el-input-group__append) {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
padding: 0;
border: none;
outline: none;
font-size: 16px;
background: transparent;
color: #212529;
box-shadow: none;
-webkit-appearance: none;
}
.form-input:focus {
outline: none;
border: none;
box-shadow: none;
:deep(.el-input__wrapper.is-focus) {
background-color: #fff;
border-color: #e53e3e;
box-shadow: 0 0 0 4px rgba(229, 62, 62, 0.1);
}
/* 控制浏览器自动填充的样式 */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 30px white inset !important;
-webkit-text-fill-color: #212529 !important;
transition: background-color 5000s ease-in-out 0s;
border: none !important;
outline: none !important;
/* 带有 append 按钮的输入框聚焦时的样式 */
:deep(.el-input-group .el-input__wrapper.is-focus) {
border-color: #e53e3e;
box-shadow: 0 0 0 4px rgba(229, 62, 62, 0.1);
}
/* 发送验证码按钮 */
.send-code-btn {
height: 32px;
margin-right: 5px;
padding: 0 10px;
border: none;
color: white;
:deep(.el-input-group.is-focus .el-input-group__append .el-button) {
border-color: #e53e3e;
box-shadow: 0 0 0 4px rgba(229, 62, 62, 0.1);
}
:deep(.el-input__prefix) {
margin-right: 12px;
color: #999;
}
:deep(.el-input__inner) {
height: 44px;
font-size: 15px;
color: #333;
}
:deep(.el-input-group__append .el-button) {
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border: 2px solid #e53e3e;
border-left: none;
margin: 0;
height: 100%;
border-radius: 0 12px 12px 0;
padding: 0 16px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
border-radius: 4px;
white-space: nowrap;
min-width: 85px;
transition: all 0.3s;
background: #e53e3e;
align-self: center;
}
.code-input-wrapper {
padding-right: 5px;
border: 2px solid #e9ecef;
border-radius: 6px;
overflow: hidden;
}
.code-input-wrapper:focus-within {
border-color: #e9ecef;
color: white;
min-width: 100px;
box-shadow: none;
transition: all 0.3s ease;
}
.send-code-btn:disabled {
:deep(.el-input-group__append .el-button:hover) {
background: linear-gradient(135deg, #d43030, #ff5a5a);
border-color: #d43030;
color: white;
transform: none;
}
:deep(.el-input-group__append .el-button.is-disabled) {
background: #cccccc;
cursor: not-allowed;
}
.send-code-btn:hover:not(:disabled) {
background: #d43030;
border-color: #cccccc;
color: #888;
transform: none;
}
/* 提示文本 */
@@ -558,79 +515,36 @@ input:-webkit-autofill:active {
margin-left: 8px;
}
/* 隐藏浏览器自带的密码控件 */
input::-ms-reveal,
input::-ms-clear {
display: none;
}
input::-webkit-credentials-auto-fill-button {
visibility: hidden;
position: absolute;
right: 0;
}
.form-input::placeholder {
color: #9ca3af;
}
.password-toggle {
padding: 0 15px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.toggle-icon-img {
width: 22px;
height: 22px;
object-fit: contain;
}
/* 重置密码按钮 */
.reset-password-btn {
width: 100%;
padding: 18px;
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
color: white;
border: none;
border-radius: 6px;
font-size: 18px;
margin: 32px 0 28px 0;
padding: 14px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
height: 52px;
background: linear-gradient(135deg, #e53e3e, #ff6b6b);
border: none;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(229, 62, 62, 0.25);
transition: all 0.3s ease;
margin: 30px 0 25px 0;
position: relative;
overflow: hidden;
box-shadow: 0 4px 15px rgba(229, 62, 62, 0.3);
}
.reset-password-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s;
}
.reset-password-btn:hover:not(:disabled)::before {
left: 100%;
}
.reset-password-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(229, 62, 62, 0.4);
transform: translateY(-1px);
box-shadow: 0 6px 30px rgba(229, 62, 62, 0.35);
background: linear-gradient(135deg, #d43030, #ff5a5a);
border: none;
}
.reset-password-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
transform: none;
box-shadow: 0 4px 15px rgba(229, 62, 62, 0.2);
.reset-password-btn:active:not(:disabled) {
transform: translateY(0);
box-shadow: 0 2px 10px rgba(229, 62, 62, 0.3);
}
:deep(.el-button.is-disabled) {
background: #cccccc;
border-color: #cccccc;
}
/* 返回登录链接 */
@@ -757,25 +671,24 @@ input::-webkit-credentials-auto-fill-button {
box-shadow: 0 8px 25px rgba(244, 67, 54, 0.3) !important;
}
/* 桌面端样式 */
@media (min-width: 1024px) {
.page-header {
padding: 30px 20px 25px;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.page-header {
padding: 45px 15px 35px;
.reset-password-page-container {
padding: 10px 10px 5px 10px;
}
.page-title {
margin: 0 0 8px 0;
}
.page-title h1 {
font-size: 30px;
}
.reset-password-form {
padding: 25px 20px;
}
.send-code-btn {
:deep(.el-input-group__append .el-button) {
font-size: 12px;
min-width: 90px;
padding: 0 10px;
@@ -783,66 +696,48 @@ input::-webkit-credentials-auto-fill-button {
}
@media (max-width: 480px) {
.reset-password-page-container {
padding: 5px 5px 3px 5px;
}
.page-header {
padding: 40px 12px 30px;
padding: 30px 20px 25px;
margin-bottom: 12px;
}
.page-title {
margin: 0 0 6px 0;
margin: 0;
}
.page-title h1 {
font-size: 26px;
.main-title {
font-size: 28px;
margin-bottom: 3px;
letter-spacing: 0.5px;
}
.subtitle {
font-size: 14px;
}
.reset-password-form {
padding: 20px 15px;
padding: 28px 20px 20px;
}
.input-icon {
padding: 12px 25px;
:deep(.el-input__inner) {
height: 42px;
font-size: 14px;
}
.icon-img {
width: 22px;
height: 22px;
.reset-password-btn {
height: 48px;
font-size: 15px;
margin: 28px 0 24px 0;
}
.toggle-icon-img {
width: 20px;
height: 20px;
}
.password-toggle {
:deep(.el-input-group__append .el-button) {
font-size: 12px;
min-width: 90px;
padding: 0 12px;
}
.send-code-btn {
font-size: 12px;
min-width: 85px;
padding: 0 8px;
}
}
/* 桌面端样式 */
@media (min-width: 1024px) {
.page-header {
padding: 45px 20px 35px;
}
.page-title h1 {
font-size: 40px;
}
.page-subtitle {
font-size: 14px;
}
.send-code-btn {
height: 40px;
font-size: 14px;
min-width: 120px;
padding: 0 15px;
}
}
</style>
</style>

Some files were not shown because too many files have changed in this diff Show More