88e030b7
王彪总
init project
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
package com.java110.acct.cmd.account;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.doc.annotation.*;
import com.java110.dto.account.AccountDto;
import com.java110.dto.integral.IntegralConfigDto;
import com.java110.dto.owner.OwnerDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.acct.IAccountInnerServiceSMO;
import com.java110.intf.acct.IIntegralConfigV1InnerServiceSMO;
import com.java110.intf.acct.IIntegralGiftDetailV1InnerServiceSMO;
import com.java110.intf.user.IOwnerV1InnerServiceSMO;
import com.java110.intf.user.IUserV1InnerServiceSMO;
import com.java110.po.account.AccountPo;
import com.java110.po.account.AccountDetailPo;
import com.java110.po.integral.IntegralGiftDetailPo;
import com.java110.service.smo.ISaveSystemErrorSMO;
import com.java110.utils.exception.CmdException;
import com.java110.utils.lock.DistributedLock;
import com.java110.utils.util.Assert;
import com.java110.utils.util.ListUtil;
import com.java110.utils.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
/**
* 积分赠送规则,提供第三方平台使用
*/
@Java110CmdDoc(title = "积分赠送",
description = "三方平台赠送积分给用户",
httpMethod = "post",
url = "http://{ip}:{port}/app/account.customSendAcct",
resource = "acctDoc",
author = "吴学文",
serviceCode = "account.customSendAcct"
)
@Java110ParamsDoc(params = {
@Java110ParamDoc(name = "link", length = 30, remark = "手机号"),
@Java110ParamDoc(name = "quantity", length = 30, remark = "赠送积分数量"),
@Java110ParamDoc(name = "acctType", length = 30, remark = "账户类型 2003 现金账户 2004 积分账户 2006 金币账户"),
|
9750b443
王彪总
fix(config): 更新配置...
|
50
|
@Java110ParamDoc(name = "communityId", length = 30, remark = "项目"),
|
88e030b7
王彪总
init project
|
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
})
@Java110ResponseDoc(
params = {
@Java110ParamDoc(name = "code", type = "int", length = 11, defaultValue = "0", remark = "返回编号,0 成功 其他失败"),
@Java110ParamDoc(name = "msg", type = "String", length = 250, defaultValue = "成功", remark = "描述"),
}
)
@Java110ExampleDoc(
reqBody = "{'link':'18909711443','quantity':'10','acctType':'2003','communityId':'12323123'}",
resBody = "{'code':0,'msg':'成功'}"
)
@Java110Cmd(serviceCode = "account.customSendAcct")
/**
* 自定义账户赠送命令类
* 处理第三方平台向用户账户赠送积分、现金等操作
* 支持多种账户类型:现金账户、积分账户、金币账户
*
* @author 吴学文
* @version 1.0
*/
public class CustomSendAcctCmd extends Cmd {
@Autowired
private IIntegralGiftDetailV1InnerServiceSMO integralGiftDetailV1InnerServiceSMOImpl;
@Autowired
private IAccountInnerServiceSMO accountInnerServiceSMOImpl;
@Autowired
private ISaveSystemErrorSMO saveSystemErrorSMOImpl;
@Autowired
private IOwnerV1InnerServiceSMO ownerInnerServiceSMOImpl;
@Autowired
private IIntegralConfigV1InnerServiceSMO integralConfigV1InnerServiceSMOImpl;
@Autowired
private IUserV1InnerServiceSMO userV1InnerServiceSMOImpl;
/**
* 参数验证方法
* 验证请求参数是否完整和有效
*
* @param event 命令事件对象,包含命令执行上下文信息
* @param context 命令数据流上下文,用于获取请求和响应数据
* @param reqJson 请求参数JSON对象,包含所有请求参数
* @throws CmdException 当参数验证失败时抛出命令异常
* @throws ParseException 当参数解析失败时抛出解析异常
*/
@Override
public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
// 验证必填参数是否存在
Assert.hasKeyAndValue(reqJson, "link", "未包含手机号");
Assert.hasKeyAndValue(reqJson, "acctType", "未包含账户类型");
Assert.hasKeyAndValue(reqJson, "quantity", "未包含赠送数量");
|
9750b443
王彪总
fix(config): 更新配置...
|
109
|
Assert.hasKeyAndValue(reqJson, "communityId", "未包含项目");
|
88e030b7
王彪总
init project
|
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
}
/**
* 执行账户赠送命令
* 主要逻辑:查询账户、创建账户(如不存在)、预存金额、处理积分赠送
*
* @param event 命令事件对象,包含命令执行上下文信息
* @param context 命令数据流上下文,用于获取请求和响应数据
* @param reqJson 请求参数JSON对象,包含所有请求参数
* @throws CmdException 当业务逻辑执行失败时抛出命令异常
* @throws ParseException 当数据解析失败时抛出解析异常
*/
@Override
public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
// 获取操作用户ID,从请求头中获取用户标识
String createUserId = context.getReqHeaders().get("user-id");
|
9750b443
王彪总
fix(config): 更新配置...
|
127
|
// 构建账户查询条件,根据手机号、账户类型和项目查询账户信息
|
88e030b7
王彪总
init project
|
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
AccountDto accountDto = new AccountDto();
accountDto.setLink(reqJson.getString("link"));
accountDto.setAcctType(reqJson.getString("acctType"));
accountDto.setPartId(reqJson.getString("communityId"));
// 查询账户信息,检查账户是否存在
List<AccountDto> accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto);
// 如果账户不存在,则创建新账户
if (accountDtos == null || accountDtos.size() < 1) {
accountDtos = addAccountDto(accountDto, reqJson);
}
// 创建账户明细对象并设置参数,用于记录账户变动
AccountDetailPo accountDetailPo = new AccountDetailPo();
accountDetailPo.setAcctId(accountDtos.get(0).getAcctId()); // 设置账户ID
accountDetailPo.setObjId(accountDtos.get(0).getObjId()); // 设置对象ID
accountDetailPo.setObjType(accountDtos.get(0).getObjType()); // 设置对象类型
accountDetailPo.setAmount(reqJson.getString("quantity")); // 设置赠送金额/积分数量
accountDetailPo.setRemark("三方平台通过手工赠送"); // 设置操作备注
// 执行预存操作,将金额/积分存入账户
int flag = accountInnerServiceSMOImpl.prestoreAccount(accountDetailPo);
// 检查预存操作是否成功,flag小于1表示操作失败
if (flag < 1) {
throw new CmdException("扣款失败");
}
// 如果是积分账户类型(2004),则额外处理积分赠送逻辑
if("2004".equals(reqJson.getString("acctType"))) {
doGiftIntegral(accountDtos.get(0), reqJson, createUserId);
}
}
/**
* 添加账户DTO对象
* 当用户账户不存在时,创建新的账户记录
*
* @param accountDto 账户数据传输对象,包含账户基本信息
* @param reqJson 请求参数JSON对象,包含创建账户所需参数
* @return 账户DTO列表,包含新创建或查询到的账户信息
*/
private List<AccountDto> addAccountDto(AccountDto accountDto, JSONObject reqJson) {
// 获取账户名称:优先使用业主名称,其次使用用户名称
String acctName = getAccountName(reqJson);
// 如果账户名称为空,返回空列表,表示无法创建账户
if (StringUtil.isEmpty(acctName)) {
return new ArrayList<>();
}
// 使用分布式锁确保账户创建的原子性,防止并发创建重复账户
String requestId = DistributedLock.getLockUUID(); // 生成唯一锁标识
String key = this.getClass().getSimpleName() + "AddCountDto" + reqJson.getString("link"); // 构建锁的key
try {
// 获取分布式锁,确保同一时间只有一个线程可以创建账户
DistributedLock.waitGetDistributedLock(key, requestId);
// 创建账户PO对象并设置参数
AccountPo accountPo = new AccountPo();
accountPo.setAmount("0"); // 初始账户余额设为0
accountPo.setAcctId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_acctId)); // 生成账户ID
accountPo.setObjId(reqJson.getString("objId")); // 设置对象ID
accountPo.setObjType(AccountDto.OBJ_TYPE_PERSON); // 设置对象类型为个人
accountPo.setAcctType(reqJson.getString("acctType")); // 设置账户类型
accountPo.setAcctName(acctName); // 设置账户名称
|
9750b443
王彪总
fix(config): 更新配置...
|
195
|
accountPo.setPartId(reqJson.getString("communityId")); // 设置项目ID
|
88e030b7
王彪总
init project
|
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
accountPo.setLink(reqJson.getString("link")); // 设置关联手机号
// 保存账户信息到数据库
accountInnerServiceSMOImpl.saveAccount(accountPo);
// 重新查询账户信息并返回,确保获取到最新的账户数据
List<AccountDto> accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto);
return accountDtos;
} finally {
// 释放分布式锁,确保锁一定会被释放
DistributedLock.releaseDistributedLock(requestId, key);
}
}
/**
* 获取账户名称
* 根据手机号查询业主或用户信息,获取账户显示名称
*
|
9750b443
王彪总
fix(config): 更新配置...
|
214
|
* @param reqJson 请求参数JSON对象,包含手机号和项目ID
|
88e030b7
王彪总
init project
|
215
216
217
218
|
* @return 账户名称,优先返回业主名称,其次返回用户名称
* @throws CmdException 当既不是业主也不是用户时抛出异常
*/
private String getAccountName(JSONObject reqJson) {
|
9750b443
王彪总
fix(config): 更新配置...
|
219
|
// 优先查询业主信息,根据手机号和项目ID查询
|
88e030b7
王彪总
init project
|
220
221
|
OwnerDto tmpOwnerDto = new OwnerDto();
tmpOwnerDto.setLink(reqJson.getString("link")); // 设置手机号
|
9750b443
王彪总
fix(config): 更新配置...
|
222
|
tmpOwnerDto.setCommunityId(reqJson.getString("communityId")); // 设置项目ID
|
88e030b7
王彪总
init project
|
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(tmpOwnerDto);
// 如果找到业主,使用业主信息
if (!ListUtil.isNull(ownerDtos)) {
reqJson.put("objId", ownerDtos.get(0).getMemberId()); // 将业主ID设置到请求参数中
return ownerDtos.get(0).getName(); // 返回业主名称
}
// 如果业主不存在,查询用户信息(游客)
UserDto userDto = new UserDto();
userDto.setTel(reqJson.getString("link")); // 设置手机号查询用户
List<UserDto> userDtos = userV1InnerServiceSMOImpl.queryUsers(userDto);
// 如果找到用户,使用用户信息
if (userDtos != null && userDtos.size() > 0) {
reqJson.put("objId", "-1"); // 设置对象ID为-1,表示游客
return userDtos.get(0).getName(); // 返回用户名称
}
// 既不是业主也不是用户,抛出异常
throw new CmdException("业主不存在");
}
/**
* 处理积分赠送逻辑
* 为积分账户创建积分赠送明细记录
*
* @param accountDto 账户数据传输对象,包含账户基本信息
* @param reqJson 请求参数JSON对象,包含赠送相关信息
* @param createUserId 创建用户ID,记录操作人
* @throws CmdException 当积分规则不存在或业主不存在时抛出异常
*/
private void doGiftIntegral(AccountDto accountDto, JSONObject reqJson,String createUserId) {
|
9750b443
王彪总
fix(config): 更新配置...
|
256
|
// 查询积分配置信息,根据项目ID查询积分规则
|
88e030b7
王彪总
init project
|
257
|
IntegralConfigDto integralConfigDto = new IntegralConfigDto();
|
9750b443
王彪总
fix(config): 更新配置...
|
258
|
integralConfigDto.setCommunityId(reqJson.getString("communityId")); // 设置项目ID
|
88e030b7
王彪总
init project
|
259
260
261
262
263
264
265
266
267
268
|
List<IntegralConfigDto> integralConfigDtos = integralConfigV1InnerServiceSMOImpl.queryIntegralConfigs(integralConfigDto);
// 验证积分规则是否存在,不存在则抛出异常
if(integralConfigDtos == null || integralConfigDtos.size()< 1){
throw new CmdException("积分规则不存在,请添加");
}
// 查询业主信息,确保业主存在
OwnerDto tmpOwnerDto = new OwnerDto();
tmpOwnerDto.setLink(reqJson.getString("link")); // 设置手机号
|
9750b443
王彪总
fix(config): 更新配置...
|
269
|
tmpOwnerDto.setCommunityId(reqJson.getString("communityId")); // 设置项目ID
|
88e030b7
王彪总
init project
|
270
271
272
273
274
275
276
277
278
|
List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(tmpOwnerDto);
// 如果业主不存在,直接返回,不记录积分赠送明细
if (ownerDtos != null && ownerDtos.size() > 0) {
return;
}
// 创建积分赠送明细记录,记录积分赠送的详细信息
IntegralGiftDetailPo integralGiftDetailPo = new IntegralGiftDetailPo();
|
9750b443
王彪总
fix(config): 更新配置...
|
279
|
integralGiftDetailPo.setCommunityId(reqJson.getString("communityId")); // 设置项目ID
|
88e030b7
王彪总
init project
|
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
integralGiftDetailPo.setDetailId(GenerateCodeFactory.getGeneratorId("11")); // 生成明细ID
integralGiftDetailPo.setConfigId(integralConfigDtos.get(0).getConfigId()); // 设置配置ID
integralGiftDetailPo.setConfigName(integralConfigDtos.get(0).getConfigName()); // 设置配置名称
integralGiftDetailPo.setRuleId("-1"); // 设置规则ID为-1,表示手工赠送
integralGiftDetailPo.setRuleName(reqJson.getString("ruleName")); // 设置规则名称
integralGiftDetailPo.setQuantity(reqJson.getString("quantity")); // 设置赠送数量
integralGiftDetailPo.setCreateUserId(createUserId); // 设置创建用户ID
integralGiftDetailPo.setUserName(ownerDtos.get(0).getName()); // 设置用户名称
integralGiftDetailPo.setTel(ownerDtos.get(0).getLink()); // 设置用户手机号
// 保存积分赠送明细到数据库
integralGiftDetailV1InnerServiceSMOImpl.saveIntegralGiftDetail(integralGiftDetailPo);
}
}
|