9.16/1
This commit is contained in:
@@ -13,6 +13,20 @@
|
||||
- User: `root`
|
||||
- 说明:所有结构变更均通过 MysqlMCP 执行并已落地到线上库。
|
||||
|
||||
### 角色与模拟数据策略(统一为店长)
|
||||
- 当前不进行角色划分,系统仅保留“店长”角色。
|
||||
- 已将所有用户记录统一为:`role='owner'`、`is_owner=1`。
|
||||
- 前端/后端权限逻辑暂未启用,后续若引入权限体系,再行扩展角色与边界。
|
||||
|
||||
### 小程序默认用户(可开关,默认关闭)
|
||||
- 目的:开发/演示阶段,便于免登录联调。
|
||||
- 机制:前端在请求头附加 `X-User-Id`(值为张老板 id=2),仅当开关开启时。
|
||||
- 开关:
|
||||
- 环境变量:`VITE_APP_ENABLE_DEFAULT_USER=true` 与 `VITE_APP_DEFAULT_USER_ID=2`
|
||||
- 或本地存储:`ENABLE_DEFAULT_USER=true` 与 `DEFAULT_USER_ID=2`
|
||||
- 关闭:不设置/置为 `false` 即可停用(生产环境默认关闭)。
|
||||
- 完全移除:删除 `frontend/common/config.js` 中默认用户配置与 `frontend/common/http.js` 中注入逻辑。
|
||||
|
||||
### 后端(Spring Boot)数据库状态
|
||||
- 依赖:`pom.xml` 未包含 `spring-boot-starter-web`、`spring-boot-starter-data-jpa`、`mysql-connector-j` 等数据库相关依赖。
|
||||
- 配置:`src/main/resources/application.properties` 仅有 `spring.application.name=demo`;未配置 `spring.datasource.*`、`spring.jpa.*`。
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.demo.dashboard;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/dashboard")
|
||||
public class DashboardController {
|
||||
|
||||
private final DashboardService dashboardService;
|
||||
|
||||
public DashboardController(DashboardService dashboardService) {
|
||||
this.dashboardService = dashboardService;
|
||||
}
|
||||
|
||||
@GetMapping("/overview")
|
||||
public ResponseEntity<DashboardOverviewResponse> overview(@RequestHeader(name = "X-Shop-Id", required = false) Long shopId) {
|
||||
long sid = (shopId == null ? 1L : shopId);
|
||||
return ResponseEntity.ok(dashboardService.getOverview(sid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.demo.dashboard;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class DashboardOverviewResponse {
|
||||
private BigDecimal todaySalesAmount;
|
||||
private BigDecimal monthGrossProfit;
|
||||
private BigDecimal stockTotalQuantity;
|
||||
|
||||
public DashboardOverviewResponse(BigDecimal todaySalesAmount, BigDecimal monthGrossProfit, BigDecimal stockTotalQuantity) {
|
||||
this.todaySalesAmount = todaySalesAmount;
|
||||
this.monthGrossProfit = monthGrossProfit;
|
||||
this.stockTotalQuantity = stockTotalQuantity;
|
||||
}
|
||||
|
||||
public BigDecimal getTodaySalesAmount() {
|
||||
return todaySalesAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getMonthGrossProfit() {
|
||||
return monthGrossProfit;
|
||||
}
|
||||
|
||||
public BigDecimal getStockTotalQuantity() {
|
||||
return stockTotalQuantity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.example.demo.dashboard;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Repository
|
||||
public class DashboardRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
public BigDecimal sumTodaySalesOrders(Long shopId) {
|
||||
Object result = entityManager.createNativeQuery(
|
||||
"SELECT COALESCE(SUM(amount), 0) FROM sales_orders " +
|
||||
"WHERE shop_id = :shopId AND status = 'approved' AND DATE(order_time) = CURRENT_DATE()"
|
||||
).setParameter("shopId", shopId).getSingleResult();
|
||||
return toBigDecimal(result);
|
||||
}
|
||||
|
||||
public BigDecimal sumMonthGrossProfitApprox(Long shopId) {
|
||||
Object result = entityManager.createNativeQuery(
|
||||
"SELECT COALESCE(SUM(soi.amount - soi.quantity * COALESCE(pp.purchase_price, 0)), 0) AS gp " +
|
||||
"FROM sales_orders so " +
|
||||
"JOIN sales_order_items soi ON soi.order_id = so.id " +
|
||||
"LEFT JOIN product_prices pp ON pp.product_id = soi.product_id AND pp.shop_id = so.shop_id " +
|
||||
"WHERE so.shop_id = :shopId AND so.status = 'approved' " +
|
||||
"AND so.order_time >= DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01') " +
|
||||
"AND so.order_time < DATE_ADD(DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01'), INTERVAL 1 MONTH)"
|
||||
).setParameter("shopId", shopId).getSingleResult();
|
||||
return toBigDecimal(result);
|
||||
}
|
||||
|
||||
public BigDecimal sumTotalInventoryQty(Long shopId) {
|
||||
Object result = entityManager.createNativeQuery(
|
||||
"SELECT COALESCE(SUM(quantity), 0) FROM inventories WHERE shop_id = :shopId"
|
||||
).setParameter("shopId", shopId).getSingleResult();
|
||||
return toBigDecimal(result);
|
||||
}
|
||||
|
||||
private BigDecimal toBigDecimal(Object value) {
|
||||
if (value == null) return BigDecimal.ZERO;
|
||||
if (value instanceof BigDecimal) return (BigDecimal) value;
|
||||
if (value instanceof Number) return BigDecimal.valueOf(((Number) value).doubleValue());
|
||||
try {
|
||||
return new BigDecimal(value.toString());
|
||||
} catch (Exception e) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.example.demo.dashboard;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class DashboardService {
|
||||
private final DashboardRepository dashboardRepository;
|
||||
|
||||
public DashboardService(DashboardRepository dashboardRepository) {
|
||||
this.dashboardRepository = dashboardRepository;
|
||||
}
|
||||
|
||||
public DashboardOverviewResponse getOverview(long shopId) {
|
||||
BigDecimal todaySales = dashboardRepository.sumTodaySalesOrders(shopId);
|
||||
BigDecimal monthGrossProfit = dashboardRepository.sumMonthGrossProfitApprox(shopId);
|
||||
BigDecimal stockTotalQty = dashboardRepository.sumTotalInventoryQty(shopId);
|
||||
return new DashboardOverviewResponse(todaySales, monthGrossProfit, stockTotalQty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user