Browse Source

Merge remote-tracking branch 'origin/dev' into dev

dev
lihuangbin666 2 weeks ago
parent
commit
7dd2afc947
  1. 26
      application-tenant/tenant-admin/pom.xml
  2. 16
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/config/CorsConfig.java
  3. 141
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/DocxTemplateController.java
  4. 122
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/LoginController.java
  5. 14
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/SysUserController.java
  6. 5
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/dto/SysUserDto.java
  7. 4
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/model/SysUser.java
  8. 2
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/vo/SysUserVo.java
  9. 4
      application-tenant/tenant-admin/src/main/resources/application-config.yml
  10. 8
      application-tenant/tenant-admin/src/main/resources/tenant-admin-dev.yml
  11. 6
      common/common-association/pom.xml
  12. 16
      common/common-association/src/main/java/apelet/association/config/FrontendConfig.java
  13. 21
      common/common-association/src/main/java/apelet/association/controller/DoPracticeProblemsController.java
  14. 79
      common/common-association/src/main/java/apelet/association/controller/HomeController.java
  15. 12
      common/common-association/src/main/java/apelet/association/dto/UserExerciseDto.java
  16. 156
      common/common-association/src/main/java/apelet/association/plugin/active/ActivityInfoDetailsPlugin.java
  17. 15
      common/common-association/src/main/java/apelet/association/plugin/active/ActivityRegistrationSavePlugin.java
  18. 98
      common/common-association/src/main/java/apelet/association/plugin/active/ActivityRegistrationUpdatePlugin.java
  19. 17
      common/common-association/src/main/java/apelet/association/plugin/active/ActivitySignConfigPlugin.java
  20. 7
      common/common-association/src/main/java/apelet/association/plugin/active/CompetitionDetailsPlugin.java
  21. 76
      common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueSaveOpPlugin.java
  22. 2
      common/common-association/src/main/java/apelet/association/plugin/member/MembershipApplyListFilterPlugin.java
  23. 72
      common/common-association/src/main/java/apelet/association/plugin/member/MembershipFeePayPlugin.java
  24. 29
      common/common-association/src/main/java/apelet/association/plugin/member/MembershipPayPopupPlugin.java
  25. 360
      common/common-association/src/main/java/apelet/association/plugin/member/MembershipSavePlugin.java
  26. 81
      common/common-association/src/main/java/apelet/association/plugin/member/UnitNameChangeFormInitPlugin.java
  27. 25
      common/common-association/src/main/java/apelet/association/plugin/member/UnitNameChangePopupPlugin.java
  28. 6
      common/common-association/src/main/java/apelet/association/plugin/question/QuestionBankListPlugin.java
  29. 19
      common/common-association/src/main/java/apelet/association/plugin/quotation/ContractPlugin.java
  30. 30
      common/common-association/src/main/java/apelet/association/task/ContractPaymentReminderTask.java
  31. 68
      common/common-association/src/main/java/apelet/association/task/UserRenewalReminderTask.java
  32. 82
      common/common-association/src/main/java/apelet/association/utils/WordDocUtil.java
  33. 4
      common/common-qy/pom.xml
  34. 2
      pom.xml

26
application-tenant/tenant-admin/pom.xml

@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!-- easypoi 内部已经依赖 poi 4.1.2,不要再单独引入poi/poi-ooxml!! -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
@ -40,6 +42,20 @@ @@ -40,6 +42,20 @@
<artifactId>easypoi-annotation</artifactId>
<version>4.4.0</version>
</dependency>
<!-- 关键补充:easypoi4.4.0缺少xmlbeans,DocumentHelper初始化失败就是缺这个 -->
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
@ -57,7 +73,7 @@ @@ -57,7 +73,7 @@
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version> <!-- 确保使用最新的稳定版本 -->
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
@ -84,7 +100,7 @@ @@ -84,7 +100,7 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-online</artifactId>
<version>1.0.0</version>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>apelet</groupId>
@ -140,7 +156,7 @@ @@ -140,7 +156,7 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-orm</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>apelet</groupId>
@ -158,8 +174,6 @@ @@ -158,8 +174,6 @@
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
@ -171,4 +185,4 @@ @@ -171,4 +185,4 @@
</plugin>
</plugins>
</build>
</project>
</project>

16
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/config/CorsConfig.java

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
package apelet.tenantadmin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // 允许所有源
.allowedMethods("*") // 允许所有请求方法
.allowedHeaders("*"); // 允许所有请求头
}
}

141
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/controller/DocxTemplateController.java

@ -0,0 +1,141 @@ @@ -0,0 +1,141 @@
package apelet.tenantadmin.tenant.controller;
import apelet.common.core.annotation.MyRequestBody;
import apelet.common.core.exception.MyRuntimeException;
import apelet.common.core.object.ObjectValue;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import cn.hutool.core.io.IoUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@RestController
@RequestMapping("/api/template")
public class DocxTemplateController {
@Autowired
private OrmGenDataSourceUtil ormGenDataSourceUtil;
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\$\\{(.+?)\\}");
/**
* 替换字符串中 ${key}JDK8兼容
*/
private String replaceContent(String text, Map<String, Object> dataMap) {
if (text == null) return "";
Matcher matcher = PLACEHOLDER_PATTERN.matcher(text);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String key = matcher.group(1).trim();
Object val = dataMap.get(key);
String realVal = val == null ? "" : val.toString();
matcher.appendReplacement(sb, Matcher.quoteReplacement(realVal));
}
matcher.appendTail(sb);
return sb.toString();
}
@GetMapping("/downloadDocx")
public void downloadDocx(@RequestParam("id") String quotationId, HttpServletResponse response) {
XWPFDocument document = null;
InputStream templateIs = null;
OutputStream out = null;
try {
// 1. 查数据
ObjectValue objectValue = ormGenDataSourceUtil.queryOne("quotation", quotationId);
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("name", objectValue.getString("name"));
hashMap.put("number", objectValue.getString("number"));
hashMap.put("create_time", objectValue.getString("create_time"));
hashMap.put("qty", objectValue.getObjectValue("qty"));
ObjectValue managerperson = objectValue.getObjectValue("managerperson");
if(managerperson != null){
managerperson = ormGenDataSourceUtil.queryOne(managerperson.getTableName(), managerperson.getString("id"));
hashMap.put("managerperson",1);
}
// 2. 读模板
File file = new File("D:\\work\\xykj-project\\xhgl\\zz-resource\\quotation_template.docx");
templateIs = new FileInputStream(file);
document = new XWPFDocument(templateIs);
// 3. 替换占位符
replaceParagraph(document, hashMap);
replaceTable(document, hashMap);
// 4. 设置响应头 —— 关键!
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setCharacterEncoding("UTF-8");
String fileName = URLEncoder.encode("报价单.docx", StandardCharsets.UTF_8.name())
.replaceAll("\\+", "%20");
// 兼容各浏览器的文件名写法
response.setHeader("Content-Disposition",
"attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + fileName);
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 5. 写出
out = response.getOutputStream();
document.write(out);
out.flush();
} catch (Exception e) {
e.printStackTrace();
throw new MyRuntimeException("导出失败: " + e.getMessage());
} finally {
IoUtil.close(document);
IoUtil.close(templateIs);
IoUtil.close(out);
}
}
private void replaceParagraph(XWPFDocument document, Map<String, Object> dataMap) {
for (XWPFParagraph paragraph : document.getParagraphs()) {
String text = paragraph.getText();
Matcher matcher = PLACEHOLDER_PATTERN.matcher(text);
if (!matcher.find()) {
continue;
}
//清空原有run
for (XWPFRun run : paragraph.getRuns()) {
run.setText("", 0);
}
String newText = replaceContent(text, dataMap);
paragraph.createRun().setText(newText);
}
}
private void replaceTable(XWPFDocument document, Map<String, Object> dataMap) {
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
String text = paragraph.getText();
Matcher matcher = PLACEHOLDER_PATTERN.matcher(text);
if (!matcher.find()) {
continue;
}
for (XWPFRun run : paragraph.getRuns()) {
run.setText("", 0);
}
String newText = replaceContent(text, dataMap);
paragraph.createRun().setText(newText);
}
}
}
}
}
}

122
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/LoginController.java

