first commit

This commit is contained in:
2025-10-27 23:13:08 +08:00
commit 476c5e7658
2968 changed files with 49547 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useAuthStore = defineStore('auth', () => {
// 状态
const userInfo = ref(null)
const token = ref(null)
const isLoggedIn = ref(false)
// 计算属性
const isAuthenticated = computed(() => {
return isLoggedIn.value && token.value && userInfo.value
})
// 登录
const login = (userData, authToken) => {
userInfo.value = userData
token.value = authToken
isLoggedIn.value = true
// 保存到本地存储
uni.setStorageSync('userInfo', userData)
uni.setStorageSync('token', authToken)
uni.setStorageSync('isLoggedIn', true)
}
// 登出
const logout = () => {
userInfo.value = null
token.value = null
isLoggedIn.value = false
// 清除本地存储
uni.removeStorageSync('userInfo')
uni.removeStorageSync('token')
uni.removeStorageSync('isLoggedIn')
console.log('用户已登出')
}
// 初始化认证状态(从本地存储恢复)
const initAuth = () => {
try {
const savedUserInfo = uni.getStorageSync('userInfo')
const savedToken = uni.getStorageSync('token')
const savedIsLoggedIn = uni.getStorageSync('isLoggedIn')
if (savedUserInfo && savedToken && savedIsLoggedIn) {
userInfo.value = savedUserInfo
token.value = savedToken
isLoggedIn.value = savedIsLoggedIn
console.log('从本地存储恢复用户状态')
}
} catch (error) {
console.error('初始化认证状态失败:', error)
}
}
// 检查登录状态
const checkAuth = () => {
return isAuthenticated.value
}
// 更新用户信息
const updateUserInfo = (newUserInfo) => {
userInfo.value = { ...userInfo.value, ...newUserInfo }
uni.setStorageSync('userInfo', userInfo.value)
}
return {
// 状态
userInfo,
token,
isLoggedIn,
// 计算属性
isAuthenticated,
// 方法
login,
logout,
initAuth,
checkAuth,
updateUserInfo
}
})
+276
View File
@@ -0,0 +1,276 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useTaskStore = defineStore('task', () => {
// 状态
const tasks = ref([])
const currentFilter = ref('all') // all, pending, completed, overdue
const currentSort = ref('dueDate') // dueDate, priority, created
const searchKeyword = ref('')
// 计算属性
const filteredTasks = computed(() => {
let filtered = tasks.value
// 按状态过滤
if (currentFilter.value === 'pending') {
filtered = filtered.filter(task => !task.completed)
} else if (currentFilter.value === 'completed') {
filtered = filtered.filter(task => task.completed)
} else if (currentFilter.value === 'overdue') {
const now = new Date()
filtered = filtered.filter(task =>
!task.completed &&
task.dueDate &&
new Date(task.dueDate) < now
)
}
// 按关键词搜索
if (searchKeyword.value) {
const keyword = searchKeyword.value.toLowerCase()
filtered = filtered.filter(task =>
task.title.toLowerCase().includes(keyword) ||
task.description.toLowerCase().includes(keyword) ||
task.tags.some(tag => tag.toLowerCase().includes(keyword))
)
}
// 排序
filtered.sort((a, b) => {
switch (currentSort.value) {
case 'priority':
const priorityOrder = { high: 3, medium: 2, low: 1 }
return (priorityOrder[b.priority] || 0) - (priorityOrder[a.priority] || 0)
case 'created':
return new Date(b.createdAt) - new Date(a.createdAt)
case 'dueDate':
default:
if (!a.dueDate && !b.dueDate) return 0
if (!a.dueDate) return 1
if (!b.dueDate) return -1
return new Date(a.dueDate) - new Date(b.dueDate)
}
})
return filtered
})
const taskStats = computed(() => {
const total = tasks.value.length
const completed = tasks.value.filter(task => task.completed).length
const pending = total - completed
const overdue = tasks.value.filter(task =>
!task.completed &&
task.dueDate &&
new Date(task.dueDate) < new Date()
).length
return {
total,
completed,
pending,
overdue,
completionRate: total > 0 ? Math.round((completed / total) * 100) : 0
}
})
// 方法
const addTask = (taskData) => {
const newTask = {
id: Date.now().toString(),
title: taskData.title,
description: taskData.description || '',
priority: taskData.priority || 'medium',
dueDate: taskData.dueDate || null,
tags: taskData.tags || [],
completed: false,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
}
tasks.value.unshift(newTask)
saveToStorage()
return newTask
}
const updateTask = (id, updates) => {
const index = tasks.value.findIndex(task => task.id === id)
if (index !== -1) {
tasks.value[index] = {
...tasks.value[index],
...updates,
updatedAt: new Date().toISOString()
}
saveToStorage()
return tasks.value[index]
}
return null
}
const deleteTask = (id) => {
const index = tasks.value.findIndex(task => task.id === id)
if (index !== -1) {
tasks.value.splice(index, 1)
saveToStorage()
return true
}
return false
}
const toggleTask = (id) => {
const task = tasks.value.find(task => task.id === id)
if (task) {
task.completed = !task.completed
task.updatedAt = new Date().toISOString()
saveToStorage()
return task
}
return null
}
const setFilter = (filter) => {
currentFilter.value = filter
}
const setSort = (sort) => {
currentSort.value = sort
}
const setSearchKeyword = (keyword) => {
searchKeyword.value = keyword
}
const clearCompleted = () => {
tasks.value = tasks.value.filter(task => !task.completed)
saveToStorage()
}
const getTaskById = (id) => {
return tasks.value.find(task => task.id === id)
}
const getTasksByTag = (tag) => {
return tasks.value.filter(task => task.tags.includes(tag))
}
const getOverdueTasks = () => {
const now = new Date()
return tasks.value.filter(task =>
!task.completed &&
task.dueDate &&
new Date(task.dueDate) < now
)
}
const getTodayTasks = () => {
const today = new Date().toDateString()
return tasks.value.filter(task =>
!task.completed &&
task.dueDate &&
new Date(task.dueDate).toDateString() === today
)
}
// 本地存储
const saveToStorage = () => {
try {
uni.setStorageSync('tasks', JSON.stringify(tasks.value))
} catch (error) {
console.error('保存任务数据失败:', error)
}
}
const loadFromStorage = () => {
try {
const stored = uni.getStorageSync('tasks')
if (stored) {
tasks.value = JSON.parse(stored)
}
} catch (error) {
console.error('加载任务数据失败:', error)
}
}
// 初始化示例数据
const initSampleData = () => {
if (tasks.value.length === 0) {
const sampleTasks = [
{
id: '1',
title: '完成项目需求分析',
description: '分析用户需求,制定详细的功能规格说明',
priority: 'high',
dueDate: new Date(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString(),
tags: ['工作', '项目'],
completed: false,
createdAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),
updatedAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString()
},
{
id: '2',
title: '准备会议材料',
description: '准备下周团队会议的PPT和资料',
priority: 'medium',
dueDate: new Date(Date.now() + 1 * 24 * 60 * 60 * 1000).toISOString(),
tags: ['工作', '会议'],
completed: false,
createdAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
updatedAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString()
},
{
id: '3',
title: '购买生活用品',
description: '去超市购买日用品和食材',
priority: 'low',
dueDate: null,
tags: ['生活', '购物'],
completed: true,
createdAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(),
updatedAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString()
},
{
id: '4',
title: '学习新技术',
description: '学习Vue 3和Pinia状态管理',
priority: 'medium',
dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
tags: ['学习', '技术'],
completed: false,
createdAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
updatedAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString()
}
]
tasks.value = sampleTasks
saveToStorage()
}
}
return {
// 状态
tasks,
currentFilter,
currentSort,
searchKeyword,
// 计算属性
filteredTasks,
taskStats,
// 方法
addTask,
updateTask,
deleteTask,
toggleTask,
setFilter,
setSort,
setSearchKeyword,
clearCompleted,
getTaskById,
getTasksByTag,
getOverdueTasks,
getTodayTasks,
loadFromStorage,
initSampleData
}
})
+205
View File
@@ -0,0 +1,205 @@
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
// 用户基本信息
userInfo: {
name: '张三',
avatar: '/static/avatar/user.png',
department: '技术部',
employeeId: 'EMP001',
position: '高级工程师',
phone: '138****8888',
email: 'zhangsan@company.com'
},
// 登录状态
token: '',
isLoggedIn: true,
// 用户权限
permissions: [
'attendance:view',
'attendance:checkin',
'leave:apply',
'leave:view',
'reimbursement:apply',
'reimbursement:view',
'task:view',
'task:create',
'meeting:book',
'customer:view',
'file:view'
],
// 用户设置
settings: {
theme: 'light', // light, dark, auto
messageEnabled: true,
nightMode: false,
language: 'zh-CN'
},
// 工作数据
workData: {
attendanceRate: 98,
completedTasks: 15,
pendingTasks: 3,
pendingApproval: 2,
pendingAmount: 2580,
thisMonthLeave: 2,
thisMonthOvertime: 8
},
// 最近使用功能
recentFunctions: [
{ icon: 'calendar', color: '#FF6B6B', label: '请假', action: 'leave' },
{ icon: 'rmb-circle', color: '#4ECDC4', label: '报销', action: 'reimbursement' },
{ icon: 'clock', color: '#45B7D1', label: '打卡', action: 'checkin' }
],
// 快捷操作配置
quickActions: [
{ icon: 'calendar', color: '#FF6B6B', label: '请假', action: 'leave' },
{ icon: 'rmb-circle', color: '#4ECDC4', label: '报销', action: 'reimbursement' },
{ icon: 'clock', color: '#45B7D1', label: '打卡', action: 'checkin' },
{ icon: 'calendar', color: '#96CEB4', label: '会议', action: 'meeting' },
{ icon: 'account', color: '#FECA57', label: '客户', action: 'customer' }
]
}),
getters: {
// 获取用户显示名称
getUserName: (state) => state.userInfo?.name || '未登录用户',
// 获取用户头像
getUserAvatar: (state) => state.userInfo?.avatar || '/static/avatar/default.png',
// 获取用户部门
getUserDepartment: (state) => state.userInfo?.department || '',
// 检查是否有特定权限
hasPermission: (state) => (permission) => {
return state.permissions.includes(permission)
},
// 获取工作数据概览
getWorkOverview: (state) => ({
attendanceRate: state.workData.attendanceRate,
completedTasks: state.workData.completedTasks,
pendingTasks: state.workData.pendingTasks,
pendingApproval: state.workData.pendingApproval,
pendingAmount: state.workData.pendingAmount
}),
// 获取当前主题
getCurrentTheme: (state) => state.settings.theme,
// 获取消息设置
getMessageSettings: (state) => ({
enabled: state.settings.messageEnabled,
nightMode: state.settings.nightMode
})
},
actions: {
// 设置用户信息
setUserInfo(info) {
this.userInfo = { ...this.userInfo, ...info }
this.isLoggedIn = true
},
// 设置token
setToken(token) {
this.token = token
},
// 更新用户设置
updateSettings(settings) {
this.settings = { ...this.settings, ...settings }
},
// 更新工作数据
updateWorkData(data) {
this.workData = { ...this.workData, ...data }
},
// 添加最近使用功能
addRecentFunction(func) {
const existingIndex = this.recentFunctions.findIndex(item => item.action === func.action)
if (existingIndex > -1) {
this.recentFunctions.splice(existingIndex, 1)
}
this.recentFunctions.unshift(func)
if (this.recentFunctions.length > 5) {
this.recentFunctions.pop()
}
},
// 更新快捷操作
updateQuickActions(actions) {
this.quickActions = actions
},
// 添加权限
addPermission(permission) {
if (!this.permissions.includes(permission)) {
this.permissions.push(permission)
}
},
// 移除权限
removePermission(permission) {
const index = this.permissions.indexOf(permission)
if (index > -1) {
this.permissions.splice(index, 1)
}
},
// 登出
logout() {
this.userInfo = {
name: '',
avatar: '',
department: '',
employeeId: '',
position: '',
phone: '',
email: ''
}
this.token = ''
this.isLoggedIn = false
this.permissions = []
this.workData = {
attendanceRate: 0,
completedTasks: 0,
pendingTasks: 0,
pendingApproval: 0,
pendingAmount: 0,
thisMonthLeave: 0,
thisMonthOvertime: 0
}
this.recentFunctions = []
this.quickActions = []
},
// 重置设置
resetSettings() {
this.settings = {
theme: 'light',
messageEnabled: true,
nightMode: false,
language: 'zh-CN'
}
}
},
persist: {
key: 'user-store',
storage: {
getItem: (key) => uni.getStorageSync(key),
setItem: (key, value) => uni.setStorageSync(key, value),
removeItem: (key) => uni.removeStorageSync(key)
}
}
})