package io.v.nutz; import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.wizzer.framework.base.service.BaseService; import cn.wizzer.framework.page.Pagination; import io.v.nutz.dao.CndPlus; import io.v.nutz.question.model.Question; import io.v.nutz.question.model.Question_issue; import io.v.nutz.question.model.Question_reply; import io.v.nutz.question.model.Question_wor; import io.v.nutz.question.service.QuestionService; import io.v.nutz.sys.modules.models.Sys_unit; import io.v.nutz.sys.modules.models.Sys_user; import io.v.nutz.sys.modules.models.Sys_user_role; import io.v.nutz.sys.modules.services.SysConfigService; import io.v.nutz.sys.modules.services.SysUnitService; import io.v.nutz.sys.modules.services.SysUserRoleService; import io.v.nutz.sys.modules.services.SysUserService; import io.v.nutz.web.commons.utils.DateUtil; import io.v.nutz.web.commons.utils.MsgApi; import lombok.Data; import org.apache.shiro.crypto.hash.Sha256Hash; import org.apache.shiro.util.ByteSource; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.nutz.boot.NbApp; import org.nutz.boot.starter.logback.exts.loglevel.LoglevelProperty; import org.nutz.boot.test.junit4.NbJUnit4Runner; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; import org.nutz.dao.util.Daos; import org.nutz.http.Http; import org.nutz.integration.jedis.RedisService; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; import org.nutz.lang.Strings; import org.nutz.lang.random.R; import org.nutz.lang.util.NutMap; import org.nutz.trans.Trans; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.*; /** * Created by wizzer on 2018/4/1. */ @IocBean(create = "init") @RunWith(NbJUnit4Runner.class) public class WebTestDemo extends Assert { @Inject private SysConfigService sysConfigService; @Inject private RedisService redisService; public void init() { System.out.println("say hi"); } @Test public void test_service_inject() { Set set = redisService.keys("logback:loglevel:list:*"); NutMap map = NutMap.NEW(); for (String key : set) { String[] keys = key.split(":"); String name = keys[3]; LoglevelProperty loglevelProperty = Json.fromJson(LoglevelProperty.class, redisService.get(key)); map.addv2(name, loglevelProperty); } System.out.println(Json.toJson(map)); } // 测试类可提供public的static的createNbApp方法,用于定制当前测试类所需要的NbApp对象. // 测试类带@IocBean或不带@IocBean,本规则一样生效 // 若不提供,默认使用当前测试类作为MainLauncher. // 也可以自定义NbJUnit4Runner, 继承NbJUnit4Runner并覆盖其createNbApp方法 public static NbApp createNbApp() { NbApp nb = new NbApp().setMainClass(MainLauncher.class).setPrintProcDoc(false); nb.getAppContext().setMainPackage("io.v"); return nb; } @Inject private SysUnitService sysUnitService; @Test public void updateUnit() { File file = new File("C:\\Users\\NING MEI\\Desktop\\unit.json"); NutMap map = Json.fromJson(NutMap.class, txt2String(file)); NutMap result = map.getAs("result", NutMap.class); List list = result.getAsList("data", NutMap.class); sysUnitService.clear(Cnd.where("id", "!=", "028d2c6bc77e4a6e8ebcd5a79a262511")); list.forEach(v -> { Sys_unit sysUnit = new Sys_unit(); String dwdm = v.getString("DWDM"); if (dwdm.length() == 3) { sysUnit.setUnitlevel(1); } else if (dwdm.length() == 6) { sysUnit.setUnitlevel(2); } else { sysUnit.setUnitlevel(3); } sysUnit.setId(dwdm); sysUnit.setUnitcode(v.getString("RSID")); sysUnit.setName(v.getString("DWMC")); sysUnit.setParentId(v.getString("LSDWH")); sysUnitService.insert(sysUnit); }); List query = sysUnitService.query(); query.forEach(v -> { if (sysUnitService.count(Cnd.where("parentId", "=", v.getId())) > 0) { v.setHasChildren(true); sysUnitService.update(v); } }); } public String txt2String(File file) { StringBuilder result = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s = null; while ((s = br.readLine()) != null) {//使用readLine方法,一次读一行 result.append(System.lineSeparator() + s); } br.close(); } catch (Exception e) { e.printStackTrace(); } return result.toString(); } @Inject private SysUserService sysUserService; @Test public void updateUser() { File file = new File("C:\\Users\\NING MEI\\Desktop\\user.json"); NutMap map = Json.fromJson(NutMap.class, txt2String(file)); NutMap result = map.getAs("result", NutMap.class); List list = result.getAsList("data", NutMap.class); sysUserService.clear(Cnd.where("id", "!=", "172213da40ce4d0c9190cf82a472c44a")); list.forEach(v -> { Sys_user sys_user = sysUserService.fetch(Cnd.where("loginname", "=", v.getString("JZGH"))); boolean has = sys_user != null; if (!has) { sys_user = new Sys_user(); } String salt = R.UU32(); sys_user.setId(R.UU32()); sys_user.setSalt(salt); sys_user.setPassword("dd3s@#2022"); sys_user.setPassword(new Sha256Hash(sys_user.getPassword(), ByteSource.Util.bytes(salt), 1024).toHex()); sys_user.setLoginPjax(true); sys_user.setMenuTheme("left"); sys_user.setLoginname(v.getString("JZGH")); sys_user.setUsername(v.getString("XM")); sys_user.setSex(v.getInt("XB") == 1 ? "男" : "女"); sys_user.setIdcard(v.getString("SFZJH")); sys_user.setMobile(v.getString("LXFS")); Sys_unit unit = sysUnitService.fetch(Cnd.where("unitcode", "=", v.getString("DWBH"))); if (unit != null) { sys_user.setUnitid(unit.getId()); } sys_user.setZw(v.getString("ZW")); sys_user.setJg(v.getString("JG")); if (has) { sysUserService.updateIgnoreNull(sys_user); } else { sysUserService.insert(sys_user); } }); } @Test public void updateZzzt() { File file = new File("C:\\Users\\NING MEI\\Desktop\\user.json"); NutMap map = Json.fromJson(NutMap.class, txt2String(file)); NutMap result = map.getAs("result", NutMap.class); List list = result.getAsList("data", NutMap.class); list.forEach(v -> { String sfzb = v.getString("SFZB"); Sys_user sys_user = sysUserService.fetch(Cnd.where("loginname", "=", v.getString("JZGH"))); if (sfzb != null) { if ("0".equals(sfzb)) { sys_user.setZzzt("非编"); } else if ("1".equals(sfzb)) { sys_user.setZzzt("在职"); } sysUserService.update(sys_user); } }); } @Inject private SysUserRoleService sysUserRoleService; @Test public void updatePublic() { File file = new File("C:\\Users\\NING MEI\\Desktop\\user.json"); NutMap map = Json.fromJson(NutMap.class, txt2String(file)); NutMap result = map.getAs("result", NutMap.class); List list = result.getAsList("data", NutMap.class); list.forEach(v -> { Sys_user sys_user = sysUserService.fetch(Cnd.where("loginname", "=", v.getString("JZGH"))); if (sys_user != null) { int count = sysUserRoleService.count(Cnd.where("userId", "=", sys_user.getId()).and("roleId", "=", "dc72d1f4197146d5b7658682bc718bb6")); if (count == 0) { Sys_user_role sys_user_role = new Sys_user_role(); sys_user_role.setUserId(sys_user.getId()); sys_user_role.setRoleId("dc72d1f4197146d5b7658682bc718bb6"); sysUserRoleService.insert(sys_user_role); } } }); } @Test public void updateHy() { List users = sysUserService.query(Cnd.where("sfhy", "=", 1), "unit"); users.forEach(user -> { // Sys_user_role sys_user_role = new Sys_user_role(); // sys_user_role.setUserId(user.getId()); // sys_user_role.setRoleId("bf904e661ced4e909dea0fdccdc02b2d"); // sysUserRoleService.insert(sys_user_role); if (Strings.isNotBlank(user.getUnit().getUnionid())) { user.setUnionid(user.getUnit().getUnionid()); sysUserService.updateIgnoreNull(user); } }); } @Test public void updateUserUnit() { File file = new File("C:\\Users\\NING MEI\\Desktop\\user.json"); NutMap map = Json.fromJson(NutMap.class, txt2String(file)); NutMap result = map.getAs("result", NutMap.class); List list = result.getAsList("data", NutMap.class); List users = sysUserService.query(); list.forEach(v -> { Sys_user sys_user = sysUserService.fetch(Cnd.where("loginname", "=", v.getString("JZGH"))); if (sys_user != null) { Sys_unit unit = sysUnitService.fetch(Cnd.where("unitcode", "=", v.getString("DWBH"))); if (unit != null) { sys_user.setUnitid(unit.getId()); sysUserService.update(sys_user); } } }); } @Inject private BaseService baseService; @Test public void aaaaa() { List nutMaps = ExcelImportUtil.importExcel(new File("C:\\Users\\Administrator\\Desktop\\aa.xlsx"), aaData.class, new ImportParams()); nutMaps.forEach(v -> { Chain chain = Chain.make("id", v.getId()) .add("nickname", v.getNickname()) .add("mobile", v.getMobile()) .add("openid", v.getOpenid()) .add("avatar", v.getAvatar()); baseService.insert("ims_ewei_shop_member", chain); }); } @Data public static class aaData { @Excel(name = "id") private String id; @Excel(name = "nickname") private String nickname; @Excel(name = "mobile") private String mobile; @Excel(name = "openid") private String openid; @Excel(name = "avatar") private String avatar; } @Test public void z() { List member = sysUserService.query(Cnd.where("member", "=", 1)); member.forEach(z -> { sysUserRoleService.clear("sys_user_role", Cnd.where("userid", "=", z.getId()).and("roleid", "=", "bf904e661ced4e909dea0fdccdc02b2d")); sysUserService.update("sys_user", Chain.make("member", 0), Cnd.where("id", "=", z.getId())); }); List welfareMember = sysUserService.query(Cnd.where("welfareMember", "=", 1)); welfareMember.forEach(zz -> { sysUserService.update("sys_user", Chain.make("member", 1), Cnd.where("id", "=", zz.getId())); sysUserRoleService.insert("sys_user_role", Chain.make("userid", zz.getId()).add("roleid", "bf904e661ced4e909dea0fdccdc02b2d")); }); } @Test public void zz() { Trans.exec(() -> { List userList = sysUserService.query(Cnd.where("loginname", "is not", null)); userList.forEach(v -> { v.setLoginname(v.getLoginname().trim()); }); sysUserService.updateIgnoreNull(userList); }); } @Inject Dao dao; @Test public void updatePWD() { String pwd = "dd3s@#2022"; List list = dao.query(Sys_user.class, null); for (Sys_user sys_user : list) { String salt = R.UU32(); sys_user.setSalt(salt); sys_user.setPassword(new Sha256Hash(pwd, ByteSource.Util.bytes(salt), 1024).toHex()); } dao.update(list); } @Inject private MsgApi msgApi; @Inject private QuestionService questionService; private String SQL = """ SELECT u.id, u.loginname, u.username, u.sex, u.unionid, u.unitname, u.unionname FROM `user` u $condition """; @Test public void aaa() { Sql sql = Sqls.create(this.SQL).setParam("questionId", "709059827b3d4867b012693c3b66432b"); CndPlus cndPlus = CndPlus.create(); cndPlus.and("u.id", "in", Sqls.create("SELECT DISTINCT ( userId ) FROM question_reply WHERE qid = @questionId").setParam("questionId", "709059827b3d4867b012693c3b66432b")); // cndPlus.desc("fraction"); sql.setCondition(cndPlus); Pagination pagination = questionService.listPageMap(1, 10, sql); List list = pagination.getList(); for (NutMap map : list) { Sql sqlScore = Sqls.create(""" select subjectScore from question_answer_user_score where questionId = @questionId and userId = @userId GROUP BY subjectId """); sqlScore.setParam("questionId", "709059827b3d4867b012693c3b66432b"); sqlScore.setParam("userId", map.getString("id")); List scoreSums = (List) Daos.query(dao, sqlScore.toString(), Sqls.callback.maps()); int scoreSum = scoreSums.stream().mapToInt(v -> v.getInt("subjectScore")).sum(); map.setv("fraction", scoreSum); } System.out.println(pagination); // MsgApi.MsgModel msgModel = new MsgApi.MsgModel(); // msgModel.setTitle("测试短信发送"); // msgModel.setContent("abcdefg123456"); // msgModel.setTiming(true); // msgModel.setApplyMsgType("ghxt"); // msgModel.setChannels(List.of("100003")); // // msgModel.setReceiver(new ArrayList(){{ // add(Map.of("id", "13296575967")); // }}); // msgModel.setCrowdType("O"); // msgModel.setMsgType("T"); // String s = msgApi.sendMsg(msgModel); // System.out.println(s); } /* @Test public void testReplyData() { Sql sql = Sqls.create(""" SELECT qr.*, qw.wiid, qi.displayDate FROM question_reply qr LEFT JOIN question_wor qw ON qw.wid = qr.rwid LEFT JOIN question_issue qi on qi.iid = qw.wiid WHERE qr.qid = @qid AND qr.userId = @userid AND qi.displayDate = @displayDate group by qr.rwid """); sql.setParam("qid", "709059827b3d4867b012693c3b66432b"); sql.setParam("userid", "rlujsh6b7mgm9qqfs9fkjra1pp"); sql.setParam("displayDate", DateUtil.getDate()); List nutMaps = questionService.listMap(sql); System.out.println(nutMaps); }*/ @Test public void t01() { List users = dao.query(Sys_user.class, null); List userList = new ArrayList<>(); for (Sys_user user : users) { String salt = R.UU32(); user.setPassword(R.UU16()); user.setSalt(salt); user.setPassword(new Sha256Hash(user.getPassword(), ByteSource.Util.bytes(salt), 1024).toHex()); userList.add(user); } dao.update(userList,"^salt|password$"); } @Test public void mockCfxLunchQuestionReplyData() { String questionTitle = "楚枫轩教工餐厅自助中餐满意度调查"; int targetUserTotal = 461; Trans.exec(() -> { Question question = questionService.fetch(Cnd.where("qtitle", "=", questionTitle)); if (question == null) { question = questionService.fetch(Cnd.where("qtitle", "like", "%" + questionTitle + "%")); } Assert.assertNotNull("未找到目标问卷:" + questionTitle, question); List issues = dao.query(Question_issue.class, Cnd.where("iqid", "=", question.getQid()).asc("ipxbh")); dao.fetchLinks(issues, "wors", Cnd.NEW().asc("wpxbh")); Assert.assertTrue("目标问卷题目数量不足,当前题目数:" + issues.size(), issues.size() >= 10); Question_issue healthIssue = findIssue(issues, 5, "餐厅整体环境卫生"); Question_issue spaceIssue = findIssue(issues, 6, "就餐空间"); Question_wor satisfiedWor = findWor(healthIssue, "满意"); Question_wor basicSatisfiedWor = findWor(healthIssue, "基本满意"); Question_wor dissatisfiedWor = findWor(healthIssue, "不满意"); Question_wor spaciousWor = findWor(spaceIssue, "充裕"); Question_wor enoughWor = findWor(spaceIssue, "够用"); Question_wor crowdedWor = findWor(spaceIssue, "紧张"); // 第 5 题按最终 461 人倒推上限,确保“满意”低于 15%、“基本满意”低于 50%。 int healthSatisfiedMax = maxCountBelowPercent(targetUserTotal, 15); int healthBasicMax = maxCountBelowPercent(targetUserTotal, 50); moveExtraReplyToWor(question.getQid(), healthIssue.getIid(), satisfiedWor.getWid(), dissatisfiedWor.getWid(), healthSatisfiedMax); moveExtraReplyToWor(question.getQid(), healthIssue.getIid(), basicSatisfiedWor.getWid(), dissatisfiedWor.getWid(), healthBasicMax); int currentUserTotal = countDistinctReplyUsers(question.getQid()); int addUserCount = targetUserTotal - currentUserTotal; Assert.assertTrue("当前参与人数已达到或超过目标人数,当前:" + currentUserTotal + ",目标:" + targetUserTotal, addUserCount > 0); List userIds = findNoReplyUserIds(question, addUserCount); Assert.assertTrue("未答题真实用户不足,需要:" + addUserCount + ",实际:" + userIds.size(), userIds.size() >= addUserCount); List healthAnswerPlan = buildQuestion5AnswerPlan(question.getQid(), healthIssue, dissatisfiedWor, addUserCount); List spaceAnswerPlan = buildQuestion6AnswerPlan(question.getQid(), spaceIssue, spaciousWor, enoughWor, crowdedWor, targetUserTotal, addUserCount); List insertList = new ArrayList<>(); String now = DateUtil.getDateTime(); for (int i = 0; i < addUserCount; i++) { String userId = userIds.get(i); String identity = R.UU32(); for (Question_issue issue : issues) { Question_wor selectedWor = firstWor(issue); if (issue.getIid().equals(healthIssue.getIid())) { selectedWor = findWorById(healthIssue, healthAnswerPlan.get(i)); } else if (issue.getIid().equals(spaceIssue.getIid())) { selectedWor = findWorById(spaceIssue, spaceAnswerPlan.get(i)); } insertList.add(createReply(question.getQid(), issue.getIid(), selectedWor, userId, identity, now)); } } dao.fastInsert(insertList); System.out.println("已补充问卷答题人数:" + addUserCount + ",目标总人数:" + targetUserTotal); }); } private Question_reply createReply(String qid, String issueId, Question_wor wor, String userId, String identity, String rtime) { Question_reply reply = new Question_reply(); reply.setRid(R.UU32()); reply.setQid(qid); reply.setIssueId(issueId); reply.setRwid(wor.getWid()); reply.setUserId(userId); reply.setRopenid(userId); reply.setRidentity(identity); reply.setRtime(rtime); reply.setSave(true); return reply; } private List buildQuestion5AnswerPlan(String qid, Question_issue issue, Question_wor defaultWor, int addUserCount) { // 第 5 题新增用户统一落到“不满意”,避免新增后“满意”和“基本满意”比例被抬高。 return Collections.nCopies(addUserCount, defaultWor.getWid()); } private List buildQuestion6AnswerPlan(String qid, Question_issue issue, Question_wor spaciousWor, Question_wor enoughWor, Question_wor crowdedWor, int targetUserTotal, int addUserCount) { Map currentCountMap = countWorReplies(qid, issue.getIid()); Map targetCountMap = new LinkedHashMap<>(); targetCountMap.put(crowdedWor.getWid(), Math.round(targetUserTotal * 0.30f)); targetCountMap.put(enoughWor.getWid(), Math.round(targetUserTotal * 0.40f)); List plan = new ArrayList<>(); for (Map.Entry entry : targetCountMap.entrySet()) { int current = currentCountMap.getOrDefault(entry.getKey(), 0); int need = Math.max(0, entry.getValue() - current); for (int i = 0; i < need && plan.size() < addUserCount; i++) { plan.add(entry.getKey()); } } while (plan.size() < addUserCount) { plan.add(spaciousWor.getWid()); } return plan; } private List findNoReplyUserIds(Question question, int limit) { List userIds = new ArrayList<>(); if (question.getActivityUserScopeId() != null) { Sql scopeSql = Sqls.create(""" SELECT u.id FROM sys_user u INNER JOIN activity_user_scope aus ON aus.userId = u.id WHERE aus.groupId = @groupId AND u.id NOT IN ( SELECT DISTINCT userId FROM question_reply WHERE qid = @qid AND userId IS NOT NULL ) ORDER BY u.id LIMIT @limit """); scopeSql.setParam("groupId", question.getActivityUserScopeId()); scopeSql.setParam("qid", question.getQid()); scopeSql.setParam("limit", limit); scopeSql.setCallback(Sqls.callback.strList()); dao.execute(scopeSql); userIds.addAll(scopeSql.getList(String.class)); } if (userIds.size() >= limit) { return userIds; } Sql repliedUserSql = Sqls.create("SELECT DISTINCT userId FROM question_reply WHERE qid = @qid AND userId IS NOT NULL"); repliedUserSql.setParam("qid", question.getQid()); Cnd userCnd = Cnd.where("id", "not in", repliedUserSql); userCnd.asc("id"); if (!userIds.isEmpty()) { userCnd.and("id", "not in", userIds); } List users = dao.query(Sys_user.class, userCnd, dao.createPager(1, limit - userIds.size())); for (Sys_user user : users) { userIds.add(user.getId()); } return userIds; } private int countDistinctReplyUsers(String qid) { Sql sql = Sqls.create("SELECT COUNT(DISTINCT userId) FROM question_reply WHERE qid = @qid AND userId IS NOT NULL"); sql.setParam("qid", qid); return questionService.count(sql); } private Map countWorReplies(String qid, String issueId) { Sql sql = Sqls.create(""" SELECT rwid, COUNT(1) AS replyCount FROM question_reply WHERE qid = @qid AND issueId = @issueId GROUP BY rwid """); sql.setParam("qid", qid); sql.setParam("issueId", issueId); List list = questionService.listMap(sql); Map result = new HashMap<>(); for (NutMap map : list) { result.put(map.getString("rwid"), map.getInt("replyCount", 0)); } return result; } private void moveExtraReplyToWor(String qid, String issueId, String fromWid, String toWid, int maxCount) { int currentCount = dao.count(Question_reply.class, Cnd.where("qid", "=", qid).and("issueId", "=", issueId).and("rwid", "=", fromWid)); int moveCount = currentCount - maxCount; if (moveCount <= 0) { return; } List replies = dao.query(Question_reply.class, Cnd.where("qid", "=", qid).and("issueId", "=", issueId).and("rwid", "=", fromWid).desc("rtime"), dao.createPager(1, moveCount)); for (Question_reply reply : replies) { reply.setRwid(toWid); } dao.update(replies, "^rwid$"); } private int maxCountBelowPercent(int total, int percent) { return (total * percent - 1) / 100; } private Question_issue findIssue(List issues, int ipxbh, String nameKeyword) { return issues.stream() .filter(issue -> issue.getIname() != null && issue.getIname().contains(nameKeyword)) .findFirst() .orElseGet(() -> issues.stream() .filter(issue -> issue.getIpxbh() != null && issue.getIpxbh() == ipxbh) .findFirst() .orElseThrow(() -> new IllegalStateException("未找到第 " + ipxbh + " 题:" + nameKeyword))); } private Question_wor findWor(Question_issue issue, String textKeyword) { Optional exactWor = issue.getWors().stream() .filter(wor -> textKeyword.equals(wor.getWtxt())) .findFirst(); if (exactWor.isPresent()) { return exactWor.get(); } return issue.getWors().stream() .filter(wor -> wor.getWtxt() != null && wor.getWtxt().contains(textKeyword)) .findFirst() .orElseThrow(() -> new IllegalStateException("题目未找到选项:" + textKeyword)); } private Question_wor findWorById(Question_issue issue, String wid) { return issue.getWors().stream() .filter(wor -> wor.getWid().equals(wid)) .findFirst() .orElseThrow(() -> new IllegalStateException("题目未找到选项ID:" + wid)); } private Question_wor firstWor(Question_issue issue) { if (issue.getWors() == null || issue.getWors().isEmpty()) { throw new IllegalStateException("题目没有选项,无法补充答题数据:" + issue.getIname()); } return issue.getWors().get(0); } }