diff --git a/backend/src/main/java/com/flower/confession/ConfessionController.java b/backend/src/main/java/com/flower/confession/ConfessionController.java
index f3cd73f..1e475ef 100644
--- a/backend/src/main/java/com/flower/confession/ConfessionController.java
+++ b/backend/src/main/java/com/flower/confession/ConfessionController.java
@@ -1,4 +1,4 @@
-package com.flower.confession;
+package com.flower.confession;
import com.flower.common.ApiException;
import com.flower.common.ApiResponse;
@@ -41,6 +41,7 @@ public class ConfessionController {
if (!order.getUserId().equals(AuthContext.get().getId())) {
throw new ApiException(403, "无权限");
}
+ ensureOrderPaid(order);
Confession confession = new Confession();
confession.setOrderId(order.getId());
confession.setUserId(order.getUserId());
@@ -68,6 +69,9 @@ public class ConfessionController {
if (!confession.getUserId().equals(AuthContext.get().getId())) {
throw new ApiException(403, "无权限");
}
+ Order order = orderRepository.findById(confession.getOrderId())
+ .orElseThrow(() -> new ApiException(404, "订单不存在"));
+ ensureOrderPaid(order);
confession.setTitle(request.getTitle());
confession.setMessage(request.getMessage());
confession.setImageUrl(request.getImageUrl());
@@ -122,4 +126,11 @@ public class ConfessionController {
private String sender;
private String content;
}
+
+ private void ensureOrderPaid(Order order) {
+ String status = order.getStatus();
+ if (!"PAID".equals(status) && !"SHIPPED".equals(status) && !"COMPLETED".equals(status)) {
+ throw new ApiException(400, "请至少支付后再定制告白");
+ }
+ }
}
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index 20b3ea0..d0e759e 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -17,19 +17,25 @@ import AdminReviews from '../views/admin/AdminReviews.vue';
Vue.use(Router);
+const originalPush = Router.prototype.push;
+Router.prototype.push = function push(location) {
+ return originalPush.call(this, location).catch((err) => err);
+};
+
const router = new Router({
routes: [
{ path: '/', component: Home },
- { path: '/product/:id', component: ProductDetail },
+ { path: '/product/:id', component: ProductDetail, meta: { requiresAuth: true } },
{ path: '/login', component: Login },
{ path: '/register', component: Register },
- { path: '/orders', component: Orders },
- { path: '/profile', component: Profile },
- { path: '/confession/create/:orderId', component: ConfessionCreate },
+ { path: '/orders', component: Orders, meta: { requiresAuth: true } },
+ { path: '/profile', component: Profile, meta: { requiresAuth: true } },
+ { path: '/confession/create/:orderId', component: ConfessionCreate, meta: { requiresAuth: true } },
{ path: '/gift/:code', component: GiftPage },
{
path: '/admin',
component: AdminLayout,
+ meta: { requiresAuth: true },
children: [
{ path: '', component: AdminDashboard },
{ path: 'products', component: AdminProducts },
@@ -41,4 +47,15 @@ const router = new Router({
]
});
+router.beforeEach((to, from, next) => {
+ if (to.matched.some((record) => record.meta.requiresAuth)) {
+ const token = localStorage.getItem('token');
+ if (!token) {
+ next({ path: '/login', query: { redirect: to.fullPath } });
+ return;
+ }
+ }
+ next();
+});
+
export default router;
diff --git a/frontend/src/views/ConfessionCreate.vue b/frontend/src/views/ConfessionCreate.vue
index c121938..300aaef 100644
--- a/frontend/src/views/ConfessionCreate.vue
+++ b/frontend/src/views/ConfessionCreate.vue
@@ -37,7 +37,10 @@