|
|
@@ -0,0 +1,306 @@
|
|
|
+package com.haha.admin.controller;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.haha.common.vo.Result;
|
|
|
+import com.haha.entity.Product;
|
|
|
+import com.haha.service.ProductService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 商品管理控制器
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RestController
|
|
|
+@RequestMapping("/products")
|
|
|
+public class ProductController {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ProductService productService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询商品列表
|
|
|
+ * @param params 查询参数
|
|
|
+ * @return 商品列表
|
|
|
+ */
|
|
|
+ @GetMapping("/list")
|
|
|
+ public Result<Map<String, Object>> list(@RequestParam Map<String, Object> params) {
|
|
|
+ try {
|
|
|
+ // 分页参数
|
|
|
+ int page = 1;
|
|
|
+ int pageSize = 10;
|
|
|
+
|
|
|
+ Object pageObj = params.get("page");
|
|
|
+ if (pageObj != null && !pageObj.toString().isEmpty()) {
|
|
|
+ page = Integer.parseInt(pageObj.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ Object pageSizeObj = params.get("pageSize");
|
|
|
+ if (pageSizeObj != null && !pageSizeObj.toString().isEmpty()) {
|
|
|
+ pageSize = Integer.parseInt(pageSizeObj.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询条件
|
|
|
+ String name = (String) params.get("name");
|
|
|
+ String barcode = (String) params.get("barcode");
|
|
|
+ String category = (String) params.get("category");
|
|
|
+ Integer syncStatus = null;
|
|
|
+ Object syncStatusObj = params.get("syncStatus");
|
|
|
+ if (syncStatusObj != null && !syncStatusObj.toString().isEmpty()) {
|
|
|
+ syncStatus = Integer.valueOf(syncStatusObj.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建查询条件
|
|
|
+ LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.like(name != null && !name.isEmpty(), Product::getName, name)
|
|
|
+ .like(barcode != null && !barcode.isEmpty(), Product::getBarcode, barcode)
|
|
|
+ .eq(category != null && !category.isEmpty(), Product::getType, category)
|
|
|
+ .eq(syncStatus != null, Product::getSyncStatus, syncStatus)
|
|
|
+ .eq(Product::getIsDeleted, 0); // 只查询未删除的
|
|
|
+
|
|
|
+ // 按创建时间倒序
|
|
|
+ wrapper.orderByDesc(Product::getCreateTime);
|
|
|
+
|
|
|
+ // 分页查询
|
|
|
+ Page<Product> pageResult = new Page<>(page, pageSize);
|
|
|
+ IPage<Product> productPage = productService.page(pageResult, wrapper);
|
|
|
+
|
|
|
+ // 填充额外字段
|
|
|
+ for (Product product : productPage.getRecords()) {
|
|
|
+ fillProductLabels(product);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> data = new HashMap<>();
|
|
|
+ data.put("list", productPage.getRecords());
|
|
|
+ data.put("total", productPage.getTotal());
|
|
|
+ data.put("pageSize", productPage.getSize());
|
|
|
+ data.put("currentPage", productPage.getCurrent());
|
|
|
+
|
|
|
+ return Result.success("查询成功", data);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询商品列表失败: {}", e.getMessage(), e);
|
|
|
+ return Result.error(500, "查询商品列表失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取商品详情
|
|
|
+ * @param id 商品ID
|
|
|
+ * @return 商品详情
|
|
|
+ */
|
|
|
+ @GetMapping("/{id}")
|
|
|
+ public Result<Product> getById(@PathVariable Long id) {
|
|
|
+ try {
|
|
|
+ Product product = productService.getById(id);
|
|
|
+ if (product == null) {
|
|
|
+ return Result.error(404, "商品不存在");
|
|
|
+ }
|
|
|
+ fillProductLabels(product);
|
|
|
+ return Result.success("查询成功", product);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询商品详情失败: productId={}, error={}", id, e.getMessage(), e);
|
|
|
+ return Result.error(500, "查询商品详情失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取商品统计数据
|
|
|
+ * @return 统计数据
|
|
|
+ */
|
|
|
+ @GetMapping("/statistics")
|
|
|
+ public Result<Map<String, Object>> getStatistics() {
|
|
|
+ try {
|
|
|
+ Map<String, Object> statistics = new HashMap<>();
|
|
|
+
|
|
|
+ // 总商品数(未删除)
|
|
|
+ long totalProducts = productService.lambdaQuery()
|
|
|
+ .eq(Product::getIsDeleted, 0)
|
|
|
+ .count();
|
|
|
+ statistics.put("totalProducts", totalProducts);
|
|
|
+
|
|
|
+ // 已同步商品数
|
|
|
+ long syncedProducts = productService.lambdaQuery()
|
|
|
+ .eq(Product::getIsDeleted, 0)
|
|
|
+ .eq(Product::getSyncStatus, 2)
|
|
|
+ .count();
|
|
|
+ statistics.put("syncedProducts", syncedProducts);
|
|
|
+
|
|
|
+ // TODO: 库存和库存总值需要从其他服务获取
|
|
|
+ statistics.put("totalStock", 0);
|
|
|
+ statistics.put("totalValue", "0.00");
|
|
|
+
|
|
|
+ return Result.success("查询成功", statistics);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询商品统计失败: {}", e.getMessage(), e);
|
|
|
+ return Result.error(500, "查询商品统计失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加商品
|
|
|
+ * @param product 商品信息
|
|
|
+ * @return 添加结果
|
|
|
+ */
|
|
|
+ @PostMapping
|
|
|
+ public Result<Product> add(@RequestBody Product product) {
|
|
|
+ try {
|
|
|
+ product.setIsDeleted(0);
|
|
|
+ product.setSyncStatus(0);
|
|
|
+ product.setCreateTime(LocalDateTime.now());
|
|
|
+ product.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ boolean success = productService.save(product);
|
|
|
+ if (success) {
|
|
|
+ return Result.success("添加成功", product);
|
|
|
+ } else {
|
|
|
+ return Result.error(500, "添加失败");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("添加商品失败: {}", e.getMessage(), e);
|
|
|
+ return Result.error(500, "添加商品失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 编辑商品
|
|
|
+ * @param id 商品ID
|
|
|
+ * @param product 商品信息
|
|
|
+ * @return 编辑结果
|
|
|
+ */
|
|
|
+ @PutMapping("/{id}")
|
|
|
+ public Result<Product> update(@PathVariable Long id, @RequestBody Product product) {
|
|
|
+ try {
|
|
|
+ Product existing = productService.getById(id);
|
|
|
+ if (existing == null) {
|
|
|
+ return Result.error(404, "商品不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ product.setId(id);
|
|
|
+ product.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ boolean success = productService.updateById(product);
|
|
|
+ if (success) {
|
|
|
+ return Result.success("更新成功", product);
|
|
|
+ } else {
|
|
|
+ return Result.error(500, "更新失败");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新商品失败: productId={}, error={}", id, e.getMessage(), e);
|
|
|
+ return Result.error(500, "更新商品失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除商品(软删除)
|
|
|
+ * @param id 商品ID
|
|
|
+ * @return 删除结果
|
|
|
+ */
|
|
|
+ @DeleteMapping("/{id}")
|
|
|
+ public Result<Void> delete(@PathVariable Long id) {
|
|
|
+ try {
|
|
|
+ Product product = productService.getById(id);
|
|
|
+ if (product == null) {
|
|
|
+ return Result.error(404, "商品不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 软删除
|
|
|
+ product.setIsDeleted(1);
|
|
|
+ product.setUpdateTime(LocalDateTime.now());
|
|
|
+ productService.updateById(product);
|
|
|
+
|
|
|
+ return Result.success("删除成功", null);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("删除商品失败: productId={}, error={}", id, e.getMessage(), e);
|
|
|
+ return Result.error(500, "删除商品失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步商品到哈哈平台
|
|
|
+ * @param id 商品ID
|
|
|
+ * @return 同步结果
|
|
|
+ */
|
|
|
+ @PostMapping("/{id}/sync")
|
|
|
+ public Result<Void> sync(@PathVariable Long id) {
|
|
|
+ try {
|
|
|
+ Product product = productService.getById(id);
|
|
|
+ if (product == null) {
|
|
|
+ return Result.error(404, "商品不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("同步商品到哈哈平台: productId={}, name={}", id, product.getName());
|
|
|
+
|
|
|
+ // TODO: 调用SDK同步商品到哈哈平台
|
|
|
+
|
|
|
+ // 更新同步状态
|
|
|
+ productService.updateSyncStatus(id, 2);
|
|
|
+
|
|
|
+ return Result.success("同步成功", null);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("同步商品失败: productId={}, error={}", id, e.getMessage(), e);
|
|
|
+ return Result.error(500, "同步商品失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充商品标签字段
|
|
|
+ * @param product 商品对象
|
|
|
+ */
|
|
|
+ private void fillProductLabels(Product product) {
|
|
|
+ // 同步状态标签
|
|
|
+ if (product.getSyncStatus() != null) {
|
|
|
+ switch (product.getSyncStatus()) {
|
|
|
+ case 0:
|
|
|
+ product.setSyncStatusLabel("未同步");
|
|
|
+ product.setSyncStatusColor("info");
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ product.setSyncStatusLabel("同步中");
|
|
|
+ product.setSyncStatusColor("warning");
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ product.setSyncStatusLabel("已同步");
|
|
|
+ product.setSyncStatusColor("success");
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ product.setSyncStatusLabel("同步失败");
|
|
|
+ product.setSyncStatusColor("danger");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ product.setSyncStatusLabel("未知");
|
|
|
+ product.setSyncStatusColor("info");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图片URL
|
|
|
+ if (product.getImageUrl() == null && product.getPic() != null) {
|
|
|
+ product.setImageUrl(product.getPic());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认值
|
|
|
+ if (product.getCategory() == null) {
|
|
|
+ product.setCategory(product.getType());
|
|
|
+ }
|
|
|
+ if (product.getPrice() == null && product.getRetailPrice() != null) {
|
|
|
+ product.setPrice(product.getRetailPrice());
|
|
|
+ }
|
|
|
+ if (product.getCost() == null && product.getCostPrice() != null) {
|
|
|
+ product.setCost(product.getCostPrice());
|
|
|
+ }
|
|
|
+ if (product.getStock() == null) {
|
|
|
+ product.setStock(0);
|
|
|
+ }
|
|
|
+ if (product.getSoldCount() == null) {
|
|
|
+ product.setSoldCount(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|