|
|
@@ -0,0 +1,354 @@
|
|
|
+package com.haha.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.haha.entity.Device;
|
|
|
+import com.haha.entity.Shop;
|
|
|
+import com.haha.mapper.ShopMapper;
|
|
|
+import com.haha.service.DeviceService;
|
|
|
+import com.haha.service.ShopService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 门店服务实现类
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements ShopService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ShopMapper shopMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DeviceService deviceService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<Shop> getPage(int page, int pageSize, Map<String, Object> params) {
|
|
|
+ Page<Shop> pageParam = new Page<>(page, pageSize);
|
|
|
+
|
|
|
+ LambdaQueryWrapper<Shop> wrapper = new LambdaQueryWrapper<>();
|
|
|
+
|
|
|
+ // 门店名称模糊查询
|
|
|
+ String name = (String) params.get("name");
|
|
|
+ wrapper.like(StringUtils.hasText(name), Shop::getName, name);
|
|
|
+
|
|
|
+ // 城市查询
|
|
|
+ String city = (String) params.get("city");
|
|
|
+ wrapper.eq(StringUtils.hasText(city), Shop::getCity, city);
|
|
|
+
|
|
|
+ // 状态查询
|
|
|
+ Object statusObj = params.get("status");
|
|
|
+ if (statusObj != null && !statusObj.toString().isEmpty()) {
|
|
|
+ Integer status = Integer.valueOf(statusObj.toString());
|
|
|
+ wrapper.eq(Shop::getStatus, status);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按创建时间倒序
|
|
|
+ wrapper.orderByDesc(Shop::getCreateTime);
|
|
|
+
|
|
|
+ IPage<Shop> shopPage = this.page(pageParam, wrapper);
|
|
|
+
|
|
|
+ // 填充设备统计信息
|
|
|
+ for (Shop shop : shopPage.getRecords()) {
|
|
|
+ fillShopStats(shop);
|
|
|
+ fillShopLabels(shop);
|
|
|
+ }
|
|
|
+
|
|
|
+ return shopPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Shop getShopWithStats(Long id) {
|
|
|
+ Map<String, Object> map = shopMapper.selectShopWithStats(id);
|
|
|
+ if (map == null || map.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ Shop shop = new Shop();
|
|
|
+ shop.setId(((Number) map.get("id")).longValue());
|
|
|
+ shop.setShopCode((String) map.get("shop_code"));
|
|
|
+ shop.setName((String) map.get("name"));
|
|
|
+ shop.setAddress((String) map.get("address"));
|
|
|
+ shop.setProvince((String) map.get("province"));
|
|
|
+ shop.setCity((String) map.get("city"));
|
|
|
+ shop.setDistrict((String) map.get("district"));
|
|
|
+
|
|
|
+ Object longitude = map.get("longitude");
|
|
|
+ if (longitude != null) {
|
|
|
+ shop.setLongitude(((Number) longitude).doubleValue());
|
|
|
+ }
|
|
|
+ Object latitude = map.get("latitude");
|
|
|
+ if (latitude != null) {
|
|
|
+ shop.setLatitude(((Number) latitude).doubleValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ shop.setContactName((String) map.get("contact_name"));
|
|
|
+ shop.setContactPhone((String) map.get("contact_phone"));
|
|
|
+ shop.setBusinessHours((String) map.get("business_hours"));
|
|
|
+ shop.setStatus(((Number) map.get("status")).intValue());
|
|
|
+ shop.setRemark((String) map.get("remark"));
|
|
|
+
|
|
|
+ // 设备统计
|
|
|
+ Object deviceCount = map.get("device_count");
|
|
|
+ shop.setDeviceCount(deviceCount != null ? ((Number) deviceCount).intValue() : 0);
|
|
|
+
|
|
|
+ Object onlineCount = map.get("online_count");
|
|
|
+ shop.setOnlineCount(onlineCount != null ? ((Number) onlineCount).intValue() : 0);
|
|
|
+
|
|
|
+ fillShopLabels(shop);
|
|
|
+
|
|
|
+ return shop;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Map<String, Object>> getAllEnabledShops() {
|
|
|
+ return shopMapper.selectAllEnabledShops();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Shop createShop(Shop shop) {
|
|
|
+ // 生成门店编码
|
|
|
+ if (!StringUtils.hasText(shop.getShopCode())) {
|
|
|
+ shop.setShopCode("SH" + System.currentTimeMillis());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认状态
|
|
|
+ if (shop.getStatus() == null) {
|
|
|
+ shop.setStatus(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ shop.setCreateTime(LocalDateTime.now());
|
|
|
+ shop.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ this.save(shop);
|
|
|
+
|
|
|
+ fillShopLabels(shop);
|
|
|
+
|
|
|
+ log.info("创建门店成功: id={}, name={}", shop.getId(), shop.getName());
|
|
|
+
|
|
|
+ return shop;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Shop updateShop(Shop shop) {
|
|
|
+ Shop existShop = this.getById(shop.getId());
|
|
|
+ if (existShop == null) {
|
|
|
+ throw new RuntimeException("门店不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ shop.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ this.updateById(shop);
|
|
|
+
|
|
|
+ Shop updated = this.getById(shop.getId());
|
|
|
+ fillShopStats(updated);
|
|
|
+ fillShopLabels(updated);
|
|
|
+
|
|
|
+ log.info("更新门店成功: id={}, name={}", shop.getId(), shop.getName());
|
|
|
+
|
|
|
+ return updated;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean toggleStatus(Long id, Integer status) {
|
|
|
+ Shop shop = this.getById(id);
|
|
|
+ if (shop == null) {
|
|
|
+ throw new RuntimeException("门店不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ LambdaUpdateWrapper<Shop> wrapper = new LambdaUpdateWrapper<>();
|
|
|
+ wrapper.eq(Shop::getId, id)
|
|
|
+ .set(Shop::getStatus, status)
|
|
|
+ .set(Shop::getUpdateTime, LocalDateTime.now());
|
|
|
+
|
|
|
+ boolean result = this.update(wrapper);
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ log.info("切换门店状态成功: id={}, status={}", id, status);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getStatistics() {
|
|
|
+ Map<String, Object> statistics = new HashMap<>();
|
|
|
+
|
|
|
+ // 总门店数
|
|
|
+ long total = this.count();
|
|
|
+ statistics.put("total", total);
|
|
|
+
|
|
|
+ // 启用门店数
|
|
|
+ long enabled = this.lambdaQuery()
|
|
|
+ .eq(Shop::getStatus, 1)
|
|
|
+ .count();
|
|
|
+ statistics.put("enabled", enabled);
|
|
|
+
|
|
|
+ // 禁用门店数
|
|
|
+ statistics.put("disabled", total - enabled);
|
|
|
+
|
|
|
+ // 总设备数
|
|
|
+ long totalDevices = deviceService.count();
|
|
|
+ statistics.put("totalDevices", totalDevices);
|
|
|
+
|
|
|
+ // 在线设备数
|
|
|
+ long onlineDevices = deviceService.lambdaQuery()
|
|
|
+ .eq(Device::getStatus, 1)
|
|
|
+ .count();
|
|
|
+ statistics.put("onlineDevices", onlineDevices);
|
|
|
+
|
|
|
+ return statistics;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Map<String, Object>> getDevicesByShopId(Long shopId) {
|
|
|
+ LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(Device::getShopId, shopId)
|
|
|
+ .orderByDesc(Device::getCreateTime);
|
|
|
+
|
|
|
+ List<Device> devices = deviceService.list(wrapper);
|
|
|
+
|
|
|
+ return devices.stream().map(device -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("id", device.getId());
|
|
|
+ map.put("deviceId", device.getDeviceId());
|
|
|
+ map.put("name", device.getName());
|
|
|
+ map.put("status", device.getStatus());
|
|
|
+ map.put("createTime", device.getCreateTime());
|
|
|
+ return map;
|
|
|
+ }).toList();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean linkDevice(Long shopId, Long deviceId) {
|
|
|
+ // 检查门店是否存在
|
|
|
+ Shop shop = this.getById(shopId);
|
|
|
+ if (shop == null) {
|
|
|
+ throw new RuntimeException("门店不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查设备是否存在
|
|
|
+ Device device = deviceService.getById(deviceId);
|
|
|
+ if (device == null) {
|
|
|
+ throw new RuntimeException("设备不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果设备已关联到其他门店,先解除关联
|
|
|
+ if (device.getShopId() != null && !device.getShopId().equals(shopId)) {
|
|
|
+ log.info("设备已关联到其他门店,将解除原关联: deviceId={}, oldShopId={}", deviceId, device.getShopId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关联设备到门店
|
|
|
+ device.setShopId(shopId);
|
|
|
+ device.setUpdateTime(LocalDateTime.now());
|
|
|
+ boolean result = deviceService.updateById(device);
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ log.info("设备关联门店成功: deviceId={}, shopId={}", deviceId, shopId);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int batchLinkDevices(Long shopId, List<Long> deviceIds) {
|
|
|
+ int count = 0;
|
|
|
+ for (Long deviceId : deviceIds) {
|
|
|
+ try {
|
|
|
+ if (linkDevice(shopId, deviceId)) {
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("设备关联门店失败: deviceId={}, error={}", deviceId, e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("批量关联设备完成: shopId={}, 总数={}, 成功={}", shopId, deviceIds.size(), count);
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean unlinkDevice(Long shopId, Long deviceId) {
|
|
|
+ // 检查设备是否属于该门店
|
|
|
+ Device device = deviceService.getById(deviceId);
|
|
|
+ if (device == null) {
|
|
|
+ throw new RuntimeException("设备不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!shopId.equals(device.getShopId())) {
|
|
|
+ throw new RuntimeException("该设备不属于当前门店");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解除关联
|
|
|
+ device.setShopId(null);
|
|
|
+ device.setUpdateTime(LocalDateTime.now());
|
|
|
+ boolean result = deviceService.updateById(device);
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ log.info("设备解除门店关联成功: deviceId={}, shopId={}", deviceId, shopId);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int batchUnlinkDevices(Long shopId, List<Long> deviceIds) {
|
|
|
+ int count = 0;
|
|
|
+ for (Long deviceId : deviceIds) {
|
|
|
+ try {
|
|
|
+ if (unlinkDevice(shopId, deviceId)) {
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("设备解除关联失败: deviceId={}, error={}", deviceId, e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("批量解除关联完成: shopId={}, 总数={}, 成功={}", shopId, deviceIds.size(), count);
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充门店设备统计信息
|
|
|
+ */
|
|
|
+ private void fillShopStats(Shop shop) {
|
|
|
+ // 统计该门店的设备数量
|
|
|
+ long deviceCount = deviceService.lambdaQuery()
|
|
|
+ .eq(Device::getShopId, shop.getId())
|
|
|
+ .count();
|
|
|
+ shop.setDeviceCount((int) deviceCount);
|
|
|
+
|
|
|
+ // 统计在线设备数量
|
|
|
+ long onlineCount = deviceService.lambdaQuery()
|
|
|
+ .eq(Device::getShopId, shop.getId())
|
|
|
+ .eq(Device::getStatus, 1)
|
|
|
+ .count();
|
|
|
+ shop.setOnlineCount((int) onlineCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充门店状态标签
|
|
|
+ */
|
|
|
+ private void fillShopLabels(Shop shop) {
|
|
|
+ if (shop.getStatus() != null) {
|
|
|
+ if (shop.getStatus() == 1) {
|
|
|
+ shop.setStatusLabel("启用");
|
|
|
+ shop.setStatusColor("success");
|
|
|
+ } else {
|
|
|
+ shop.setStatusLabel("禁用");
|
|
|
+ shop.setStatusColor("danger");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|