@ -70,6 +70,7 @@ import java.nio.charset.StandardCharsets; @@ -70,6 +70,7 @@ import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 登录接口控制器类
*
@ -138,6 +139,7 @@ public class LoginController { @@ -138,6 +139,7 @@ public class LoginController {
private static final String SHOW_NAME_FIELD = "showName";
private static final String SHOW_ORDER_FIELD = "showOrder";
private static final String HEAD_IMAGE_URL_FIELD = "headImageUrl";
private static final String SIGNATURE_IMAGE = "signatureImage";
private static final String THIRD_PARTY_CONFIG = "third_party_config";
@ -145,20 +147,18 @@ public class LoginController { @@ -145,20 +147,18 @@ public class LoginController {
private OrmGenDataSourceUtil ormGenDataSourceUtil;
@PostMapping("/getEhrLtpa")
@NoAuthInterface
public ResponseResult<JSONObject> getEhrLtap(
@MyRequestBody String username
){
) {
EasConfig easConfig = ApplicationContextHolder.getBean("easConfig");
String path = easConfig.getLtpaToken();
// String path = "/ehrapp/yd/LtpaToken.properties"; // 测试环境地址
System.out.println("getEasSsoUrl path = " + path);
String password = LtpaTokenManager.generate(username, path).toString();
JSONObject jsonData = new JSONObject();
jsonData.put("ltap",password);
jsonData.put("ltap", password);
return ResponseResult.success(jsonData);
}
@ -220,7 +220,7 @@ public class LoginController { @@ -220,7 +220,7 @@ public class LoginController {
if (entryValue.get(entryFiledKey) instanceof ObjectValue) {
ObjectValue entityValue = (ObjectValue) entryValue.get(entryFiledKey);
Long pk = entityValue.getPkValue();
if (pk == null || pk == 0L) {
if (pk == 0L) {
continue;
}
entityValue = ormGenDataSourceUtil.queryOne(entityValue.getTableName(), pk);
@ -610,7 +610,7 @@ public class LoginController { @@ -610,7 +610,7 @@ public class LoginController {
return;
}
responseInfo.setDownloadUri("/tenantadmin/upms/login/downloadHeadImage");
String newHeadImage = JSONArray.toJSONString(CollUtil.newArrayList(responseInfo));
String newHeadImage = JSON.toJSONString(CollUtil.newArrayList(responseInfo));
if (!sysUserService.changeHeadImage(TokenData.takeFromRequest().getUserId(), newHeadImage)) {
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST));
return;
@ -657,7 +657,7 @@ public class LoginController { @@ -657,7 +657,7 @@ public class LoginController {
log.info("Rest api login.");
try {
// Object tokenObj = redissonClient.getBucket(appid).get();
String accessToken="";
String accessToken = "";
// if (tokenObj != null) {
// accessToken=tokenObj.toString();
// }else {
@ -669,7 +669,7 @@ public class LoginController { @@ -669,7 +669,7 @@ public class LoginController {
paramMap.put("scope", "app");
// 发送 POST 请求
String tokenData = HttpUtil.post(tokenUrl, paramMap);
if (StringUtils.isBlank(tokenData)){
if (StringUtils.isBlank(tokenData)) {
return ResponseResult.error("500", "通过appId获取AccessToken失败,appId:" + appid);
}
JSONObject tokenJson = JSONObject.parseObject(tokenData);
@ -679,10 +679,10 @@ public class LoginController { @@ -679,10 +679,10 @@ public class LoginController {
accessToken = ((JSONObject) (tokenJson.get("data"))).get("accessToken").toString();
//accessToken的有效时间为6400秒,在该有效期内多次获取均返回同一token,
//连许多次请求会被拦截,因此需要本地缓存。为防止极端情况,设置过期时间为6200s
redissonClient.getBucket(appid).set(accessToken,6200,TimeUnit.SECONDS);
redissonClient.getBucket(appid).set(accessToken, 6200, TimeUnit.SECONDS);
// }
String jsonInputString = String.format("{\"appid\":\"%s\", \"ticket\":\"%s\"}", appid, ticket);
String infoUrl="https://www.yunzhijia.com/gateway/ticket/user/acquirecontext?accessToken="+accessToken;
String infoUrl = "https://www.yunzhijia.com/gateway/ticket/user/acquirecontext?accessToken=" + accessToken;
String userStr = HttpUtil.post(infoUrl, jsonInputString);
log.info("validateHubCloudLogin appid:{}, ticket:{} ", appid, ticket);
JSONObject userObj = JSONObject.parseObject(userStr);
@ -729,11 +729,11 @@ public class LoginController { @@ -729,11 +729,11 @@ public class LoginController {
log.info("Rest api mlogin.");
try {
// Object tokenObj = redissonClient.getBucket(appid).get();
String accessToken="";
String accessToken = "";
// if (tokenObj != null) {
// accessToken=tokenObj.toString();
// }else {
if(StringUtils.isEmpty(appid)){
if (StringUtils.isEmpty(appid)) {
appid = hubCloudAppId;
}
String tokenUrl = "https://www.yunzhijia.com/gateway/oauth2/token/getAccessToken";
@ -744,7 +744,7 @@ public class LoginController { @@ -744,7 +744,7 @@ public class LoginController {
paramMap.put("scope", "app");
// 发送 POST 请求
String tokenData = HttpUtil.post(tokenUrl, paramMap);
if (StringUtils.isBlank(tokenData)){
if (StringUtils.isBlank(tokenData)) {
return ResponseResult.error("500", "通过appId获取AccessToken失败,appId:" + appid);
}
JSONObject tokenJson = JSONObject.parseObject(tokenData);
@ -754,10 +754,10 @@ public class LoginController { @@ -754,10 +754,10 @@ public class LoginController {
accessToken = ((JSONObject) (tokenJson.get("data"))).get("accessToken").toString();
//accessToken的有效时间为6400秒,在该有效期内多次获取均返回同一token,
//连许多次请求会被拦截,因此需要本地缓存。为防止极端情况,设置过期时间为6200s
redissonClient.getBucket(appid).set(accessToken,6200,TimeUnit.SECONDS);
redissonClient.getBucket(appid).set(accessToken, 6200, TimeUnit.SECONDS);
// }
String jsonInputString = String.format("{\"appid\":\"%s\", \"ticket\":\"%s\"}", appid, ticket);
String infoUrl="https://www.yunzhijia.com/gateway/ticket/user/acquirecontext?accessToken="+accessToken;
String infoUrl = "https://www.yunzhijia.com/gateway/ticket/user/acquirecontext?accessToken=" + accessToken;
String userStr = HttpUtil.post(infoUrl, jsonInputString);
log.info("validateHubCloudLogin appid:{}, ticket:{} ", appid, ticket);
JSONObject userObj = JSONObject.parseObject(userStr);
@ -804,27 +804,27 @@ public class LoginController { @@ -804,27 +804,27 @@ public class LoginController {
log.info("Rest api login.");
try {
Object tokenObj = redissonClient.getBucket(appKey).get();
String accessToken="";
String accessToken = "";
if (tokenObj != null) {
accessToken=tokenObj.toString();
}else {
accessToken = tokenObj.toString();
} else {
String tokenUrl = "https://api.dingtalk.com/v1.0/oauth2/accessToken";
String jsonInputString = String.format(
"{\"appKey\":\"%s\", \"appSecret\":\"%s\"}",
appKey, dingTalkSecret);
// 发送 POST 请求
String tokenData = HttpUtil.post(tokenUrl, jsonInputString);
if (StringUtils.isBlank(tokenData)){
if (StringUtils.isBlank(tokenData)) {
return ResponseResult.error("500", "通过appKey获取AccessToken失败,appKey:" + appKey);
}
JSONObject tokenJson = JSONObject.parseObject(tokenData);
accessToken = tokenJson.get("accessToken").toString();
//accessToken的有效时间为7200秒,在该有效期内多次获取均返回同一token,
//连许多次请求会被拦截,因此需要本地缓存。为防止极端情况,设置过期时间为6200s
redissonClient.getBucket(appKey).set(accessToken,7000,TimeUnit.SECONDS);
redissonClient.getBucket(appKey).set(accessToken, 7000, TimeUnit.SECONDS);
}
String jsonInputString = String.format("{\"code\":\"%s\"}",code);
String infoUrl="https://oapi.dingtalk.com/topapi/v2/user/getuserinfo?access_token="+accessToken;
String jsonInputString = String.format("{\"code\":\"%s\"}", code);
String infoUrl = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo?access_token=" + accessToken;
String userStr = HttpUtil.post(infoUrl, jsonInputString);
log.info("validateHubCloudLogin appKey:{}, code:{} ", appKey, code);
JSONObject userObj = JSONObject.parseObject(userStr);
@ -841,7 +841,7 @@ public class LoginController { @@ -841,7 +841,7 @@ public class LoginController {
if (user.getUserStatus() == SysUserStatus.STATUS_LOCKED) {
return ResponseResult.error(ErrorCodeEnum.INVALID_USER_STATUS, "登录失败,用户账号被锁定!");
}
JSONObject jsonData = this.buildLoginData(user,null,null);
JSONObject jsonData = this.buildLoginData(user, null, null);
return ResponseResult.success(jsonData);
} catch (Exception e) {
e.printStackTrace();
@ -869,14 +869,14 @@ public class LoginController { @@ -869,14 +869,14 @@ public class LoginController {
log.info("Rest api login.");
try {
if(StringUtils.isBlank(ticket)){
return ResponseResult.error("500","ticket不能为空");
if (StringUtils.isBlank(ticket)) {
return ResponseResult.error("500", "ticket不能为空");
}
String jsonInputString = String.format("{\"ticket\":\"%s\",\"appId\":\"%s\",\"checkType\":1}",ticket,appId);
String jsonInputString = String.format("{\"ticket\":\"%s\",\"appId\":\"%s\",\"checkType\":1}", ticket, appId);
log.info("doLoginValidateDingTalkmJzt ", jsonInputString);
String userStr = HttpUtil.post(ticketUrl, jsonInputString);
if(StringUtils.isBlank(userStr)){
return ResponseResult.error("500","ticket异常:"+ticket);
if (StringUtils.isBlank(userStr)) {
return ResponseResult.error("500", "ticket异常:" + ticket);
}
log.info(" get user result:", userStr);
JSONObject userObj = JSONObject.parseObject(userStr);
@ -896,7 +896,7 @@ public class LoginController { @@ -896,7 +896,7 @@ public class LoginController {
return ResponseResult.success(jsonData);
} catch (Exception e) {
e.printStackTrace();
return ResponseResult.error("500", "自动登录失败:"+e.getMessage());
return ResponseResult.error("500", "自动登录失败:" + e.getMessage());
}
}
@ -1114,24 +1114,24 @@ public class LoginController { @@ -1114,24 +1114,24 @@ public class LoginController {
}
private String getShrRole(String zwcjName){
private String getShrRole(String zwcjName) {
String roleId = "";
if(!StringUtils.isEmpty(zwcjName)){
if (!StringUtils.isEmpty(zwcjName)) {
SysRole role = new SysRole();
if(!zwcjName.equals("员工")){//非员工
if (!zwcjName.equals("员工")) {//非员工
role.setRoleName("非员工");
List<SysRole> roleList = sysRoleService.getSysRoleList(role,"");
if(roleList.size() > 0){
List<SysRole> roleList = sysRoleService.getSysRoleList(role, "");
if (roleList.size() > 0) {
roleId = roleId + roleList.get(0).getRoleId();
}
}
role.setRoleName(zwcjName);
List<SysRole> roleList = sysRoleService.getSysRoleList(role,"");
if(roleList.size() > 0){
if(StringUtils.isEmpty(roleId)){
roleId = roleList.get(0).getRoleId()+"";
}else{
roleId = roleId +","+roleList.get(0).getRoleId();
List<SysRole> roleList = sysRoleService.getSysRoleList(role, "");
if (roleList.size() > 0) {
if (StringUtils.isEmpty(roleId)) {
roleId = roleList.get(0).getRoleId() + "";
} else {
roleId = roleId + "," + roleList.get(0).getRoleId();
}
}
}
@ -1144,33 +1144,15 @@ public class LoginController { @@ -1144,33 +1144,15 @@ public class LoginController {
String sessionId = user.getLoginName() + "_" + deviceType + "_" + MyCommonUtil.generateUuid();
JSONObject jsonData = this.createResponseData(user, sessionId);
TokenData tokenData = this.buildTokenData(user, sessionId, deviceType);
String zwcjName = null;
try {
String result = (String)EasUtil.executeOsfServiceWs("com.kingdee.shr.custom.plat.osf.service.GetPersonalDataService"
,user.getLoginName(),new HashMap());
JSONObject personData = JSONObject.parseObject(result);
tokenData.setPersonId((String) personData.get("personId"));
jsonData.put("personData", JSONObject.parseObject(result));
zwcjName = (String)personData.get("zwcjName");
}catch(Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
this.putTokenDataToSessionCache(tokenData);
// 这里手动将TokenData存入request,便于OperationLogAspect统一处理操作日志。
TokenData.addToRequest(tokenData);
List<MobileEntry> mobileEntryList;
String roleId = getShrRole(zwcjName);
if(!StringUtils.isEmpty(roleId)){
mobileEntryList = mobileEntryService.getMobileEntryListByRoleIds(roleId);
}else{
if (isAdmin) {
mobileEntryList = mobileEntryService.getAllListByOrder(SHOW_ORDER_FIELD);
} else {
mobileEntryList = mobileEntryService.getMobileEntryListByRoleIds(tokenData.getRoleIds());
}
if (isAdmin) {
mobileEntryList = mobileEntryService.getAllListByOrder(SHOW_ORDER_FIELD);
} else {
mobileEntryList = mobileEntryService.getMobileEntryListByRoleIds(tokenData.getRoleIds());
}
jsonData.put("mobileEntryList", mobileEntryList);
Set<String> permSet = new HashSet<>();
if (!isAdmin) {
@ -1185,11 +1167,11 @@ public class LoginController { @@ -1185,11 +1167,11 @@ public class LoginController {
if (mobileEntry.getPcurl() != null) {
mobileEntry.setPcurl(EasUtil.getEasSsoUrl(user.getLoginName(), mobileEntry.getPcurl()));
}
if(mobileEntry.getExtraUrl() != null){
if(mobileEntry.getExtraUrl().contains("?")){
mobileEntry.setExtraUrl(mobileEntry.getExtraUrl()+"&userNumber="+user.getLoginName());
}else{
mobileEntry.setExtraUrl(mobileEntry.getExtraUrl()+"?userNumber="+user.getLoginName());
if (mobileEntry.getExtraUrl() != null) {
if (mobileEntry.getExtraUrl().contains("?")) {
mobileEntry.setExtraUrl(mobileEntry.getExtraUrl() + "&userNumber=" + user.getLoginName());
} else {
mobileEntry.setExtraUrl(mobileEntry.getExtraUrl() + "?userNumber=" + user.getLoginName());
}
}
}
@ -1205,8 +1187,6 @@ public class LoginController { @@ -1205,8 +1187,6 @@ public class LoginController {
sysPermService.putUserSysPermCache(sessionId, user.getUserId(), permSet);
sysDataPermService.putDataPermCache(sessionId, user.getUserId(), user.getDeptId());
}
return jsonData;
}
@ -1221,7 +1201,7 @@ public class LoginController { @@ -1221,7 +1201,7 @@ public class LoginController {
jsonData.put(IS_ADMIN, user.getUserType() == SysUserType.TYPE_ADMIN);
if (user.getDeptId() != null) {
SysDept dept = sysDeptService.getById(user.getDeptId());
if(dept != null){
if (dept != null) {
jsonData.put("deptName", dept.getDeptName());
}
@ -1552,4 +1532,6 @@ public class LoginController { @@ -1552,4 +1532,6 @@ public class LoginController {
private List<String> permCodeList;
private List<String> permList;
}
}

14
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/SysUserController.java

@ -20,6 +20,7 @@ import apelet.tenantadmin.upms.model.SysUser; @@ -20,6 +20,7 @@ import apelet.tenantadmin.upms.model.SysUser;
import apelet.tenantadmin.upms.service.SysUserService;
import apelet.tenantadmin.upms.vo.SysUserVo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -225,7 +226,7 @@ public class SysUserController { @@ -225,7 +226,7 @@ public class SysUserController {
* @return 应答结果对象包含查询结果集
*/
@PostMapping("/list")
public ResponseResult<MyPageData<SysUserVo>> list(
public ResponseResult<?> list(
@MyRequestBody SysUserDto sysUserDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
@ -235,7 +236,16 @@ public class SysUserController { @@ -235,7 +236,16 @@ public class SysUserController {
SysUser sysUserFilter = MyModelUtil.copyTo(sysUserDtoFilter, SysUser.class);
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
List<SysUser> sysUserList = sysUserService.getSysUserListWithRelation(sysUserFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(sysUserList, SysUser.INSTANCE));
MyPageData<SysUserVo> sysUserVoMyPageData = MyPageUtil.makeResponseData(sysUserList, SysUser.INSTANCE);
sysUserVoMyPageData.getDataList().forEach(f ->{
List<SysUser> collect = sysUserList.stream().filter(u -> f.getUserId().equals(u.getUserId())).collect(Collectors.toList());
SysUser sysUser = collect.get(0);
f.setSignatureImage(sysUser.getSignatureImage());
});
return ResponseResult.success(sysUserVoMyPageData);
}

5
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/dto/SysUserDto.java

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
package apelet.tenantadmin.upms.dto;
import apelet.common.core.annotation.UploadFlagColumn;
import apelet.common.core.upload.UploadStoreTypeEnum;
import apelet.common.core.validator.AddGroup;
import apelet.common.core.validator.ConstDictRef;
import apelet.common.core.validator.UpdateGroup;
@ -70,6 +72,9 @@ public class SysUserDto { @@ -70,6 +72,9 @@ public class SysUserDto {
@Schema(description = "用户头像的Url")
private String headImageUrl;
@Schema(description = "签名")
private String signatureImage;
/**
* 用户状态(0: 正常 1: 锁定)
*/

4
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/model/SysUser.java

@ -63,6 +63,10 @@ public class SysUser { @@ -63,6 +63,10 @@ public class SysUser {
@UploadFlagColumn(storeType = UploadStoreTypeEnum.LOCAL_SYSTEM)
private String headImageUrl;
@UploadFlagColumn(storeType = UploadStoreTypeEnum.LOCAL_SYSTEM)
private String signatureImage;
/**
* 用户状态(0: 正常 1: 锁定)
*/

2
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/vo/SysUserVo.java

@ -53,6 +53,8 @@ public class SysUserVo { @@ -53,6 +53,8 @@ public class SysUserVo {
@Schema(description = "用户头像的Url")
private String headImageUrl;
@Schema(description = "签名")
private String signatureImage;
/**
* 用户状态(0: 正常 1: 锁定)
*/

4
application-tenant/tenant-admin/src/main/resources/application-config.yml

@ -88,11 +88,11 @@ aliyun: @@ -88,11 +88,11 @@ aliyun:
oss:
enabled: true
expireSeconds: 1000
endpoint: https://oss-cn-beijing.aliyuncs.com
endpoint: oss-cn-beijing.aliyuncs.com
accessKey: LTAI5t5fEgzRRtdmBvczVS6r
secretKey: uESFiyyi6EwCkM5w4a4pbx6TmVhqgx
bucketName: yy-test12
nginxOssUrl:
minio:
enabled: false

8
application-tenant/tenant-admin/src/main/resources/tenant-admin-dev.yml

@ -218,9 +218,9 @@ spring: @@ -218,9 +218,9 @@ spring:
password: X7&9p8L2@6z4K7!8
driverClassName: com.mysql.cj.jdbc.Driver
name: tenant-admin
initialSize: 10
minIdle: 10
maxActive: 50
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
@ -229,7 +229,7 @@ spring: @@ -229,7 +229,7 @@ spring:
maxOpenPreparedStatements: 20
validationQuery: SELECT 'x'
testWhileIdle: true
testOnBorrow: false
testOnBorrow: true
testOnReturn: false
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
filters: stat,wall

6
common/common-association/pom.xml

@ -42,17 +42,17 @@ @@ -42,17 +42,17 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-generator</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>apelet</groupId>
<artifactId>common-online</artifactId>
<version>1.0.0</version>
<version>1.0.3</version>
</dependency>
<dependency>
<artifactId>common-orm</artifactId>
<groupId>apelet</groupId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
<dependency>
<artifactId>common-msg-notice</artifactId>

16
common/common-association/src/main/java/apelet/association/config/FrontendConfig.java

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
package apelet.association.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
@Data
public class FrontendConfig {
// @Value("${frontend.address}")
public String address;
}

21
common/common-association/src/main/java/apelet/association/controller/DoPracticeProblemsController.java

@ -74,8 +74,10 @@ public class DoPracticeProblemsController { @@ -74,8 +74,10 @@ public class DoPracticeProblemsController {
long batchNumber = IdUtil.getSnowflakeNextId();
result.put("batchNumber", batchNumber);
collection.forEach(f -> {
ObjectValue examQuestions = f.getObjectValue("exam_questions_id");
for (int i = 0; i < collection.size(); i++) {
ObjectValue object = collection.getObject(i);
ObjectValue examQuestions = object.getObjectValue("exam_questions_id");
list.add(examQuestions.getString("id"));
ObjectValue userExercise = new ObjectValue("user_exercise");
@ -92,7 +94,9 @@ public class DoPracticeProblemsController { @@ -92,7 +94,9 @@ public class DoPracticeProblemsController {
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
List<Map<String, Object>> examQuestionsList = new ArrayList<>();
result.put("examQuestionsList", examQuestionsList);
@ -101,7 +105,9 @@ public class DoPracticeProblemsController { @@ -101,7 +105,9 @@ public class DoPracticeProblemsController {
filter.add(new FilterItem("type", FilterItem.not_equals, 4));
ObjectCollection examQuestions = ormGenDataSourceUtil.query("exam_questions", filter, new Selector());
int no = 1;
for (ObjectValue examQuestion : examQuestions) {
for (int i = 0; i < examQuestions.size(); i++) {
ObjectValue examQuestion = examQuestions.getObject(i);
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("id", examQuestion.getString("id"));
hashMap.put("no", no);
@ -118,11 +124,16 @@ public class DoPracticeProblemsController { @@ -118,11 +124,16 @@ public class DoPracticeProblemsController {
hashMap.put("difficulty", examQuestion.getString("difficulty"));
ObjectCollection examQuestionsEntry = examQuestion.getObjectCollection("exam_questions_entry");
List<Map<String, Object>> option = new ArrayList<>();
examQuestionsEntry.forEach(f -> option.add(f.getValues()));
for (int i1 = 0; i1 < examQuestionsEntry.size(); i1++) {
ObjectValue object = examQuestionsEntry.getObject(i1);
option.add(object.getValues());
}
hashMap.put("options", option);
examQuestionsList.add(hashMap);
no++;
}
return ResponseResult.success(result);
}

79
common/common-association/src/main/java/apelet/association/controller/HomeController.java

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
package apelet.association.controller;
import apelet.association.utils.WordDocUtil;
import apelet.common.core.annotation.NoAuthInterface;
import apelet.common.core.object.*;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.FilterItem;
import apelet.common.orm.impl.Selector;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* 课程管理
*/
@RestController
@RequestMapping("/tenantadmin/home")
public class HomeController {
@Autowired
private OrmGenDataSourceUtil ormGenDataSourceUtil;
@PostMapping("/homeData")
public ResponseResult<?> homeData() {
HashMap<String, Integer> map = new HashMap<>();
//报名审核
map.put("ApplicationReview", 0);
//会费逾期
ObjectCollection feePay = ormGenDataSourceUtil.query("membership_fee_pay", new Filter(), new Selector());
ArrayList<Map> objects = new ArrayList<>();
for (int i = 0; i < feePay.size(); i++) {
objects.add(feePay.getObject(i).getValues());
}
Map<Object, List<Map>> parentMap = objects.stream().collect(Collectors.groupingBy(m -> m.get("parent_id")));
AtomicInteger OverdueMembershipFees = new AtomicInteger();
parentMap.forEach((k, v) -> {
// 是否存在任意一条 end_time > 当前时间
boolean anyAfterNow = v.stream()
.anyMatch(m2 -> {
Object endTimeObj = m2.get("end_time");
if(endTimeObj == null){
return false;
}
Date endTime = (Date) endTimeObj;
// end_time > 当前时间
return endTime.after(new Date());
});
if(anyAfterNow){
OverdueMembershipFees.getAndIncrement();
}
});
map.put("OverdueMembershipFees", OverdueMembershipFees.get());
// 入会申请
Filter filter = new Filter();
filter.add(new FilterItem("billstatus", FilterItem.not_equals, "C"));
ObjectCollection membershipApply = ormGenDataSourceUtil.query("membership_apply", filter, new Selector());
map.put("MembershipApplication", membershipApply.size());
return ResponseResult.success(map);
}
}

12
common/common-association/src/main/java/apelet/association/dto/UserExerciseDto.java

@ -1,19 +1,19 @@ @@ -1,19 +1,19 @@
package apelet.association.dto;
import apelet.association.model.UserExercise;
import apelet.association.model.*;
import lombok.Data;
import org.flowable.spring.security.UserDto;
import java.util.List;
@Data
public class UserExerciseDto {
public class UserExerciseDto extends ExamQuestions {
// 考试id
Long examId;
// 考试
Exam exam;
// 题库id
Long questionBankId;
// 题库
QuestionBank questionBank;
// 答题用户id
Long userId;

156
common/common-association/src/main/java/apelet/association/plugin/active/ActivityInfoDetailsPlugin.java

@ -0,0 +1,156 @@ @@ -0,0 +1,156 @@
package apelet.association.plugin.active;
import apelet.association.utils.MyFileUtil;
import apelet.association.utils.QRCodeUtil;
import apelet.common.core.exception.MyRuntimeException;
import apelet.common.core.object.ObjectCollection;
import apelet.common.core.object.ObjectValue;
import apelet.common.core.upload.UploadResponseInfo;
import apelet.common.core.util.ApplicationContextHolder;
import apelet.common.core.util.RsaUtil;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.online.abstractplugin.ListPlugin;
import apelet.common.online.dto.OnlineEventPluginExecuteDto;
import apelet.common.online.model.OnlineDatasource;
import apelet.common.online.model.OnlineTable;
import apelet.common.online.model.constant.AttributeEnum;
import apelet.common.online.service.OnlineDatasourceService;
import apelet.common.online.service.OnlineTableService;
import apelet.common.orm.impl.FilterItem;
import apelet.common.orm.impl.Selector;
import apelet.common.orm.impl.SelectorItem;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 活动详情
*/
public class ActivityInfoDetailsPlugin extends ListPlugin {
private final OrmGenDataSourceUtil ormGenDataSourceUtil;
private final MyFileUtil myFileUtil;
private final QRCodeUtil qrCodeUtil;
private final OnlineDatasourceService onlineDatasourceService;
private final OnlineTableService onlineTableService;
public ActivityInfoDetailsPlugin() {
myFileUtil = ApplicationContextHolder.getBean(MyFileUtil.class);
qrCodeUtil = ApplicationContextHolder.getBean(QRCodeUtil.class);
ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class);
onlineDatasourceService = ApplicationContextHolder.getBean(OnlineDatasourceService.class);
onlineTableService = ApplicationContextHolder.getBean(OnlineTableService.class);
}
@Override
public void formCreated(String widgetVariableName, ObjectValue objectValue) {
this.setWidgetAttribute("id", AttributeEnum.SHOW, false);
}
@Override
public void change(String widgetVariableName, ObjectValue objectValue) {
//添加 会员
if (widgetVariableName.equals("table1786587576012")) {
ObjectCollection memberInvitations = objectValue.getObjectCollection("member_invitation");
List<ObjectValue> collect = memberInvitations.stream().filter(f -> f.getString("rowkey").equals(objectValue.getString("rowkeysubset"))).collect(Collectors.toList());
if (!collect.isEmpty()) {
ObjectValue memberInvitation = collect.get(0);
ObjectValue membershipApplyId = memberInvitation.getObjectValue("membership_apply_id");
if (membershipApplyId == null) {
return;
}
ObjectValue membershipApply = ormGenDataSourceUtil.queryOne(membershipApplyId.getTableName(), membershipApplyId.getString("id"));
ObjectCollection applyEntry = membershipApply.getObjectCollection("membership_apply_entry");
if (applyEntry == null) {
return;
}
ObjectValue entryObject = applyEntry.getObject(0);
this.setWidgetAttributeByEntry("table1786587576012", "unit_name", AttributeEnum.VALUE_CHANGE, membershipApply.getString("unit_name"), objectValue.getString("rowkeysubset"));
this.setWidgetAttributeByEntry("table1786587576012", "person", AttributeEnum.VALUE_CHANGE, entryObject.getString("contact_name"), objectValue.getString("rowkeysubset"));
this.setWidgetAttributeByEntry("table1786587576012", "phone", AttributeEnum.VALUE_CHANGE, entryObject.getString("contact_phone"), objectValue.getString("rowkeysubset"));
}
}
//专家邀请
if(widgetVariableName.equals("table1786587648327")){
ObjectCollection expertInvitations = objectValue.getObjectCollection("expert_invitation");
List<ObjectValue> collect = expertInvitations.stream().filter(f -> f.getString("rowkey").equals(objectValue.getString("rowkeysubset"))).collect(Collectors.toList());
if (!collect.isEmpty()) {
ObjectValue expertInvitation = collect.get(0);
ObjectValue expert = expertInvitation.getObjectValue("expert_id");
expert = ormGenDataSourceUtil.queryOne(expert.getTableName(), expert.getString("id"));
this.setWidgetAttributeByEntry("table1786587648327", "person", AttributeEnum.VALUE_CHANGE, expert.getString("name"), objectValue.getString("rowkeysubset"));
this.setWidgetAttributeByEntry("table1786587648327", "phone", AttributeEnum.VALUE_CHANGE, expert.getString("phone"), objectValue.getString("rowkeysubset"));
}
}
//访客邀请
if(widgetVariableName.equals("table1786587726532")){
}
}
@Override
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) {
// 生成报名二维码
if (widgetVariableName.equals("button1786587153460")) {
String registrationQr = objectValue.getString("registration_qr");
if (StringUtils.isNotEmpty(registrationQr)) {
this.showErrorMessage("当前已存在报名二维码, 请勿重复生成!!!");
return;
}
OnlineEventPluginExecuteDto dto = getDto();
String savePath = System.getProperty("user.dir") + "\\zz-resource\\qrcode";
File QRFile = null;
try {
OnlineDatasource onlineDatasource = onlineDatasourceService.getById(dto.getModel().getDatasourceId());
OnlineTable table = onlineTableService.getOnlineTableFromCache(onlineDatasource.getMasterTableId());
// 生成 报名二维码
long id = objectValue.getLong("id");
String url = "http://192.168.100.42:8099" + "/#/?" +
"loginName=" + "admin" +
"&password=" + "123456" +
"&entryId=" + "2087710350152568832" +
"&bindType=" + "1" +
"&onlineFormId=" + "2048951917157027840" +
"&activeId=" + id;
byte[] checkInQr = qrCodeUtil.generateQrCode(url, 350, 350);
QRFile = MyFileUtil.writeToFile(checkInQr, savePath, "qrcode-" + System.currentTimeMillis() + ".png");
MultipartFile checkInMultipart = MyFileUtil.readFileAsMultipartFile(QRFile, "image/png");
UploadResponseInfo registrationQR = myFileUtil.uploadMyFile(table, "qr", true, checkInMultipart);
String s = "[" + new JSONObject(BeanUtil.beanToMap(registrationQR)).toJSONString() + "]";
this.setWidgetAttribute("registrationQr", AttributeEnum.VALUE_CHANGE, s);
this.setWidgetAttribute("qr", AttributeEnum.VALUE_CHANGE, s);
objectValue.put("registration_qr", s);
objectValue.put("qr", s);
Selector selector = new Selector();
selector.getList().add(new SelectorItem("registration_qr"));
ormGenDataSourceUtil.update(objectValue.getTableName(), objectValue, selector);
} catch (Exception e) {
e.printStackTrace();
throw new MyRuntimeException(e.getMessage());
} finally {
QRFile.delete();
}
}
}
}

15
common/common-association/src/main/java/apelet/association/plugin/active/ActivityRegistrationSavePlugin.java

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
package apelet.association.plugin.active;
import apelet.common.core.object.ObjectValue;
import apelet.common.online.plugin.EndOperationTransactionArgs;
import apelet.common.online.plugin.OperationServicePlugIn;
public class ActivityRegistrationSavePlugin extends OperationServicePlugIn {
@Override
public void endOperationTransaction(EndOperationTransactionArgs e) {
ObjectValue objectValue = e.getModel();
}
}

98
common/common-association/src/main/java/apelet/association/plugin/active/ActivityRegistrationUpdatePlugin.java

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
package apelet.association.plugin.active;
import apelet.common.core.exception.MyRuntimeException;
import apelet.common.core.object.ObjectCollection;
import apelet.common.core.object.ObjectValue;
import apelet.common.core.util.ApplicationContextHolder;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.online.abstractplugin.ListPlugin;
import apelet.common.online.dto.OnlineEventPluginExecuteDto;
import apelet.common.online.model.constant.AttributeEnum;
import apelet.common.online.plugin.EndOperationTransactionArgs;
import apelet.common.online.plugin.OperationServicePlugIn;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.FilterItem;
import apelet.common.orm.impl.Selector;
import com.alibaba.fastjson.JSONObject;
public class ActivityRegistrationUpdatePlugin extends ListPlugin {
private OrmGenDataSourceUtil ormGenDataSourceUtil;
public ActivityRegistrationUpdatePlugin() {
ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class);
}
@Override
public void formCreated(String widgetVariableName, ObjectValue objectValue) {
setWidgetAttribute("id", AttributeEnum.SHOW, false);
JSONObject eventparams = JSONObject.parseObject(objectValue.getString("eventparams"));
JSONObject jsonObject = eventparams.getJSONObject("urlParams");
String activeId = jsonObject.getString("activeId");
if(activeId == null){
throw new MyRuntimeException("活动id不能为空");
}
ObjectValue active = ormGenDataSourceUtil.queryOne("association_activity", activeId);
this.setWidgetAttribute("name", AttributeEnum.VALUE_CHANGE, active.get("name"));
this.setWidgetAttribute("startDate", AttributeEnum.VALUE_CHANGE, active.get("start_time"));
this.setWidgetAttribute("endDate", AttributeEnum.VALUE_CHANGE, active.get("end_time"));
this.setWidgetAttribute("parentId", AttributeEnum.VALUE_CHANGE, active.get("id"));
this.setWidgetAttribute("parentId", AttributeEnum.SHOW, false);
}
@Override
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) {
String unitName = objectValue.getString("unit_name");
String person = objectValue.getString("person");
String phone = objectValue.getString("phone");
String parentId = objectValue.getString("parent_id");
Filter filter1 = new Filter();
filter1.add(new FilterItem("unit_name", FilterItem.equals, unitName));
filter1.add(new FilterItem("person", FilterItem.equals, person));
filter1.add(new FilterItem("phone", FilterItem.equals, phone));
filter1.add(new FilterItem("parent_id", FilterItem.equals, parentId));
ObjectCollection collection = ormGenDataSourceUtil.query("activity_register", filter1, new Selector());
if(!collection.isEmpty()){
this.showWarningMessage("当前单位联系人已报名成功, 请勿重复提交!!!");
this.cancelOperate();
return;
}
ObjectValue activityRegister = new ObjectValue("activity_register");
activityRegister.put("unit_name", unitName);
activityRegister.put("person", person);
activityRegister.put("phone", phone);
activityRegister.put("parent_id", parentId);
Filter filter = new Filter();
filter.add(new FilterItem("unit_name", FilterItem.equals, unitName));
ObjectCollection membershipApplyList = ormGenDataSourceUtil.query("membership_apply", filter, new Selector());
filter = new Filter();
filter.add(new FilterItem("name", FilterItem.equals, person));
ObjectCollection expertManageList = ormGenDataSourceUtil.query("expert_manage", filter, new Selector());
if(membershipApplyList != null && !membershipApplyList.isEmpty()){
ObjectValue object = membershipApplyList.getObject(0);
activityRegister.put("membership_apply_id", object);
}else if(expertManageList != null && !expertManageList.isEmpty()){
ObjectValue object = expertManageList.getObject(0);
activityRegister.put("expert_manage_id", object);
}
try {
ormGenDataSourceUtil.addNew(activityRegister.getTableName(), activityRegister);
} catch (Exception e) {
throw new MyRuntimeException(e.getMessage());
}
this.showMessage("保存成功");
this.cancelOperate();
}
}

17
common/common-association/src/main/java/apelet/association/plugin/active/ActivitySignConfigPlugin.java

@ -36,6 +36,8 @@ import java.util.Map; @@ -36,6 +36,8 @@ import java.util.Map;
@Slf4j
public class ActivitySignConfigPlugin extends ListPlugin {
private final String url = "http://58.48.135.5:8069";
private final MyFileUtil myFileUtil;
private final QRCodeUtil qrCodeUtil;
@ -108,8 +110,8 @@ public class ActivitySignConfigPlugin extends ListPlugin { @@ -108,8 +110,8 @@ public class ActivitySignConfigPlugin extends ListPlugin {
// 生成二维码
String savePath = System.getProperty("user.dir") + "\\zz-resource\\qrcode";
File checkOutFile;
File checkInFile;
File checkOutFile = null;
File checkInFile = null;
try {
Object activityId = objectValue.get("id");
Object activityName = objectValue.get("name");
@ -117,14 +119,14 @@ public class ActivitySignConfigPlugin extends ListPlugin { @@ -117,14 +119,14 @@ public class ActivitySignConfigPlugin extends ListPlugin {
OnlineDatasource onlineDatasource = onlineDatasourceService.getById(model.getDatasourceId());
OnlineTable table = onlineTableService.getOnlineTableFromCache(onlineDatasource.getMasterTableId());
String checkIn = "http://192.168.100.22:8080/#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + activityName + "&type=" + 1;
String checkIn = url + "/#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + activityName + "&type=" + 1;
byte[] checkInQr = qrCodeUtil.generateQrCode(checkIn, 350, 350);
checkInFile = MyFileUtil.writeToFile(checkInQr, savePath, "qrcode-" + System.currentTimeMillis() + ".png");
MultipartFile checkInMultipart = MyFileUtil.readFileAsMultipartFile(checkInFile, "image/png");
UploadResponseInfo checkInUpload = myFileUtil.uploadMyFile(table, "sign_in_code", true, checkInMultipart);
this.setWidgetAttribute("signInCode", AttributeEnum.VALUE_CHANGE, checkInUpload);
String checkOut = "http://192.168.100.22:8080/#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + activityName + "&type=" + 2;
String checkOut = url + "#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + activityName + "&type=" + 2;
byte[] checkOutQr = qrCodeUtil.generateQrCode(checkOut, 300, 300);
checkOutFile = MyFileUtil.writeToFile(checkOutQr, savePath, "qrcode-" + System.currentTimeMillis() + ".png");
MultipartFile checkOutMultipart = MyFileUtil.readFileAsMultipartFile(checkOutFile, "image/png");
@ -133,13 +135,6 @@ public class ActivitySignConfigPlugin extends ListPlugin { @@ -133,13 +135,6 @@ public class ActivitySignConfigPlugin extends ListPlugin {
} catch (Exception e) {
e.printStackTrace();
throw new MyRuntimeException("二维码生成失败, 请联系管理员!!!");
} finally {
try {
FileUtils.cleanDirectory(new File(savePath));
} catch (IOException e) {
e.printStackTrace();
System.err.println("文件刪除失敗!!!");
}
}
}
}

7
common/common-association/src/main/java/apelet/association/plugin/active/CompetitionDetailsPlugin.java

@ -30,9 +30,10 @@ public class CompetitionDetailsPlugin extends ListPlugin { @@ -30,9 +30,10 @@ public class CompetitionDetailsPlugin extends ListPlugin {
filter.add(new FilterItem("association_activity_id",FilterItem.equals, objectValue.get("id")));
ObjectCollection collection = ormGenDataSourceUtil.query("competition_entries", filter, new Selector());
JSONArray jsonArray = new JSONArray();
collection.forEach(f -> {
jsonArray.add(f.getValues());
});
for (int i = 0; i < collection.size(); i++) {
jsonArray.add(collection.getObject(i).getValues());
}
setWidgetAttribute("table1783059589608", AttributeEnum.ADD_ROWS, jsonArray);
}

76
common/common-association/src/main/java/apelet/association/plugin/clueManage/ClueSaveOpPlugin.java

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
package apelet.association.plugin.clueManage;
import apelet.common.core.exception.MyRuntimeException;
import apelet.common.core.object.ObjectCollection;
import apelet.common.core.object.ObjectValue;
import apelet.common.core.object.TokenData;
import apelet.common.core.util.ApplicationContextHolder;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.online.plugin.*;
import apelet.common.orm.impl.Selector;
import apelet.common.orm.impl.SelectorItem;
import cn.hutool.core.date.DateUtil;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: ClueActivateOpPlugin
* @Author: lihuangbin
* @Date: 2026/5/11
* @Description: 激活放弃的线索
*/
public class ClueSaveOpPlugin extends OperationServicePlugIn {
private final OrmGenDataSourceUtil ormGenDataSourceUtil;
private final RedissonClient redissonClient;
public ClueSaveOpPlugin() {
ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class);
redissonClient = ApplicationContextHolder.getBean(RedissonClient.class);
}
@Override
public void endOperationTransaction(EndOperationTransactionArgs e) {
ObjectValue objectValue = e.getModel();
String redisKey = "clue -- " + DateUtil.today();
RBucket<Map<Long, Map<Long, String>>> bucket = redissonClient.getBucket(redisKey);
Map<Long, Map<Long, String>> map;
// 修复:key存在则读取,不存在新建空map
if (bucket.isExists()) {
map = bucket.get();
} else {
map = new HashMap<>();
}
Long userId = TokenData.takeFromRequest().getUserId();
Map<Long, String> userClueMap = map.get(userId);
if (userClueMap == null || userClueMap.isEmpty()) {
userClueMap = new HashMap<>();
}
String context = "完成线索, 名称: " +objectValue.getString("name")
+ ", 咨询内容: " + objectValue.getString("seek_info");
userClueMap.put(objectValue.getLong("id"), context);
map.put(userId, userClueMap);
bucket.set(map);
// 判断:key不存在,写入同时设置过期;key已经存在,只更新value,**不修改TTL**
if (!bucket.isExists()) {
// 计算到次日0点毫秒
LocalDateTime tomorrowZero = LocalDate.now().plusDays(1).atStartOfDay();
long expireMs = ChronoUnit.MILLIS.between(LocalDateTime.now(), tomorrowZero);
// 原子:只有key不存在才写入并设置过期
bucket.expire(expireMs, TimeUnit.MILLISECONDS);
}
}
}

2
common/common-association/src/main/java/apelet/association/plugin/member/MembershipApplyListFilterPlugin.java

@ -20,7 +20,7 @@ public class MembershipApplyListFilterPlugin extends ListPlugin { @@ -20,7 +20,7 @@ public class MembershipApplyListFilterPlugin extends ListPlugin {
/**
* 非历史记录
*/
private static final String IS_HISTORY_NO = "0";
private static final String IS_HISTORY_NO = "1";
@Override
protected Filter getFilter() {

72
common/common-association/src/main/java/apelet/association/plugin/member/MembershipFeePayPlugin.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
package apelet.association.plugin.member;
import apelet.common.core.exception.MyRuntimeException;
import apelet.common.core.object.ObjectCollection;
import apelet.common.core.object.ObjectValue;
import apelet.common.core.util.ApplicationContextHolder;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.online.abstractplugin.ExecutePluginParent;
import apelet.common.online.dto.OnlineEventPluginExecuteDto;
import apelet.common.online.model.ShowParameter;
import apelet.common.online.model.constant.AttributeEnum;
import apelet.common.online.model.constant.ShowTypeEnum;
import apelet.common.online.model.constant.ViewStatus;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.FilterItem;
import apelet.common.orm.impl.Selector;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
public class MembershipFeePayPlugin extends ExecutePluginParent {
private OrmGenDataSourceUtil ormGenDataSourceUtil;
public MembershipFeePayPlugin(){
ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class);
}
@Override
public void formCreated(String widgetVariableName, ObjectValue objectValue) {
super.formCreated(widgetVariableName, objectValue);
OnlineEventPluginExecuteDto dto = getDto();
Map eventParams = dto.getEventParams();
if (eventParams != null) {
this.setWidgetAttribute("parentId", AttributeEnum.VALUE_CHANGE, eventParams.get("id"));
this.setWidgetAttribute("parentId", AttributeEnum.SHOW, false);
this.setWidgetAttribute("membershipDate", AttributeEnum.VALUE_CHANGE, eventParams.get("create_time"));
this.setWidgetAttribute("membershipType", AttributeEnum.VALUE_CHANGE, eventParams.get("membership_type"));
}
}
@Override
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) {
if(widgetVariableName.equals("保存")){
String parentId = objectValue.getString("parent_id");
Date startTime1= objectValue.getDate("membership_date");
Date endTime1 = objectValue.getDate("end_time");
Filter filter = new Filter();
filter.add(new FilterItem("parent_id", FilterItem.equals, parentId));
ObjectCollection collection = ormGenDataSourceUtil.query(objectValue.getTableName(), filter, new Selector());
for (int i = 0; i < collection.size(); i++) {
ObjectValue object = collection.getObject(i);
Date startTime2= object.getDate("membership_date");
Date endTime2 = object.getDate("end_time");
// 判断 startTime - endTime 和 startTime2 - endTime2 是否存在交集
if (startTime1.before(endTime2) && startTime2.before(endTime1)) {
// 存在交集,抛出异常
throw new MyRuntimeException("会费已缴纳, 请勿重复缴纳!!!");
}
}
}
}
}

29
common/common-association/src/main/java/apelet/association/plugin/member/MembershipPayPopupPlugin.java

@ -22,11 +22,6 @@ public class MembershipPayPopupPlugin extends ExecutePluginParent { @@ -22,11 +22,6 @@ public class MembershipPayPopupPlugin extends ExecutePluginParent {
*/
private static final Object FORM_ID = "2049040032123064320";
/**
* 触发按钮的标识 - 对应表单上按钮的 key/标识
* 点击此按钮时触发弹窗
*/
private static final String BUTTON_KEY = "会费缴纳";
/**
* 按钮点击事件
@ -38,19 +33,21 @@ public class MembershipPayPopupPlugin extends ExecutePluginParent { @@ -38,19 +33,21 @@ public class MembershipPayPopupPlugin extends ExecutePluginParent {
@Override
public void buttonTriggered(String buttonKey, ObjectValue objectValue) {
// 仅响应指定按钮的点击事件
if (!BUTTON_KEY.equals(buttonKey)) {
return;
if ("会费缴纳".equals(buttonKey)) {
// 调用 showForm 打开 membershipFeePay 表单
ShowParameter showParameter = new ShowParameter();
showParameter.setFormId(FORM_ID.toString());
showParameter.setHowType(ShowTypeEnum.OPEN_ONLINE_MODAL);
showParameter.setStatus(ViewStatus.EDIT);
Map<String, Object> customParam = new HashMap<>();
customParam.putAll(objectValue.getValues());
showParameter.setCustomParam(customParam);
super.showForm(showParameter);
}
// 调用 showForm 打开 membershipFeePay 表单
ShowParameter showParameter = new ShowParameter();
showParameter.setFormId(FORM_ID.toString());
showParameter.setHowType(ShowTypeEnum.OPEN_ONLINE_MODAL);
showParameter.setStatus(ViewStatus.EDIT);
Map<String, Object> customParam = new HashMap<>();
customParam.put("id", " ");
showParameter.setCustomParam(customParam);
super.showForm(showParameter);
}
}

360
common/common-association/src/main/java/apelet/association/plugin/member/MembershipSavePlugin.java

@ -0,0 +1,360 @@ @@ -0,0 +1,360 @@
package apelet.association.plugin.member;
import apelet.common.core.exception.MyRuntimeException;
import apelet.common.core.object.ObjectCollection;
import apelet.common.core.object.ObjectValue;
import apelet.common.online.abstractplugin.ExecutePluginParent;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.FilterItem;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: test
* @Date: 2026/8/14
* @Description: PC 与移动端共用的"保存"插件
* 场景移动端小程序无法直连后端调试 PC 表单与移动端绑定同一个插件
* PC 上点击"保存"即可复现移动端小程序的保存逻辑控制台/日志可看到保存报错
*
* 保存逻辑
* 1. 根据表单 id 区分"新增""修改"
* - 新增id 为空/0先按 unit_name 验重已存在则拒绝新增否则生成单据号S + yyyyMMdd + 4 位流水 addNew
* - 修改id 非空 id 直接 update不验重
* 2. 无论新增还是修改均写入默认值flow_status / flow_approval_status / org / srcbillid / srcbillnumber / srcentryid = 0history = 1
*/
public class MembershipSavePlugin extends ExecutePluginParent {
/** 保存的目标主表 */
private static final String TABLE_NAME = "membership_apply";
/** 单据号前缀 */
private static final String NUMBER_PREFIX = "S";
/** 单据号日期格式 */
private static final String DATE_PATTERN = "yyyyMMdd";
/** 流水号位数(不足补零,如 0001) */
private static final int SEQ_LENGTH = 4;
/** 唯一键:单位名称数据库字段 */
private static final String FIELD_UNIT_NAME = "unit_name";
/** 数据库字段 -> 表单控件 key 映射(与 UnitNameChangeFormInitPlugin 保持一致) */
private static final Map<String, String> DB_FIELD_WIDGET_MAPPING = new HashMap<>();
static {
DB_FIELD_WIDGET_MAPPING.put("create_user_id", "createUserId");
DB_FIELD_WIDGET_MAPPING.put("create_time", "createTime");
DB_FIELD_WIDGET_MAPPING.put("update_user_id", "updateUserId");
DB_FIELD_WIDGET_MAPPING.put("update_time", "updateTime");
DB_FIELD_WIDGET_MAPPING.put("deleted_flag", "deletedFlag");
DB_FIELD_WIDGET_MAPPING.put("is_history", "history");
DB_FIELD_WIDGET_MAPPING.put("nature_unit", "natureUnit");
DB_FIELD_WIDGET_MAPPING.put("unit_name", "unitName");
DB_FIELD_WIDGET_MAPPING.put("membership_manger_id", "membershipMangerId");
DB_FIELD_WIDGET_MAPPING.put("membership_type", "membershipType");
DB_FIELD_WIDGET_MAPPING.put("menbership_attributes", "menbershipAttributes");
DB_FIELD_WIDGET_MAPPING.put("scope_business", "scopeBusiness");
DB_FIELD_WIDGET_MAPPING.put("business_regist_number", "businessRegistNumber");
DB_FIELD_WIDGET_MAPPING.put("regist_capital", "registCapital");
DB_FIELD_WIDGET_MAPPING.put("regist_time", "registTime");
DB_FIELD_WIDGET_MAPPING.put("company_address", "companyAddress");
DB_FIELD_WIDGET_MAPPING.put("version_number", "versionNumber");
DB_FIELD_WIDGET_MAPPING.put("change_reason", "changeReason");
}
/** 保存时需要跳过的非主表字段(objectValue 中的控件 key) */
private static final String[] SKIP_WIDGET_KEYS = {
"id", // 主键,由框架自动生成或单独处理
"eventparams", // 弹窗参数,非表字段
"sourcebillid", // 来源单据参数
"srcbillid",
"sourcebillnumber",
"srcbillnumber",
"membership_apply_entry", // 子表(本次保存不处理子表)
"table1777360622546",
"rowkeysubset" // 框架内部字段
};
/**
* 按钮点击事件处理"保存"按钮
*
* @param widgetVariableName 按钮标识
* @param objectValue 当前表单数据对象
*/
@Override
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) {
// 仅响应"保存"按钮
if (!"保存".equals(widgetVariableName)) {
return;
}
try {
// 根据表单 id 区分新增/修改
boolean isNew = isNewBill(objectValue);
if (isNew) {
// 新增:先按 unit_name 验重,再生成单据号入库
saveAsNew(objectValue);
this.showMessage("保存成功(新增)");
} else {
// 修改:按 id 直接更新,不验重
saveAsUpdate(objectValue);
this.showMessage("保存成功(修改)");
}
this.cancelOperate();
} catch (Exception e) {
// 保存失败:打印完整堆栈到控制台/日志,便于定位移动端小程序保存报错
e.printStackTrace();
// 抛出异常,让 PC 端弹窗显示具体错误
throw new MyRuntimeException("保存失败:" + e.getMessage());
}
}
/**
* 判断当前表单是新增还是修改
* 表单 id 为空或 0 视为新增否则视为修改
*
* @param objectValue 表单数据对象
* @return true 表示新增
*/
private boolean isNewBill(ObjectValue objectValue) {
Object idObj = objectValue.get("id");
if (idObj == null) {
return true;
}
String idStr = idObj.toString().trim();
return idStr.isEmpty() || "0".equals(idStr);
}
/**
* 新增逻辑 unit_name 验重 -> 生成单据号 -> addNew
*
* @param objectValue 表单数据对象
*/
private void saveAsNew(ObjectValue objectValue) throws Exception {
// 取唯一键单位名称(兼容 unit_name / unitName 两种控件 key)
String unitName = getUnitName(objectValue);
// 新增验重:unit_name 已存在则拒绝新增
ObjectValue existBill = findExistBillByUnitName(unitName);
if (existBill != null) {
throw new MyRuntimeException("单位【" + unitName + "】已存在,请勿重复新增");
}
// 自动生成单据号(S + yyyyMMdd + 4 位流水号)
String number = generateNumber();
// 组装数据库记录并新增
ObjectValue newBill = buildNewBill(objectValue, number);
ormGenDataSourceUtil().addNew(TABLE_NAME, newBill);
}
/**
* 修改逻辑 id 组装记录并 update不验重
* 先查出原记录的单据号 number 并填回避免整体覆盖更新时把 number 置为 null
*
* @param objectValue 表单数据对象
*/
private void saveAsUpdate(ObjectValue objectValue) throws Exception {
ObjectValue updateBill = buildUpdateBill(objectValue);
// 按主键查询原记录,把单据号 number 填回(update 为整体覆盖,缺失字段会被置空)
Object idObj = objectValue.get("id");
if (idObj != null) {
Filter filter = new Filter();
filter.add(new FilterItem("id", FilterItem.equals, idObj));
ObjectCollection collection = ormGenDataSourceUtil().query(TABLE_NAME, filter, null);
if (collection != null && !collection.isEmpty()) {
String existNumber = collection.getObject(0).getString("number");
if (existNumber != null && !existNumber.isEmpty()) {
updateBill.put("number", existNumber);
}
}
}
ormGenDataSourceUtil().update(TABLE_NAME, updateBill, null);
}
/**
* 根据单位名称查询已存在的单据用于新增验重
*
* @param unitName 单位名称
* @return 已存在的单据不存在返回 null
*/
private ObjectValue findExistBillByUnitName(String unitName) throws Exception {
if (unitName == null || unitName.trim().isEmpty()) {
return null;
}
Filter filter = new Filter();
filter.add(new FilterItem(FIELD_UNIT_NAME, FilterItem.equals, unitName));
ObjectCollection collection = ormGenDataSourceUtil().query(TABLE_NAME, filter, null);
if (collection != null && !collection.isEmpty()) {
return collection.getObject(0);
}
return null;
}
/**
* 组装新增记录填充表单字段 + 单据号 + 默认值
*
* @param objectValue 表单数据对象
* @param number 自动生成的单据号
* @return 组装好的数据库记录
*/
private ObjectValue buildNewBill(ObjectValue objectValue, String number) {
ObjectValue newBill = new ObjectValue(TABLE_NAME);
fillFields(newBill, objectValue);
// 设置自动生成的单据号
newBill.put("number", number);
// 设置默认值
setDefaultValues(newBill);
return newBill;
}
/**
* 组装修改记录带主键 id覆盖表单字段单据号保留数据库原值
*
* @param objectValue 表单数据对象
* @return 组装好的数据库记录
*/
private ObjectValue buildUpdateBill(ObjectValue objectValue) {
ObjectValue bill = new ObjectValue(TABLE_NAME);
// 主键 id 作为 update 条件
Object idObj = objectValue.get("id");
if (idObj != null) {
bill.put("id", idObj);
}
fillFields(bill, objectValue);
// 设置默认值
setDefaultValues(bill);
return bill;
}
/**
* 把表单字段复制到目标记录跳过 idnumber非主表字段控件 key 转数据库字段
*
* @param target 目标数据库记录
* @param source 表单数据对象
*/
private void fillFields(ObjectValue target, ObjectValue source) {
Map values = source.getValues();
if (values == null) {
return;
}
for (Object item : values.entrySet()) {
Map.Entry entry = (Map.Entry) item;
String widgetKey = entry.getKey().toString();
// 跳过主键、参数、子表等非主表字段
if (shouldSkipField(widgetKey)) {
continue;
}
// 控件 key 转成数据库字段名
String dbKey = getDbFieldKey(widgetKey);
// id 由单独逻辑处理,number 保留数据库原值(新增时才生成)
if ("id".equals(dbKey) || "number".equals(dbKey)) {
continue;
}
target.put(dbKey, entry.getValue());
}
}
/**
* 设置默认值流程状态/来源单据等字段 = 0
*
* @param bill 数据库记录
*/
private void setDefaultValues(ObjectValue bill) {
bill.put("flow_status", 0);
bill.put("flow_approval_status", 0);
bill.put("org", 0);
bill.put("srcbillid", 0);
bill.put("srcbillnumber", 0);
bill.put("srcentryid", 0);
bill.put("history", 0);
}
/**
* 自动生成单据号S + yyyyMMdd + 当天最大流水号 + 1 4 位零
* 例如当天已有 S202608140001则生成 S202608140002
*
* @return 新单据号
*/
private String generateNumber() throws Exception {
String prefix = NUMBER_PREFIX + LocalDate.now().format(DateTimeFormatter.ofPattern(DATE_PATTERN));
// 查询当天所有单据号,取最大流水号
Filter filter = new Filter();
filter.add(new FilterItem("number", FilterItem.like, prefix + "%"));
ObjectCollection collection = ormGenDataSourceUtil().query(TABLE_NAME, filter, null);
int maxSeq = 0;
if (collection != null) {
for (int i = 0; i < collection.size(); i++) {
String number = collection.getObject(i).getString("number");
if (number != null && number.length() > prefix.length()) {
try {
// 截取前缀后的流水号部分并比较
int seq = Integer.parseInt(number.substring(prefix.length()));
if (seq > maxSeq) {
maxSeq = seq;
}
} catch (NumberFormatException ignored) {
// 忽略非数字流水号
}
}
}
}
// 流水号 +1 并补零到指定位数
return prefix + String.format("%0" + SEQ_LENGTH + "d", maxSeq + 1);
}
/**
* 获取单位名称唯一键兼容 unit_name / unitName 两种控件 key
*
* @param objectValue 表单数据对象
* @return 单位名称
*/
private String getUnitName(ObjectValue objectValue) {
String unitName = objectValue.getString(FIELD_UNIT_NAME);
if (unitName == null || unitName.isEmpty()) {
unitName = objectValue.getString("unitName");
}
return unitName;
}
/**
* 判断字段是否需要跳过主键/弹窗参数/来源参数/子表等
*
* @param widgetKey 控件 key
* @return true 表示跳过
*/
private boolean shouldSkipField(String widgetKey) {
for (String skipKey : SKIP_WIDGET_KEYS) {
if (skipKey.equalsIgnoreCase(widgetKey)) {
return true;
}
}
return false;
}
/**
* 控件 key 转数据库字段名通过 DB_FIELD_WIDGET_MAPPING 反向查找
* 若未匹配则原样返回可能是数据库字段名或无需转换的字段
*
* @param widgetKey 控件 key
* @return 数据库字段名
*/
private String getDbFieldKey(String widgetKey) {
for (Map.Entry<String, String> entry : DB_FIELD_WIDGET_MAPPING.entrySet()) {
if (entry.getValue().equalsIgnoreCase(widgetKey)) {
return entry.getKey();
}
}
return widgetKey;
}
}

81
common/common-association/src/main/java/apelet/association/plugin/member/UnitNameChangeFormInitPlugin.java

@ -98,6 +98,7 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent { @@ -98,6 +98,7 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent {
// 获取源单据ID
String sourceBillId = getSourceBillId(objectValue);
String sourceBillNumber = getSourceBillNumber(objectValue);
this.setWidgetAttribute("history",AttributeEnum.VALUE_CHANGE, "0");
// 如果没有源单据ID,说明不是变更操作,正常返回
if (sourceBillId == null || sourceBillId.isEmpty()) {
@ -147,6 +148,10 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent { @@ -147,6 +148,10 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent {
if (sourceBillId == null || sourceBillId.trim().isEmpty()) {
sourceBillId = objectValue.getString(PARAM_BILL_ID_ALT);
}
Object idObj = objectValue.get("id");
if (idObj != null && !Integer.valueOf(0).equals(idObj)) {
return false;
}
return sourceBillId != null && !sourceBillId.trim().isEmpty();
}
@ -156,6 +161,8 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent { @@ -156,6 +161,8 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent {
throw new RuntimeException("获取数据库连接失败");
}
int version = markOldBillsHistory(ormUtil, objectValue);
ObjectValue newBill = new ObjectValue("membership_apply");
Map values = objectValue.getValues();
for (Object item : values.entrySet()) {
@ -166,6 +173,8 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent { @@ -166,6 +173,8 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent {
}
newBill.put(getDbFieldKey(key), entry.getValue());
}
newBill.put("history", "0");
newBill.put("version_number", version);
ObjectCollection detailEntry = copyEntryForManualSave(objectValue.getObjectCollection(CHILD_WIDGET_KEY));
if (detailEntry != null && !detailEntry.isEmpty()) {
@ -175,6 +184,64 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent { @@ -175,6 +184,64 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent {
ormUtil.addNew("membership_apply", newBill);
}
private int markOldBillsHistory(OrmGenDataSourceUtil ormUtil, ObjectValue objectValue) throws Exception {
String sourceBillId = getSourceBillId(objectValue);
if (sourceBillId == null || sourceBillId.trim().isEmpty()) {
sourceBillId = objectValue.getString(PARAM_BILL_ID);
}
if (sourceBillId == null || sourceBillId.trim().isEmpty()) {
sourceBillId = objectValue.getString(PARAM_BILL_ID_ALT);
}
if (sourceBillId == null || sourceBillId.trim().isEmpty()) {
return 1;
}
apelet.common.orm.impl.Filter sourceFilter = new apelet.common.orm.impl.Filter();
sourceFilter.add(new apelet.common.orm.impl.FilterItem("id", "=", sourceBillId));
ObjectCollection sourceCollection = ormUtil.query("membership_apply", sourceFilter, null);
if (sourceCollection == null || sourceCollection.isEmpty()) {
return 1;
}
ObjectValue sourceBill = sourceCollection.getObject(0);
if (sourceBill == null) {
return 1;
}
String number = sourceBill.getString("number");
if (number == null || number.trim().isEmpty()) {
return 1;
}
apelet.common.orm.impl.Filter sameNumberFilter = new apelet.common.orm.impl.Filter();
sameNumberFilter.add(new apelet.common.orm.impl.FilterItem("number", "=", number));
ObjectCollection sameBills = ormUtil.query("membership_apply", sameNumberFilter, null);
if (sameBills == null || sameBills.isEmpty()) {
sourceBill.put("history", "1");
sourceBill.put("version_number", 1);
ormUtil.update("membership_apply", sourceBill, null);
return 2;
}
List<ObjectValue> bills = new java.util.ArrayList<>();
for (int i = 0; i < sameBills.size(); i++) {
ObjectValue bill = sameBills.getObject(i);
if (bill != null) {
bills.add(bill);
}
}
bills.sort(java.util.Comparator.comparingInt(this::getVersionNumberSafe));
int version = 1;
for (ObjectValue bill : bills) {
bill.put("history", "1");
bill.put("version_number", version);
ormUtil.update("membership_apply", bill, null);
version++;
}
return version;
}
private boolean shouldSkipManualSaveField(String key) {
return "id".equals(key)
|| "eventparams".equals(key)
@ -391,21 +458,13 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent { @@ -391,21 +458,13 @@ public class UnitNameChangeFormInitPlugin extends ExecutePluginParent {
int version = 1;
if (sameBills != null && !sameBills.isEmpty()) {
List<ObjectValue> bills = new java.util.ArrayList<>();
for (int i = 0; i < sameBills.size(); i++) {
ObjectValue bill = sameBills.getObject(i);
if (bill != null) {
bills.add(bill);
int billVersion = getVersionNumberSafe(bill);
if (billVersion >= version) {
version = billVersion + 1;
}
}
bills.sort(java.util.Comparator.comparingInt(this::getVersionNumberSafe));
for (ObjectValue bill : bills) {
bill.put("is_history", 1);
bill.put("version_number", version);
ormUtil.update("membership_apply", bill, null);
version++;
}
}
objectValue.put("is_history", 0);

25
common/common-association/src/main/java/apelet/association/plugin/member/UnitNameChangePopupPlugin.java

@ -50,6 +50,31 @@ public class UnitNameChangePopupPlugin extends ListPlugin { @@ -50,6 +50,31 @@ public class UnitNameChangePopupPlugin extends ListPlugin {
return filter;
}
@Override
protected void afterLoadData(List<Map<String, Object>> dataList) {
super.afterLoadData(dataList);
}
@Override
public void afterLoadFormData(String widgetVariableName, ObjectValue objectValue) {
super.afterLoadFormData(widgetVariableName, objectValue);
}
@Override
public void beforeLoadTableData(String widgetVariableName, ObjectValue objectValue) {
OnlineEventPluginExecuteDto dto = getDto();
super.beforeLoadTableData(widgetVariableName, objectValue);
}
@Override
public void formCreated(String widgetVariableName, ObjectValue objectValue) {
super.formCreated(widgetVariableName, objectValue);
}
/**
* 按钮点击事件列表按钮
* 点击"变更"按钮时通过 getSelectData 获取列表中选中行的单据数据

6
common/common-association/src/main/java/apelet/association/plugin/question/QuestionBankListPlugin.java

@ -39,7 +39,8 @@ public class QuestionBankListPlugin extends ListPlugin { @@ -39,7 +39,8 @@ public class QuestionBankListPlugin extends ListPlugin {
return;
}
long batchNumber = IdUtil.getSnowflakeNextId();
collection.forEach(f -> {
for (int i = 0; i < collection.size(); i++) {
ObjectValue f = collection.getObject(i);
ObjectValue userExercise = new ObjectValue("user_exercise");
userExercise.put("question_bank_id", questionBank);
userExercise.put("exam_questions_id", f.getObjectValue("exam_questions_id"));
@ -51,7 +52,8 @@ public class QuestionBankListPlugin extends ListPlugin { @@ -51,7 +52,8 @@ public class QuestionBankListPlugin extends ListPlugin {
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
ObjectValue object = collection.getObject(0);
ObjectValue examQuestions = object.getObjectValue("exam_questions_id");
ShowParameter showParameter = new ShowParameter();

19
common/common-association/src/main/java/apelet/association/plugin/quotation/ContractPlugin.java

@ -1,9 +1,14 @@ @@ -1,9 +1,14 @@
package apelet.association.plugin.quotation;
import apelet.association.utils.WordDocUtil;
import apelet.common.core.object.ObjectValue;
import apelet.common.online.abstractplugin.ListPlugin;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.FilterItem;
import java.time.LocalDate;
import java.util.Map;
/*
合同列表界面设置过滤条件
@ -15,4 +20,18 @@ public class ContractPlugin extends ListPlugin { @@ -15,4 +20,18 @@ public class ContractPlugin extends ListPlugin {
filter.add(new FilterItem("status", FilterItem.equals, "3"));
return filter;
}
@Override
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) {
if(widgetVariableName.equals("合同导出")){
try {
Map values = objectValue.getValues();
String template = System.getProperty("user.dir") + "\\zz-resource\\quotation_template.docx";
String outPath = System.getProperty("user.dir") + "\\zz-resource\\quotation_"+ System.currentTimeMillis()+".docx";
WordDocUtil.renderLocalDoc(template, outPath, values);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}

30
common/common-association/src/main/java/apelet/association/task/ContractPaymentReminderTask.java

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
package apelet.association.task;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.orm.impl.Filter;
import apelet.msgnotice.service.SystemMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ContractPaymentReminderTask {
// 提前 30 天提醒
private static final int REMIND_BEFORE_DAYS = 7;
@Autowired
private OrmGenDataSourceUtil ormGenDataSourceUtil;
@Autowired
private SystemMessageService systemMessageService;
@Scheduled(cron = "0 0 1 * * ?")
public void sendRemind() {
Filter filter = new Filter();
// ormGenDataSourceUtil.query("", )
}
}

68
common/common-association/src/main/java/apelet/association/task/UserRenewalReminderTask.java

@ -6,6 +6,8 @@ import apelet.common.core.object.ObjectValue; @@ -6,6 +6,8 @@ import apelet.common.core.object.ObjectValue;
import apelet.common.generator.utils.OrmGenDataSourceUtil;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.Selector;
import apelet.msgnotice.dto.SendSystemMessageDto;
import apelet.msgnotice.service.SystemMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -13,6 +15,7 @@ import org.springframework.stereotype.Component; @@ -13,6 +15,7 @@ import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
@Component
@ -20,11 +23,13 @@ public class UserRenewalReminderTask { @@ -20,11 +23,13 @@ public class UserRenewalReminderTask {
// 提前 30 天提醒
private static final int REMIND_BEFORE_DAYS = 30;
// 会员年度天数(固定 365)
private static final int YEAR_DAYS = 365;
@Autowired
private OrmGenDataSourceUtil ormGenDataSourceUtil;
@Autowired
private SystemMessageService systemMessageService;
@Scheduled(cron = "0 0 1 * * ?")
public void sendRemind() {
ObjectCollection collection = ormGenDataSourceUtil.query("membership_apply", new Filter(), new Selector());
@ -33,40 +38,37 @@ public class UserRenewalReminderTask { @@ -33,40 +38,37 @@ public class UserRenewalReminderTask {
}
for (int i = 0; i < collection.size(); i++) {
ObjectValue objectValue = collection.getObject(i);
Date registTime = objectValue.getDate("regist_time");
if (needRemind(registTime)) {
// TODO 发送消息提示续费
ObjectCollection feePay = objectValue.getObjectCollection("membership_fee_pay");
Date endTime = null;
for (int j = 0; j < feePay.size(); j++) {
if (j == 0) {
endTime = feePay.getObject(j).getDate("end_time");
} else {
Date endTime1 = feePay.getObject(j).getDate("end_time");
if (endTime1.after(endTime)) {
endTime = endTime1;
}
}
}
// 判断 Date endTime 30天后是否是今天
LocalDate endLocalDate = endTime.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
// endTime +30天
LocalDate plus30Day = endLocalDate.plusDays(30);
// 获取今天日期
LocalDate today = LocalDate.now();
if (plus30Day.isEqual(today)) {
// 发送消息提醒
SendSystemMessageDto sendSystemMessageDto = new SendSystemMessageDto();
sendSystemMessageDto.setTitle("会员续费提醒");
sendSystemMessageDto.setContent("您的会员期限还有30天到期,请及时续费。");
sendSystemMessageDto.setRecipientUserIds(Arrays.asList(objectValue.getLong("membership_manger_id")));
systemMessageService.sendSystemMessage(sendSystemMessageDto);
}
}
}
public boolean needRemind(Date date) {
LocalDate today = LocalDate.now();
LocalDate join = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
if (today.isBefore(join)) {
return false;
}
// 入会到今天总天数
long totalDays = ChronoUnit.DAYS.between(join, today);
// 第几个年度(从 1 开始)
int yearIndex = (int) (totalDays / YEAR_DAYS) + 1;
// 该年度到期日
LocalDate expireDate = join.plusDays((long) YEAR_DAYS * yearIndex);
// 提醒开始日:到期前 30 天
LocalDate remindStart = expireDate.minusDays(REMIND_BEFORE_DAYS);
// 今天在 [remindStart, expireDate] 区间内,则提醒
return !today.isBefore(remindStart) && !today.isAfter(expireDate);
}
}

82
common/common-association/src/main/java/apelet/association/utils/WordDocUtil.java

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
package apelet.association.utils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import java.io.*;
import java.util.Map;
public class WordDocUtil {
/**
* 本地模板生成docx文件输出到本地磁盘
*
* @param templateLocalPath 本地模板绝对路径
* @param outLocalPath 输出文件路径
* @param dataMap 填充数据
* @throws Exception IO异常
*/
public static void renderLocalDoc(String templateLocalPath, String outLocalPath, Map<String, Object> dataMap) throws Exception {
// 自动创建输出文件夹
File outFile = new File(outLocalPath);
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
Configure config = Configure.builder()
.buildGramer("#{", "}")
.build();
try (InputStream templateIn = new FileInputStream(templateLocalPath);
OutputStream fileOut = new FileOutputStream(outLocalPath);
XWPFTemplate template = XWPFTemplate.compile(templateIn, config).render(dataMap)) {
template.write(fileOut);
}
}
/**
* 新增模板渲染直接输出到输出流用于浏览器下载不生成本地临时文件
* @param templateLocalPath 模板文件路径
* @param outputStream response.getOutputStream()
* @param dataMap 填充数据
* @throws Exception ex
*/
public static void renderToOutputStream(String templateLocalPath, OutputStream outputStream, Map<String, Object> dataMap) throws Exception {
Configure config = Configure.builder()
.buildGramer("#{", "}")
.build();
try (InputStream templateIn = new FileInputStream(templateLocalPath);
XWPFTemplate template = XWPFTemplate.compile(templateIn, config).render(dataMap)) {
template.write(outputStream);
}
}
/**
* OSS/网络URL图片构建签字图片专用
*
* @param ossUrl OSS完整图片地址 https://xxx.oss-cn-beijing.aliyuncs.com/sign/sign001.png
* @param widthCm 图片宽度 单位cm
* @param heightCm 图片高度 单位cm
* @return PictureRenderData
*/
public static PictureRenderData getOssPic(String ossUrl, double widthCm, double heightCm) {
// poi‑tl size 参数单位是 像素,注意:不是厘米!!!
return Pictures.ofUrl(ossUrl)
.size((int) widthCm, (int) heightCm)
.create();
}
// 本地图片(备用)
public static PictureRenderData getLocalPic(String imgLocalPath, double width, double height) {
return Pictures.ofLocal(imgLocalPath).size((int) width, (int) height).create();
}
// base64图片(备用)
public static PictureRenderData getBase64Pic(String base64Str, double width, double height) {
return Pictures.ofBase64(base64Str, PictureType.PNG)
.size((int) width, (int) height)
.create();
}
}

4
common/common-qy/pom.xml

@ -26,12 +26,12 @@ @@ -26,12 +26,12 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-generator</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>apelet</groupId>
<artifactId>common-orm</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
</dependencies>

2
pom.xml

@ -289,7 +289,7 @@ @@ -289,7 +289,7 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-orm</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save