diff --git a/client/src/api/admin.ts b/client/src/api/admin.ts index 7950be3..73e5a38 100644 --- a/client/src/api/admin.ts +++ b/client/src/api/admin.ts @@ -10,6 +10,10 @@ export interface Dashboard { growthPercent: number lastMonthTxCount: number lastMonthTxAmount: number + monthlyExpense?: number + monthlyIncome?: number + lastMonthExpense?: number + lastMonthIncome?: number } /** 用户信息(管理员视角) */ diff --git a/client/src/api/auth.ts b/client/src/api/auth.ts index fa6adc3..ea02ca2 100644 --- a/client/src/api/auth.ts +++ b/client/src/api/auth.ts @@ -6,6 +6,7 @@ export interface LoginResult { userId: number nickname: string avatar_url: string + role?: string } /** H5 演示登录 */ diff --git a/client/src/api/budget.ts b/client/src/api/budget.ts index 8cb4966..18725b3 100644 --- a/client/src/api/budget.ts +++ b/client/src/api/budget.ts @@ -15,5 +15,5 @@ export function getBudget(month?: string, group_id?: number | null) { /** 设置预算 */ export function setBudget(amount: number, month: string) { - return request<{ id: number }>({ url: '/budget', method: 'POST', data: { amount, month } }) + return request({ url: '/budget', method: 'POST', data: { amount, month } }) } diff --git a/client/src/api/notification.ts b/client/src/api/notification.ts index f8d9f51..dac0ef5 100644 --- a/client/src/api/notification.ts +++ b/client/src/api/notification.ts @@ -1,4 +1,5 @@ import { request } from '@/utils/request' +import { API_BASE } from '@/config' /** 通知 */ export interface Notification { @@ -64,6 +65,42 @@ export function markAllRead() { return request({ url: '/notifications/read-all', method: 'PUT' }) } +/** 上传通知图片(返回文件名) */ +export function uploadNotificationImage(filePath: string): Promise<{ image_url: string }> { + return new Promise((resolve, reject) => { + const token = uni.getStorageSync('xc:token') + uni.uploadFile({ + url: `${API_BASE}/notifications/upload-image`, + filePath, + name: 'file', + header: { + ...(token ? { Authorization: `Bearer ${token}` } : {}) + }, + success: (res) => { + try { + const data = JSON.parse(res.data) + if (data.code === 0) { + resolve(data.data) + } else { + reject(data) + } + } catch { + reject({ message: '上传失败' }) + } + }, + fail: () => reject({ message: '网络错误' }) + }) + }) +} + +/** 获取通知图片完整 URL */ +export function getNotificationImageUrl(filename: string): string { + if (!filename) return '' + // 如果已经是完整 URL 或 blob URL,直接返回 + if (filename.startsWith('http') || filename.startsWith('blob:')) return filename + return `${API_BASE}/notifications/image/${filename}` +} + /** 发布公告 */ export function publishNotification(data: PublishParams) { return request<{ id: number }>({ url: '/notifications', method: 'POST', data }) diff --git a/client/src/components/Numpad/Numpad.vue b/client/src/components/Numpad/Numpad.vue index 588397d..1b820ab 100644 --- a/client/src/components/Numpad/Numpad.vue +++ b/client/src/components/Numpad/Numpad.vue @@ -90,40 +90,42 @@ function onConfirm() { diff --git a/client/src/pages/admin/notifications/index.vue b/client/src/pages/admin/notifications/index.vue new file mode 100644 index 0000000..2964df7 --- /dev/null +++ b/client/src/pages/admin/notifications/index.vue @@ -0,0 +1,822 @@ +