|
70 | 70 | import org.json.JSONObject; |
71 | 71 |
|
72 | 72 | import java.text.ParseException; |
| 73 | +import java.text.SimpleDateFormat; |
73 | 74 | import java.util.*; |
74 | 75 |
|
75 | 76 | import static org.b3log.symphony.util.Symphonys.QN_ENABLED; |
@@ -436,6 +437,7 @@ public static void register() { |
436 | 437 | Dispatcher.post("/admin/pic", adminProcessor::markPic, middlewares); |
437 | 438 | Dispatcher.post("/admin/user/{userId}/cardBg", adminProcessor::setCardBg, middlewares); |
438 | 439 | Dispatcher.get("/admin/stats", adminProcessor::getStats, middlewares); |
| 440 | + Dispatcher.post("/admin/pay-salary", adminProcessor::paySalary); |
439 | 441 | } |
440 | 442 |
|
441 | 443 | final public static ChannelStatsManager manager = new ChannelStatsManager(); |
@@ -2915,6 +2917,120 @@ public void rebuildOneArticleSearchIndex(final RequestContext context) { |
2915 | 2917 | context.sendRedirect(Latkes.getServePath() + "/admin/articles"); |
2916 | 2918 | } |
2917 | 2919 |
|
| 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 | + |
2918 | 3034 | private void updateArticleSearchIndex(final JSONObject article) { |
2919 | 3035 | if (null == article || Article.ARTICLE_TYPE_C_DISCUSSION == article.optInt(Article.ARTICLE_TYPE) |
2920 | 3036 | || Article.ARTICLE_TYPE_C_THOUGHT == article.optInt(Article.ARTICLE_TYPE)) { |
|
0 commit comments