Skip to content

Commit a8e5245

Browse files
committed
feat(admin): 添加管理员发放工资功能
- 实现了批量发放工资接口,支持向多个员工发放积分 - 添加了用户身份验证和权限检查机制 - 集成了积分转账服务和通知系统 - 实现了详细的日志记录和操作结果统计 - 添加了错误处理和失败情况的详细反馈 - 创建了工资发放的时间戳记录和完成状态跟踪
1 parent 6df9a7a commit a8e5245

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

src/main/java/org/b3log/symphony/processor/AdminProcessor.java

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import org.json.JSONObject;
7171

7272
import java.text.ParseException;
73+
import java.text.SimpleDateFormat;
7374
import java.util.*;
7475

7576
import static org.b3log.symphony.util.Symphonys.QN_ENABLED;
@@ -436,6 +437,7 @@ public static void register() {
436437
Dispatcher.post("/admin/pic", adminProcessor::markPic, middlewares);
437438
Dispatcher.post("/admin/user/{userId}/cardBg", adminProcessor::setCardBg, middlewares);
438439
Dispatcher.get("/admin/stats", adminProcessor::getStats, middlewares);
440+
Dispatcher.post("/admin/pay-salary", adminProcessor::paySalary);
439441
}
440442

441443
final public static ChannelStatsManager manager = new ChannelStatsManager();
@@ -2915,6 +2917,120 @@ public void rebuildOneArticleSearchIndex(final RequestContext context) {
29152917
context.sendRedirect(Latkes.getServePath() + "/admin/articles");
29162918
}
29172919

2920+
/**
2921+
* Pays salary to employees.
2922+
*
2923+
* @param context the specified context
2924+
*/
2925+
public void paySalary(final RequestContext context) {
2926+
final JSONObject requestJSON = context.requestJSON();
2927+
JSONObject currentUser = Sessions.getUser();
2928+
try {
2929+
currentUser = ApiProcessor.getUserByKey(context.param("apiKey"));
2930+
} catch (NullPointerException ignored) {
2931+
}
2932+
try {
2933+
currentUser = ApiProcessor.getUserByKey(requestJSON.optString("apiKey"));
2934+
} catch (NullPointerException ignored) {
2935+
}
2936+
if (null == currentUser) {
2937+
context.sendError(401);
2938+
context.abort();
2939+
return;
2940+
}
2941+
2942+
if (!Role.ROLE_ID_C_ADMIN.equals(currentUser.optString(User.USER_ROLE))) {
2943+
context.sendError(401);
2944+
context.abort();
2945+
return;
2946+
}
2947+
2948+
final JSONArray employees = requestJSON.optJSONArray("employees");
2949+
2950+
if (null == employees || employees.length() == 0) {
2951+
context.renderJSON(StatusCodes.ERR).renderMsg("员工列表不能为空");
2952+
return;
2953+
}
2954+
2955+
final StringBuilder logMessage = new StringBuilder("发工资详情:\n");
2956+
final long startTime = System.currentTimeMillis();
2957+
int successCount = 0;
2958+
int failCount = 0;
2959+
final StringBuilder failDetails = new StringBuilder();
2960+
2961+
for (int i = 0; i < employees.length(); i++) {
2962+
final JSONObject employee = employees.optJSONObject(i);
2963+
final String userName = employee.optString("userName");
2964+
final int amount = employee.optInt("amount");
2965+
2966+
if (StringUtils.isBlank(userName) || amount <= 0) {
2967+
failCount++;
2968+
failDetails.append("用户名:").append(userName).append(",工资数额无效\n");
2969+
continue;
2970+
}
2971+
2972+
try {
2973+
final JSONObject user = userQueryService.getUserByName(userName);
2974+
if (null == user) {
2975+
failCount++;
2976+
failDetails.append("用户名:").append(userName).append(",用户不存在\n");
2977+
continue;
2978+
}
2979+
2980+
final String toId = user.optString(Keys.OBJECT_ID);
2981+
final String memo = "发放工资";
2982+
final String transferId = pointtransferMgmtService.transfer(Pointtransfer.ID_C_SYS, toId,
2983+
Pointtransfer.TRANSFER_TYPE_C_ACCOUNT2ACCOUNT, amount, toId,
2984+
System.currentTimeMillis(), memo);
2985+
final JSONObject notification = new JSONObject();
2986+
notification.put(Notification.NOTIFICATION_USER_ID, toId);
2987+
notification.put(Notification.NOTIFICATION_DATA_ID, transferId);
2988+
notificationMgmtService.addPointTransferNotification(notification);
2989+
2990+
if (null != transferId) {
2991+
successCount++;
2992+
logMessage.append(userName).append(":").append(amount).append(" 积分\n");
2993+
} else {
2994+
failCount++;
2995+
failDetails.append("用户名:").append(userName).append(",转账失败\n");
2996+
}
2997+
} catch (final Exception e) {
2998+
failCount++;
2999+
failDetails.append("用户名:").append(userName).append(",错误:").append(e.getMessage()).append("\n");
3000+
LOGGER.log(Level.ERROR, "Pay salary to [" + userName + "] failed", e);
3001+
}
3002+
}
3003+
3004+
final long endTime = System.currentTimeMillis();
3005+
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3006+
final String completeTime = sdf.format(new Date(endTime));
3007+
3008+
logMessage.append("\n成功发放:").append(successCount).append(" 人\n");
3009+
if (failCount > 0) {
3010+
logMessage.append("发放失败:").append(failCount).append(" 人\n");
3011+
logMessage.append("失败详情:\n").append(failDetails);
3012+
}
3013+
logMessage.append("\n完成时间:").append(completeTime);
3014+
3015+
// 生成日志
3016+
LogsService.simpleLog(context, "发放工资", logMessage.toString());
3017+
3018+
// 返回结果
3019+
final JSONObject result = new JSONObject();
3020+
result.put("successCount", successCount);
3021+
result.put("failCount", failCount);
3022+
result.put("completeTime", completeTime);
3023+
result.put("logMessage", logMessage.toString());
3024+
3025+
if (failCount > 0) {
3026+
context.renderJSON(StatusCodes.SUCC).renderJSON(result);
3027+
context.renderMsg("部分员工发放失败");
3028+
} else {
3029+
context.renderJSON(StatusCodes.SUCC).renderJSON(result);
3030+
context.renderMsg("工资发放成功");
3031+
}
3032+
}
3033+
29183034
private void updateArticleSearchIndex(final JSONObject article) {
29193035
if (null == article || Article.ARTICLE_TYPE_C_DISCUSSION == article.optInt(Article.ARTICLE_TYPE)
29203036
|| Article.ARTICLE_TYPE_C_THOUGHT == article.optInt(Article.ARTICLE_TYPE)) {

0 commit comments

Comments
 (0)