| @@ -76,6 +76,9 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| @Autowired | |||
| WxCUserMapper wxCUserMapper; | |||
| @Autowired | |||
| WxCardInfoMapper cardInfoMapper; | |||
| JSONObject errorRefundReqMap = JSON.parseObject("{\n" + | |||
| " \"SYSTEMERROR\": {\n" + | |||
| @@ -361,6 +364,19 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| // 卡退款,把卡余额设为0 | |||
| if (wxCouponOrder.getCouponType().equals(EnumCouponType.CARD_MULTIMCH.getCode())) { | |||
| WxCardInfo updateCardInfo = new WxCardInfo(); | |||
| updateCardInfo.setId(couponOrderId); | |||
| updateCardInfo.setRemainingAmount(0); | |||
| try { | |||
| cardInfoMapper.updateById(updateCardInfo); | |||
| } catch (Exception e) { | |||
| logger.error("db failed: wxCardInfo-" + couponOrderId + ", e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| // 查找支付订单 | |||
| WxPayOrder payOrderQ = new WxPayOrder(); | |||
| payOrderQ.updateTenantInfo(wxCouponOrder); | |||
| @@ -167,10 +167,10 @@ public class ShiroConfig { | |||
| } | |||
| @Bean | |||
| public SecurityManager securityManager(@Qualifier("myRetryLimitCredentialsMatcher") MyRetryLimitCredentialsMatcher matcher) { | |||
| public SecurityManager securityManager() { | |||
| DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); | |||
| //设置realm. | |||
| securityManager.setRealm(myShiroRealm(matcher)); | |||
| securityManager.setRealm(myShiroRealm()); | |||
| // 自定义缓存实现 使用redis | |||
| //securityManager.setCacheManager(cacheManager()); | |||
| // 自定义session管理 使用redis | |||
| @@ -179,9 +179,9 @@ public class ShiroConfig { | |||
| } | |||
| @Bean | |||
| public MyShiroRealm myShiroRealm(MyRetryLimitCredentialsMatcher matcher) { | |||
| public MyShiroRealm myShiroRealm() { | |||
| MyShiroRealm myShiroRealm = new MyShiroRealm(); | |||
| myShiroRealm.setCredentialsMatcher(matcher); | |||
| myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); | |||
| return myShiroRealm; | |||
| } | |||
| @@ -194,7 +194,6 @@ public class ShiroConfig { | |||
| * | |||
| * @return | |||
| */ | |||
| @Bean(name = "myRetryLimitCredentialsMatcher") | |||
| public MyRetryLimitCredentialsMatcher hashedCredentialsMatcher() { | |||
| MyRetryLimitCredentialsMatcher hashedCredentialsMatcher = new MyRetryLimitCredentialsMatcher(); | |||
| @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule; | |||
| import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | |||
| import com.iformall.interceptor.HttpServletRequestWrapperFilter; | |||
| import com.iformall.interceptor.RequestInterceptor; | |||
| import com.iformall.service.MallResourceService; | |||
| import com.iformall.ueditor.ActionEnter; | |||
| import com.iformall.ueditor.ConfigManager; | |||
| import com.iformall.ueditor.UEditorConfig; | |||
| @@ -44,10 +45,13 @@ public class WebConfig implements WebMvcConfigurer { | |||
| @Autowired | |||
| private RequestInterceptor requestInterceptor; | |||
| @Autowired | |||
| private MallResourceService mallResourceService; | |||
| @Bean | |||
| @ConditionalOnMissingBean(ActionEnter.class) | |||
| public ActionEnter actionEnter() { | |||
| ActionEnter actionEnter = new ActionEnter(ConfigManager.getInstance(uEditorConfig, awsProperty)); | |||
| ActionEnter actionEnter = new ActionEnter(ConfigManager.getInstance(uEditorConfig, awsProperty, mallResourceService)); | |||
| return actionEnter; | |||
| } | |||
| @@ -72,7 +76,7 @@ public class WebConfig implements WebMvcConfigurer { | |||
| * | |||
| * @return | |||
| */ | |||
| @Bean | |||
| @Bean("myCharacterEncodingFilter") | |||
| public Filter characterEncodingFilter() { | |||
| CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); | |||
| characterEncodingFilter.setEncoding("UTF-8"); | |||
| @@ -0,0 +1,32 @@ | |||
| package com.iformall.config; | |||
| import me.chanjar.weixin.mp.api.WxMpService; | |||
| import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
| import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
| import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.stereotype.Component; | |||
| @Component | |||
| public class WechatMpConfig { | |||
| @Autowired | |||
| private WechatWebProperties wechatWebProperties; | |||
| @Bean | |||
| public WxMpService wxMpService() { | |||
| //创建WxMpService实例并设置appid和sectret | |||
| WxMpService wxMpService = new WxMpServiceImpl(); | |||
| //这里的设置方式是跟着这个sdk的文档写的 | |||
| wxMpService.setWxMpConfigStorage(wxConfigProvider()); | |||
| return wxMpService; | |||
| } | |||
| public WxMpConfigStorage wxConfigProvider(){ | |||
| WxMpDefaultConfigImpl wxConfigProvider = new WxMpDefaultConfigImpl(); | |||
| wxConfigProvider.setAppId(wechatWebProperties.getAppId()); | |||
| wxConfigProvider.setSecret(wechatWebProperties.getSecret()); | |||
| return wxConfigProvider; | |||
| } | |||
| } | |||
| @@ -0,0 +1,59 @@ | |||
| package com.iformall.config; | |||
| import org.apache.commons.lang3.builder.ToStringBuilder; | |||
| import org.apache.commons.lang3.builder.ToStringStyle; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import org.springframework.stereotype.Component; | |||
| /** | |||
| * Stormeye | |||
| */ | |||
| @Component | |||
| @ConfigurationProperties(prefix = "wechat.web") | |||
| public class WechatWebProperties { | |||
| /** | |||
| * 设置微信第三方平台-微信登录的web应用appid | |||
| */ | |||
| private String appId; | |||
| /** | |||
| * 设置微信第三方平台-微信登录的web应用app secret | |||
| */ | |||
| private String secret; | |||
| /** | |||
| * 网页URL | |||
| * @return | |||
| */ | |||
| private String url; | |||
| public String getAppId() { | |||
| return appId; | |||
| } | |||
| public void setAppId(String appId) { | |||
| this.appId = appId; | |||
| } | |||
| public String getSecret() { | |||
| return secret; | |||
| } | |||
| public void setSecret(String secret) { | |||
| this.secret = secret; | |||
| } | |||
| public String getUrl() { | |||
| return url; | |||
| } | |||
| public void setUrl(String url) { | |||
| this.url = url; | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return ToStringBuilder.reflectionToString(this, | |||
| ToStringStyle.MULTI_LINE_STYLE); | |||
| } | |||
| } | |||
| @@ -132,6 +132,7 @@ public class HomeController extends BaseController { | |||
| UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword()); | |||
| subject.login(token); | |||
| isLogin = true; | |||
| logger.info("ADMIN USER:"+user.getUsername() + ", password:" + user.getPassword()); | |||
| } catch (UnknownAccountException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(ErrorCode.USER_IS_EMPTY); | |||
| @@ -221,6 +222,14 @@ public class HomeController extends BaseController { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| } | |||
| if (user == null) { | |||
| logger.error(ErrorCode.USER_IS_EMPTY.getMessage()); | |||
| return new ResultData(ErrorCode.USER_IS_EMPTY); | |||
| } | |||
| if (user.getStatus()==null ||!EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) { | |||
| logger.error(ErrorCode.USER_IS_LOCKED.getMessage()); | |||
| return new ResultData(ErrorCode.USER_IS_LOCKED); | |||
| } | |||
| boolean isLogin = false; | |||
| try { | |||
| @@ -327,6 +336,14 @@ public class HomeController extends BaseController { | |||
| List<MallUserInfoVo> userList = mallUserInfoService.getUserByPhone(phone); | |||
| if(userList.size() == 1) { | |||
| MallUserInfoVo user = userList.get(0); | |||
| if (user == null) { | |||
| logger.error(ErrorCode.USER_IS_EMPTY.getMessage()); | |||
| return new ResultData(ErrorCode.USER_IS_EMPTY); | |||
| } | |||
| if (user.getStatus()==null ||!EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) { | |||
| logger.error(ErrorCode.USER_IS_LOCKED.getMessage()); | |||
| return new ResultData(ErrorCode.USER_IS_LOCKED); | |||
| } | |||
| // check 验证码正确 | |||
| boolean isValidCode = false; | |||
| try { | |||
| @@ -1,6 +1,7 @@ | |||
| package com.iformall.controller.sys; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.iformall.annotation.SystemControllerLog; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| @@ -9,6 +10,7 @@ import com.iformall.domain.po.MallUserAction; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.domain.vo.MallUserInfoVo; | |||
| import com.iformall.enums.EnumMallUserAction; | |||
| import com.iformall.enums.EnumMallUserStatus; | |||
| import com.iformall.enums.EnumUserAdmin; | |||
| import com.iformall.service.MallUserActionService; | |||
| import com.iformall.service.MallUserInfoService; | |||
| @@ -122,6 +124,14 @@ public class WechatLoginController extends BaseController { | |||
| Map<String, Object> ret = new HashMap<>(); | |||
| // 唯一用户 | |||
| MallUserInfo user = userList.get(0); | |||
| if (user == null) { | |||
| ret.put("code", ErrorCode.USER_IS_EMPTY.getCode()); | |||
| ret.put("message", ErrorCode.USER_IS_EMPTY.getMessage()); | |||
| } | |||
| if (user.getStatus()==null ||!EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) { | |||
| ret.put("code", ErrorCode.USER_IS_LOCKED.getCode()); | |||
| ret.put("message", ErrorCode.USER_IS_LOCKED.getMessage()); | |||
| } | |||
| boolean isLogin = false; | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| @@ -156,7 +166,7 @@ public class WechatLoginController extends BaseController { | |||
| response.addCookie(unameCookie); | |||
| MallUserAction action = new MallUserAction(); | |||
| action.setTenantId(info.getTenantId()); | |||
| action.updateTenantInfo(info); | |||
| action.setType(EnumMallUserAction.CONTROLLER.getCode()); | |||
| action.setIp(ipaddress); | |||
| action.setUserId(info.getId()); | |||
| @@ -271,6 +281,12 @@ public class WechatLoginController extends BaseController { | |||
| log.info("KEY: " + openKey + " deleted"); | |||
| MallUserInfo userInfo = mallUserInfoService.getByUsername(userName); | |||
| if (userInfo == null) { | |||
| return new ResultData(ErrorCode.USER_IS_EMPTY); | |||
| } | |||
| if (userInfo.getStatus()==null ||!EnumMallUserStatus.VALID.getCode().equals(userInfo.getStatus())) { | |||
| return new ResultData(ErrorCode.USER_IS_LOCKED); | |||
| } | |||
| if(userInfo.getWebOpenId().equals(openId)) { | |||
| boolean isLogin = false; | |||
| try { | |||
| @@ -291,7 +307,7 @@ public class WechatLoginController extends BaseController { | |||
| response.addCookie(unameCookie); | |||
| MallUserAction action = new MallUserAction(); | |||
| action.setTenantId(info.getTenantId()); | |||
| action.updateTenantInfo(info); | |||
| action.setType(EnumMallUserAction.CONTROLLER.getCode()); | |||
| action.setIp(ipaddress); | |||
| action.setUserId(info.getId()); | |||
| @@ -322,6 +338,7 @@ public class WechatLoginController extends BaseController { | |||
| @ApiOperation(value = "微信第三方登录绑定", notes = "请配置此callback到网页redirect_uri") | |||
| @GetMapping("bindWebOpenId") | |||
| @SystemControllerLog(description = "微信第三方登录绑定") | |||
| public void userBindWebOpenId(String code, String state, HttpServletRequest request, HttpServletResponse response) { | |||
| log.debug("[" + getIpAddr() + "] WechatLoginController::bindWebOpenId"); | |||
| String host = request.getHeader("host"); | |||
| @@ -368,6 +385,7 @@ public class WechatLoginController extends BaseController { | |||
| @ApiOperation(value = "微信第三方登录解绑", notes = "请配置此callback到网页redirect_uri") | |||
| @GetMapping("cleanWebOpenId") | |||
| @SystemControllerLog(description = "微信第三方登录解绑") | |||
| public ResultData cleanWebOpenId(@ModelAttribute MallUserInfo userInfo) { | |||
| log.debug("[" + getIpAddr() + "] WechatLoginController::cleanWebOpenId"); | |||
| MallUserInfo user = getUser(); | |||
| @@ -1,23 +1,13 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.enums.EnumLoginType; | |||
| import com.iformall.enums.EnumMallUserStatus; | |||
| import com.iformall.service.MallUserInfoService; | |||
| import org.apache.shiro.authc.AuthenticationInfo; | |||
| import org.apache.shiro.authc.AuthenticationToken; | |||
| import org.apache.shiro.authc.DisabledAccountException; | |||
| import org.apache.shiro.authc.UnknownAccountException; | |||
| import org.apache.shiro.authc.credential.HashedCredentialsMatcher; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import javax.annotation.Resource; | |||
| @Configuration | |||
| public class MyRetryLimitCredentialsMatcher extends HashedCredentialsMatcher { | |||
| @Resource | |||
| private MallUserInfoService userService; | |||
| @Override | |||
| public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { | |||
| @@ -26,14 +16,6 @@ public class MyRetryLimitCredentialsMatcher extends HashedCredentialsMatcher { | |||
| if(tk.getType().equals(EnumLoginType.NOPASSWD)){ | |||
| // 获取用户的输入的账号. | |||
| String username = (String)tk.getPrincipal(); | |||
| MallUserInfo user = userService.getByUsername(username); | |||
| if(user == null) { | |||
| throw new UnknownAccountException(ErrorCode.USER_IS_EMPTY.getMessage()); | |||
| } | |||
| // 用户被禁用 | |||
| if(user.getStatus()==null ||!EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) { | |||
| throw new DisabledAccountException(ErrorCode.USER_IS_LOCKED.getMessage()); | |||
| } | |||
| return true; | |||
| } | |||
| boolean matches = super.doCredentialsMatch(authcToken, info); | |||
| @@ -69,7 +69,7 @@ public class ActionEnter { | |||
| case ActionMap.UPLOAD_VIDEO: | |||
| case ActionMap.UPLOAD_FILE: | |||
| conf = this.configManager.getConfig(actionCode); | |||
| state = new Uploader(request, conf).doExec(); | |||
| state = new Uploader(request, conf, configManager.getMallResourceService()).doExec(); | |||
| break; | |||
| case ActionMap.CATCH_IMAGE: | |||
| @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONArray; | |||
| import com.alibaba.fastjson.JSONException; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.iformall.config.AwsProperty; | |||
| import com.iformall.service.MallResourceService; | |||
| import com.iformall.ueditor.define.ActionMap; | |||
| import java.io.*; | |||
| @@ -28,13 +29,15 @@ public final class ConfigManager { | |||
| //配置信息 | |||
| private UEditorConfig uEditorConfig; | |||
| private AwsProperty awsProperty; | |||
| private MallResourceService mallResourceService; | |||
| /* | |||
| * 通过一个给定的路径构建一个配置管理器, 该管理器要求地址路径所在目录下必须存在config.properties文件 | |||
| */ | |||
| private ConfigManager(UEditorConfig uEditorConfig, AwsProperty awsProperty) throws IOException { | |||
| private ConfigManager(UEditorConfig uEditorConfig, AwsProperty awsProperty, MallResourceService mallResourceService) throws IOException { | |||
| this.uEditorConfig = uEditorConfig; | |||
| this.awsProperty = awsProperty; | |||
| this.mallResourceService = mallResourceService; | |||
| String configPath = uEditorConfig.getConfig(); | |||
| configPath = configPath == null || configPath.isEmpty() ? configFileName : configPath; | |||
| this.initEnv(configPath); | |||
| @@ -46,10 +49,10 @@ public final class ConfigManager { | |||
| * @param uEditorConfig 配置文件 | |||
| * @return 配置管理器实例或者null | |||
| */ | |||
| public static ConfigManager getInstance(UEditorConfig uEditorConfig, AwsProperty awsProperty) { | |||
| public static ConfigManager getInstance(UEditorConfig uEditorConfig, AwsProperty awsProperty, MallResourceService mallResourceService) { | |||
| try { | |||
| return new ConfigManager(uEditorConfig, awsProperty); | |||
| return new ConfigManager(uEditorConfig, awsProperty, mallResourceService); | |||
| } catch (Exception e) { | |||
| System.err.println("UEditor ConfigManager load error~"); | |||
| return null; | |||
| @@ -57,6 +60,14 @@ public final class ConfigManager { | |||
| } | |||
| public MallResourceService getMallResourceService() { | |||
| return mallResourceService; | |||
| } | |||
| public void setMallResourceService(MallResourceService mallResourceService) { | |||
| this.mallResourceService = mallResourceService; | |||
| } | |||
| // 验证配置文件加载是否正确 | |||
| public boolean valid() { | |||
| return this.jsonConfig != null; | |||
| @@ -12,10 +12,15 @@ import com.amazonaws.services.s3.AmazonS3ClientBuilder; | |||
| import com.amazonaws.services.s3.model.CannedAccessControlList; | |||
| import com.amazonaws.services.s3.model.ObjectMetadata; | |||
| import com.amazonaws.services.s3.model.PutObjectRequest; | |||
| import com.iformall.domain.po.MallResource; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.service.MallResourceService; | |||
| import com.iformall.shiro.UserSession; | |||
| import com.iformall.ueditor.define.BaseState; | |||
| import com.iformall.ueditor.define.State; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.shiro.SecurityUtils; | |||
| import org.apache.shiro.session.Session; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.web.multipart.MultipartFile; | |||
| @@ -33,11 +38,18 @@ public class Uploader { | |||
| private HttpServletRequest request = null; | |||
| private Map<String, Object> conf = null; | |||
| private MallResourceService mallResourceService = null; | |||
| private AmazonS3 s3 = null; | |||
| public Uploader(HttpServletRequest request, Map<String, Object> conf) { | |||
| private String getFileName(TenantEntity tenantEntity, String fileName) { | |||
| fileName = tenantEntity.getTenantId() + "/" + fileName; | |||
| return fileName; | |||
| } | |||
| public Uploader(HttpServletRequest request, Map<String, Object> conf, MallResourceService mallResourceService) { | |||
| this.request = request; | |||
| this.conf = conf; | |||
| this.mallResourceService = mallResourceService; | |||
| this.s3 = AmazonS3ClientBuilder.standard() | |||
| .withRegion(conf.get("clientRegion").toString()) | |||
| .withCredentials(new AWSCredentialsProvider() { | |||
| @@ -63,14 +75,22 @@ public class Uploader { | |||
| this.conf); | |||
| } else { | |||
| MultipartFile multiReq= ((MultipartHttpServletRequest) this.request).getFile("upfile"); | |||
| String tenantId = (String)SecurityUtils.getSubject().getSession().getAttribute(UserSession.tenantId); | |||
| Session session = SecurityUtils.getSubject().getSession(); | |||
| String tenantId = (String)session.getAttribute(UserSession.tenantId); | |||
| TenantEntity tenantEntity = new TenantEntity(){{ | |||
| setTenantId(tenantId); | |||
| }}; | |||
| if (StringUtils.isBlank(tenantId)) { | |||
| logger.error("TENANT is null"); | |||
| } | |||
| String fileName = UUID.randomUUID().toString(); | |||
| int dot = multiReq.getOriginalFilename().lastIndexOf('.'); | |||
| if (dot >= 0) { | |||
| fileName = tenantId + "/" + fileName + multiReq.getOriginalFilename().substring(dot, multiReq.getOriginalFilename().length()); | |||
| String fileFormat = multiReq.getOriginalFilename().substring(dot, multiReq.getOriginalFilename().length()); | |||
| fileName = getFileName(tenantEntity, fileName + fileFormat); | |||
| } else { | |||
| fileName = tenantId + "/" + fileName; | |||
| fileName = getFileName(tenantEntity, fileName); | |||
| } | |||
| state = state = new BaseState(true); | |||
| @@ -89,7 +109,15 @@ public class Uploader { | |||
| .withCannedAcl(CannedAccessControlList.PublicRead)); | |||
| URL url = s3.getUrl(conf.get("bucketName").toString(), fileName); | |||
| //logger.info(url.toString()); | |||
| state.putInfo("url", url.toString()); | |||
| MallResource mr = new MallResource(); | |||
| mr.updateTenantInfo(tenantEntity); | |||
| mr.setBucket(conf.get("bucketName").toString()); | |||
| mr.setS3Key(fileName); | |||
| mr.setUrl(url.toString()); | |||
| mallResourceService.saveOrUpdate(mr); | |||
| } catch (AmazonServiceException ase) { | |||
| /* | |||
| logger.warn("Caught an AmazonServiceException, which " + | |||
| @@ -7,6 +7,7 @@ public class UrlCheck { | |||
| public static boolean checkUrl(String url) { | |||
| return url.contains("awsFileUpload") | |||
| || url.contains("awsImgUpload") | |||
| || url.contains("awsFilesUpload") | |||
| || url.contains("downQrCode") | |||
| || url.contains("cimgUpload") | |||