feat: 添加工作台

This commit is contained in:
Ray.Hao
2025-10-15 21:39:33 +08:00
parent 78740b0e50
commit 703171a2d8
7 changed files with 204 additions and 25 deletions

1
components.d.ts vendored
View File

@@ -21,6 +21,7 @@ declare module 'vue' {
WdCard: typeof import('wot-design-uni/components/wd-card/wd-card.vue')['default']
WdCell: typeof import('wot-design-uni/components/wd-cell/wd-cell.vue')['default']
WdCellGroup: typeof import('wot-design-uni/components/wd-cell-group/wd-cell-group.vue')['default']
WdCheckbox: typeof import('wot-design-uni/components/wd-checkbox/wd-checkbox.vue')['default']
WdCollapse: typeof import('wot-design-uni/components/wd-collapse/wd-collapse.vue')['default']
WdCollapseItem: typeof import('wot-design-uni/components/wd-collapse-item/wd-collapse-item.vue')['default']
WdConfigProvider: typeof import('wot-design-uni/components/wd-config-provider/wd-config-provider.vue')['default']

View File

@@ -8,7 +8,7 @@ export interface TabbarItem {
const tabbarItems = ref<TabbarItem[]>([
{ name: "home", value: null, active: true, title: "首页", icon: "home" },
{ name: "work", value: null, active: false, title: "工作台", icon: "apps" },
{ name: "work", value: null, active: false, title: "工作台", icon: "laptop" },
{ name: "mine", value: null, active: false, title: "我的", icon: "user" },
]);

View File

@@ -33,9 +33,7 @@
"style": {
"navigationBarTitleText": "工作台"
},
"meta": {
"requireAuth": true
}
"layout": "tabbar"
},
{
"path": "pages/mine/about/index",
@@ -72,6 +70,46 @@
"navigationBarTitleText": "设置"
}
},
{
"path": "pages/work/config/index",
"type": "page",
"name": "config",
"style": {
"navigationBarTitleText": "系统配置"
}
},
{
"path": "pages/work/log/index",
"type": "page",
"name": "log",
"style": {
"navigationBarTitleText": "系统日志"
}
},
{
"path": "pages/work/notice/index",
"type": "page",
"name": "notice",
"style": {
"navigationBarTitleText": "通知公告"
}
},
{
"path": "pages/work/role/index",
"type": "page",
"name": "role",
"style": {
"navigationBarTitleText": "角色管理"
}
},
{
"path": "pages/work/user/index",
"type": "page",
"name": "user",
"style": {
"navigationBarTitleText": "用户管理"
}
},
{
"path": "pages/mine/settings/account/index",
"type": "page"
@@ -88,6 +126,14 @@
"path": "pages/mine/settings/network/index",
"type": "page"
},
{
"path": "pages/mine/settings/privacy/index",
"type": "page",
"name": "privacy",
"style": {
"navigationBarTitleText": "隐私政策"
}
},
{
"path": "pages/mine/settings/theme/index",
"type": "page",
@@ -123,6 +169,9 @@
{
"pagePath": "pages/index/index"
},
{
"pagePath": "pages/work/index"
},
{
"pagePath": "pages/mine/index"
}

View File

@@ -94,10 +94,16 @@
<!-- 底部协议 -->
<view class="login-agreement">
<text class="login-agreement__text">登录即同意</text>
<text class="login-agreement__link" @click="navigateToUserAgreement">用户协议</text>
<text class="login-agreement__text"></text>
<text class="login-agreement__link" @click="navigateToPrivacy">隐私政策</text>
<wd-checkbox v-model="isAgreePolicy" shape="square" size="16px">
<view class="login-agreement__content">
<text class="login-agreement__text">我已阅读并同意</text>
<text class="login-agreement__link" @click.stop="navigateToUserAgreement">
用户协议
</text>
<text class="login-agreement__text"></text>
<text class="login-agreement__link" @click.stop="navigateToPrivacy">隐私政策</text>
</view>
</wd-checkbox>
</view>
</view>
@@ -125,6 +131,7 @@ const loading = ref(false);
const userStore = useUserStore();
const showPassword = ref(false);
const loginType = ref<"account" | "phone">("account");
const isAgreePolicy = ref(false); // 是否同意隐私协议
const { authState, getLoginCode, getPhoneNumber } = useWechat();
// 登录表单数据
@@ -142,21 +149,16 @@ onLoad((options) => {
}
});
// 强制清除输入框背景色
onMounted(() => {
setTimeout(() => {
const inputs = document.querySelectorAll("input");
inputs.forEach((input) => {
input.style.backgroundColor = "transparent";
input.style.boxShadow = "none";
});
}, 100);
});
// 账号密码登录处理
const handleAccountLogin = () => {
if (loading.value) return;
// 检查是否同意隐私协议
if (!isAgreePolicy.value) {
toast.error("请先阅读并同意用户协议和隐私政策");
return;
}
// 表单验证
if (!loginFormData.value.username) {
toast.error("请输入用户名");
@@ -193,6 +195,13 @@ const handleAccountLogin = () => {
// 微信一键登录(通过手机号)
const handleWechatPhoneLogin = async (e: any) => {
if (loading.value || authState.value.isLogining) return;
// 检查是否同意隐私协议
if (!isAgreePolicy.value) {
toast.error("请先阅读并同意用户协议和隐私政策");
return;
}
loading.value = true;
try {
@@ -234,6 +243,13 @@ const handleWechatPhoneLogin = async (e: any) => {
// 微信授权登录处理
const handleWechatLogin = async () => {
if (loading.value) return;
// 检查是否同意隐私协议
if (!isAgreePolicy.value) {
toast.error("请先阅读并同意用户协议和隐私政策");
return;
}
loading.value = true;
try {
@@ -313,8 +329,8 @@ const navigateToPrivacy = () => {
.login-card {
position: relative;
z-index: 2;
width: 80%;
max-width: 600rpx; // 限制最大宽度
width: 85%; // 移动端保持两边边距
max-width: 420px; // 桌面端最大宽度
padding: 50rpx 40rpx;
background-color: var(--wot-color-bg);
border: 1rpx solid var(--wot-color-border);
@@ -452,16 +468,29 @@ const navigateToPrivacy = () => {
// 登录协议
.login-agreement {
display: flex;
align-items: flex-start;
justify-content: center;
margin-top: 60rpx;
font-size: 24rpx;
:deep(.wd-checkbox) {
align-items: flex-start;
}
&__content {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
line-height: 1.6;
}
&__text {
color: var(--wot-color-text-secondary);
}
&__link {
color: var(--wot-color-theme);
text-decoration: underline;
}
}
</style>

View File

@@ -0,0 +1,94 @@
<template>
<view class="page-container dark:text-[var(--wot-color-text)]">
<wd-collapse v-model="activeNames" accordion>
<wd-collapse-item
v-for="(section, index) in privacyContent"
:key="index"
:title="section.title"
:name="String(index)"
>
<view class="py-3 px-4">
<text class="text-base leading-relaxed text-gray-600">{{ section.content }}</text>
</view>
</wd-collapse-item>
</wd-collapse>
<view class="mt-6 px-4">
<wd-button type="primary" block @click="handleAgree">我已阅读并同意</wd-button>
</view>
</view>
</template>
<script lang="ts" setup>
const activeNames = ref(["0"]); // 默认展开第一项
const privacyContent = [
{
title: "1. 引言",
content:
"我们非常重视用户的隐私权,特制定本《隐私政策》。本政策旨在向您说明我们如何收集、使用、存储和保护您的个人信息,以及您所享有的权利。请您仔细阅读本政策,了解我们对您个人信息的处理规则。",
},
{
title: "2. 我们收集的信息",
content:
"为了向您提供服务,我们可能会收集以下信息:(1)您主动提供的信息:如注册时提供的账号、昵称、头像等;(2)我们在您使用服务过程中收集的信息:如设备信息、日志信息等;(3)经您授权的第三方共享的信息。我们承诺,所有信息的收集均基于合法、正当、必要的原则。",
},
{
title: "3. 我们如何使用您的信息",
content:
"我们会将收集到的信息用于以下用途:(1)向您提供、维护、改进我们的服务;(2)回应您的请求,处理您的订单;(3)向您推送通知、更新等重要信息;(4)进行数据分析,以改进产品性能和用户体验;(5)保障服务安全,防止欺诈。我们不会将您的信息用于本政策未载明的其他用途。",
},
{
title: "4. 我们如何共享、转让、公开披露您的信息",
content:
"我们不会与任何公司、组织和个人共享您的个人信息,除非:(1)事先获得您的明确同意;(2)根据法律法规或政府的强制性规定;(3)与我们的关联公司共享(我们会要求其遵守本隐私政策);(4)与我们的合作伙伴共享(仅为实现本政策所述目的,且受严格的数据保护协议约束)。",
},
{
title: "5. 我们如何保护您的信息",
content:
"我们非常重视个人信息安全,采取了符合业界标准的安全措施来保护您的信息:(1)采用加密技术对信息传输和存储进行保护;(2)建立严格的数据访问权限控制和监控机制;(3)对员工进行数据安全培训;(4)定期进行安全审计。但请理解,由于技术限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全。",
},
{
title: "6. 您的权利",
content:
"您对自己的个人信息享有以下权利:(1)访问权:您有权访问您的个人信息;(2)更正权:发现信息有误时,您有权要求我们更正;(3)删除权:在特定情形下,您有权要求我们删除您的个人信息;(4)撤回同意权:您可以撤回您此前做出的授权同意;(5)注销账户权:您有权注销您的账户。如需行使上述权利,请联系我们。",
},
{
title: "7. 未成年人保护",
content:
"我们非常重视对未成年人个人信息的保护。若您是未满18周岁的未成年人在使用我们的服务前应确保事先取得监护人的同意。对于经监护人同意使用我们服务的未成年人我们只会在法律允许、监护人明确同意或保护未成年人所必需的情况下使用、共享或披露此信息。",
},
{
title: "8. 隐私政策的修改",
content:
"我们可能会不时修改本隐私政策。对于重大变更,我们会通过显著方式向您告知(包括但不限于推送通知、弹窗提示等)。未经您明确同意,我们不会削减您依据本隐私政策所应享有的权利。本政策所指的重大变更包括但不限于:服务模式的重大变化、个人信息使用目的的变更等。",
},
{
title: "9. 联系我们",
content:
"如果您对本隐私政策有任何疑问、意见或建议或在使用我们的服务过程中遇到任何与个人信息保护相关的问题欢迎通过以下方式与我们联系。我们将在15个工作日内回复您的请求。",
},
];
// 同意隐私政策
const handleAgree = () => {
uni.showToast({
title: "感谢您的支持",
icon: "success",
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
};
</script>
<route lang="json">
{
"name": "privacy",
"style": {
"navigationBarTitleText": "隐私政策"
}
}
</route>
<style lang="scss" scoped></style>

View File

@@ -1,11 +1,11 @@
<template>
<view class="page-container work">
<view class="work">
<template v-for="(item, index) in gridList" :key="index">
<wd-card :title="item.title">
<wd-grid clickable :column="4">
<wd-grid-item
v-for="(child, index) in item.children"
:key="index"
v-for="(child, childIndex) in item.children"
:key="childIndex"
:v-has-perm="child.prem"
use-slot
@click="handleNavClick(child)"

View File

@@ -14,15 +14,21 @@ interface NavigateToOptions {
"/pages/mine/profile/complete-profile" |
"/pages/mine/profile/index" |
"/pages/mine/settings/index" |
"/pages/work/config/index" |
"/pages/work/log/index" |
"/pages/work/notice/index" |
"/pages/work/role/index" |
"/pages/work/user/index" |
"/pages/mine/settings/account/index" |
"/pages/mine/settings/agreement/index" |
"/pages/mine/settings/network/index" |
"/pages/mine/settings/privacy/index" |
"/pages/mine/settings/theme/index";
}
interface RedirectToOptions extends NavigateToOptions {}
interface SwitchTabOptions {
url: "/pages/index/index" | "/pages/mine/index"
url: "/pages/index/index" | "/pages/work/index" | "/pages/mine/index"
}
type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;