diff --git a/backend/main.py b/backend/main.py
index 4fa4148..9ac83ce 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -1420,11 +1420,15 @@ def get_notifications(user=Depends(get_current_user)):
if not user["id"]:
return []
conn = get_db()
+ # Only show notifications created after user registration
+ user_created = conn.execute("SELECT created_at FROM users WHERE id = ?", (user["id"],)).fetchone()
+ created_at = user_created["created_at"] if user_created else "2000-01-01"
rows = conn.execute(
"SELECT id, title, body, is_read, created_at FROM notifications "
"WHERE (target_user_id = ? OR (target_user_id IS NULL AND (target_role = ? OR target_role = 'all'))) "
+ "AND created_at >= ? "
"ORDER BY is_read ASC, id DESC LIMIT 200",
- (user["id"], user["role"])
+ (user["id"], user["role"], created_at)
).fetchall()
conn.close()
return [dict(r) for r in rows]
diff --git a/frontend/src/views/MyDiary.vue b/frontend/src/views/MyDiary.vue
index bd00166..a9632eb 100644
--- a/frontend/src/views/MyDiary.vue
+++ b/frontend/src/views/MyDiary.vue
@@ -241,18 +241,57 @@
-
+
💼 商业认证
-
申请商业认证后可使用商业核算功能。
-
-
-
💼 商业认证
-
✅ 已认证商业用户
+
+
+
+
+
⏳
+
认证申请审核中
+
商户名:{{ bizApp.business_name }}
+
提交时间:{{ formatDate(bizApp.created_at) }}
+
+
+
+
+
+
+
❌
+
认证申请未通过
+
原因:{{ bizApp.reject_reason }}
+
+ 你可以修改信息后重新申请。
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 申请商业认证后可使用商业核算功能,请填写以下信息。
+
+
+
+
+
+
+
+
+
+
@@ -300,13 +339,20 @@ const displayName = ref('')
const oldPassword = ref('')
const newPassword = ref('')
const confirmPassword = ref('')
+const businessName = ref('')
const businessReason = ref('')
+const bizApp = ref({ status: null })
onMounted(async () => {
await diaryStore.loadDiary()
displayName.value = auth.user.display_name || ''
await loadBrandSettings()
returnRecipeId.value = localStorage.getItem('oil_return_recipe_id') || null
+ // Load business application status
+ try {
+ const bizRes = await api('/api/my-business-application')
+ if (bizRes.ok) bizApp.value = await bizRes.json()
+ } catch {}
// 从商业核算跳转过来,滚到商业认证区域
if (route.query.section === 'biz-cert') {
await nextTick()
@@ -623,13 +669,30 @@ async function changePassword() {
}
async function applyBusiness() {
+ if (!businessName.value.trim()) {
+ ui.showToast('请填写商户名称')
+ return
+ }
try {
- await api('/api/business-apply', {
+ const res = await api('/api/business-apply', {
method: 'POST',
- body: JSON.stringify({ reason: businessReason.value }),
+ body: JSON.stringify({
+ business_name: businessName.value.trim(),
+ document: businessReason.value.trim(),
+ }),
})
- businessReason.value = ''
- ui.showToast('申请已提交,请等待审核')
+ if (res.ok) {
+ businessName.value = ''
+ businessReason.value = ''
+ bizApp.value = { status: 'pending', business_name: businessName.value }
+ ui.showToast('申请已提交,请等待管理员审核')
+ // Reload status
+ const bizRes = await api('/api/my-business-application')
+ if (bizRes.ok) bizApp.value = await bizRes.json()
+ } else {
+ const err = await res.json().catch(() => ({}))
+ ui.showToast(err.detail || '提交失败')
+ }
} catch {
ui.showToast('提交失败')
}
@@ -1084,6 +1147,20 @@ async function applyBusiness() {
text-align: center;
}
+.biz-status {
+ padding: 16px;
+ border-radius: 12px;
+ text-align: center;
+ margin-bottom: 12px;
+}
+.biz-status-icon { font-size: 32px; margin-bottom: 8px; }
+.biz-status-text { font-size: 15px; font-weight: 600; margin-bottom: 4px; }
+.biz-status-detail { font-size: 12px; color: #999; }
+.biz-approved { background: #e8f5e9; color: #2e7d5a; }
+.biz-pending { background: #fff8e1; color: #e65100; }
+.biz-rejected { background: #fce4ec; color: #c62828; }
+.biz-reject-reason { font-size: 13px; margin-top: 8px; padding: 8px 12px; background: rgba(0,0,0,0.05); border-radius: 8px; }
+
/* Buttons */
.btn-primary {
background: linear-gradient(135deg, #7ec6a4 0%, #4a9d7e 100%);
diff --git a/frontend/src/views/UserManagement.vue b/frontend/src/views/UserManagement.vue
index 0709927..e299dbd 100644
--- a/frontend/src/views/UserManagement.vue
+++ b/frontend/src/views/UserManagement.vue
@@ -27,8 +27,8 @@
- {{ app.user_name || app.display_name }}
- {{ app.reason }}
+ {{ app.display_name || app.username }}
+ 商户名:{{ app.business_name }}
@@ -101,7 +101,7 @@ import { ref, computed, onMounted } from 'vue'
import { useAuthStore } from '../stores/auth'
import { useUiStore } from '../stores/ui'
import { api } from '../composables/useApi'
-import { showConfirm } from '../composables/useDialog'
+import { showConfirm, showPrompt } from '../composables/useDialog'
const auth = useAuthStore()
const ui = useUiStore()
@@ -248,8 +248,13 @@ async function approveBusiness(app) {
async function rejectBusiness(app) {
const id = app._id || app.id
+ const reason = await showPrompt('请输入拒绝原因(选填):')
+ if (reason === null) return
try {
- const res = await api(`/api/business-applications/${id}/reject`, { method: 'POST' })
+ const res = await api(`/api/business-applications/${id}/reject`, {
+ method: 'POST',
+ body: JSON.stringify({ reason: reason || '' }),
+ })
if (res.ok) {
businessApps.value = businessApps.value.filter(item => (item._id || item.id) !== id)
ui.showToast('已拒绝')