upload project source code

This commit is contained in:
2026-04-30 18:49:43 +08:00
commit 9b394ba682
2277 changed files with 660945 additions and 0 deletions

View File

@@ -0,0 +1,433 @@
<template>
<view class="settings-screen">
<view class="settings-bg"></view>
<!-- 状态栏占位 -->
<view class="status-bar-placeholder"></view>
<!-- Header -->
<view class="settings-header">
<view class="settings-back-btn" @click="handleBack">
<text class="settings-back-icon"></text>
</view>
<text class="settings-title">设置与反馈</text>
<view class="settings-header-placeholder"></view>
</view>
<!-- Content -->
<scroll-view scroll-y class="settings-content">
<view class="settings-content-inner">
<!-- Section 1: 偏好设置 -->
<!-- <view class="settings-section">
<view class="settings-item settings-item-border">
<view class="settings-item-left">
<text class="settings-item-icon">🔔</text>
<text class="settings-item-label">推送通知</text>
</view>
<view class="settings-switch" :class="{ 'settings-switch-active': pushEnabled }"
@click="togglePush">
<view class="settings-switch-thumb"
:class="{ 'settings-switch-thumb-active': pushEnabled }"></view>
</view>
</view>
<view class="settings-item">
<view class="settings-item-left">
<text class="settings-item-icon">🔊</text>
<text class="settings-item-label">音效反馈</text>
</view>
<view class="settings-switch" :class="{ 'settings-switch-active': soundEnabled }"
@click="toggleSound">
<view class="settings-switch-thumb"
:class="{ 'settings-switch-thumb-active': soundEnabled }"></view>
</view>
</view>
</view> -->
<!-- Section 2: 支持 -->
<view class="settings-section">
<view class="settings-item settings-item-border settings-item-clickable" @click="handleFeedback">
<view class="settings-item-left">
<text class="settings-item-icon">💬</text>
<text class="settings-item-label">意见反馈</text>
</view>
<text class="settings-item-arrow"></text>
</view>
<view class="settings-item settings-item-border settings-item-clickable" @click="handleFAQ">
<view class="settings-item-left">
<text class="settings-item-icon"></text>
<text class="settings-item-label">常见问题</text>
</view>
<text class="settings-item-arrow"></text>
</view>
<view class="settings-item settings-item-clickable" @click="handlePrivacy">
<view class="settings-item-left">
<text class="settings-item-icon">🛡</text>
<text class="settings-item-label">隐私政策</text>
</view>
<text class="settings-item-arrow"></text>
</view>
</view>
<!-- Section 3: 快速反馈 -->
<view class="settings-feedback-section">
<text class="settings-feedback-title">快速反馈</text>
<textarea class="settings-feedback-textarea" v-model="feedbackText" placeholder="您遇到的问题或建议..."
:maxlength="500" />
<view class="settings-feedback-btn" @click="submitFeedback">
<text class="settings-feedback-btn-text">提交反馈</text>
</view>
</view>
<!-- 退出登录 -->
<view class="settings-logout-btn" @click="handleLogout">
<text class="settings-logout-text">退出登录</text>
</view>
<!-- 版本信息 -->
<view class="settings-version">
<text class="settings-version-text">当前版本 v1.0.2</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { userApi } from "@/api";
import { logout } from "@/utils/auth";
declare const uni: any;
const emit = defineEmits<{
back: [];
navigate: [screen: string];
}>();
const pushEnabled = ref(true);
const soundEnabled = ref(true);
const feedbackText = ref("");
const togglePush = () => {
pushEnabled.value = !pushEnabled.value;
uni.showToast({
title: pushEnabled.value ? "已开启推送通知" : "已关闭推送通知",
icon: "none"
});
};
const toggleSound = () => {
soundEnabled.value = !soundEnabled.value;
uni.showToast({
title: soundEnabled.value ? "已开启音效反馈" : "已关闭音效反馈",
icon: "none"
});
};
const handleFeedback = () => {
emit('navigate', 'feedback');
};
const handleFAQ = () => {
emit('navigate', 'faq');
};
const handlePrivacy = () => {
emit('navigate', 'privacy');
};
const submitFeedback = async () => {
if (!feedbackText.value.trim()) {
uni.showToast({ title: "请输入反馈内容", icon: "none" });
return;
}
try {
await userApi.submitFeedback({
content: feedbackText.value.trim(),
feedback_type: 'other'
});
uni.showToast({ title: "感谢您的反馈!", icon: "success" });
feedbackText.value = "";
} catch (error: any) {
uni.showToast({
title: error.msg || "提交失败,请稍后重试",
icon: "none"
});
}
};
const handleLogout = () => {
// Web 环境使用 confirmuni-app 环境使用 showModal
if (typeof uni?.showModal === "function") {
uni.showModal({
title: "提示",
content: "确定要退出登录吗?",
success: (res: any) => {
if (res.confirm) {
logout();
uni.showToast({ title: "已退出登录", icon: "success" });
}
},
});
} else {
const confirmed = confirm("确定要退出登录吗?");
if (confirmed) {
logout();
if (typeof uni?.showToast === "function") {
uni.showToast({ title: "已退出登录", icon: "success" });
}
}
}
};
const handleBack = () => {
emit('back');
};
</script>
<style scoped>
.settings-screen {
height: 100%;
display: flex;
flex-direction: column;
background-color: #f0efe9;
position: relative;
}
.status-bar-placeholder {
height: var(--status-bar-height, 0);
width: 100%;
flex-shrink: 0;
}
.settings-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
opacity: 0.3;
background-image: url("https://www.transparenttextures.com/patterns/rice-paper.png");
}
/* Header */
.settings-header {
position: relative;
z-index: 10;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
border-bottom: 1rpx solid #dcd3c9;
background-color: rgba(253, 251, 247, 0.8);
backdrop-filter: blur(10rpx);
}
.settings-back-btn {
width: 64rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
padding: 0;
margin-left: -16rpx;
}
.settings-back-icon {
font-size: 48rpx;
color: #5a5a5a;
font-weight: 300;
}
.settings-title {
font-size: 32rpx;
font-weight: 700;
color: #2c2c2c;
letter-spacing: 0.2em;
}
.settings-header-placeholder {
width: 64rpx;
}
/* Content */
.settings-content {
flex: 1;
height: 0;
position: relative;
z-index: 10;
}
.settings-content-inner {
padding: 32rpx;
}
/* Section */
.settings-section {
background-color: #fffdf9;
border-radius: 24rpx;
border: 1rpx solid #e5e5e5;
overflow: hidden;
margin-bottom: 32rpx;
}
.settings-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
}
.settings-item-border {
border-bottom: 1rpx solid #f0f0f0;
}
.settings-item-clickable {
transition: background-color 0.2s;
}
.settings-item-clickable:active {
background-color: #fafafa;
}
.settings-item-left {
display: flex;
align-items: center;
gap: 24rpx;
}
.settings-item-icon {
font-size: 32rpx;
}
.settings-item-label {
font-size: 28rpx;
color: #2c2c2c;
}
.settings-item-arrow {
font-size: 32rpx;
color: #ccc;
}
/* Switch */
.settings-switch {
width: 80rpx;
height: 40rpx;
border-radius: 40rpx;
background-color: #ccc;
position: relative;
transition: background-color 0.3s;
}
.settings-switch-active {
background-color: #8b2323;
}
.settings-switch-thumb {
position: absolute;
top: 4rpx;
left: 4rpx;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2);
transition: left 0.3s;
}
.settings-switch-thumb-active {
left: 44rpx;
}
/* Feedback Section */
.settings-feedback-section {
margin-bottom: 32rpx;
}
.settings-feedback-title {
font-size: 24rpx;
font-weight: 700;
color: #8b2323;
margin-bottom: 16rpx;
display: block;
padding: 0 8rpx;
}
.settings-feedback-textarea {
width: 100%;
height: 192rpx;
background-color: #fffdf9;
border: 1rpx solid #e5e5e5;
border-radius: 24rpx;
padding: 24rpx;
font-size: 28rpx;
color: #2c2c2c;
box-sizing: border-box;
}
.settings-feedback-btn {
width: 100%;
margin-top: 16rpx;
padding: 24rpx 0;
background-color: #2c2c2c;
border-radius: 16rpx;
border: none;
display: flex;
justify-content: center;
}
.settings-feedback-btn-text {
font-size: 24rpx;
font-weight: 700;
color: #f2e6d8;
}
/* Logout Button */
.settings-logout-btn {
width: 100%;
padding: 24rpx 0;
background-color: #fffdf9;
border: 1rpx solid #e5e5e5;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 16rpx;
margin-bottom: 32rpx;
transition: background-color 0.2s;
}
.settings-logout-btn:active {
background-color: #fff5f5;
}
.settings-logout-icon {
font-size: 28rpx;
}
.settings-logout-text {
font-size: 28rpx;
font-weight: 700;
color: #8b2323;
}
/* Version */
.settings-version {
text-align: center;
padding: 32rpx 0;
}
.settings-version-text {
font-size: 20rpx;
color: #ccc;
}
</style>