-
{{ category }}
-
{{ title }}
-
-
${{ price }}
-
1 × ${{ price }}
+
+
+
+
+
+
![]()
+
+
+
+
{{ item.ProductName }}
+
+
+
¥{{ item.PriceAtAddition.toFixed(2) }}
+
+
+ –
+ {{ item.Quantity }}
+ +
+
+
¥{{ subtotal }}
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+}
+
+
+
diff --git a/src/frontend/src/components/cards/category_card.vue b/src/frontend/src/components/cards/category_card.vue
index 2dfcec1..e1ccc43 100644
--- a/src/frontend/src/components/cards/category_card.vue
+++ b/src/frontend/src/components/cards/category_card.vue
@@ -1,5 +1,5 @@
-
+
{{ name }}
{{ price }}
diff --git a/src/frontend/src/components/cards/order_info_card.vue b/src/frontend/src/components/cards/order_info_card.vue
index b814264..7e06add 100644
--- a/src/frontend/src/components/cards/order_info_card.vue
+++ b/src/frontend/src/components/cards/order_info_card.vue
@@ -5,53 +5,97 @@
from {{ date }}
-
-
Items
-
{{ items }}
+
+
+ 收件人
+ {{ recipient }}
+
+
+ 联系电话
+ {{ phone }}
+
+
+ 配送地址
+ {{ shipping }}
+
+
+ 支付状态
+ {{ payment }}
+
+
+ 备注
+ {{ notes }}
+
-
- Shipping
- {{ shipping }}
-
-
- Payment
- {{ payment }}
-
-
- Total
- ${{ total.toFixed(2) }}
-
-
-
Status
-
- {{ status }}
-
+
+
订单商品 (共{{ itemCount }}件)
+
+
+
+
+
+
+
+
+ 无图片
+
+
+
{{ scope.row.ProductNameAtPurchase }}
+
+
+
+
+
+ ¥{{ parseFloat(scope.row.PriceAtPurchase).toFixed(2) }}
+
+
+
+
+
+ ¥{{ parseFloat(scope.row.Subtotal).toFixed(2) }}
+
+
+
+
+
+ 总计: ¥{{ total.toFixed(2) }}
@@ -90,4 +134,38 @@
.order-row:not(:last-child) {
border-bottom: 1px solid #f0f0f0;
}
+ .items-table {
+ margin: 16px 0;
+ }
+ .product-cell {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ }
+ .product-image {
+ width: 50px;
+ height: 50px;
+ border-radius: 4px;
+ }
+ .image-placeholder {
+ width: 50px;
+ height: 50px;
+ background: #f5f7fa;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #909399;
+ font-size: 12px;
+ }
+ .order-total {
+ text-align: right;
+ margin-top: 16px;
+ font-weight: 500;
+ font-size: 16px;
+ }
+ .price {
+ color: #f56c6c;
+ font-size: 18px;
+ margin-left: 8px;
+ }
\ No newline at end of file
diff --git a/src/frontend/src/components/cards/product_card.vue b/src/frontend/src/components/cards/product_card.vue
new file mode 100644
index 0000000..e25fb87
--- /dev/null
+++ b/src/frontend/src/components/cards/product_card.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
![]()
+
+ {{ product.ProductName }}
+
+
¥ {{ product.Price }}
+
+
+
+
diff --git a/src/frontend/src/views/Merchant_manage.vue b/src/frontend/src/components/cards/shop_card.vue
similarity index 100%
rename from src/frontend/src/views/Merchant_manage.vue
rename to src/frontend/src/components/cards/shop_card.vue
diff --git a/src/frontend/src/components/cards/store_card.vue b/src/frontend/src/components/cards/store_card.vue
new file mode 100644
index 0000000..824547d
--- /dev/null
+++ b/src/frontend/src/components/cards/store_card.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
![]()
+
+
+ {{ statusLabel }}
+
+
+
+
+
+
+
{{ truncatedDescription }}
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/cards/user_info.vue b/src/frontend/src/components/cards/user_info.vue
index 29908b1..8f78d54 100644
--- a/src/frontend/src/components/cards/user_info.vue
+++ b/src/frontend/src/components/cards/user_info.vue
@@ -13,10 +13,12 @@
-
@@ -24,7 +26,15 @@
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/OrderManage.vue b/src/frontend/src/components/dashboard/OrderManage.vue
deleted file mode 100644
index 71e1b24..0000000
--- a/src/frontend/src/components/dashboard/OrderManage.vue
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/admin/StoreChangeReviewer.vue b/src/frontend/src/components/dashboard/admin/StoreChangeReviewer.vue
new file mode 100644
index 0000000..a87a274
--- /dev/null
+++ b/src/frontend/src/components/dashboard/admin/StoreChangeReviewer.vue
@@ -0,0 +1,342 @@
+
+
+
+
+
+
+
+
+
+
+ {{ translateRequestType(row.RequestType) }}
+
+
+
+
+
+
+ {{ getStoreName(row) }}
+
+
+
+
+
+
+ {{ translateRequestStatus(row.Status) }}
+
+
+
+
+
+ {{ formatDate(row.CreationTime) }}
+
+
+
+
+ 查看详情
+
+ 审核
+
+
+
+
+
+
+
+
+
+
+ {{ selectedRequest.ChangeRequestID }}
+
+
+ {{ selectedRequest.StoreID || '新店铺申请' }}
+
+
+
+ {{ translateRequestType(selectedRequest.RequestType) }}
+
+
+
+ {{ selectedRequest.RequestingUserID }}
+
+
+
+ {{ translateRequestStatus(selectedRequest.Status) }}
+
+
+
+ {{ formatDate(selectedRequest.CreationTime) }}
+
+
+ {{ selectedRequest.ReviewTimestamp ? formatDate(selectedRequest.ReviewTimestamp) : '尚未审核' }}
+
+
+ {{ selectedRequest.AdminReviewerID || '尚未指派' }}
+
+
+ {{ selectedRequest.SubmitterNotes || '无' }}
+
+
+ {{ selectedRequest.AdminNotes || '无' }}
+
+
+ {{ formatDate(selectedRequest.LastUpdatedDate) }}
+
+
+
+
申请内容
+
+
+
+ {{ selectedRequest.ProposedData_JSON?.StoreName || '-' }}
+
+
+ {{ selectedRequest.ProposedData_JSON?.Description || '-' }}
+
+
+ {{ selectedRequest.ProposedData_JSON?.LogoURL || '-' }}
+
+
+ {{ translateStoreStatus(selectedRequest.ProposedData_JSON?.StoreStatus) || '-' }}
+
+
+
+
+
+
+ 审核决定
+
+
+
+ 通过
+ 拒绝
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/dashboard/manage/order_manage_card.vue b/src/frontend/src/components/dashboard/manage/order_manage_card.vue
deleted file mode 100644
index 56d7193..0000000
--- a/src/frontend/src/components/dashboard/manage/order_manage_card.vue
+++ /dev/null
@@ -1,211 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{ row.label }}
-
-
-
-
- {{ form.status }}
-
-
- {{ row.value }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 取消
- 保存
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/General.vue b/src/frontend/src/components/dashboard/merchant/General.vue
similarity index 100%
rename from src/frontend/src/components/dashboard/General.vue
rename to src/frontend/src/components/dashboard/merchant/General.vue
diff --git a/src/frontend/src/components/dashboard/merchant/OrderManage.vue b/src/frontend/src/components/dashboard/merchant/OrderManage.vue
new file mode 100644
index 0000000..a4f7d2a
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/OrderManage.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
订单管理
+
+
+
+
+
+ 刷新
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/StoreChangeRequests.vue b/src/frontend/src/components/dashboard/merchant/StoreChangeRequests.vue
new file mode 100644
index 0000000..164f00f
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/StoreChangeRequests.vue
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+ {{ translateRequestType(row.RequestType) }}
+
+
+
+
+
+ {{ getStoreName(row) }}
+
+
+
+
+
+ {{ translateRequestStatus(row.Status) }}
+
+
+
+
+
+ {{ formatDate(row.CreationTime) }}
+
+
+
+
+ {{ row.ReviewTimestamp ? formatDate(row.ReviewTimestamp) : '-' }}
+
+
+
+
+ 查看详情
+
+
+
+
+
+
+
+
+ {{ selectedRequest.ChangeRequestID }}
+
+
+
+ {{ translateRequestType(selectedRequest.RequestType) }}
+
+
+
+
+ {{ translateRequestStatus(selectedRequest.Status) }}
+
+
+
+ {{ formatDate(selectedRequest.CreationTime) }}
+
+
+ {{ selectedRequest.ReviewTimestamp ? formatDate(selectedRequest.ReviewTimestamp) : '尚未审核' }}
+
+
+ {{ selectedRequest.AdminReviewerID || '尚未指派' }}
+
+
+ {{ selectedRequest.SubmitterNotes || '无' }}
+
+
+ {{ selectedRequest.AdminNotes || '无' }}
+
+
+ {{ formatDate(selectedRequest.LastUpdatedDate) }}
+
+
+
+
申请内容
+
+
+
+ {{ selectedRequest.ProposedData_JSON?.StoreName || '-' }}
+
+
+ {{ selectedRequest.ProposedData_JSON?.Description || '-' }}
+
+
+ {{ selectedRequest.ProposedData_JSON?.LogoURL || '-' }}
+
+
+ {{ translateStoreStatus(selectedRequest.ProposedData_JSON?.StoreStatus) || '-' }}
+
+
+
+
+
+
+
+
+
+
+
+ 确定要删除此申请吗?此操作不可撤销。
+
+
+ 取消
+ 确认删除
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/dashboard/merchant/StoreManagement.vue b/src/frontend/src/components/dashboard/merchant/StoreManagement.vue
new file mode 100644
index 0000000..51ab98d
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/StoreManagement.vue
@@ -0,0 +1,467 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/dashboard/merchant/orderManage/OrderCard.vue b/src/frontend/src/components/dashboard/merchant/orderManage/OrderCard.vue
new file mode 100644
index 0000000..792db81
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/orderManage/OrderCard.vue
@@ -0,0 +1,240 @@
+
+
+
+
+
+
+
+
+
+
+ {{ label }}:
+ {{ order[key] }}
+
+
+
+
+
+
订单商品 ({{ order.Items.length }}件)
+
+
+
+
+
+
{{ row.ProductNameAtPurchase }}
+
+
+
+
+
+
+
+
+
+
+
+ 更新状态
+ 查看详情
+
+
+
+
+
+
+ {{ translateStatus(order.OrderStatus) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确认更新
+
+
+
+
+
+
+ {{ detail.OrderID }}
+ {{ detail.UserID }}
+ {{ detail.StoreID }}
+ {{ detail.PaymentTransactionID }}
+ {{ detail.OrderStatus }}
+ {{ detail.PaymentStatus }}
+ ¥{{ detail.OrderTotalAmount }}
+ ¥{{ detail.DiscountAmount }}
+ ¥{{ detail.ShippingFee }}
+ ¥{{ detail.FinalAmountForThisOrder }}
+ {{ formatDate(detail.CreationTime) }}
+ {{ formatDate(detail.PaymentConfirmationTime) }}
+ {{ formatDate(detail.ShippingTime) }}
+ {{ formatDate(detail.DeliveryTime) }}
+ {{ formatDate(detail.CompletionTime) }}
+ {{ formatDate(detail.LastUpdatedDate) }}
+ {{ detail.Notes_ByUser }}
+ {{ detail.Notes_ByMerchant }}
+ {{ detail.ShippingAddress_RecipientName }}
+ {{ detail.ShippingAddress_PhoneNumber }}
+ {{ detail.ShippingAddress_Full }}
+
+ 订单商品 (共{{ detail.Items.length }}件)
+
+
+
+
+
+
+
+ 关闭
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/ProductFormDialog.vue b/src/frontend/src/components/dashboard/merchant/storeManage/ProductFormDialog.vue
new file mode 100644
index 0000000..48c4df6
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/ProductFormDialog.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 保存
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/ProductListTable.vue b/src/frontend/src/components/dashboard/merchant/storeManage/ProductListTable.vue
new file mode 100644
index 0000000..a5a4097
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/ProductListTable.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ 无图片
+
+
+
+ ¥{{ row.Price }}
+
+
+ {{ translateStatus(row.ProductStatus) }}
+
+
+
+ 编辑
+ 更新库存
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/ProductManagementDialog.vue b/src/frontend/src/components/dashboard/merchant/storeManage/ProductManagementDialog.vue
new file mode 100644
index 0000000..3f10cce
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/ProductManagementDialog.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/StockDialog.vue b/src/frontend/src/components/dashboard/merchant/storeManage/StockDialog.vue
new file mode 100644
index 0000000..01c674f
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/StockDialog.vue
@@ -0,0 +1,46 @@
+
+
+
+ {{ product?.ProductName }}
+ {{ product?.StockQuantity }}
+
+
+
+ 取消
+ 确认更新
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/StoreForm.vue b/src/frontend/src/components/dashboard/merchant/storeManage/StoreForm.vue
new file mode 100644
index 0000000..b521e60
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/StoreForm.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/StoreFormDialog.vue b/src/frontend/src/components/dashboard/merchant/storeManage/StoreFormDialog.vue
new file mode 100644
index 0000000..87d4b42
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/StoreFormDialog.vue
@@ -0,0 +1,52 @@
+
+
+
+
+ 取消
+ 提交申请
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/StoreHeader.vue b/src/frontend/src/components/dashboard/merchant/storeManage/StoreHeader.vue
new file mode 100644
index 0000000..3a66d9a
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/StoreHeader.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/dashboard/merchant/storeManage/StoreListTable.vue b/src/frontend/src/components/dashboard/merchant/storeManage/StoreListTable.vue
new file mode 100644
index 0000000..b6f6b1a
--- /dev/null
+++ b/src/frontend/src/components/dashboard/merchant/storeManage/StoreListTable.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+ {{ translateStatus(row.StoreStatus) }}
+
+
+
+
+ 编辑
+ 管理商品
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/explore/FilterSidebar.vue b/src/frontend/src/components/explore/FilterSidebar.vue
new file mode 100644
index 0000000..631b8da
--- /dev/null
+++ b/src/frontend/src/components/explore/FilterSidebar.vue
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/explore/ProductGrid.vue b/src/frontend/src/components/explore/ProductGrid.vue
new file mode 100644
index 0000000..694564d
--- /dev/null
+++ b/src/frontend/src/components/explore/ProductGrid.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/components/home/CategoryList.vue b/src/frontend/src/components/home/CategoryList.vue
index 704092f..015a1db 100644
--- a/src/frontend/src/components/home/CategoryList.vue
+++ b/src/frontend/src/components/home/CategoryList.vue
@@ -1,14 +1,23 @@
diff --git a/src/frontend/src/components/home/HeroCarousel.vue b/src/frontend/src/components/home/HeroCarousel.vue
index 3dd8ef9..b091862 100644
--- a/src/frontend/src/components/home/HeroCarousel.vue
+++ b/src/frontend/src/components/home/HeroCarousel.vue
@@ -13,45 +13,50 @@ const rawSlides = [
// 生成带 .src 的 slides
const slides = rawSlides.map(s => ({
...s,
- src: new URL(`../../assets/images/promo/${s.img}`, import.meta.url).href
+ src: `http://localhost:8000/src/assets/images/promo/${s.img}`
}))
/** 提取主色(或平均色)的函数(仅取左右两侧像素,不取上下) */
function extractAverageColor(img: HTMLImageElement, edgeRatio = 0.05): string {
- const w = img.naturalWidth
- const h = img.naturalHeight
- // 限制画布分辨率,避免内存过大
- const cw = 200
- const ch = Math.round((h / w) * cw)
+ try {
+ const w = img.naturalWidth
+ const h = img.naturalHeight
+ // 限制画布分辨率,避免内存过大
+ const cw = 200
+ const ch = Math.round((h / w) * cw)
- const canvas = document.createElement('canvas')
- canvas.width = cw
- canvas.height = ch
- const ctx = canvas.getContext('2d')!
- ctx.drawImage(img, 0, 0, cw, ch)
+ const canvas = document.createElement('canvas')
+ canvas.width = cw
+ canvas.height = ch
+ const ctx = canvas.getContext('2d')!
+ ctx.drawImage(img, 0, 0, cw, ch)
- const data = ctx.getImageData(0, 0, cw, ch).data
- const edgeW = Math.max(1, Math.floor(cw * edgeRatio))
+ const data = ctx.getImageData(0, 0, cw, ch).data
+ const edgeW = Math.max(1, Math.floor(cw * edgeRatio))
- let r = 0, g = 0, b = 0, count = 0
- // 只累计左右两侧像素
- for (let y = 0; y < ch; y++) {
- for (let x = 0; x < cw; x++) {
- if (x < edgeW || x >= cw - edgeW) {
- const idx = (y * cw + x) * 4
- r += data[idx]
- g += data[idx + 1]
- b += data[idx + 2]
- count++
+ let r = 0, g = 0, b = 0, count = 0
+ // 只累计左右两侧像素
+ for (let y = 0; y < ch; y++) {
+ for (let x = 0; x < cw; x++) {
+ if (x < edgeW || x >= cw - edgeW) {
+ const idx = (y * cw + x) * 4
+ r += data[idx]
+ g += data[idx + 1]
+ b += data[idx + 2]
+ count++
+ }
}
}
- }
- if (count === 0) count = 1
- r = Math.round(r / count)
- g = Math.round(g / count)
- b = Math.round(b / count)
- return `rgb(${r}, ${g}, ${b})`
+ if (count === 0) count = 1
+ r = Math.round(r / count)
+ g = Math.round(g / count)
+ b = Math.round(b / count)
+ return `rgb(${r}, ${g}, ${b})`
+ } catch (error) {
+ console.warn('无法提取图片颜色,使用默认颜色', error)
+ return '#f5f5f5'
+ }
}
// 每张 slide 都保存一个 bgColor
@@ -81,6 +86,7 @@ function onImgLoad(e: Event, idx: number) {
:src="s.src"
class="banner-img"
alt=""
+ crossorigin="anonymous"
@load="e => onImgLoad(e, idx)"
/>
diff --git a/src/frontend/src/components/layout/NaviBar.vue b/src/frontend/src/components/layout/NaviBar.vue
index 86d5560..fe37f9c 100644
--- a/src/frontend/src/components/layout/NaviBar.vue
+++ b/src/frontend/src/components/layout/NaviBar.vue
@@ -1,13 +1,33 @@
diff --git a/src/frontend/src/components/layout/UserLayout.vue b/src/frontend/src/components/layout/UserLayout.vue
new file mode 100644
index 0000000..2352ac1
--- /dev/null
+++ b/src/frontend/src/components/layout/UserLayout.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/frontend/src/components/product/PriceBox.vue b/src/frontend/src/components/product/PriceBox.vue
index d1b2bca..eb49edb 100644
--- a/src/frontend/src/components/product/PriceBox.vue
+++ b/src/frontend/src/components/product/PriceBox.vue
@@ -7,7 +7,7 @@