包含完整功能模块: - 设备激活(直销激活码模式 + 代销免激活码模式) - 微信支付 + 天卡订单 - 天卡池管理 + 异步橘视厅SDK激活 - 第三方合作伙伴接口(代销模式) - 签名鉴权(appKey/appSecret + nonce防重放) - 天卡消耗(事务 + 幂等 + 并发控制) - 媒资接口(三级授权过滤) - 审计日志 - 定价策略(3层:门店 > 渠道 > 平台) - 分账(微信分账 + 分润规则) - Docker部署(含Redis容器)
166 lines
5.1 KiB
Java
166 lines
5.1 KiB
Java
package io.as.modules.daycard.controller;
|
||
|
||
import io.as.common.annotation.AuditAction;
|
||
import io.as.common.exception.ASException;
|
||
import io.as.common.utils.R;
|
||
import io.as.modules.daycard.entity.DayCardActivationCodeEntity;
|
||
import io.as.modules.daycard.service.DayCardActivationCodeService;
|
||
import io.as.modules.sys.entity.SysOrgEntity;
|
||
import io.as.modules.sys.service.SysOrgService;
|
||
import io.swagger.annotations.Api;
|
||
import io.swagger.annotations.ApiOperation;
|
||
import io.swagger.annotations.ApiParam;
|
||
import org.apache.commons.lang.StringUtils;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.Date;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* 天卡设备激活码管理(管理后台用)
|
||
* <p>管理后台按门店生成激活码,App 端 init 时输入激活码完成设备注册绑定</p>
|
||
*/
|
||
@Api(tags = "天卡设备激活码")
|
||
@RestController
|
||
@RequestMapping("/manage/daycard/activation-code")
|
||
public class DayCardActivationCodeController {
|
||
|
||
@Autowired
|
||
private DayCardActivationCodeService dayCardActivationCodeService;
|
||
|
||
@Autowired
|
||
private SysOrgService sysOrgService;
|
||
|
||
/**
|
||
* 按门店查询激活码列表
|
||
*/
|
||
@ApiOperation("按门店查询激活码列表")
|
||
@GetMapping("/list/{storeOrgId}")
|
||
public R listByStore(@PathVariable("storeOrgId") Long storeOrgId) {
|
||
List<DayCardActivationCodeEntity> list = dayCardActivationCodeService.listByStoreOrgId(storeOrgId);
|
||
List<Map<String, Object>> result = new ArrayList<>();
|
||
for (DayCardActivationCodeEntity entity : list) {
|
||
result.add(toMap(entity));
|
||
}
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("list", result);
|
||
return R.dataSuccess(data);
|
||
}
|
||
|
||
/**
|
||
* 为门店生成激活码(每门店一个,已存在则返回已有的)
|
||
*/
|
||
@ApiOperation("为门店生成激活码")
|
||
@AuditAction(value = "ACTCODE_GENERATE", description = "生成门店激活码")
|
||
@PostMapping("/generate")
|
||
public R generate(@RequestBody GenerateRequest request) {
|
||
if (request.getStoreOrgId() == null) {
|
||
throw new ASException("门店组织ID不能为空");
|
||
}
|
||
// 校验门店存在
|
||
SysOrgEntity storeOrg = sysOrgService.getById(request.getStoreOrgId());
|
||
if (storeOrg == null) {
|
||
throw new ASException("门店不存在");
|
||
}
|
||
// 从门店 mpath 解析渠道
|
||
Long channelOrgId = resolveChannelOrgId(storeOrg);
|
||
DayCardActivationCodeEntity entity = dayCardActivationCodeService.generateForStore(
|
||
request.getStoreOrgId(), channelOrgId, request.getRemark());
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("data", toMap(entity));
|
||
return R.dataSuccess(data);
|
||
}
|
||
|
||
/**
|
||
* 重新生成激活码 code(旧 code 失效)
|
||
*/
|
||
@ApiOperation("重新生成激活码")
|
||
@AuditAction(value = "ACTCODE_REGENERATE", description = "重新生成激活码")
|
||
@PostMapping("/{id}/regenerate")
|
||
public R regenerate(@PathVariable("id") Long id) {
|
||
String newCode = dayCardActivationCodeService.regenerateCode(id);
|
||
Map<String, Object> item = new HashMap<>();
|
||
item.put("code", newCode);
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("data", item);
|
||
return R.dataSuccess(data);
|
||
}
|
||
|
||
/**
|
||
* 启用/禁用激活码
|
||
*/
|
||
@ApiOperation("启用/禁用激活码")
|
||
@AuditAction(value = "ACTCODE_UPDATE_STATUS", description = "修改激活码状态")
|
||
@PutMapping("/{id}/status")
|
||
public R updateStatus(@PathVariable("id") Long id, @RequestBody UpdateStatusRequest request) {
|
||
dayCardActivationCodeService.updateStatus(id, request.getStatus());
|
||
return R.ok();
|
||
}
|
||
|
||
/**
|
||
* 删除激活码(软删除)
|
||
*/
|
||
@ApiOperation("删除激活码")
|
||
@AuditAction(value = "ACTCODE_DELETE", description = "删除激活码")
|
||
@DeleteMapping("/{id}")
|
||
public R delete(@PathVariable("id") Long id) {
|
||
dayCardActivationCodeService.delete(id);
|
||
return R.ok();
|
||
}
|
||
|
||
// ==================== 内部方法 ====================
|
||
|
||
/**
|
||
* 从门店 mpath 解析渠道组织ID(mpath 第2段)
|
||
*/
|
||
private Long resolveChannelOrgId(SysOrgEntity storeOrg) {
|
||
if (storeOrg == null || StringUtils.isBlank(storeOrg.getMpath())) {
|
||
return null;
|
||
}
|
||
String[] segments = storeOrg.getMpath().split("\\.");
|
||
if (segments.length >= 2) {
|
||
try {
|
||
return Long.parseLong(segments[1]);
|
||
} catch (NumberFormatException e) {
|
||
return null;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
private Map<String, Object> toMap(DayCardActivationCodeEntity entity) {
|
||
Map<String, Object> m = new HashMap<>();
|
||
m.put("id", entity.getId());
|
||
m.put("code", entity.getCode());
|
||
m.put("channelOrgId", entity.getChannelOrgId());
|
||
m.put("storeOrgId", entity.getStoreOrgId());
|
||
m.put("status", entity.getStatus());
|
||
m.put("maxDeviceCount", entity.getMaxDeviceCount());
|
||
m.put("activatedCount", entity.getActivatedCount());
|
||
m.put("remark", entity.getRemark());
|
||
m.put("createdAt", entity.getCreatedAt());
|
||
return m;
|
||
}
|
||
|
||
/**
|
||
* 生成激活码请求
|
||
*/
|
||
@lombok.Data
|
||
public static class GenerateRequest {
|
||
private Long storeOrgId;
|
||
private String remark;
|
||
}
|
||
|
||
/**
|
||
* 更新状态请求
|
||
*/
|
||
@lombok.Data
|
||
public static class UpdateStatusRequest {
|
||
private String status;
|
||
}
|
||
}
|