This commit is contained in:
chc
2022-10-21 11:26:55 +08:00
160 changed files with 198564 additions and 1035 deletions

View File

@@ -15,6 +15,15 @@
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>

View File

@@ -473,13 +473,25 @@ public enum CachePrefix {
* 店铺分类
*/
STORE_CATEGORY,
/**
* 用户菜单
*/
MENU_USER_ID,
/**
* 用户菜单
* <p>
* 这个缓存并非永久缓存而是300秒缓存也就是说修改用户关联的部门关联的角色
* 部门关联的角色角色关联的菜单等等最多需要5分钟才能生效
*/
STORE_MENU_USER_ID,
/**
* 用户菜单
*/
USER_MENU,
/**
* 用户菜单
*/
STORE_USER_MENU,
/**
* 订单暂时缓存
*/

View File

@@ -138,7 +138,14 @@ public enum ResultCode {
USER_CONNECT_BANDING_ERROR(20023, "当前联合登陆方式,已绑定其他账号,需进行解绑操作"),
USER_CONNECT_NOT_EXIST_ERROR(20024, "暂无联合登陆信息,无法实现一键注册功能,请点击第三方登录进行授权"),
USER_POINTS_ERROR(20024, "用户积分不足"),
CLERK_SUPPER(20025, "店主无法操作"),
CLERK_SAVE_ERROR(20026, "店员保存失败"),
CLERK_NOT_FOUND_ERROR(20027, "店员不存在"),
USER_STATUS_ERROR(20028, "用户已禁用"),
CLERK_USER_ERROR(20029, "此账户已经绑定其他店铺"),
CLERK_ALREADY_EXIT_ERROR(20030, "店员已经存在"),
CLERK_DISABLED_ERROR(20031, "店员已禁用"),
CLERK_CURRENT_SUPPER(20032, "无法删除当前登录店员"),
/**
* 权限
*/
@@ -147,6 +154,10 @@ public enum ResultCode {
PERMISSION_MENU_ROLE_ERROR(21003, "菜单已绑定角色,请先删除或编辑角色"),
PERMISSION_DEPARTMENT_DELETE_ERROR(21004, "部门已经绑定管理员,请先删除或编辑管理员"),
PERMISSION_BEYOND_TEN(21005, "最多可以设置10个角色"),
PERMISSION_NOT_FOUND_ERROR(21006, "部门不存在"),
PERMISSION_ROLE_NOT_FOUND_ERROR(21007, "角色不存在"),
PERMISSION_CLERK_BAND_ERROR(21008, "此手机号码已绑定其他店铺 "),
/**
* 分销
@@ -390,7 +401,7 @@ public enum ResultCode {
STORE_NOT_EXIST(50001, "此店铺不存在"),
STORE_NAME_EXIST_ERROR(50002, "店铺名称已存在!"),
STORE_APPLY_DOUBLE_ERROR(50003, "已有店铺,无需重复申请!"),
STORE_APPLY_DOUBLE_ERROR(50003, "经拥有店铺!"),
STORE_NOT_OPEN(50004, "该会员未开通店铺"),
STORE_NOT_LOGIN_ERROR(50005, "未登录店铺"),
STORE_CLOSE_ERROR(50006, "店铺关闭,请联系管理员"),

View File

@@ -18,7 +18,7 @@ import javax.validation.ConstraintViolationException;
import java.util.List;
/**
* 全局异常异常处理
* 异常处理
*
* @author Chopper
*/
@@ -74,6 +74,15 @@ public class GlobalControllerExceptionHandler {
}
return ResultUtil.error(ResultCode.ERROR.code(), errorMsg);
}
/*
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public ResultMessage<Object> constraintExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
log.error("全局异常[RuntimeException]:", e);
return ResultUtil.error(001, e.getMessage());
}*/
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)

View File

@@ -0,0 +1,30 @@
package cn.lili.common.fulu.core;
/**
* @Auther: chenYing
* @Date: 2019/8/26 0026 15:08
*/
public interface MethodConst {
//卡密下单接口method方法
String OPEN_API_CARD_ORDER_ADD = "fulu.order.card.add";
// 根据话费查询归属地和城市编码,面值,城市等信息
String OPEN_API_CHECK_PHONE = "fulu.mobile.info.get";
// 直充下单接口method方法
String OPEN_API_DIRECT_ORDER_ADD = "fulu.order.direct.add";
// 获取商品信息接口method方法
String OPEN_API_GOODS_GET = "fulu.goods.info.get";
// 获取商品模板信息接口method方法
String OPEN_API_GOODS_TEMPLATE_GET = "fulu.goods.template.get";
// 查单接口method方法
String OPEN_API_ORDER_GET = "fulu.order.info.get";
// 话费下单接口method方法
String OPEN_API_PHONE_ORDER_ADD = "fulu.order.mobile.add";
// 流量下单接口method方法
String OPEN_API_TRAFFIC_ORDER_ADD = "fulu.order.data.add";
// 获取用户信息接口method方法
String OPEN_API_USER_INFO_GET = "fulu.user.info.get";
//获取商品列表method方法
String OPEN_API_GOODS_LIST = "fulu.goods.list.get";
}

View File

@@ -0,0 +1,58 @@
package cn.lili.common.fulu.core.http;
import cn.lili.common.fulu.core.utils.HttpUtil;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:16
*/
public class FuluClient implements IFuluClient {
private static volatile ExecutorService executor;
private String url;
public FuluClient() {
this.url = "http://openapi.fulu.com/api/getway";
}
public FuluClient(String url) {
this.url = url;
}
/**
* 创建线程池
*/
private static void createThreadPool() {
if (executor == null) {
synchronized (FuluClient.class) {
if (executor == null) {
executor = Executors.newCachedThreadPool();
}
}
}
}
@Override
public String send(final String postData) {
String result = HttpUtil.sendPostJson(this.url, postData);
return result;
}
@Override
public Future<String> sendAsync(final String postData) {
createThreadPool();
return executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
String result = HttpUtil.sendPostJson(url, postData);
return result;
}
});
}
}

View File

@@ -0,0 +1,27 @@
package cn.lili.common.fulu.core.http;
import java.util.concurrent.Future;
/**
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:15
*/
public interface IFuluClient {
/**
* 同步请求openapi2.0
*
* @param postData
* @return String
*/
String send(final String postData);
/**
* 异步请求openapi2.0
*
* @param postData
* @return Future<String>
*/
Future<String> sendAsync(final String postData);
}

View File

@@ -0,0 +1,47 @@
package cn.lili.common.fulu.core.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
/**
* @Auther: chenYing
* @Date: 2019/8/27 0027 17:38
*/
public class CardUtil {
private static final String ALGORITHM = "AES/ECB/PKCS7Padding";
private CardUtil() {
}
public static String cardDecode(String str, byte[] key) {
byte[] bytes = org.apache.commons.codec.binary.Base64.decodeBase64(str);
String result = null;
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decoded = cipher.doFinal(bytes);
result = new String(decoded, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
return result;
}
public static String cardEncode(String str, byte[] key) {
byte[] result = null;
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
result = cipher.doFinal(str.getBytes("UTF-8"));
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
return new String(org.apache.commons.codec.binary.Base64.encodeBase64(result));
}
}

View File

@@ -0,0 +1,19 @@
package cn.lili.common.fulu.core.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Auther: chenYing
* @Date: 2019/8/19 0019 15:17
*/
public class DateFormatUtil {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private DateFormatUtil() {
}
public static String currentDateTime() {
return new SimpleDateFormat(DATE_FORMAT).format(new Date());
}
}

View File

@@ -0,0 +1,206 @@
package cn.lili.common.fulu.core.utils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.*;
/**
* @author cheny
*/
public class HttpUtil {
private static Logger log = LoggerFactory.getLogger(HttpUtil.class);
public final static int CONNECT_TIMEOUT = 10000;
public final static int READ_TIMEOUT = 10000;
private static final String ENCODING_GBK = "GBK";
/**
* POST请求json字符串形式数据
*
* @param url 请求地址
* @param param 请求的json数据
* @return response body
* @throws Exception
*/
public static String sendPostJson(String url, String param) {
return sendPostWithHeads(url, param, "application/json", null);
}
private static String sendPostWithHeads(String url, String param, String contentType, Map<String, String> heads) {
PrintWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
HttpURLConnection conn = null;
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
conn = (HttpURLConnection) realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestMethod("POST");// 提交模式
conn.setConnectTimeout(CONNECT_TIMEOUT);// 连接超时 单位毫秒
conn.setReadTimeout(READ_TIMEOUT);// 读取超时 单位毫秒
if (contentType != null && !contentType.isEmpty()) {
conn.setRequestProperty("Content-Type", contentType);
}
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
// 添加头信息
if (heads != null && !heads.isEmpty()) {
for (String key : heads.keySet()) {
conn.setRequestProperty(key, heads.get(key));
}
}
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("send POST request exception :" + e.getMessage(), e);
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (conn != null) {
conn.disconnect();
}
} catch (Exception e2) {
throw new RuntimeException("close Connection exception :" + e2.getMessage(), e2);
}
}
return result.toString();
}
/**
* POST请求String字符串形式数据
*
* @param url
* @param paramXmlStr
* @return
*/
public static String sendPostXmlStr(String url, String paramXmlStr) {
String tmpparamXmlStr = "";
try {
tmpparamXmlStr = URLEncoder.encode(paramXmlStr, ENCODING_GBK);
tmpparamXmlStr = sendPostWithHeads(url, tmpparamXmlStr, "application/xml", null);
tmpparamXmlStr = URLDecoder.decode(tmpparamXmlStr,ENCODING_GBK);
}catch (Exception e){
e.printStackTrace();
log.error("post请求URL数据转码报错{}", e.getMessage());
}
return tmpparamXmlStr;
}
/**
* POST请求String字符串形式数据
*
* @param url
* @param paramXmlStr
* @return
*/
public static String sendPostXmlUrlencode(String url, String paramXmlStr) {
String tmpparamXmlStr = "";
Map<String, String> rspMap = new LinkedHashMap<>();
rspMap.put("req", paramXmlStr);
try {
tmpparamXmlStr = URLEncoder.encode(paramXmlStr, ENCODING_GBK);
tmpparamXmlStr = doPostMapParams(url, rspMap);
tmpparamXmlStr = URLDecoder.decode(tmpparamXmlStr,ENCODING_GBK);
}catch (Exception e){
e.printStackTrace();
log.error("post请求URL数据转码报错{}", e.getMessage());
}
return tmpparamXmlStr;
}
/**
* 发送POST请求
* @param url String对象为 目的地址
* @param parameters 请求参数Map类型。
* @return 远程响应结果
*/
public static String doPostMapParams(String url, Map<String, String> parameters) {
BufferedReader in = null;
try {
// 定义HttpClient
HttpClient client = new DefaultHttpClient();
// 实例化HTTP方法
HttpPost request = new HttpPost();
request.setURI(new URI(url));
//设置参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (Iterator iter = parameters.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value = String.valueOf(parameters.get(name));
nvps.add(new BasicNameValuePair(name, value));
}
request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = client.execute(request);
int code = response.getStatusLine().getStatusCode();
if(code == 200){ //请求成功
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent(),"UTF-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
return sb.toString();
}else{
System.out.println("状态码:" + code);
return null;
}
}
catch(Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,41 @@
package cn.lili.common.fulu.core.utils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class JSONUtil {
private static Gson gson = new Gson();
/**
* 将 JSON 字符串转为 Java 对象
*/
public static <T> T fromJSON(String json, Class<T> type) {
T obj;
try {
obj = gson.fromJson(json, type);
} catch (Exception e) {
throw new RuntimeException(e);
}
return obj;
}
/**
* json字符串转list或者map
*/
public static <T> T fromJSON(String json, TypeToken<T> typeToken) {
return gson.fromJson(json, typeToken.getType());
}
/**
* 将 Java 对象转为 JSON 字符串
*/
public static <T> String toJSON(T obj) {
String jsonStr;
try {
jsonStr = gson.toJson(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
return jsonStr;
}
}

View File

@@ -0,0 +1,342 @@
package cn.lili.common.fulu.core.utils;
import cn.lili.common.fulu.core.MethodConst;
import cn.lili.common.fulu.model.*;
import cn.lili.common.fulu.sdk.DefaultOpenApiClient;
import cn.lili.modules.store.entity.dto.FuLuConfigureDTO;
import com.alibaba.fastjson.JSON;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.*;
public class Test {
private final static String APP_KEY = "lzHi7ewuTkplx2ePX0eQzN65TIFRk1zFClcoj1Jim/MHmu0X7ZqxMtSLENhvr1xD";
private final static Logger LOGGER = LoggerFactory.getLogger(Test.class);
private final static String SYS_SECRET = "9da68b0f8bcb470e84c3d30e343727e2";
private final static String URL = "http://openapi.fulu.com/api/getway";
// private final static String APP_KEY = "i4esv1l+76l/7NQCL3QudG90Fq+YgVfFGJAWgT+7qO1Bm9o/adG/1iwO2qXsAXNB";
// private final static Logger LOGGER = LoggerFactory.getLogger(Test.class);
// private final static String SYS_SECRET = "0a091b3aa4324435aab703142518a8f7";
// private final static String URL = "http://pre.openapi.fulu.com/api/getway";
private static String repeat(String ch, int num) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < num; i++) {
str.append(ch);
}
return str.toString();
}
private static void waitFor(Future<String> future) throws Exception {
while (!future.isDone()) {
TimeUnit.MILLISECONDS.sleep(500);
}
LOGGER.info("excuteAsync\n{}", future.get());
}
/**
* 卡密下单
*
* @throws Exception
*/
public static void cardOrderAddTest(FuLuConfigureDTO fuLuConfigureDTO, Integer productId, Integer buyNum,String orderSn) throws Exception {
LOGGER.info("\n卡密下单{}", repeat("=", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_CARD_ORDER_ADD);
InputCardOrderDto dto = new InputCardOrderDto();
dto.setProductId(productId);
dto.setCustomerOrderNo(orderSn);
dto.setBuyNum(buyNum);
client.setBizObject(dto);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
dto.setCustomerOrderNo(UUID.randomUUID().toString());
waitFor(client.excuteAsync());
}
/**
* 直充下单
*
* @throws Exception
*/
public static void directOrderAddTest(FuLuConfigureDTO fuLuConfigureDTO, Integer productId, Integer buyNum,String qrCode,String orderSn) throws Exception {
LOGGER.info("\n直充下单{}", repeat("=", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_DIRECT_ORDER_ADD);
InputDirectOrderDto dto = new InputDirectOrderDto();
dto.setProductId(productId);
dto.setBuyNum(buyNum);
client.setBizObject(dto);
int count = 1;
for (String chargeAccount : Arrays.asList(qrCode)) {
dto.setChargeAccount(chargeAccount);
dto.setCustomerOrderNo(orderSn);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
if (count++ >= 3) {
waitFor(client.excuteAsync());
} else {
LOGGER.info("excuteAsync\n{}\n{}", client.excuteAsync().get(), repeat("-", 100));
}
}
}
/**
* 手机号归属地
*
* @throws Exception
*/
public void matchPhoneProducGetTest(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n手机号归属地{}", repeat("=", 100));
DefaultOpenApiClient client = new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_CHECK_PHONE);
InputMatchPhoneProductListDto dto = new InputMatchPhoneProductListDto();
dto.setFaceValue(50D);
int count = 1;
for (String phone : Arrays.asList("15972368779", "13971553804")) {
dto.setPhone(phone);
client.setBizObject(dto);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
if (count++ >= 2) {
waitFor(client.excuteAsync());
} else {
LOGGER.info("excuteAsync\n{}\n{}", client.excuteAsync().get(), repeat("-", 100));
}
}
}
/**
* 订单查单
*
* @throws Exception
*/
public void orderInfoGetTest(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n订单查单{}", repeat("=", 100));
DefaultOpenApiClient client = new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_ORDER_GET);
InputOrderGetDto dto = new InputOrderGetDto();
client.setBizObject(dto);
int count = 1;
for (String customerOrderNo : Arrays
.asList("0d19f8e4-5af3-490d-a8d8-47fd457da7de", "31b6b96b-a21e-4bc4-bc0c-6e77a2ffb698")) {
dto.setCustomerOrderNo(customerOrderNo);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
if (count++ >= 2) {
Future<String> future = client.excuteAsync();
waitFor(future);
Map<String, String> result = JSONUtil.fromJSON(future.get(), new TypeToken<Map>() {
});
Map<String, Object> resultMap = JSONUtil.fromJSON(result.get("result"), new TypeToken<Map<String, Object>>() {
});
List<Map<String, String>> cardList = (List<Map<String, String>>) resultMap.get("cards");
StringBuilder decodeStr = new StringBuilder();
for (Map<String, String> map : cardList) {
decodeStr.append("card_number").append(map.get("card_number")).append("desc_card_number")
.append(CardUtil.cardDecode(map.get("card_number"), SYS_SECRET.getBytes("UTF-8")));
decodeStr.append(" card_pwd").append(map.get("card_pwd")).append("card_pwd")
.append(CardUtil.cardDecode(map.get("card_pwd"), SYS_SECRET.getBytes("UTF-8")));
decodeStr.append("\n");
}
System.out.println(decodeStr.toString());
System.out.println(CardUtil.cardEncode("CD10002502019061217430016421", SYS_SECRET.getBytes("UTF-8")));
} else {
LOGGER.info("excuteAsync\n{}\n{}", client.excuteAsync().get(), repeat("-", 100));
}
}
}
/**
* 话费下单
*
* @throws Exception
*/
public void phoneOrderAddTest(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n话费下单{}", repeat("=", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_PHONE_ORDER_ADD);
InputPhoneOrderDto dto = new InputPhoneOrderDto();
dto.setChargeValue(Double.valueOf(50));
int count = 1;
for (String chargePhone : Arrays.asList("15972368779", "13971553804")) {
dto.setCustomerOrderNo(UUID.randomUUID().toString());
dto.setChargePhone(chargePhone);
client.setBizObject(dto);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
dto.setCustomerOrderNo(UUID.randomUUID().toString());
if (count++ >= 2) {
waitFor(client.excuteAsync());
} else {
LOGGER.info("excuteAsync\n{}\n{}", client.excuteAsync().get(), repeat("-", 100));
}
}
}
/**
* 获得商品信息
*
* @throws Exception
*/
public static Map<String, Object> productInfoGetTest(FuLuConfigureDTO fuLuConfigureDTO,String productIdS) throws Exception {
LOGGER.info("\n获得商品信息{}", repeat("=", 100));
DefaultOpenApiClient client = new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_GOODS_GET);
InputProductDto dto = new InputProductDto();
int count = 1;
Map<String, Object> maps = new HashMap();
for (String productId : Arrays.asList(productIdS)) {
dto.setProductId(productId);
client.setBizObject(dto);
maps = (Map) JSON.parse(client.excute());
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
if (count++ >= 10) {
waitFor(client.excuteAsync());
} else {
LOGGER.info("excuteAsync\n{}\n{}", client.excuteAsync().get(), repeat("-", 100));
}
}
return maps;
}
/**
* 获得商品模板信息
*
* @throws Exception
*/
public void productTemplateGetTest(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n获得商品模板信息{}", repeat("=", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_GOODS_TEMPLATE_GET);
InputProductTemplateDto dto = new InputProductTemplateDto();
dto.setTemplateId("e1dac0ea-dc86-4c9d-a778-c9e19203ecb8");
client.setBizObject(dto);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
waitFor(client.excuteAsync());
}
/**
* 流量下单
*
* @throws Exception
*/
public void trafficOrderAddTest(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n流量下单{}", repeat("=", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_TRAFFIC_ORDER_ADD);
InputTrafficOrderDto dto = new InputTrafficOrderDto();
dto.setChargeValue(Double.valueOf(1024));
dto.setPacketKind(4);
int count = 1;
for (String chargePhone : Arrays.asList("15972368779", "13971553804")) {
client.setBizObject(dto);
dto.setChargePhone(chargePhone);
dto.setCustomerOrderNo(UUID.randomUUID().toString());
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
dto.setCustomerOrderNo(UUID.randomUUID().toString());
if (count++ >= 2) {
waitFor(client.excuteAsync());
} else {
LOGGER.info("excuteAsync\n{}\n{}", client.excuteAsync().get(), repeat("-", 100));
}
}
}
/**
* 用户信息
*
* @throws Exception
*/
public static void userInfoGetTest(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n用户信息{}", repeat("=", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_USER_INFO_GET);
InputUserDto dto = new InputUserDto();
client.setBizObject(dto);
LOGGER.info("excute\n{}\n{}", client.excute(), repeat("-", 100));
waitFor(client.excuteAsync());
}
/**
* 用户信息:高并发场景
*
* @throws Exception
*/
public static void userInfoGetTest2(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n用户信息高并发场景{}", repeat("=", 100));
Executor executor = Executors.newCachedThreadPool();
final int count = 10;
final CountDownLatch downLatch = new CountDownLatch(count);
for (int i = 0; i < count; ++i) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
String name = Thread.currentThread().getName();
LOGGER.info("\n线程名{}{}", name, repeat("+", 100));
DefaultOpenApiClient client =
new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_USER_INFO_GET);
InputUserDto dto = new InputUserDto();
client.setBizObject(dto);
LOGGER.info("\n线程名{}\n{}\n{}", name, client.excute(), repeat("+", 100));
waitFor(client.excuteAsync());
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
} finally {
downLatch.countDown();
}
}
});
}
downLatch.await();
}
/* 获得商品信息列表
*
* @throws Exception
*/
public static String getGoodsInfoList(FuLuConfigureDTO fuLuConfigureDTO) throws Exception {
LOGGER.info("\n获得商品信息{}", repeat("=", 100));
DefaultOpenApiClient client = new DefaultOpenApiClient(URL, fuLuConfigureDTO.getAppMerchantKey(), fuLuConfigureDTO.getAppSecretKey(), MethodConst.OPEN_API_GOODS_LIST);
InputProductDto dto = new InputProductDto();
client.setBizObject(dto);
return client.excute().toString();
}
public static void main(String[] args) {
try {
// productInfoGetTest();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,159 @@
package cn.lili.common.fulu.model;
import cn.lili.common.fulu.core.utils.DateFormatUtil;
import cn.lili.common.fulu.core.utils.JSONUtil;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @Auther: chenYing
* @Date: 2019/8/19 0019 10:49
*/
public class CommonRequest implements Serializable {
private static final long serialVersionUID = 2L;
@SerializedName(value = "app_auth_token")
private String appAuthToken = "";
@SerializedName(value = "app_key")
private String appKey;
@SerializedName(value = "biz_content")
private String bizContent = "{}";
private transient Map<String, Object> bizContentMap = Collections.emptyMap();
private String charset;
private String format;
private String method;
private String sign;
@SerializedName(value = "sign_type")
private String signType;
private String timestamp;
private String version;
public CommonRequest() {
format = "json";
version = "2.0";
charset = "utf-8";
signType = "md5";
// timestamp = "2019-08-20 13:59:38";
timestamp = DateFormatUtil.currentDateTime();
}
public String getAppAuthToken() {
return appAuthToken;
}
public void setAppAuthToken(String appAuthToken) {
this.appAuthToken = appAuthToken;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getBizContent() {
if (!bizContentMap.isEmpty()) {
bizContent = JSONUtil.toJSON(bizContentMap);
}
return bizContent;
}
/**
* 直接将变量以json格式保存
*
* @param bizContent bizContent
*/
public void setBizContent(String bizContent) {
if (bizContent != null && !"".equals(bizContent.trim())) {
Map<String, Object> dataMap = JSONUtil.fromJSON(bizContent, new TypeToken<Map<String, Object>>() {
});
if (bizContentMap.isEmpty()) {
bizContentMap = new HashMap<String, Object>();
}
bizContentMap.putAll(dataMap);
}
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getSignType() {
return signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
/**
* 以key:value形式保存程序会转换为json格式
*
* @param key key
* @param value value
*/
public void setBizContent(String key, Object value) {
if (bizContentMap.isEmpty()) {
bizContentMap = new HashMap<String, Object>();
}
bizContentMap.put(key, value);
}
protected Object getBizContentValue(String key) {
return bizContentMap.get(key);
}
}

View File

@@ -0,0 +1,56 @@
package cn.lili.common.fulu.model;
/**
* 卡密订单input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 15:35
*/
public class InputCardOrderDto extends CommonRequest {
public InputCardOrderDto() {
super();
setMethod("fulu.order.card.add");
}
/**
* 购买数量
*
* @return Integer
*/
public Integer getBuyNum() {
Object value = getBizContentValue("buy_num");
return value != null ? Integer.valueOf(value.toString()) : null;
}
public void setBuyNum(Integer buyNum) {
setBizContent("buy_num", buyNum);
}
/**
* 外部订单号
*
* @return String
*/
public String getCustomerOrderNo() {
Object value = getBizContentValue("customer_order_no");
return value != null ? String.valueOf(value) : null;
}
public void setCustomerOrderNo(String customerOrderNo) {
setBizContent("customer_order_no", customerOrderNo);
}
/**
* 商品编号
*
* @return Integer
*/
public Integer getProductId() {
Object value = getBizContentValue("product_id");
return value != null ? Integer.valueOf(value.toString()) : null;
}
public void setProductId(Integer productId) {
setBizContent("product_id", productId);
}
}

View File

@@ -0,0 +1,213 @@
package cn.lili.common.fulu.model;
/**
* 直充商品订单input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 15:39
*/
public class InputDirectOrderDto extends CommonRequest {
public InputDirectOrderDto() {
super();
setMethod("fulu.order.direct.add");
}
/**
* 购买数量
*
* @return Integer
*/
public Integer getBuyNum() {
Object value = getBizContentValue("buy_num");
return value != null ? Integer.valueOf(value.toString()) : null;
}
public void setBuyNum(Integer buyNum) {
setBizContent("buy_num", buyNum);
}
/**
* 充值账号
*
* @return String
*/
public String getChargeAccount() {
Object value = getBizContentValue("charge_account");
return value != null ? String.valueOf(value) : null;
}
public void setChargeAccount(String chargeAccount) {
setBizContent("charge_account", chargeAccount);
}
/**
* 充值游戏名称
*
* @return String
*/
public String getChargeGameName() {
Object value = getBizContentValue("charge_game_name");
return value != null ? String.valueOf(value) : null;
}
public void setChargeGameName(String chargeGameName) {
setBizContent("charge_game_name", chargeGameName);
}
/**
* 充值游戏区
*
* @return String
*/
public String getChargeGameRegion() {
Object value = getBizContentValue("charge_game_region");
return value != null ? String.valueOf(value) : null;
}
public void setChargeGameRegion(String chargeGameRegion) {
setBizContent("charge_game_region", chargeGameRegion);
}
/**
* 充值游戏角色
*
* @return String
*/
public String getChargeGameRole() {
Object value = getBizContentValue("charge_game_role");
return value != null ? String.valueOf(value) : null;
}
public void setChargeGameRole(String chargeGameRole) {
setBizContent("charge_game_role", chargeGameRole);
}
/**
* 充值游戏服
*
* @return String
*/
public String getChargeGameSrv() {
Object value = getBizContentValue("charge_game_srv");
return value != null ? String.valueOf(value) : null;
}
public void setChargeGameSrv(String chargeGameSrv) {
setBizContent("charge_game_srv", chargeGameSrv);
}
/**
* 下单真实Ip区域商品要传
*
* @return String
*/
public String getChargeIp() {
Object value = getBizContentValue("charge_ip");
return value != null ? String.valueOf(value) : null;
}
public void setChargeIp(String chargeIp) {
setBizContent("charge_ip", chargeIp);
}
/**
* 充值密码,部分游戏类要传
*
* @return String
*/
public String getChargePassword() {
Object value = getBizContentValue("charge_password");
return value != null ? String.valueOf(value) : null;
}
public void setChargePassword(String chargePassword) {
setBizContent("charge_password", chargePassword);
}
/**
* 充值类型
*
* @return String
*/
public String getChargeType() {
Object value = getBizContentValue("charge_type");
return value != null ? String.valueOf(value) : null;
}
public void setChargeType(String chargeType) {
setBizContent("charge_type", chargeType);
}
/**
* 联系QQ
*
* @return String
*/
public String getContactQq() {
Object value = getBizContentValue("contact_qq");
return value != null ? String.valueOf(value) : null;
}
public void setContactQq(String contactQq) {
setBizContent("contact_qq", contactQq);
}
/**
* 联系电话
*
* @return String
*/
public String getContactTel() {
Object value = getBizContentValue("contact_tel");
return value != null ? String.valueOf(value) : null;
}
public void setContactTel(String contactTel) {
setBizContent("contact_tel", contactTel);
}
/**
* 外部订单号
*
* @return String
*/
public String getCustomerOrderNo() {
Object value = getBizContentValue("customer_order_no");
return value != null ? String.valueOf(value) : null;
}
public void setCustomerOrderNo(String customerOrderNo) {
setBizContent("customer_order_no", customerOrderNo);
}
/**
* 商品编号
*
* @return Integer
*/
public Integer getProductId() {
Object value = getBizContentValue("product_id");
return value != null ? Integer.valueOf(value.toString()) : null;
}
public void setProductId(Integer productId) {
setBizContent("product_id", productId);
}
/**
* 剩余数量
*
* @return Integer
*/
public Integer getRemainingNumber() {
Object value = getBizContentValue("remaining_number");
return value != null ? Integer.valueOf(value.toString()) : null;
}
public void setRemainingNumber(Integer remainingNumber) {
setBizContent("remaining_number", remainingNumber);
}
}

View File

@@ -0,0 +1,44 @@
package cn.lili.common.fulu.model;
/**
* 手机号归属地input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:08
*/
public class InputMatchPhoneProductListDto extends CommonRequest {
public InputMatchPhoneProductListDto() {
super();
setMethod("fulu.mobile.info.get");
}
/**
* 面值
*
* @return Double
*/
public Double getFaceValue() {
Object value = getBizContentValue("face_value");
return value != null ? Double.valueOf(value.toString()) : null;
}
public void setFaceValue(Double faceValue) {
setBizContent("face_value", faceValue);
}
/**
* 手机号
*
* @return String
*/
public String getPhone() {
Object value = getBizContentValue("phone");
return value != null ? String.valueOf(value) : null;
}
public void setPhone(String phone) {
setBizContent("phone", phone);
}
}

View File

@@ -0,0 +1,31 @@
package cn.lili.common.fulu.model;
/**
* 订单查单input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 15:23
*/
public class InputOrderGetDto extends CommonRequest {
public InputOrderGetDto() {
super();
setMethod("fulu.order.info.get");
}
/**
* 外部订单号
*
* @return String
*/
public String getCustomerOrderNo() {
Object value = getBizContentValue("customer_order_no");
return value != null ? String.valueOf(value) : null;
}
public void setCustomerOrderNo(String customerOrderNo) {
setBizContent("customer_order_no", customerOrderNo);
}
}

View File

@@ -0,0 +1,57 @@
package cn.lili.common.fulu.model;
/**
* 话费订单input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 15:31
*/
public class InputPhoneOrderDto extends CommonRequest {
public InputPhoneOrderDto() {
super();
setMethod("fulu.order.mobile.add");
}
/**
* 充值手机号
*
* @return String
*/
public String getChargePhone() {
Object value = getBizContentValue("charge_phone");
return value != null ? String.valueOf(value) : null;
}
public void setChargePhone(String chargePhone) {
setBizContent("charge_phone", chargePhone);
}
/**
* 充值数额
*
* @return Double
*/
public Double getChargeValue() {
Object value = getBizContentValue("charge_value");
return value != null ? Double.valueOf(value.toString()) : null;
}
public void setChargeValue(Double chargeValue) {
setBizContent("charge_value", chargeValue);
}
/**
* 外部订单号
*
* @return String
*/
public String getCustomerOrderNo() {
Object value = getBizContentValue("customer_order_no");
return value != null ? String.valueOf(value) : null;
}
public void setCustomerOrderNo(String customerOrderNo) {
setBizContent("customer_order_no", customerOrderNo);
}
}

View File

@@ -0,0 +1,30 @@
package cn.lili.common.fulu.model;
/**
* 商品信息input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:04
*/
public class InputProductDto extends CommonRequest {
public InputProductDto() {
super();
setMethod("fulu.goods.info.get");
}
/**
* 商品编号
*
* @return String
*/
public String getProductId() {
Object value = getBizContentValue("product_id");
return value != null ? String.valueOf(value) : null;
}
public void setProductId(String productId) {
setBizContent("product_id", productId);
}
}

View File

@@ -0,0 +1,29 @@
package cn.lili.common.fulu.model;
/**
* 商品模板信息input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:01
*/
public class InputProductTemplateDto extends CommonRequest {
public InputProductTemplateDto() {
super();
setMethod("fulu.goods.template.get");
}
/**
* 商品模板编号
*
* @return String
*/
public String getTemplateId() {
Object value = getBizContentValue("template_id");
return value != null ? String.valueOf(value) : null;
}
public void setTemplateId(String templateId) {
setBizContent("template_id", templateId);
}
}

View File

@@ -0,0 +1,72 @@
package cn.lili.common.fulu.model;
/**
* 流量订单input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 13:50
*/
public class InputTrafficOrderDto extends CommonRequest {
public InputTrafficOrderDto() {
super();
setMethod("fulu.order.data.add");
}
/**
* 充值手机号
*
* @return String
*/
public String getChargePhone() {
Object value = getBizContentValue("charge_phone");
return value != null ? String.valueOf(value) : null;
}
public void setChargePhone(String chargePhone) {
setBizContent("charge_phone", chargePhone);
}
/**
* 充值数额M
*
* @return Double
*/
public Double getChargeValue() {
Object value = getBizContentValue("charge_value");
return value != null ? Double.valueOf(value.toString()) : null;
}
public void setChargeValue(Double chargeValue) {
setBizContent("charge_value", chargeValue);
}
/**
* 外部订单号
*
* @return String
*/
public String getCustomerOrderNo() {
Object value = getBizContentValue("customer_order_no");
return value != null ? String.valueOf(value) : null;
}
public void setCustomerOrderNo(String customerOrderNo) {
setBizContent("customer_order_no", customerOrderNo);
}
/**
* 流量性质 1:小时 2:日 3:7天 4:月 5:季度 6:半年 7:年
*
* @return Integer
*/
public Integer getPacketKind() {
Object value = getBizContentValue("packet_kind");
return value != null ? Integer.valueOf(value.toString()) : null;
}
public void setPacketKind(Integer packetKind) {
setBizContent("packet_kind", packetKind);
}
}

View File

@@ -0,0 +1,15 @@
package cn.lili.common.fulu.model;
/**
* 用户信息input dto
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:06
*/
public class InputUserDto extends CommonRequest {
public InputUserDto() {
super();
setMethod("fulu.user.info.get");
}
}

View File

@@ -0,0 +1,46 @@
package cn.lili.common.fulu.model.response;
/**
* 响应对象
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 15:06
*/
public class DefaultClientResponse {
private String code;
private String message;
private String result;
private String sign;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}

View File

@@ -0,0 +1,129 @@
package cn.lili.common.fulu.sdk;
import cn.lili.common.fulu.core.http.FuluClient;
import cn.lili.common.fulu.core.http.IFuluClient;
import cn.lili.common.fulu.core.utils.JSONUtil;
import cn.lili.common.fulu.model.CommonRequest;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.Arrays;
import java.util.concurrent.Future;
/**
* 默认OpenApi客户请求实现
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:45
*/
public class DefaultOpenApiClient implements IDefaultOpenApiClient {
/**
* 商户AppKey
*/
private String appKey;
/**
* 业务参数
*/
private CommonRequest bizContent;
/**
* http请求
*/
private IFuluClient fuluClient;
/**
* 方法
*/
private String method;
/**
* 应用秘钥
*/
private String sysSecret;
// public DefaultOpenApiClient(String url, String appKey, String sysSecret) {
// this.appKey = appKey;
// this.sysSecret = sysSecret;
//
// if (url == null || "".equals(url.trim())) {
// this.fuluClient = new FuluClient();
// } else {
// this.fuluClient = new FuluClient(url);
// }
// }
/**
* 如果url没改变可以使用这个构造
*
* @param appKey appKey
* @param sysSecret sysSecret
*/
// public DefaultOpenApiClient(String appKey, String sysSecret) {
// this.appKey = appKey;
// this.fuluClient = new FuluClient();
// this.sysSecret = sysSecret;
// }
/**
* 使用public void setBizContent(String bizContent)此方法method不能为空必填
* 或者使用其它构造调用fulu.sup.open.api.model.CommonRequest的setMethod也可以
*
* @param url url
* @param appKey appKey
* @param sysSecret sysSecret
* @param method method
*/
public DefaultOpenApiClient(String url, String appKey, String sysSecret, String method) {
this.appKey = appKey;
this.sysSecret = sysSecret;
this.method = method;
if (url == null || "".equals(url.trim())) {
this.fuluClient = new FuluClient();
} else {
this.fuluClient = new FuluClient(url);
}
}
@Override
public String excute() {
doSign();
return fuluClient.send(JSONUtil.toJSON(this.bizContent));
}
@Override
public Future<String> excuteAsync() {
doSign();
return fuluClient.sendAsync(JSONUtil.toJSON(this.bizContent));
}
@Override
public void setBizContent(String bizContent) {
this.bizContent = new CommonRequest();
this.bizContent.setBizContent(bizContent);
this.bizContent.setAppKey(this.appKey);
this.bizContent.setMethod(this.method);
}
@Override
public void setBizObject(CommonRequest bizModel) {
this.bizContent = bizModel;
this.bizContent.setAppKey(this.appKey);
if (method != null && !"".equals(method)) {
this.bizContent.setMethod(this.method);
}
}
private void doSign() {
if (bizContent.getMethod() == null || "".equals(bizContent.getMethod().trim())) {
throw new RuntimeException("param \"method\" can not blank!");
}
this.bizContent.setSign(null);
this.bizContent.getBizContent();
String json = JSONUtil.toJSON(this.bizContent);
char[] charArray = json.toCharArray();
Arrays.sort(charArray);
String signStr = new String(charArray);
signStr = String.format("%s%s", signStr, sysSecret);
this.bizContent.setSign(DigestUtils.md5Hex(signStr));
}
}

View File

@@ -0,0 +1,44 @@
package cn.lili.common.fulu.sdk;
import cn.lili.common.fulu.model.CommonRequest;
import java.util.concurrent.Future;
/**
* 默认OpenApi客户请求接口
*
* @Auther: chenYing
* @Date: 2019/8/19 0019 16:40
*/
public interface IDefaultOpenApiClient {
/**
* 执行请求,同步方法
*
* @return String
*/
String excute();
/**
* 执行请求,异步方法
*
* @return Future<String>
*/
Future<String> excuteAsync();
/**
* 设置业务参数
*
* @param bizContent
*/
@Deprecated
void setBizContent(String bizContent);
/**
* 设置业务参数
*/
void setBizObject(CommonRequest bizModel);
}

View File

@@ -16,21 +16,21 @@ public class SmsTemplateProperties {
/**
* 登录
*/
private String lOGIN = "SMS_205755300";
private String lOGIN = "SMS_185821482";
/**
* 注册
*/
private String REGISTER = "SMS_205755298";
private String REGISTER = "SMS_185821482";
/**
* 找回密码
*/
private String FIND_USER = "SMS_205755301";
private String FIND_USER = "SMS_185821482";
/**
* 设置密码
*/
private String UPDATE_PASSWORD = "SMS_205755297";
private String UPDATE_PASSWORD = "SMS_185821482";
/**
* 设置支付密码
*/
private String WALLET_PASSWORD = "SMS_205755297";
private String WALLET_PASSWORD = "SMS_185821482";
}

View File

@@ -24,8 +24,7 @@ public class VerificationCodeProperties {
/**
* 水印
*/
private String watermark = "LILI-SHOP";
private String watermark = "";
/**
* 干扰数量 最大数量
*/

View File

@@ -51,6 +51,11 @@ public class AuthUser implements Serializable {
* storeId
*/
private String storeId;
/**
* 如果角色是商家则存在此店铺id字段
* clerkId
*/
private String clerkId;
/**
* 如果角色是商家,则存在此店铺名称字段
@@ -79,4 +84,14 @@ public class AuthUser implements Serializable {
this.isSuper = isSuper;
this.nickName = nickName;
}
public AuthUser(String username, String id, UserEnums manager, String nickName, Boolean isSuper, String clerkId,String face) {
this.username = username;
this.id = id;
this.role = manager;
this.isSuper = isSuper;
this.nickName = nickName;
this.clerkId = clerkId;
this.face = face;
}
}

View File

@@ -17,7 +17,7 @@ public class SecretKeyUtil {
public static SecretKey generalKey() {
//自定义
byte[] encodedKey = Base64.decodeBase64("cuAihCz53DZRjZwbsGcZJ2Ai6At+T142uphtJMsk7iQ=");
javax.crypto.SecretKey key = Keys.hmacShaKeyFor(encodedKey);
SecretKey key = Keys.hmacShaKeyFor(encodedKey);
return key;
}

View File

@@ -34,9 +34,9 @@ public class TokenUtil {
/**
* 构建token
*
* @param username 主体
* @param claim 私有声明
* @param longTerm 长时间特殊token 如:移动端,微信小程序等
* @param username 主体
* @param claim 私有声明
* @param longTerm 长时间特殊token 如:移动端,微信小程序等
* @param userEnums 用户枚举
* @return TOKEN
*/
@@ -62,7 +62,7 @@ public class TokenUtil {
* 刷新token
*
* @param oldRefreshToken 刷新token
* @param userEnums 用户枚举
* @param userEnums 用户枚举
* @return token
*/
public Token refreshToken(String oldRefreshToken, UserEnums userEnums) {

View File

@@ -55,7 +55,7 @@ public class IpUtils {
}
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
ip = "127.0.0.1";
ip = "106.124.130.167";
}
return ip;
}

View File

@@ -98,7 +98,7 @@ public abstract class BaseElasticsearchService {
log.info(" whether all of the nodes have acknowledged the request : {}", createIndexResponse.isAcknowledged());
log.info(" Indicates whether the requisite number of shard copies were started for each shard in the index before timing out :{}", createIndexResponse.isShardsAcknowledged());
} catch (Exception e) {
log.error("创建索引错误",e);
log.error("创建索引错误", e);
throw new ElasticsearchException("创建索引 {" + index + "} 失败:" + e.getMessage());
}
}
@@ -339,8 +339,7 @@ public abstract class BaseElasticsearchService {
" }\n" +
" }\n";
PutMappingRequest request = new PutMappingRequest(index)
.source(source, XContentType.JSON);
PutMappingRequest request = new PutMappingRequest(index).source(source, XContentType.JSON);
CountDownLatch latch = new CountDownLatch(1);
client.indices().putMappingAsync(
request,
@@ -445,7 +444,7 @@ public abstract class BaseElasticsearchService {
try {
searchResponse = client.search(searchRequest, COMMON_OPTIONS);
} catch (IOException e) {
log.error("es 搜索错误",e);
log.error("es 搜索错误", e);
}
return searchResponse;
}

View File

@@ -77,7 +77,11 @@ public class AuthConfig {
/**
* 针对国外服务可以单独设置代理
* HttpConfig config = new HttpConfig();
<<<<<<< HEAD
* config.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("106.124.130.167", 10080)));
=======
* config.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080)));
>>>>>>> ae0c4aea12996d3d72eca7c6ccdc97922373e4d7
* config.setTimeout(15000);
*
* @since 1.15.5

View File

@@ -47,9 +47,9 @@ public class AuthChecker {
if (!GlobalAuthUtils.isHttpProtocol(redirectUri) && !GlobalAuthUtils.isHttpsProtocol(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI, connectAuth);
}
//支付宝在创建回调地址时不允许使用localhost或者127.0.0.1
//支付宝在创建回调地址时不允许使用localhost或者106.124.130.167
if (ConnectAuthEnum.ALIPAY == connectAuth && GlobalAuthUtils.isLocalHost(redirectUri)) {
//The redirect uri of alipay is forbidden to use localhost or 127.0.0.1
//The redirect uri of alipay is forbidden to use localhost or 106.124.130.167
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI, connectAuth);
}
}

View File

@@ -171,7 +171,7 @@ public class GlobalAuthUtils {
* @return true: 本地主机(域名), false: 非本地主机(域名)
*/
public static boolean isLocalHost(String url) {
return StringUtils.isEmpty(url) || url.contains("127.0.0.1") || url.contains("localhost");
return StringUtils.isEmpty(url) || url.contains("106.124.130.167") || url.contains("localhost");
}

View File

@@ -0,0 +1,34 @@
package cn.lili.modules.file.plugin;
import java.io.InputStream;
import java.util.List;
public interface QiNiuManagerPlugin {
/**
* 文件流上传
*
* @param inputStream
* @param key
* @return
*/
String inputStreamUpload(InputStream inputStream, String key);
/**
* 删除文件
*
* @param key
*/
void deleteFile(List<String> key);
/**
* 根据原图生成规定尺寸的图片
*
* @param url 连接
* @param width 宽
* @param height 高
* @return
*/
String getUrl(String url, Integer width, Integer height);
}

View File

@@ -0,0 +1,143 @@
package cn.lili.modules.file.plugin.impl;
import cn.hutool.core.util.StrUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.file.plugin.QiNiuManagerPlugin;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.OssSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.InputStream;
import java.util.List;
/**
* 阿里oss 文件操作
*
* @author Chopper
*/
@Component
@Slf4j
public class QiNiuFileManagerPlugin implements QiNiuManagerPlugin {
@Autowired
private SettingService settingService;
/**
* 下一个初始化配置参数的时间
* 这里为了防止多次调用redis减少与redis的交互时间
*/
private static Long nextInitSetting;
/**
* 暂时设定3分账请求一次设置
*/
private static final Long INTERVAL = 60 * 3 * 1000L;
/**
* 静态设置,最快三分钟更新一次
*/
private static OssSetting ossSetting;
private Auth auth;
private UploadManager uploadManager;
private BucketManager bucketManager;
/**
* 获取oss client
*
* @return
*/
private OSS getQiNiuOssClient() {
OssSetting ossSetting = getSetting();
return new OSSClientBuilder().build(
ossSetting.getEndPoint(),
ossSetting.getAccessKeyId(),
ossSetting.getAccessKeySecret());
}
/**
* 获取配置
*
* @return
*/
private OssSetting getSetting() {
//如果没有配置或者没有下次刷新时间或者下次刷新时间小于当前时间则从redis 更新一次
if (ossSetting == null || nextInitSetting == null || nextInitSetting < System.currentTimeMillis()) {
Setting setting = settingService.get(SettingEnum.OSS_SETTING.name());
if (setting == null || StrUtil.isBlank(setting.getSettingValue())) {
throw new ServiceException(ResultCode.OSS_NOT_EXIST);
}
nextInitSetting = System.currentTimeMillis() + INTERVAL;
ossSetting = new Gson().fromJson(setting.getSettingValue(), OssSetting.class);
return ossSetting;
}
return ossSetting;
}
@Override
public String inputStreamUpload(InputStream inputStream, String key) {
OssSetting ossSetting = getSetting();
auth = Auth.create(ossSetting.getAccessKeyId(), ossSetting.getAccessKeySecret());
uploadManager = new UploadManager(new Configuration());
String upToken = auth.uploadToken(ossSetting.getBucketName());
try {
Response response = uploadManager.put(inputStream, ossSetting.getPicLocation() +"/"+ key, upToken, null, "image/jpg");
if (response.statusCode == 200) {
return ossSetting.getEndPoint() + "/"+ ossSetting.getPicLocation() + "/" + key;
}
} catch (QiniuException e) {
e.printStackTrace();
}
return "";
}
@Override
public void deleteFile(List<String> key) {
OssSetting ossSetting = getSetting();
if (bucketManager == null) {
if (auth == null) {
auth = Auth.create(ossSetting.getAccessKeyId(), ossSetting.getAccessKeySecret());
}
bucketManager = new BucketManager(auth, new Configuration());
}
//
// for (int i = 0; 0 < key.size(); i++) {
// try {
// bucketManager.delete(ossSetting.getBucketName()+ "/"+ ossSetting.getPicLocation(), key.get(i));
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
}
@Override
public String getUrl(String url, Integer width, Integer height) {
//缩略图全路径
//返回缩略图全路径
return url + "?x-oss-process=style/" + width + "X" + height;
}
}

View File

@@ -4,6 +4,7 @@ import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.SearchVO;
import cn.lili.modules.file.entity.File;
@@ -12,7 +13,6 @@ import cn.lili.modules.file.mapper.FileMapper;
import cn.lili.modules.file.plugin.FilePlugin;
import cn.lili.modules.file.plugin.FilePluginFactory;
import cn.lili.modules.file.service.FileService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

View File

@@ -8,6 +8,7 @@ import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.goods.entity.dto.DraftGoodsDTO;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.dto.GoodsOperationFuLuDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;

View File

@@ -0,0 +1,67 @@
package cn.lili.modules.goods.entity.dto;
import cn.lili.modules.goods.entity.dos.Category;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
/**
* 商品导入DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GoodsImportDTO {
@ApiModelProperty(value = "商品名称")
private String goodsName;
@ApiModelProperty(value = "商品卖点")
private String sellingPoint;
@ApiModelProperty(value = "商品分类")
private Category category;
@ApiModelProperty(value = "运费模板")
private String template;
@ApiModelProperty(value = "计量单位")
private String goodsUnit;
@ApiModelProperty(value = "发布状态")
private Boolean release;
@ApiModelProperty(value = "商品图片")
private List<Map<String, String>> images;
private List<String> goodsGalleryList;
@ApiModelProperty(value = "成本价")
private Double cost;
@ApiModelProperty(value = "销售价")
private Double price;
@ApiModelProperty(value = "库存")
private Integer quantity;
@ApiModelProperty(value = "重量")
private Double weight;
@ApiModelProperty(value = "货号")
private String sn;
@ApiModelProperty(value = "详情")
private String intro;
@ApiModelProperty(value = "规格项")
private String skuKey;
@ApiModelProperty(value = "规格值")
private String skuValue;
}

View File

@@ -1,6 +1,9 @@
package cn.lili.modules.goods.entity.dto;
import cn.lili.common.validation.EnumValue;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.hibernate.validator.constraints.Length;
@@ -8,6 +11,8 @@ import org.hibernate.validator.constraints.Length;
import javax.validation.Valid;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -126,9 +131,49 @@ public class GoodsOperationDTO implements Serializable {
@ApiModelProperty(value = "批发商品规则")
private List<WholesaleDTO> wholesaleList;
@ApiModelProperty(value = "注意事项")
private String needingAttention;
@ApiModelProperty(value = "是否为年度会员专属")
private Boolean annualFeeExclusive;
@ApiModelProperty(value = "浏览权限")
private String browsePermissions;
public String getGoodsName() {
//对商品对名称做一个极限处理。这里没有用xss过滤是因为xss过滤为全局过滤影响很大。
// 业务中,全局代码中只有商品名称不能拥有英文逗号,是由于商品名称存在一个数据库联合查询,结果要根据逗号分组
return goodsName.replace(",", "");
}
public GoodsOperationDTO(GoodsImportDTO goodsImportDTO) {
this.price = goodsImportDTO.getPrice();
this.goodsName = goodsImportDTO.getGoodsName();
this.intro = goodsImportDTO.getIntro();
this.mobileIntro = goodsImportDTO.getIntro();
this.quantity = goodsImportDTO.getQuantity();
this.goodsGalleryList = goodsImportDTO.getGoodsGalleryList();
this.templateId = goodsImportDTO.getTemplate();
this.sellingPoint = goodsImportDTO.getSellingPoint();
this.salesModel = GoodsSalesModeEnum.RETAIL.name();
this.goodsUnit = goodsImportDTO.getGoodsUnit();
this.goodsType = GoodsTypeEnum.PHYSICAL_GOODS.name();
this.release = goodsImportDTO.getRelease();
this.recommend=false;
Map<String, Object> map = new HashMap<>();
map.put("sn", goodsImportDTO.getSn());
map.put("price", goodsImportDTO.getPrice());
map.put("cost", goodsImportDTO.getCost());
map.put("weight", goodsImportDTO.getWeight());
map.put("quantity", goodsImportDTO.getQuantity());
map.put(goodsImportDTO.getSkuKey(), goodsImportDTO.getSkuValue());
map.put("images", goodsImportDTO.getImages());
List<Map<String, Object>> skuList = new ArrayList<>();
skuList.add(map);
this.skuList = skuList;
}
}

View File

@@ -0,0 +1,137 @@
package cn.lili.modules.goods.entity.dto;
import cn.lili.common.validation.EnumValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import org.hibernate.validator.constraints.Length;
import javax.validation.Valid;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* 商品编辑DTO
*
* @author pikachu
* @since 2020-02-24 19:27:20
*/
@Data
@ToString
public class GoodsOperationFuLuDTO implements Serializable {
private static final long serialVersionUID = -509667581371776913L;
@ApiModelProperty(hidden = true)
private String goodsId;
@ApiModelProperty(value = "商品价格", required = true)
@NotNull(message = "商品价格不能为空")
@Min(value = 0, message = "商品价格不能为负数")
@Max(value = 99999999, message = "商品价格不能超过99999999")
private Double price;
@ApiModelProperty(value = "分类path")
private String categoryPath;
@ApiModelProperty(value = "店铺分类id", required = true)
@Size(max = 200, message = "选择了太多店铺分类")
private String storeCategoryPath;
@ApiModelProperty(value = "品牌id")
@Min(value = 0, message = "品牌值不正确")
private String brandId;
@ApiModelProperty(value = "商品名称", required = true)
@NotEmpty(message = "商品名称不能为空")
@Length(max = 50, message = "商品名称不能超过50个字符")
private String goodsName;
@ApiModelProperty(value = "详情")
private String intro;
@ApiModelProperty(value = "商品移动端详情")
private String mobileIntro;
@ApiModelProperty(value = "库存")
@Min(value = 0, message = "库存不能为负数")
@Max(value = 99999999, message = "库存不能超过99999999")
private Integer quantity;
@ApiModelProperty(value = "是否立即发布")
private Boolean release;
@ApiModelProperty(value = "是否是推荐商品")
private Boolean recommend;
@ApiModelProperty(value = "商品参数")
private List<GoodsParamsDTO> goodsParamsDTOList;
@ApiModelProperty(value = "商品图片")
private List<String> goodsGalleryList;
@ApiModelProperty(value = "运费模板id,不需要运费模板时值是0", required = true)
@NotNull(message = "运费模板不能为空没有运费模板时传值0")
@Min(value = 0, message = "运费模板值不正确")
private String templateId;
@ApiModelProperty(value = "sku列表")
@Valid
private List<Map<String, Object>> skuList;
@ApiModelProperty(value = "卖点")
private String sellingPoint;
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
@ApiModelProperty(value = "是否有规格", hidden = true)
private String haveSpec;
@ApiModelProperty(value = "销售模式", required = true)
private String goodsUnit;
@ApiModelProperty(value = "商品描述")
private String info;
@ApiModelProperty(value = "是否重新生成sku数据")
private Boolean regeneratorSkuFlag = true;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型")
@EnumValue(strValues = {"PHYSICAL_GOODS", "VIRTUAL_GOODS", "E_COUPON"}, message = "商品类型参数值错误")
private String goodsType;
/**
* 商品视频
*/
@ApiModelProperty(value = "商品视频")
private String goodsVideo;
public String getGoodsName() {
//对商品对名称做一个极限处理。这里没有用xss过滤是因为xss过滤为全局过滤影响很大。
// 业务中,全局代码中只有商品名称不能拥有英文逗号,是由于商品名称存在一个数据库联合查询,结果要根据逗号分组
return goodsName.replace(",", "");
}
//福禄所需参数
@ApiModelProperty(value = "商品编号", required = true)
@Length(max = 30, message = "商品编号太长不能超过30个字符")
private String sn;
@ApiModelProperty(value = "市场价格", required = true)
@NotNull(message = "市场价格不能为空")
private Double cost;
@ApiModelProperty(value = "重量", required = true)
@NotNull(message = "商品重量不能为空")
@Min(value = 0, message = "重量不能为负数")
@Max(value = 99999999, message = "重量不能超过99999999")
private Double weight;
}

View File

@@ -0,0 +1,20 @@
package cn.lili.modules.goods.service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
public interface GoodsImportService {
/**
* 下载导入列表
* @param response
*/
void download(HttpServletResponse response);
/**
* 导入商品
*/
void importExcel(MultipartFile files) throws Exception;
}

View File

@@ -2,6 +2,7 @@ package cn.lili.modules.goods.service;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.dto.GoodsOperationFuLuDTO;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
@@ -184,4 +185,4 @@ public interface GoodsService extends IService<Goods> {
*/
long countStoreGoodsNum(String storeId);
}
}

View File

@@ -0,0 +1,281 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.GoodsUnit;
import cn.lili.modules.goods.entity.dto.GoodsImportDTO;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.vos.CategoryVO;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsUnitService;
import cn.lili.modules.goods.service.GoodsImportService;
import cn.lili.modules.store.entity.vos.FreightTemplateVO;
import cn.lili.modules.store.service.FreightTemplateService;
import cn.lili.modules.store.service.StoreDetailService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class GoodsImportServiceImpl implements GoodsImportService {
@Autowired
private FreightTemplateService freightTemplateService;
@Autowired
private StoreDetailService storeDetailService;
@Autowired
private CategoryService categoryService;
@Autowired
private GoodsUnitService goodsUnitService;
@Autowired
private GoodsService goodsService;
@Override
public void download(HttpServletResponse response) {
String storeId = "1376369067769724928";
// //Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
//创建Excel工作薄对象
Workbook workbook = new HSSFWorkbook();
//生成一个表格 设置:页签
Sheet sheet = workbook.createSheet("导入模板");
//创建第1行
Row row0 = sheet.createRow(0);
row0.createCell(0).setCellValue("商品名称");
row0.createCell(1).setCellValue("商品卖点");
row0.createCell(2).setCellValue("商品分类");
row0.createCell(3).setCellValue("运费模板");
row0.createCell(4).setCellValue("计量单位");
row0.createCell(5).setCellValue("发布状态");
row0.createCell(6).setCellValue("商品图片");
row0.createCell(7).setCellValue("成本价");
row0.createCell(8).setCellValue("销售价");
row0.createCell(9).setCellValue("库存");
row0.createCell(10).setCellValue("重量");
row0.createCell(11).setCellValue("货号");
row0.createCell(12).setCellValue("详情");
row0.createCell(13).setCellValue("规格项");
row0.createCell(14).setCellValue("规格值");
sheet.setColumnWidth(0, 7000);
sheet.setColumnWidth(1, 7000);
sheet.setColumnWidth(2, 7000);
sheet.setColumnWidth(3, 7000);
sheet.setColumnWidth(4, 7000);
sheet.setColumnWidth(5, 3000);
sheet.setColumnWidth(6, 7000);
sheet.setColumnWidth(7, 3000);
sheet.setColumnWidth(8, 3000);
sheet.setColumnWidth(9, 3000);
sheet.setColumnWidth(10, 3000);
sheet.setColumnWidth(11, 7000);
sheet.setColumnWidth(12, 7000);
sheet.setColumnWidth(13, 3000);
sheet.setColumnWidth(14, 3000);
String goodsManagementCategory = storeDetailService.getStoreDetail(storeId).getGoodsManagementCategory();
List<CategoryVO> categoryVOList = this.categoryService.getStoreCategory(goodsManagementCategory.split(","));
List<String> categoryNameList = new ArrayList<>();
//先简单写,后期优化
//循环三次添加值
//循环列表存放ID-分类名称
for (CategoryVO categoryVO1 : categoryVOList) {
for (CategoryVO categoryVO2 : categoryVO1.getChildren()) {
for (CategoryVO categoryVO3 : categoryVO2.getChildren()) {
categoryNameList.add(categoryVO3.getId() + "-" + categoryVO3.getName());
}
}
}
List<String> freightTemplateNameList = new ArrayList<>();
//循环列表存放ID-运费模板名称
for (FreightTemplateVO freightTemplateVO : freightTemplateService.getFreightTemplateList(storeId)) {
freightTemplateNameList.add(freightTemplateVO.getId() + "-" + freightTemplateVO.getName());
}
//获取计量单位
List<String> goodsUnitList = new ArrayList<>();
List<GoodsUnit> goodsUnitListVO = goodsUnitService.list();
for (GoodsUnit goodsUnit : goodsUnitListVO) {
goodsUnitList.add(goodsUnit.getId() + "-" + goodsUnit.getName());
}
//添加分类
this.excelTo255(workbook, "hiddenCategoryVO", 1, categoryNameList.toArray(new String[]{}), 1, 5000, 2, 2);
//添加运费模板
this.excelTo255(workbook, "hiddenFreightTemplateVO", 2, freightTemplateNameList.toArray(new String[]{}), 1, 5000, 3, 3);
//添加计量单位
this.excelTo255(workbook, "hiddenGoodsUnit", 3, goodsUnitList.toArray(new String[]{}), 1, 5000, 4, 4);
//添加计量单位
this.excelTo255(workbook, "hiddenRelease", 4, new String[]{"上架", "仓库中"}, 1, 5000, 5, 5);
ServletOutputStream out = null;
try {
//设置公共属性,列表名称
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("下载商品导入模板", "UTF8") + ".xls");
out = response.getOutputStream();
workbook.write(out);
} catch (Exception e) {
log.error("下载商品导入模板错误", e);
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void importExcel(MultipartFile files) throws Exception {
InputStream inputStream;
List<GoodsImportDTO> goodsImportDTOList = new ArrayList<>();
inputStream = files.getInputStream();
ExcelReader excelReader = ExcelUtil.getReader(inputStream);
// 读取列表
// 检测数据-查看分类、模板、计量单位是否存在
List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());
for (List<Object> objects : read) {
GoodsImportDTO goodsImportDTO = new GoodsImportDTO();
String categoryId = objects.get(2).toString().substring(0, objects.get(2).toString().indexOf("-"));
Category category = categoryService.getCategoryById(categoryId);
if (category == null) {
throw new ServiceException("商品分类不存在:" + objects.get(2).toString().substring(objects.get(2).toString().indexOf("-")));
}
String templateId = objects.get(3).toString().substring(0, objects.get(3).toString().indexOf("-"));
FreightTemplateVO freightTemplateVO = freightTemplateService.getFreightTemplate(templateId);
if (freightTemplateVO == null) {
throw new ServiceException("配送模板不存在:" + objects.get(3).toString().substring(objects.get(3).toString().indexOf("-")));
}
goodsImportDTO.setGoodsName(objects.get(0).toString());
goodsImportDTO.setSellingPoint(objects.get(1).toString());
goodsImportDTO.setCategory(category);
goodsImportDTO.setTemplate(templateId);
goodsImportDTO.setGoodsUnit(objects.get(4).toString().substring(objects.get(4).toString().indexOf("-") + 1));
goodsImportDTO.setRelease(objects.get(5).toString().equals("上架") ? true : false);
List<Map<String, String>> images = new ArrayList<>();
List<String> goodsGalleryList = new ArrayList<>();
Map<String, String> map = new HashMap<>();
map.put("url", objects.get(6).toString());
images.add(map);
goodsGalleryList.add(objects.get(6).toString());
goodsImportDTO.setImages(images);
goodsImportDTO.setGoodsGalleryList(goodsGalleryList);
goodsImportDTO.setCost(Convert.toDouble(objects.get(7)));
goodsImportDTO.setPrice(Convert.toDouble(objects.get(8)));
goodsImportDTO.setQuantity(Convert.toInt(objects.get(9)));
goodsImportDTO.setWeight(Convert.toDouble(objects.get(10)));
goodsImportDTO.setSn(objects.get(11).toString());
goodsImportDTO.setIntro("<p>" + objects.get(12).toString() + "</p>");
goodsImportDTO.setSkuKey(objects.get(13).toString());
goodsImportDTO.setSkuValue(objects.get(14).toString());
goodsImportDTOList.add(goodsImportDTO);
}
//添加商品
addGoodsList(goodsImportDTOList);
}
/**
* 添加商品
*
* @param goodsImportDTOList
*/
private void addGoodsList(List<GoodsImportDTO> goodsImportDTOList) {
for (GoodsImportDTO goodsImportDTO : goodsImportDTOList) {
GoodsOperationDTO goodsOperationDTO = new GoodsOperationDTO(goodsImportDTO);
//获取父
Category parentCategory = categoryService.getCategoryById(goodsImportDTO.getCategory().getParentId());
goodsOperationDTO.setCategoryPath(parentCategory.getParentId() + "," + parentCategory.getId() + "," + goodsImportDTO.getCategory().getParentId());
//添加商品
goodsService.addGoods(goodsOperationDTO);
}
}
/**
* 表格
*
* @param workbook 表格
* @param sheetName sheet名称
* @param sheetNameIndex 开始
* @param sheetData 数据
* @param firstRow 开始行
* @param lastRow 结束行
* @param firstCol 开始列
* @param lastCol 结束列
*/
private void excelTo255(Workbook workbook, String sheetName, int sheetNameIndex, String[] sheetData,
int firstRow, int lastRow, int firstCol, int lastCol) {
//将下拉框数据放到新的sheet里然后excle通过新的sheet数据加载下拉框数据
Sheet hidden = workbook.createSheet(sheetName);
//创建单元格对象
Cell cell = null;
//遍历我们上面的数组将数据取出来放到新sheet的单元格中
for (int i = 0, length = sheetData.length; i < length; i++) {
//取出数组中的每个元素
String name = sheetData[i];
//根据i创建相应的行对象说明我们将会把每个元素单独放一行
Row row = hidden.createRow(i);
//创建每一行中的第一个单元格
cell = row.createCell(0);
//然后将数组中的元素赋值给这个单元格
cell.setCellValue(name);
}
// 创建名称,可被其他单元格引用
Name namedCell = workbook.createName();
namedCell.setNameName(sheetName);
// 设置名称引用的公式
namedCell.setRefersToFormula(sheetName + "!$A$1:$A$" + sheetData.length);
//加载数据,将名称为hidden的sheet中的数据转换为List形式
DVConstraint constraint = DVConstraint.createFormulaListConstraint(sheetName);
// 设置第一列的3-65534行为下拉列表
// (3, 65534, 2, 2) ====> (起始行,结束行,起始列,结束列)
CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
// 将设置下拉选的位置和数据的对应关系 绑定到一起
DataValidation dataValidation = new HSSFDataValidation(regions, constraint);
//将第二个sheet设置为隐藏
workbook.setSheetHidden(sheetNameIndex, true);
//将数据赋给下拉列表
workbook.getSheetAt(0).addValidationData(dataValidation);
}
}

View File

@@ -18,6 +18,7 @@ import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsGallery;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.dto.GoodsOperationFuLuDTO;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
@@ -170,7 +171,9 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
//检查商品
this.checkGoods(goods);
//向goods加入图片
this.setGoodsGalleryParam(goodsOperationDTO.getGoodsGalleryList().get(0), goods);
if (goodsOperationDTO.getGoodsGalleryList().size() > 0 ) {
this.setGoodsGalleryParam(goodsOperationDTO.getGoodsGalleryList().get(0), goods);
}
//添加商品参数
if (goodsOperationDTO.getGoodsParamsDTOList() != null && !goodsOperationDTO.getGoodsParamsDTOList().isEmpty()) {
//给商品参数填充值
@@ -188,6 +191,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
@Override
@Transactional(rollbackFor = Exception.class)
public void editGoods(GoodsOperationDTO goodsOperationDTO, String goodsId) {
@@ -216,6 +220,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
this.generateEs(goods);
}
@Override
public GoodsVO getGoodsVO(String goodsId) {
//缓存获取,如果没有则读取缓存
@@ -699,4 +704,4 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
return queryWrapper;
}
}
}

View File

@@ -0,0 +1,17 @@
package cn.lili.modules.kdBrid.service;
/**
* 快递鸟电子面单业务层实现
*
* @author chc
* @since 2022-4-12 10:12:43
*/
public interface KdNiaoService {
/**
* 生成电子面单
* @param orderSn 订单编号
* @param logisticsId 物流公司
* @return 电子面单模板
*/
String createElectronicsFaceSheet(String orderSn, String logisticsId) throws Exception;
}

View File

@@ -0,0 +1,383 @@
package cn.lili.modules.kdBrid.serviceImpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.OperationalJudgment;
import cn.lili.modules.kdBrid.service.KdNiaoService;
import cn.lili.modules.member.service.StoreLogisticsService;
import cn.lili.modules.order.order.aop.OrderLogPoint;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.enums.DeliverStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.store.entity.dos.StoreLogistics;
import cn.lili.modules.store.entity.dto.StoreDeliverGoodsAddressDTO;
import cn.lili.modules.store.service.StoreDetailService;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.KuaidiSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.LogisticsService;
import cn.lili.modules.system.service.SettingService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.Gson;
import groovy.util.logging.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 快递鸟电子面单业务层实现
*
* @author chc
* @since 2022-4-12 10:12:43
*/
@Service
@Slf4j
public class KdNiaoServiceImpl implements KdNiaoService {
/**
* 订单货物
*/
@Autowired
OrderItemService orderItemService;
/**
* 订单
*/
@Autowired
OrderService orderService;
/**
* 物流公司
*/
@Autowired
LogisticsService logisticsService;
/**
* 商家店铺
*/
@Autowired
StoreDetailService storeDetailService;
/**
* 配置
*/
@Autowired
SettingService settingService;
/**
* 店铺-物流
*/
@Autowired
StoreLogisticsService storeLogisticsService;
@Override
@OrderLogPoint(description = "'订单['+#orderSn+']发货,发货单号['+#logisticsNo+'],已打印电子面单'", orderSn = "#orderSn")
@Transactional(rollbackFor = Exception.class)
public String createElectronicsFaceSheet(String orderSn, String logisticsId) throws Exception {
//电子面单模板
String printTemplate = null;
//获取订单及子订单
Order order = OperationalJudgment.judgment(orderService.getBySn(orderSn));
List<OrderItem> orderItems = orderItemService.getByOrderSn(orderSn);
Setting setting = settingService.get(SettingEnum.KUAIDI_SETTING.name());
if (CharSequenceUtil.isBlank(setting.getSettingValue())) {
throw new ServiceException(ResultCode.LOGISTICS_NOT_SETTING);
}
KuaidiSetting kuaidiSetting = new Gson().fromJson(setting.getSettingValue(), KuaidiSetting.class);
//ID
String EBusinessID = kuaidiSetting.getEbusinessID();
//KEY
String AppKey = kuaidiSetting.getAppKey();
//请求url
String ReqURL = kuaidiSetting.getSheetReqURL();
//如果订单未发货,并且订单状态值等于待发货
if (order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) && order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) {
//获取对应物流
Logistics logistics = logisticsService.getById(logisticsId);
//物流为空,抛出异常
if (logistics == null) {
throw new ServiceException(ResultCode.ORDER_LOGISTICS_ERROR);
}
//获取店家的物流信息
LambdaQueryWrapper<StoreLogistics> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(StoreLogistics::getLogisticsId, logisticsId);
lambdaQueryWrapper.eq(StoreLogistics::getStoreId, order.getStoreId());
StoreLogistics storeLogistics = storeLogisticsService.getOne(lambdaQueryWrapper);
//获取店家信息
StoreDeliverGoodsAddressDTO storeDeliverGoodsAddressDTO = storeDetailService.getStoreDeliverGoodsAddressDto(order.getStoreId());
//收件人地址
String[] ConsigneeAddress = order.getConsigneeAddressPath().split(",");
//发件人地址
String[] consignorAddress = storeDeliverGoodsAddressDTO.getSalesConsignorAddressPath().split(",");
//组装快递鸟应用级参数
String resultDate = "{" +
"'OrderCode': '" + orderSn + "'," + //订单编码
"'ShipperCode': '" + logistics.getCode() + "'," + //快递公司编码
"'CustomerName': '"+storeLogistics.getCustomerName()+"'," +//客户编码
"'CustomerPwd': '"+storeLogistics.getCustomerPwd()+"'," + //客户密码
"'MonthCode': '"+storeLogistics.getMonthCode()+"'," + //密钥
"'SendSite': '"+storeLogistics.getSendSite()+"'," + //归属网点
"'SendStaff': '"+storeLogistics.getSendStaff()+"'," + //收件快递员
"'PayType': "+storeLogistics.getPayType()+"," +
"'ExpType': "+storeLogistics.getExpType()+"," +
//发件人信息
"'Sender': {" +
"'Name': '" + storeDeliverGoodsAddressDTO.getSalesConsignorName() + "'," +
"'Mobile': '" + storeDeliverGoodsAddressDTO.getSalesConsignorMobile() + "'," +
"'ProvinceName': '" + consignorAddress[0] + "'," + //省
"'CityName': '" + consignorAddress[1] + "'," + //市
"'ExpAreaName': '" + consignorAddress[2] + "'," + //区
"'Address': '" + storeDeliverGoodsAddressDTO.getSalesConsignorDetail() + "'" + //发件人详细地址
"}," +
//收件人信息
"'Receiver': {" +
"'Name': '" + order.getConsigneeName() + "'," +
"'Mobile': '" + order.getConsigneeMobile() + "'," +
"'ProvinceName': '" + ConsigneeAddress[0] + "'," + //省
"'CityName': '" + ConsigneeAddress[1] + "'," + //市
"'ExpAreaName': '" + ConsigneeAddress[2] + "'," + //区
"'Address': '" + order.getConsigneeDetail() + "'" + //收件人详细地址
"}," +
//商品信息
"'Commodity': [";
//子订单信息
for (OrderItem orderItem : orderItems) {
resultDate = resultDate + "{" +
"'GoodsName': '" + orderItem.getGoodsName() + "'," +
"'Goodsquantity': '" + orderItem.getNum() + "'" +
"},";
}
resultDate = resultDate + "]," +
"'Quantity': "+orderItems.size()+"," + //包裹数
"'IsReturnPrintTemplate':1,"+ //生成电子面单模板
"'Remark': '" + order.getRemark() + "'"+//商家备注
"}";
//组织系统级参数
Map<String, String> params = new HashMap<>();
//进行格式加密
params.put("RequestData", urlEncoder(resultDate, "UTF-8"));
params.put("EBusinessID", EBusinessID);
params.put("RequestType", "1007");
String dataSign = encrypt(resultDate, AppKey, "UTF-8");
params.put("DataSign", dataSign);
params.put("DataType", "2");
// 以form表单形式提交post请求post请求体中包含了应用级参数和系统级参数
String result = sendPost(ReqURL, params);
//根据公司业务处理返回的信息......
JSONObject obj = JSONObject.parseObject(result);
if(!"100".equals(obj.getString("ResultCode"))){
return obj.getString("Reason");
}
JSONObject orderJson = JSONObject.parseObject(obj.getString("Order"));
//电子面单模板
printTemplate = obj.getString("PrintTemplate");
//进行发货
orderService.delivery(orderSn, orderJson.getString("LogisticCode"), logisticsId);
}
return printTemplate;
}
/**
* MD5加密
*
* @param str 内容
* @param charset 编码方式
* @throws Exception
*/
@SuppressWarnings("unused")
private String MD5(String str, String charset) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes(charset));
byte[] result = md.digest();
StringBuffer sb = new StringBuffer(32);
for (int i = 0; i < result.length; i++) {
int val = result[i] & 0xff;
if (val <= 0xf) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString().toLowerCase();
}
/**
* base64编码
*
* @param str 内容
* @param charset 编码方式di
* @throws UnsupportedEncodingException
*/
private String base64(String str, String charset) throws UnsupportedEncodingException {
return base64Encode(str.getBytes(charset));
}
@SuppressWarnings("unused")
private String urlEncoder(String str, String charset) throws UnsupportedEncodingException {
return URLEncoder.encode(str, charset);
}
/**
* 电商Sign签名生成
*
* @param content 内容
* @param keyValue Appkey
* @param charset 编码方式
* @return DataSign签名
* @throws UnsupportedEncodingException ,Exception
*/
@SuppressWarnings("unused")
private String encrypt(String content, String keyValue, String charset) throws Exception {
if (keyValue != null) {
return base64(MD5(content + keyValue, charset), charset);
}
return base64(MD5(content, charset), charset);
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param params 请求的参数集合
* @return 远程资源的响应结果
*/
@SuppressWarnings("unused")
private String sendPost(String url, Map<String, String> params) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
URL realUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
//发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
//POST方法
conn.setRequestMethod("POST");
//设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.connect();
//获取URLConnection对象对应的输出流
out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
//发送请求参数
if (params != null) {
StringBuilder param = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (param.length() > 0) {
param.append("&");
}
param.append(entry.getKey());
param.append("=");
param.append(entry.getValue());
}
out.write(param.toString());
}
//flush输出流的缓冲
out.flush();
//定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result.toString();
}
private static final char[] BASE64_ENCODE_CHARS = new char[]{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
public static String base64Encode(byte[] data) {
StringBuffer sb = new StringBuffer();
int len = data.length;
int i = 0;
int b1, b2, b3;
while (i < len) {
b1 = data[i++] & 0xff;
if (i == len) {
sb.append(BASE64_ENCODE_CHARS[b1 >>> 2]);
sb.append(BASE64_ENCODE_CHARS[(b1 & 0x3) << 4]);
sb.append("==");
break;
}
b2 = data[i++] & 0xff;
if (i == len) {
sb.append(BASE64_ENCODE_CHARS[b1 >>> 2]);
sb.append(BASE64_ENCODE_CHARS[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(BASE64_ENCODE_CHARS[(b2 & 0x0f) << 2]);
sb.append("=");
break;
}
b3 = data[i++] & 0xff;
sb.append(BASE64_ENCODE_CHARS[b1 >>> 2]);
sb.append(BASE64_ENCODE_CHARS[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
sb.append(BASE64_ENCODE_CHARS[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
sb.append(BASE64_ENCODE_CHARS[b3 & 0x3f]);
}
return sb.toString();
}
}

View File

@@ -0,0 +1,81 @@
package cn.lili.modules.member.entity.dos;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.modules.member.entity.dto.ClerkAddDTO;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 店员Model
*
* @author wget
* @title: Clerk
* @projectName lilishop
* @date 2021/12/28 7:39 下午
*/
@Data
@TableName("li_clerk")
@ApiModel(value = "店员")
@NoArgsConstructor
@AllArgsConstructor
public class Clerk extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "店员名称")
private String clerkName;
@ApiModelProperty(value = "会员ID")
private String memberId;
@ApiModelProperty(value = "店铺ID")
private String storeId;
@ApiModelProperty(value = "所属部门id")
private String departmentId;
@ApiModelProperty(value = "角色id集合")
private String roleIds;
@ApiModelProperty(value = "是否是店主", hidden = true)
private Boolean shopkeeper = false;
@ApiModelProperty(value = "是否是超级管理员 超级管理员/普通管理员")
private Boolean isSuper = false;
@ApiModelProperty(value = "状态 默认true正常 false禁用")
private Boolean status = true;
/**
* 构建店员
*
* @param clerkAddDTO
*/
public Clerk(ClerkAddDTO clerkAddDTO) {
if (clerkAddDTO.getRoles()!=null && !clerkAddDTO.getRoles().isEmpty()) {
this.roleIds = CharSequenceUtil.join(",", clerkAddDTO.getRoles());
}
this.memberId = clerkAddDTO.getMemberId();
this.departmentId = clerkAddDTO.getDepartmentId();
this.storeId = clerkAddDTO.getStoreId();
this.clerkName = clerkAddDTO.getUsername();
}
public Clerk(Store store){
this.memberId = store.getMemberId();
this.storeId = store.getId();
this.clerkName = store.getMemberName();
this.setShopkeeper(true);
this.setIsSuper(true);
this.setStatus(true);
}
}

View File

@@ -0,0 +1,36 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.mybatis.BaseIdEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 用户角色
*
* @author Chopper
* @since 2020/11/19 12:18
*/
@Data
@TableName("li_clerk_role")
@ApiModel(value = "用户角色")
@Builder
@NoArgsConstructor
public class StoreClerkRole extends BaseIdEntity {
@ApiModelProperty(value = "店员唯一id")
private String clerkId;
@ApiModelProperty(value = "角色唯一id")
private String roleId;
public StoreClerkRole(String clerkId, String roleId) {
this.clerkId = clerkId;
this.roleId = roleId;
}
}

View File

@@ -0,0 +1,37 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
/**
* 部门
*
* @author Chopper
* @since 2020/11/19 11:57
*/
@Data
@TableName("li_store_department")
@ApiModel(value = "店铺部门")
public class StoreDepartment extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "店铺id", hidden = true)
private String storeId;
@ApiModelProperty(value = "部门名称")
@NotEmpty(message = "部门名称不能为空")
private String title;
@ApiModelProperty(value = "父id")
@NotEmpty(message = "父id不能为空")
private String parentId;
@ApiModelProperty(value = "排序值")
private Double sortOrder;
}

View File

@@ -0,0 +1,34 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 角色部门绑定关系
*
* @author Chopper
* @since 2020/11/19 12:18
*/
@Data
@TableName("li_store_department_role")
@ApiModel(value = "店铺角色部门")
@NoArgsConstructor
@AllArgsConstructor
public class StoreDepartmentRole extends BaseEntity {
private static final long serialVersionUID = 2342812932116647050L;
@ApiModelProperty(value = "角色id")
private String roleId;
@ApiModelProperty(value = "部门id")
private String departmentId;
}

View File

@@ -0,0 +1,48 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 菜单权限
*
* @author Chopper
* @since 2020/11/19 12:12
*/
@Data
@TableName("li_store_menu")
@ApiModel(value = "店铺菜单权限")
public class StoreMenu extends BaseEntity {
private static final long serialVersionUID = 7050744476203495207L;
@ApiModelProperty(value = "菜单标题")
private String title;
@ApiModelProperty(value = "路由名称")
private String name;
@ApiModelProperty(value = "路径")
private String path;
@ApiModelProperty(value = "菜单层级")
private Integer level;
@ApiModelProperty(value = "前端目录文件")
private String frontRoute;
@ApiModelProperty(value = "父id")
private String parentId = "0";
@ApiModelProperty(value = "排序值")
private Double sortOrder;
@ApiModelProperty(value = "权限URL*号模糊匹配,逗号分割")
private String permission;
}

View File

@@ -0,0 +1,35 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 角色权限绑定关系
*
* @author Chopper
* @since 2020/11/19 12:18
*/
@Data
@TableName("li_store_menu_role")
@ApiModel(value = "店铺角色权限")
public class StoreMenuRole extends BaseEntity {
private static final long serialVersionUID = -4680260092546996026L;
@ApiModelProperty(value = "角色id")
private String roleId;
@ApiModelProperty(value = "菜单")
private String menuId;
@ApiModelProperty(value = "店铺id")
private String storeId;
@ApiModelProperty(value = "是否拥有操作数据权限,为否则只有查看权限")
private Boolean isSuper;
}

View File

@@ -0,0 +1,36 @@
package cn.lili.modules.member.entity.dos;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 部门
*
* @author Chopper
* @since 2020/11/19 11:57
*/
@Data
@TableName("li_store_role")
@ApiModel(value = "店铺角色")
public class StoreRole extends BaseEntity {
@ApiModelProperty(value = "角色名")
@NotEmpty(message = "角色名称必填")
private String name;
@ApiModelProperty(value = "店铺id", hidden = true)
private String storeId;
@ApiModelProperty(value = "是否为注册默认角色")
private Boolean defaultRole = false;
@ApiModelProperty(value = "备注")
private String description;
}

View File

@@ -0,0 +1,64 @@
package cn.lili.modules.member.entity.dto;
import cn.lili.common.security.sensitive.Sensitive;
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.util.List;
/**
* 店员dto
*
* @author wget
* @title: Clerk
* @projectName lilishop
* @date 2021/12/28 7:39 下午
*/
@Data
@NoArgsConstructor
public class ClerkAddDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "会员用户名")
@NotEmpty(message = "会员用户名不能为空")
@Length(max = 30, message = "会员用户名不能超过20个字符")
private String username;
@ApiModelProperty(value = "会员密码")
@NotEmpty(message = "会员密码不能为空")
private String password;
@NotEmpty(message = "手机号码不能为空")
@ApiModelProperty(value = "手机号码", required = true)
@Sensitive(strategy = SensitiveStrategy.PHONE)
private String mobile;
@ApiModelProperty(value = "所属部门id")
private String departmentId;
@ApiModelProperty(value = "是否是超级管理员 超级管理员/普通管理员")
private Boolean isSuper = false;
@ApiModelProperty(value = "角色")
private List<String> roles;
@ApiModelProperty(value = "会员id", required = true)
private String memberId;
@ApiModelProperty(value = "是否是店主", hidden = true)
private Boolean shopkeeper = false;
@ApiModelProperty(value = "店铺id", hidden = true)
private String storeId;
}

View File

@@ -0,0 +1,46 @@
package cn.lili.modules.member.entity.dto;
import cn.lili.common.security.sensitive.Sensitive;
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* 店员dto
*
* @author wget
* @title: Clerk
* @projectName lilishop
* @date 2021/12/28 7:39 下午
*/
@Data
@NoArgsConstructor
public class ClerkEditDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "店员id", hidden = true)
private String id;
@ApiModelProperty(value = "会员密码")
private String password;
@ApiModelProperty(value = "状态")
private Boolean status;
@ApiModelProperty(value = "所属部门id")
private String departmentId;
@ApiModelProperty(value = "是否是超级管理员 超级管理员/普通管理员")
private Boolean isSuper = false;
@ApiModelProperty(value = "角色")
private List<String> roles;
}

View File

@@ -0,0 +1,48 @@
package cn.lili.modules.member.entity.dto;
import cn.lili.mybatis.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
/**
* 管理员入库dto
*
* @author Chopper
* @since 2020/11/16 19:55
*/
@Data
@ApiModel(value = "店员操作dto")
public class ClerkOperationDTO extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户名")
@Length(max = 20,message = "用户名长度不能超过20个字符")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "昵称")
@Length(max = 10,message = "昵称长度不能超过10个字符")
private String nickName;
@ApiModelProperty(value = "手机")
@Length(max = 11,message = "手机号长度不能超过11")
private String mobile;
@ApiModelProperty(value = "头像")
private String avatar;
@ApiModelProperty(value = "描述/详情/备注")
private String description;
@ApiModelProperty(value = "所属部门id")
private String departmentId;
@ApiModelProperty(value = "是否为超级管理员")
private Boolean isSuper;
}

View File

@@ -0,0 +1,41 @@
package cn.lili.modules.member.entity.dto;
import cn.lili.mybatis.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
/**
* 店员查询
*
* @author Chopper
* @since 2020/11/16 19:55
*/
@Data
@ApiModel(value = "店员查询")
public class ClerkQueryDTO extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "店员名称")
@Length(max = 20, message = "用户名长度不能超过20个字符")
private String clerkName;
@ApiModelProperty(value = "手机")
@Length(max = 11, message = "手机号长度不能超过11")
private String mobile;
@ApiModelProperty(value = "所属部门id")
private String departmentId;
@ApiModelProperty(value = "是否为超级管理员")
private Boolean isSuper;
@ApiModelProperty(value = "状态")
private Boolean status;
@ApiModelProperty(value = "店铺id", hidden = true)
private String storeId;
}

View File

@@ -24,6 +24,10 @@ public class ManagerMemberEditDTO {
@NotNull(message = "用户ID不能为空")
private String id;
@ApiModelProperty(value = "会员用户名,用户名不能进行修改", required = true)
@NotNull(message = "会员用户名不能为空")
private String username;
@ApiModelProperty(value = "会员密码")
private String password;

View File

@@ -0,0 +1,44 @@
package cn.lili.modules.member.entity.vo;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.dos.StoreMenu;
import cn.lili.modules.member.entity.dos.StoreRole;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 管理员VO
*
* @author Chopper
* @since 2020-11-22 09:17
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ClerkVO extends Clerk {
private static final long serialVersionUID = -2378384199695839312L;
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "所属部门名称")
private String departmentTitle;
@ApiModelProperty(value = "用户拥有角色")
private List<StoreRole> roles;
@ApiModelProperty(value = "用户拥有的权限")
private List<StoreMenu> menus;
public ClerkVO(Clerk clerk) {
BeanUtil.copyProperties(clerk, this);
}
}

View File

@@ -28,11 +28,11 @@ public class MemberVO implements Serializable {
private String id;
@ApiModelProperty(value = "会员用户名")
@Sensitive(strategy = SensitiveStrategy.PHONE)
@Sensitive(strategy = SensitiveStrategy.USERNAME)
private String username;
@ApiModelProperty(value = "昵称")
@Sensitive(strategy = SensitiveStrategy.PHONE)
private String nickName;
@ApiModelProperty(value = "会员性别,1为男0为女")

View File

@@ -0,0 +1,28 @@
package cn.lili.modules.member.entity.vo;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.member.entity.dos.StoreDepartment;
import cn.lili.modules.permission.entity.dos.Department;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 部门VO
*
* @author Chopper
* @since 2020-11-23 18:48
*/
@Data
public class StoreDepartmentVO extends StoreDepartment {
private List<StoreDepartmentVO> children = new ArrayList<>();
public StoreDepartmentVO() {
}
public StoreDepartmentVO(StoreDepartment storeDepartment) {
BeanUtil.copyProperties(storeDepartment, this);
}
}

View File

@@ -0,0 +1,45 @@
package cn.lili.modules.member.entity.vo;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.member.entity.dos.StoreMenu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* 菜单VO 展示模型
*
* @author Chopper
* @since 2020/11/20 15:38
*/
@Data
public class StoreMenuVO extends StoreMenu {
@ApiModelProperty(value = "子菜单")
private List<StoreMenuVO> children = new ArrayList<>();
public StoreMenuVO() {
}
public StoreMenuVO(StoreMenu storeMenu) {
BeanUtil.copyProperties(storeMenu, this);
}
public List<StoreMenuVO> getChildren() {
if (children != null) {
children.sort(new Comparator<StoreMenuVO>() {
@Override
public int compare(StoreMenuVO o1, StoreMenuVO o2) {
return o1.getSortOrder().compareTo(o2.getSortOrder());
}
});
return children;
}
return null;
}
}

View File

@@ -0,0 +1,29 @@
package cn.lili.modules.member.entity.vo;
import cn.lili.modules.member.entity.dos.StoreMenu;
import cn.lili.modules.permission.entity.dos.Menu;
import lombok.Data;
/**
* RoleMenuVO
*
* @author Chopper
* @since 2020-11-24 11:45
*/
@Data
public class StoreUserMenuVO extends StoreMenu {
private static final long serialVersionUID = -7478870595109016162L;
/**
* 是否是超级管理员
*/
private Boolean isSuper;
public Boolean getSuper() {
if (this.isSuper == null) {
return false;
}
return isSuper;
}
}

View File

@@ -0,0 +1,34 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.vo.ClerkVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* 店员数据处理层
*
* @author wget
* @title: ClerkMapper
* @projectName lilishop
* @date 2021/12/28 7:39 下午
*/
public interface ClerkMapper extends BaseMapper<Clerk> {
/**
* 查询店员分页数据
* @param page 分页信息
* @param ew 店铺ID
* @return
*/
@Select("select li_clerk.*,m.id,m.mobile as mobile from li_clerk inner join li_member as m on li_clerk.member_id = m.id ${ew.customSqlSegment}")
IPage<ClerkVO> selectClerkPage(Page page, @Param(Constants.WRAPPER) QueryWrapper ew);
}

View File

@@ -23,7 +23,8 @@ public interface FootprintMapper extends BaseMapper<FootPrint> {
*
* @param memberId 会员ID
*/
@Delete("DELETE FROM li_foot_print l1 WHERE l1.id IN (" +
@Delete("DELETE FROM li_foot_print WHERE id IN ("+
"SELECT l2.id FROM (" +
"SELECT l3.id FROM li_foot_print l3 WHERE l3.member_id=${memberId} ORDER BY id DESC LIMIT 100,100) l2)")
void deleteLastFootPrint(String memberId);

View File

@@ -0,0 +1,13 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.StoreClerkRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 角色权限数据处理层
* @author Chopper
* @since 2020-11-22 09:17
*/
public interface StoreClerkRoleMapper extends BaseMapper<StoreClerkRole> {
}

View File

@@ -0,0 +1,14 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.StoreDepartment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 部门数据处理层
*
* @author Chopper
* @since 2020-11-22 09:17
*/
public interface StoreDepartmentMapper extends BaseMapper<StoreDepartment> {
}

View File

@@ -0,0 +1,14 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.StoreDepartmentRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 店铺部门角色数据处理层
*
* @author Chopper
* @since 2020-11-22 09:17
*/
public interface StoreDepartmentRoleMapper extends BaseMapper<StoreDepartmentRole> {
}

View File

@@ -21,7 +21,7 @@ public interface StoreLogisticsMapper extends BaseMapper<StoreLogistics> {
* @param storeId 店铺ID
* @return 物流公司列表
*/
@Select("SELECT l.* FROM li_logistics l RIGHT JOIN li_store_logistics sl ON l.id=sl.logistics_id WHERE sl.store_id=#{storeId} AND l.disabled='OPEN'")
@Select("SELECT l.id as logistics_id,l.name FROM li_logistics l RIGHT JOIN li_store_logistics sl ON l.id=sl.logistics_id WHERE sl.store_id=#{storeId} AND l.disabled='OPEN'")
List<StoreLogisticsVO> getSelectedStoreLogistics(String storeId);
/**
@@ -39,7 +39,35 @@ public interface StoreLogisticsMapper extends BaseMapper<StoreLogistics> {
* @param storeId 店铺列表
* @return 店铺地址VO列表
*/
@Select("SELECT *, ( SELECT sl.id FROM li_store_logistics sl WHERE l.id = sl.logistics_id AND sl.store_id=#{storeId} ) AS selected FROM li_logistics l WHERE l.disabled='OPEN';")
@Select("SELECT id as logistics_id , `name` , ( SELECT sl.id FROM li_store_logistics sl WHERE l.id = sl.logistics_id AND sl.store_id=#{storeId} ) AS selected,(SELECT sl.face_sheet_flag FROM li_store_logistics sl WHERE l.id = sl.logistics_id AND sl.store_id = #{storeId}) as face_sheet_flag FROM li_logistics l WHERE l.disabled='OPEN';")
//@Select("SELECT *, ( SELECT sl.id FROM li_store_logistics sl WHERE l.id = sl.logistics_id AND sl.store_id=#{storeId} ) AS selected FROM li_logistics l WHERE l.disabled='OPEN';")
List<StoreLogisticsVO> getStoreLogistics(String storeId);
/**
* 店铺已选择的物流公司
* @param storeId 店铺Id
* @return 物流公司列表
*/
@Select("SELECT sl.logistics_id,l.name,sl.face_sheet_flag FROM li_logistics l INNER JOIN li_store_logistics sl on sl.logistics_id=l.id WHERE l.disabled = 'OPEN' AND store_id=#{storeId};")
List<StoreLogisticsVO> getOpenStoreLogistics(String storeId);
/**
* 店铺未选择的物流公司
* @param storeId 店铺Id
* @return 物流公司列表
*/
@Select("SELECT id as logistics_id,name FROM li_logistics WHERE id not in(SELECT logistics_id FROM li_store_logistics WHERE store_id=#{storeId}) AND disabled = 'OPEN'")
List<StoreLogisticsVO> getCloseStroreLogistics(String storeId);
/**
* 获取店铺选择的物流公司并使用了电子面单
*
* @param storeId 店铺ID
* @return 物流公司列表
*/
@Select("SELECT id as logistics_id , `name` FROM li_logistics WHERE disabled='OPEN'" +
"AND id in(SELECT logistics_id FROM li_store_logistics WHERE store_id=#{storeId} and face_sheet_flag=1)")
List<StoreLogisticsVO> getSelectedStoreLogisticsUseFaceSheet(String storeId);
}

View File

@@ -0,0 +1,44 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.StoreMenu;
import cn.lili.modules.member.entity.vo.StoreUserMenuVO;
import cn.lili.modules.permission.entity.dos.Menu;
import cn.lili.modules.permission.entity.vo.UserMenuVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 菜单数据处理层
*
* @author Chopper
* @since 2020-11-22 09:17
*/
public interface StoreMenuMapper extends BaseMapper<StoreMenu> {
/**
* 根据用户获取菜单列表
*
* @param userId 用户ID
* @return 菜单列表
*/
@Select("SELECT menu.* FROM li_store_menu AS menu WHERE menu.id IN (" +
"SELECT rm.menu_id FROM li_store_menu_role AS rm WHERE rm.role_id IN (" +
"SELECT ur.role_id FROM li_clerk_role AS ur WHERE ur.clerk_id=#{userId}) OR rm.role_id IN (" +
"SELECT dr.role_id FROM li_store_department_role AS dr WHERE dr.department_id=(" +
"SELECT department_id FROM li_clerk AS au WHERE au.id = #{userId})))")
List<StoreMenu> findByUserId(String userId);
/**
* 根据用户获取菜单权限
*
* @param userId 用户ID
* @return 用户菜单VO列表
*/
@Select("SELECT rm.is_super as is_super,m.*FROM li_store_menu AS m INNER JOIN li_store_menu_role AS rm ON rm.menu_id=m.id WHERE rm.role_id IN (" +
"SELECT ur.role_id FROM li_clerk_role AS ur WHERE ur.clerk_id=#{userId}) OR rm.role_id IN (" +
"SELECT dr.role_id FROM li_store_department_role AS dr INNER JOIN li_clerk AS au ON au.department_id=dr.department_id " +
"WHERE au.id=#{userId}) GROUP BY m.id,rm.is_super ORDER BY rm.is_super desc")
List<StoreUserMenuVO> getUserRoleMenu(String userId);
}

View File

@@ -0,0 +1,14 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.StoreMenuRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 角色菜单数据处理层
*
* @author Chopper
* @since 2020-11-22 09:17
*/
public interface StoreMenuRoleMapper extends BaseMapper<StoreMenuRole> {
}

View File

@@ -0,0 +1,15 @@
package cn.lili.modules.member.mapper;
import cn.lili.modules.member.entity.dos.StoreRole;
import cn.lili.modules.permission.entity.dos.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 店铺角色数据处理层
*
* @author Chopper
* @since 2020-11-22 09:17
*/
public interface StoreRoleMapper extends BaseMapper<StoreRole> {
}

View File

@@ -0,0 +1,99 @@
package cn.lili.modules.member.service;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dto.ClerkAddDTO;
import cn.lili.modules.member.entity.dto.ClerkEditDTO;
import cn.lili.modules.member.entity.dto.ClerkQueryDTO;
import cn.lili.modules.member.entity.vo.ClerkVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 店员业务层
*
* @author wget
* @title: ClerkService
* @projectName lilishop
* @date 2021/12/28 7:42 下午
*/
public interface ClerkService extends IService<Clerk> {
/**
* 店员查询
*
* @param page
* @param clerkQueryDTO
* @return
*/
IPage<ClerkVO> clerkForPage(PageVO page, ClerkQueryDTO clerkQueryDTO);
/**
* 查询店员详细
*
* @param id 店员id
* @return
*/
ClerkVO get(String id);
/**
* 修改店员信息
*
* @param clerkEditDTO 店员
* @return
*/
Clerk updateClerk(ClerkEditDTO clerkEditDTO);
/**
* 保存店员
*
* @param clerkAddDTO 店员
* @return
*/
Clerk saveClerk(ClerkAddDTO clerkAddDTO);
/**
* 根据会员id获取店员信息
*
* @param memberId 会员id
* @return
*/
Clerk getClerkByMemberId(String memberId);
/**
* 重置店员密码
*
* @param ids 店员ids
*/
void resetPassword(List<String> ids);
/**
* 删除店员
*
* @param ids 店员ids
*/
void deleteClerk(List<String> ids);
/**
* 检测会员有效性
*
* @param mobile 手机号码
* @return
*/
Member checkClerk(String mobile);
/**
* 店员状态操作
*
* @param id 店员id
* @param status 状态
*/
void disable(String id, Boolean status);
}

View File

@@ -26,7 +26,6 @@ import java.util.Map;
* @since 2020-02-25 14:10:16
*/
public interface MemberService extends IService<Member> {
/**
* 默认密码
*/
@@ -40,13 +39,12 @@ public interface MemberService extends IService<Member> {
Member getUserInfo();
/**
* 是否可以通过手机获取用户
* 通过手机获取用户
*
* @param uuid UUID
* @param mobile 手机号
* @return 操作状态
*/
boolean findByMobile(String uuid, String mobile);
Member findByMobile(String mobile);
/**
* 通过用户名获取用户
@@ -93,11 +91,22 @@ public interface MemberService extends IService<Member> {
/**
* 修改用户密码
*
* @param memberId 会员id
* @param oldPassword 旧密码
* @param newPassword 新密码
* @return 操作结果
*/
Member modifyPass(String oldPassword, String newPassword);
Member modifyPass(String memberId, String oldPassword, String newPassword);
/**
* 注册会员
*
* @param userName 会员
* @param password 密码
* @param mobilePhone mobilePhone
* @return 处理结果
*/
Token register(String userName, String password, String mobilePhone);
/**
* 是否可以初始化密码
@@ -121,17 +130,6 @@ public interface MemberService extends IService<Member> {
* @return 操作结果
*/
void cancellation(String password);
/**
* 注册会员
*
* @param userName 会员
* @param password 密码
* @param mobilePhone mobilePhone
* @return 处理结果
*/
Token register(String userName, String password, String mobilePhone);
/**
* 修改当前会员的手机号
*
@@ -252,6 +250,24 @@ public interface MemberService extends IService<Member> {
*/
void logout(UserEnums userEnums);
/**
* <<<<<<< HEAD
* 修改会员是否拥有店铺
*
* @param haveStore 是否拥有店铺
* @param storeId 店铺id
* @param memberIds 会员id
* @return
*/
void updateHaveShop(Boolean haveStore, String storeId, List<String> memberIds);
/**
* 重置会员密码为123456
*
* @param ids 会员id
*/
void resetPassword(List<String> ids);
/**
* 获取所有会员的手机号
*
@@ -269,7 +285,6 @@ public interface MemberService extends IService<Member> {
/**
* 获取用户VO
*
* @param id 会员id
* @return 用户VO
*/

View File

@@ -0,0 +1,41 @@
package cn.lili.modules.member.service;
import cn.lili.modules.member.entity.dos.StoreClerkRole;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 店铺店员角色业务层
*
* @author Chopper
* @since 2020/11/17 3:46 下午
*/
public interface StoreClerkRoleService extends IService<StoreClerkRole> {
/**
* 根据用户查看拥有的角色
*
* @param clerkId 店员id
* @return
*/
List<StoreClerkRole> listByUserId(String clerkId);
/**
* 根据店员id查看角色
*
* @param clerkId 店员id
* @return
*/
List<String> listId(String clerkId);
/**
* 更新用户拥有的角色
*
* @param clerkId 店员id
* @param storeClerkRoles 角色权限
*/
void updateClerkRole(String clerkId, List<StoreClerkRole> storeClerkRoles);
}

View File

@@ -0,0 +1,38 @@
package cn.lili.modules.member.service;
import cn.lili.modules.member.entity.dos.StoreDepartmentRole;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 部门角色业务层
*
* @author Chopper
* @since 2020/11/22 12:08
*/
public interface StoreDepartmentRoleService extends IService<StoreDepartmentRole> {
/**
* 根据部门获取角色集合
*
* @param storeDepartmentId 店铺部门id
* @return
*/
List<StoreDepartmentRole> listByDepartmentId(String storeDepartmentId);
/**
* 更新部门角色关联
*
* @param storeDepartmentId 店铺部门id
* @param storeDepartmentRoles 店铺部门角色
*/
void updateByDepartmentId(String storeDepartmentId, List<StoreDepartmentRole> storeDepartmentRoles);
/**
* 根据部门id删除部门与角色关联
*
* @param ids id集合
*/
void deleteByDepartment(List<String> ids);
}

View File

@@ -0,0 +1,40 @@
package cn.lili.modules.member.service;
import cn.lili.modules.member.entity.dos.StoreDepartment;
import cn.lili.modules.member.entity.vo.StoreDepartmentVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 店铺部门业务层
*
* @author Chopper
* @since 2020/11/17 3:43 下午
*/
public interface StoreDepartmentService extends IService<StoreDepartment> {
/**
* 获取部门树
*
* @param initWrapper
* @return
*/
List<StoreDepartmentVO> tree(QueryWrapper<StoreDepartment> initWrapper);
/**
* 删除部门
*
* @param ids
*/
void deleteByIds(List<String> ids);
/**
* 更新店铺部门
*
* @param storeDepartment 店铺部门
* @return
*/
Boolean update(StoreDepartment storeDepartment);
}

View File

@@ -1,6 +1,7 @@
package cn.lili.modules.member.service;
import cn.lili.modules.store.entity.dos.StoreLogistics;
import cn.lili.modules.store.entity.dto.StoreLogisticsCustomerDTO;
import cn.lili.modules.system.entity.vo.StoreLogisticsVO;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -45,7 +46,48 @@ public interface StoreLogisticsService extends IService<StoreLogistics> {
* @param storeId 店铺id
* @return 店铺物流公司
*/
StoreLogistics add(String logisticsId, String storeId);
StoreLogistics add(String logisticsId, String storeId, StoreLogisticsCustomerDTO storeLogisticsCustomerDTO);
/**
* 获取当前店铺已选择的物流公司并使用电子面单列表
*
* @param storeId 店铺id
* @return 物流公司列表
*/
List<StoreLogisticsVO> getStoreSelectedLogisticsUseFaceSheet(String storeId);
/**
* 修改店铺-物流公司电子面单参数
* @param logisticsId 物流公司设置id
* @param storeId 店铺id
* @return 店铺物流公司
*/
StoreLogistics update(String logisticsId, String storeId, StoreLogisticsCustomerDTO storeLogisticsCustomerDTO);
/**
* 获取店铺物流信息回填
* @param logisticsId 物流id
* @return 店铺物流信息
*/
StoreLogistics getStoreLogisticsInfo(String logisticsId);
/**
* 获取当前店铺已开启的物流公司列表
*
* @param storeId 店铺id
* @return 物流公司列表
*/
List<StoreLogisticsVO> getOpenStoreLogistics(String storeId);
/**
* 获取当前店铺未开启的物流公司列表
*
* @param storeId 店铺id
* @return 物流公司列表
*/
List<StoreLogisticsVO> getCloseStoreLogistics(String storeId);
}

View File

@@ -0,0 +1,57 @@
package cn.lili.modules.member.service;
import cn.lili.modules.member.entity.dos.StoreMenuRole;
import cn.lili.modules.member.entity.vo.StoreUserMenuVO;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 角色菜单接口
*
* @author Chopper
* @since 2020/11/22 11:43
*/
public interface StoreMenuRoleService extends IService<StoreMenuRole> {
/**
* 通过角色获取菜单权限列表
*
* @param roleId
* @return
*/
List<StoreMenuRole> findByRoleId(String roleId);
/**
* 根据角色集合获取拥有的菜单具体权限
*
* @param clerkId
* @return
*/
List<StoreUserMenuVO> findAllMenu(String clerkId,String memberId);
/**
* 更新某角色拥有到菜单
*
* @param roleId 角色id
* @param roleMenus
*/
void updateRoleMenu(String roleId, List<StoreMenuRole> roleMenus);
/**
* 根据角色id 删除数据
*
* @param roleId
*/
void delete(String roleId);
/**
* 根据角色id 删除数据
*
* @param roleId
*/
void delete(List<String> roleId);
}

View File

@@ -0,0 +1,74 @@
package cn.lili.modules.member.service;
import cn.lili.modules.member.entity.dos.StoreMenu;
import cn.lili.modules.member.entity.vo.StoreMenuVO;
import cn.lili.modules.permission.entity.dto.MenuSearchParams;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.cache.annotation.CacheConfig;
import java.util.List;
/**
* 店铺菜单权限业务层
*
* @author Chopper
* @since 2020/11/17 3:45 下午
*/
@CacheConfig(cacheNames = "{store_menu}")
public interface StoreMenuService extends IService<StoreMenu> {
/**
* 通过用户的菜单权限
*
* @return
*/
List<StoreMenuVO> findUserTree();
/**
* 通过用户id获取
*
* @param userId
* @return
*/
List<StoreMenu> findUserList(String userId);
/**
* 根据角色id获取菜单集合
*
* @param roleIds
* @return
*/
List<StoreMenu> findByRoleIds(String roleIds);
/**
* 树形结构
*
* @return
*/
List<StoreMenuVO> tree();
/**
* 查询列表
*
* @param menuSearchParams
* @return
*/
List<StoreMenu> searchList(MenuSearchParams menuSearchParams);
/**
* 批量删除
*
* @param ids
*/
void deleteIds(List<String> ids);
/**
* 添加更新菜单
*
* @param storeMenu 菜单数据
* @return 是否成功
*/
boolean saveOrUpdateMenu(StoreMenu storeMenu);
}

View File

@@ -0,0 +1,56 @@
package cn.lili.modules.member.service;
import cn.lili.modules.member.entity.dos.StoreRole;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 角色业务层
*
* @author Chopper
* @since 2020/11/17 3:45 下午
*/
public interface StoreRoleService extends IService<StoreRole> {
/**
* 获取默认角色
*
* @param defaultRole
* @return
*/
List<StoreRole> findByDefaultRole(Boolean defaultRole);
/**
* 批量删除角色
*
* @param roleIds
*/
void deleteRoles(List<String> roleIds);
/**
* 修改角色
*
* @param storeRole 店铺角色
* @return
*/
Boolean update(StoreRole storeRole);
/**
* 保存店铺角色
*
* @param storeRole 店铺角色
* @return
*/
Boolean saveStoreRole(StoreRole storeRole);
/**
* 当前店铺 根据角色id查询角色
*
* @param ids 角色id
* @return
*/
List<StoreRole> list(List<String> ids);
}

View File

@@ -0,0 +1,323 @@
package cn.lili.modules.member.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.StoreClerkRole;
import cn.lili.modules.member.entity.dos.StoreRole;
import cn.lili.modules.member.entity.dto.ClerkAddDTO;
import cn.lili.modules.member.entity.dto.ClerkEditDTO;
import cn.lili.modules.member.entity.dto.ClerkQueryDTO;
import cn.lili.modules.member.entity.vo.ClerkVO;
import cn.lili.modules.member.mapper.ClerkMapper;
import cn.lili.modules.member.service.*;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 店员业务实现
*
* @author wget
* @title: ClerkServiceImpl
* @projectName lilishop
* @date 2021/12/28 8:13 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ClerkServiceImpl extends ServiceImpl<ClerkMapper, Clerk> implements ClerkService {
@Autowired
private StoreRoleService storeRoleService;
@Autowired
private StoreDepartmentService storeDepartmentService;
@Autowired
private MemberService memberService;
@Autowired
private StoreClerkRoleService storeClerkRoleService;
@Override
public IPage<ClerkVO> clerkForPage(PageVO page, ClerkQueryDTO clerkQueryDTO) {
QueryWrapper<ClerkVO> clerkVOQueryWrapper = new QueryWrapper<>();
clerkVOQueryWrapper.eq("li_clerk.store_id", UserContext.getCurrentUser().getStoreId());
clerkVOQueryWrapper.eq(StringUtils.isNotEmpty(clerkQueryDTO.getDepartmentId()), "li_clerk.department_id", clerkQueryDTO.getDepartmentId());
clerkVOQueryWrapper.like(StringUtils.isNotEmpty(clerkQueryDTO.getClerkName()), "li_clerk.clerk_name", clerkQueryDTO.getClerkName());
clerkVOQueryWrapper.like(StringUtils.isNotEmpty(clerkQueryDTO.getMobile()), "m.mobile", clerkQueryDTO.getMobile());
IPage<ClerkVO> clerkPage = this.baseMapper.selectClerkPage(PageUtil.initPage(page), clerkVOQueryWrapper);
return clerkPage;
/*Page<Clerk> clerkPage = page(initPage, initWrapper);
if (clerkPage.getRecords().size() > 0) {
List<StoreRole> roles = storeRoleService.list(new QueryWrapper<StoreRole>()
.eq("store_id", UserContext.getCurrentUser().getStoreId()));
List<StoreDepartment> departments = storeDepartmentService.list(new QueryWrapper<StoreDepartment>()
.eq("store_id", UserContext.getCurrentUser().getStoreId()));
List<String> memberIds = new ArrayList<>();
clerkPage.getRecords().forEach(clerk -> {
memberIds.add(clerk.getMemberId());
});
List<Member> members = memberService.list(new QueryWrapper<Member>().in("id", memberIds));
List<ClerkVO> result = new ArrayList<>();
clerkPage.getRecords().forEach(clerk -> {
ClerkVO clerkVO = new ClerkVO(clerk);
if (!CharSequenceUtil.isEmpty(clerk.getDepartmentId())) {
try {
clerkVO.setDepartmentTitle(
departments.stream().filter
(department -> department.getId().equals(clerk.getDepartmentId()))
.collect(Collectors.toList())
.get(0)
.getTitle()
);
} catch (Exception e) {
log.error("填充部门信息异常", e);
}
}
clerkVO.setMobile(
members.stream().filter
(member -> member.getId().equals(clerk.getMemberId()))
.collect(Collectors.toList())
.get(0)
.getMobile()
);
if (!StringUtils.isEmpty(clerk.getRoleIds())) {
try {
List<String> memberRoles = Arrays.asList(clerk.getRoleIds().split(","));
clerkVO.setRoles(
roles.stream().filter
(role -> memberRoles.contains(role.getId()))
.collect(Collectors.toList())
);
} catch (Exception e) {
log.error("填充部门信息异常", e);
}
}
result.add(clerkVO);
});
Page<ClerkVO> pageResult = new Page(clerkPage.getCurrent(), clerkPage.getSize(), clerkPage.getTotal());
pageResult.setRecords(result);
return pageResult;
}
return new Page<ClerkVO>();*/
}
@Override
public ClerkVO get(String id) {
Clerk clerk = this.getById(id);
ClerkVO clerkVO = new ClerkVO(clerk);
//手机号码
clerkVO.setMobile(memberService.getById(clerk.getMemberId()).getMobile());
if (!CharSequenceUtil.isEmpty(clerk.getDepartmentId())) {
clerkVO.setDepartmentTitle(storeDepartmentService.getById(clerk.getDepartmentId()).getTitle());
}
if (!StringUtils.isEmpty(clerk.getRoleIds())) {
List<String> memberRoles = Arrays.asList(clerk.getRoleIds().split(","));
List<StoreRole> roles = storeRoleService.list(new QueryWrapper<StoreRole>()
.eq("store_id", UserContext.getCurrentUser().getStoreId()));
clerkVO.setRoles(
roles.stream().filter
(role -> memberRoles.contains(role.getId()))
.collect(Collectors.toList())
);
}
return clerkVO;
}
@Override
public Clerk updateClerk(ClerkEditDTO clerkEditDTO) {
Clerk clerk = this.getById(clerkEditDTO.getId());
if (clerk != null) {
//校验当前店员是否是当前店铺的
if (!clerk.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
if (clerkEditDTO.getIsSuper()) {
clerk.setRoleIds("");
} else {
//角色赋值
if (!clerkEditDTO.getRoles().isEmpty()) {
clerk.setRoleIds(CharSequenceUtil.join(",", clerkEditDTO.getRoles()));
}
}
//部门校验
if (StringUtils.isNotEmpty(clerkEditDTO.getDepartmentId())) {
if (storeDepartmentService.getById(clerkEditDTO.getDepartmentId()) != null) {
clerk.setDepartmentId(clerkEditDTO.getDepartmentId());
} else {
throw new ServiceException(ResultCode.PERMISSION_NOT_FOUND_ERROR);
}
}
clerk.setIsSuper(clerkEditDTO.getIsSuper());
this.updateById(clerk);
return clerk;
}
throw new ServiceException(ResultCode.CLERK_NOT_FOUND_ERROR);
}
@Override
public Clerk saveClerk(ClerkAddDTO clerkAddDTO) {
Clerk clerk = new Clerk(clerkAddDTO);
clerk.setShopkeeper(clerkAddDTO.getShopkeeper());
clerk.setIsSuper(clerkAddDTO.getIsSuper());
//校验此会员是否已经是店员
Clerk temp = this.getClerkByMemberId(clerkAddDTO.getMemberId());
if (temp != null && !temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.CLERK_USER_ERROR);
}
if (temp != null && temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.CLERK_ALREADY_EXIT_ERROR);
}
//部门校验
if (StringUtils.isNotEmpty(clerkAddDTO.getDepartmentId())) {
if (storeDepartmentService.getById(clerkAddDTO.getDepartmentId()) == null) {
throw new ServiceException(ResultCode.PERMISSION_NOT_FOUND_ERROR);
}
}
//角色校验
if (clerkAddDTO.getRoles() != null && clerkAddDTO.getRoles().size() > 0) {
List<StoreRole> storeRoles = storeRoleService.list(clerkAddDTO.getRoles());
if (storeRoles.size() != clerkAddDTO.getRoles().size()) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
}
this.save(clerk);
//判断用户角色权限不为超级会员且权限路径不为空
if(clerkAddDTO.getIsSuper()==false && clerkAddDTO.getRoles()!=null){
//添加店员用户角色
List<StoreClerkRole> storeClerkRoleList = new ArrayList<>();
clerkAddDTO.getRoles().stream().forEach(a -> {
storeClerkRoleList.add(StoreClerkRole.builder().clerkId(clerk.getId()).roleId(a).build());
});
storeClerkRoleService.saveBatch(storeClerkRoleList);
}
return clerk;
}
@Override
public Clerk getClerkByMemberId(String memberId) {
return this.getOne(new QueryWrapper<Clerk>().eq("member_id", memberId));
}
@Override
public void resetPassword(List<String> ids) {
QueryWrapper<Clerk> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId());
queryWrapper.in("id", ids);
List<Clerk> clerks = this.baseMapper.selectList(queryWrapper);
//校验要重置的店员是否是当前店铺的店员
if (clerks.size() != ids.size()) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
//店员密码就是会员密码所以要组织会员修改密码参数信息
List<String> memberIds = new ArrayList<>();
clerks.forEach(clerk -> {
//如果是店主无法重置密码
if (clerk.getShopkeeper()) {
throw new ServiceException(ResultCode.CLERK_SUPPER);
}
memberIds.add(clerk.getMemberId());
});
memberService.resetPassword(memberIds);
}
@Override
public void deleteClerk(List<String> ids) {
QueryWrapper<Clerk> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId());
queryWrapper.in("id", ids);
List<Clerk> clerks = this.baseMapper.selectList(queryWrapper);
if (clerks.size() > 0) {
//校验要重置的店员是否是当前店铺的店员
if (clerks.size() != ids.size()) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
//删除店员
this.removeByIds(ids);
//更改会员为为拥有店铺
List<String> memberIds = new ArrayList<>();
clerks.forEach(clerk -> {
//无法删除当前登录的店员
if (UserContext.getCurrentUser().getClerkId().equals(clerk.getId())) {
throw new ServiceException(ResultCode.CLERK_CURRENT_SUPPER);
}
//无法删除店主
if (clerk.getShopkeeper()) {
throw new ServiceException(ResultCode.CLERK_SUPPER);
}
memberIds.add(clerk.getMemberId());
});
memberService.updateHaveShop(false, null, memberIds);
}
}
@Override
public Member checkClerk(String mobile) {
//校验是否已经是会员
Member member = memberService.findByMobile(mobile);
if (member != null) {
//校验要添加的会员是否已经是店主
if (member.getHaveStore()) {
throw new ServiceException(ResultCode.STORE_APPLY_DOUBLE_ERROR);
}
//校验会员的有效性
if (!member.getDisabled()) {
throw new ServiceException(ResultCode.USER_STATUS_ERROR);
}
//校验此会员是否已经是店员
Clerk clerk = this.getClerkByMemberId(member.getId());
if (clerk != null && !clerk.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.CLERK_USER_ERROR);
}
if (clerk != null && clerk.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.CLERK_ALREADY_EXIT_ERROR);
}
return member;
}
return new Member();
}
@Override
public void disable(String id, Boolean status) {
Clerk clerk = this.getById(id);
if (clerk == null) {
throw new ServiceException(ResultCode.USER_NOT_EXIST);
}
//店主无法禁用
if (clerk.getShopkeeper() && clerk.getStatus()) {
throw new ServiceException(ResultCode.CLERK_SUPPER);
}
clerk.setStatus(status);
this.updateById(clerk);
}
}

View File

@@ -27,7 +27,7 @@ import java.util.List;
* @since 2020/11/17 3:44 下午
*/
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = java.lang.Exception.class)
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class MemberNoticeSenterServiceImpl extends ServiceImpl<MemberNoticeSenterMapper, MemberNoticeSenter> implements MemberNoticeSenterService {
/**

View File

@@ -5,7 +5,6 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.aop.annotation.DemoSite;
import cn.lili.common.context.ThreadContextHolder;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.SwitchEnum;
@@ -19,6 +18,7 @@ import cn.lili.common.security.token.Token;
import cn.lili.common.sensitive.SensitiveWordsFilter;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.CookieUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.UuidUtils;
import cn.lili.common.vo.PageVO;
@@ -43,6 +43,7 @@ import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.entity.enums.StoreStatusEnum;
import cn.lili.modules.store.service.StoreService;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.MemberTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -50,6 +51,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -260,38 +262,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
// 发送会员注册信息
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member));
}
@Override
public Member editOwn(MemberEditDTO memberEditDTO) {
//查询会员信息
Member member = this.findByUsername(Objects.requireNonNull(UserContext.getCurrentUser()).getUsername());
//传递修改会员信息
BeanUtil.copyProperties(memberEditDTO, member);
//修改会员
this.updateById(member);
return member;
}
@Override
@DemoSite
public Member modifyPass(String oldPassword, String newPassword) {
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser == null) {
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
Member member = this.getById(tokenUser.getId());
//判断旧密码输入是否正确
if (!new BCryptPasswordEncoder().matches(oldPassword, member.getPassword())) {
throw new ServiceException(ResultCode.USER_OLD_PASSWORD_ERROR);
}
//修改会员密码
LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.eq(Member::getId, member.getId());
lambdaUpdateWrapper.set(Member::getPassword, new BCryptPasswordEncoder().encode(newPassword));
this.update(lambdaUpdateWrapper);
return member;
}
@Override
public boolean canInitPass() {
AuthUser tokenUser = UserContext.getCurrentUser();
@@ -410,6 +380,11 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
@Override
public Member updateMember(ManagerMemberEditDTO managerMemberEditDTO) {
//判断是否用户登录并且会员ID为当前登录会员ID
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser == null) {
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
//过滤会员昵称敏感词
if (CharSequenceUtil.isNotBlank(managerMemberEditDTO.getNickName())) {
managerMemberEditDTO.setNickName(SensitiveWordsFilter.filter(managerMemberEditDTO.getNickName()));
@@ -649,6 +624,31 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
}
}
@Override
public void updateHaveShop(Boolean haveStore, String storeId, List<String> memberIds) {
List<Member> members = this.baseMapper.selectBatchIds(memberIds);
if (members.size() > 0) {
members.forEach(member -> {
member.setHaveStore(haveStore);
if (haveStore) {
member.setStoreId(storeId);
} else {
member.setStoreId(null);
}
});
this.updateBatchById(members);
}
}
@Override
public void resetPassword(List<String> ids) {
String password = new BCryptPasswordEncoder().encode(StringUtils.md5("123456"));
LambdaUpdateWrapper<Member> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.in(Member::getId, ids);
lambdaUpdateWrapper.set(Member::getPassword, password);
this.update(lambdaUpdateWrapper);
}
/**
* 获取所有会员的手机号
*
@@ -765,4 +765,5 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
throw new ServiceException(ResultCode.USER_EXIST);
}
}
}

View File

@@ -0,0 +1,52 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.modules.member.entity.dos.StoreClerkRole;
import cn.lili.modules.member.mapper.StoreClerkRoleMapper;
import cn.lili.modules.member.service.StoreClerkRoleService;
import cn.lili.modules.permission.entity.dos.UserRole;
import cn.lili.modules.permission.mapper.UserRoleMapper;
import cn.lili.modules.permission.service.UserRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 用户权限业务层实现
*
* @author Chopper
* @since 2020/11/17 3:52 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreClerkRoleServiceImpl extends ServiceImpl<StoreClerkRoleMapper, StoreClerkRole> implements StoreClerkRoleService {
@Override
public List<StoreClerkRole> listByUserId(String clerkId) {
QueryWrapper<StoreClerkRole> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("clerk_id", clerkId);
return this.baseMapper.selectList(queryWrapper);
}
@Override
public List<String> listId(String clerkId) {
List<StoreClerkRole> userRoleList = this.listByUserId(clerkId);
List<String> strings = new ArrayList<>();
userRoleList.forEach(item -> strings.add(item.getRoleId()));
return strings;
}
@Override
public void updateClerkRole(String clerkId, List<StoreClerkRole> storeClerkRoles) {
//删除
QueryWrapper<StoreClerkRole> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("clerk_id", clerkId);
this.remove(queryWrapper);
//保存
this.saveBatch(storeClerkRoles);
}
}

View File

@@ -0,0 +1,49 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.member.entity.dos.StoreDepartmentRole;
import cn.lili.modules.member.mapper.StoreDepartmentRoleMapper;
import cn.lili.modules.member.service.StoreDepartmentRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 部门角色业务层实现
*
* @author Chopper
* @since 2020/11/22 12:08
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreDepartmentRoleServiceImpl extends ServiceImpl<StoreDepartmentRoleMapper, StoreDepartmentRole> implements StoreDepartmentRoleService {
@Override
public List<StoreDepartmentRole> listByDepartmentId(String storeDepartmentId) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("department_id", storeDepartmentId);
return this.baseMapper.selectList(queryWrapper);
}
@Override
public void updateByDepartmentId(String storeDepartmentId, List<StoreDepartmentRole> storeDepartmentRoles) {
if (storeDepartmentRoles.size() > 0) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("department_id", storeDepartmentId);
this.remove(queryWrapper);
this.saveBatch(storeDepartmentRoles);
}
}
@Override
public void deleteByDepartment(List<String> ids) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.in("department_id", ids);
this.remove(queryWrapper);
}
}

View File

@@ -0,0 +1,112 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.dos.StoreDepartment;
import cn.lili.modules.member.entity.vo.StoreDepartmentVO;
import cn.lili.modules.member.mapper.StoreDepartmentMapper;
import cn.lili.modules.member.service.ClerkService;
import cn.lili.modules.member.service.StoreDepartmentRoleService;
import cn.lili.modules.member.service.StoreDepartmentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 店铺部门业务层实现
*
* @author Chopper
* @since 2020/11/17 3:47 下午
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreDepartmentServiceImpl extends ServiceImpl<StoreDepartmentMapper, StoreDepartment> implements StoreDepartmentService {
@Autowired
private StoreDepartmentRoleService storeDepartmentRoleService;
@Autowired
private ClerkService clerkService;
@Override
public void deleteByIds(List<String> ids) {
//校验是否有操作店铺部门权限
List<StoreDepartment> storeDepartments = this.list(new QueryWrapper<StoreDepartment>()
.in("id", ids)
.eq("store_id", UserContext.getCurrentUser().getStoreId()));
if (storeDepartments.size() != ids.size()) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
//校验店员是否绑定部门
if (clerkService.count(new QueryWrapper<Clerk>().in("department_id", ids)) > 0) {
throw new ServiceException(ResultCode.PERMISSION_DEPARTMENT_DELETE_ERROR);
}
//删除店铺部门
this.removeByIds(ids);
//删除店铺部门角色
storeDepartmentRoleService.deleteByDepartment(ids);
}
@Override
public List<StoreDepartmentVO> tree(QueryWrapper<StoreDepartment> initWrapper) {
try {
List<StoreDepartment> departments = this.list(initWrapper);
List<StoreDepartmentVO> all = new ArrayList<>();
departments.forEach(item -> all.add(new StoreDepartmentVO(item)));
List<StoreDepartmentVO> tree = new ArrayList<>();
all.forEach(item -> {
if ("0".equals(item.getParentId())) {
initChild(item, all);
tree.add(item);
}
});
return tree;
} catch (Exception e) {
log.error("部门业务错误", e);
return null;
}
}
/**
* 递归初始化子树
*
* @param tree 树结构
* @param departmentVOS 数据库对象集合
*/
private void initChild(StoreDepartmentVO tree, List<StoreDepartmentVO> departmentVOS) {
departmentVOS.stream()
.filter(item -> (item.getParentId().equals(tree.getId())))
.forEach(child -> {
StoreDepartmentVO childTree = new StoreDepartmentVO(child);
initChild(childTree, departmentVOS);
tree.getChildren().add(childTree);
});
}
@Override
public Boolean update(StoreDepartment storeDepartment) {
StoreDepartment temp = this.getById(storeDepartment);
//校验部门是否存在
if (temp == null) {
throw new ServiceException(ResultCode.PERMISSION_NOT_FOUND_ERROR);
}
//校验店铺权限
if (!temp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
return this.updateById(storeDepartment);
}
}

View File

@@ -1,8 +1,10 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.member.mapper.StoreLogisticsMapper;
import cn.lili.modules.member.service.StoreLogisticsService;
import cn.lili.modules.store.entity.dos.StoreLogistics;
import cn.lili.modules.store.entity.dto.StoreLogisticsCustomerDTO;
import cn.lili.modules.system.entity.vo.StoreLogisticsVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -10,6 +12,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
/**
* 物流公司业务层实现
@@ -37,16 +40,57 @@ public class StoreLogisticsServiceImpl extends ServiceImpl<StoreLogisticsMapper,
}
@Override
public StoreLogistics add(String logisticsId, String storeId) {
public List<StoreLogisticsVO> getStoreSelectedLogisticsUseFaceSheet(String storeId) {
return this.baseMapper.getSelectedStoreLogisticsUseFaceSheet(storeId);
}
@Override
public StoreLogistics update(String logisticsId, String storeId,StoreLogisticsCustomerDTO storeLogisticsCustomerDTO) {
LambdaQueryWrapper<StoreLogistics> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(StoreLogistics::getLogisticsId, logisticsId);
lambdaQueryWrapper.eq(StoreLogistics::getStoreId, storeId);
this.remove(lambdaQueryWrapper);
StoreLogistics ResultstoreLogistics = new StoreLogistics(storeLogisticsCustomerDTO);
ResultstoreLogistics.setStoreId(storeId);
ResultstoreLogistics.setLogisticsId(logisticsId);
this.save(ResultstoreLogistics);
return ResultstoreLogistics;
}
@Override
public StoreLogistics getStoreLogisticsInfo( String logisticsId) {
String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
return this.getOne(new LambdaQueryWrapper<StoreLogistics>().eq(StoreLogistics::getStoreId,storeId).eq(StoreLogistics::getLogisticsId,logisticsId));
}
@Override
public List<StoreLogisticsVO> getOpenStoreLogistics(String storeId) {
List<StoreLogisticsVO> openStoreLogistics = this.baseMapper.getOpenStoreLogistics(storeId);
for(StoreLogisticsVO storeLogisticsVO:openStoreLogistics){
storeLogisticsVO.setSelected("1");
}
return openStoreLogistics;
}
@Override
public List<StoreLogisticsVO> getCloseStoreLogistics(String storeId) {
return this.baseMapper.getCloseStroreLogistics(storeId);
}
@Override
public StoreLogistics add(String logisticsId, String storeId, StoreLogisticsCustomerDTO storeLogisticsCustomerDTO){
//判断是否已经选择过,如果没有选择则进行添加
LambdaQueryWrapper<StoreLogistics> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(StoreLogistics::getLogisticsId, logisticsId);
lambdaQueryWrapper.eq(StoreLogistics::getStoreId, storeId);
StoreLogistics storeLogistics=null;
if (this.getOne(lambdaQueryWrapper) == null) {
StoreLogistics storeLogistics = new StoreLogistics(storeId, logisticsId);
this.save(storeLogistics);
return storeLogistics;
}
storeLogistics=new StoreLogistics(storeLogisticsCustomerDTO);
storeLogistics.setStoreId(storeId);
storeLogistics.setLogisticsId(logisticsId);
this.save(storeLogistics);
return storeLogistics;
}
return null;
}

View File

@@ -0,0 +1,104 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.member.entity.dos.StoreMenuRole;
import cn.lili.modules.member.entity.vo.StoreUserMenuVO;
import cn.lili.modules.member.mapper.StoreMenuMapper;
import cn.lili.modules.member.mapper.StoreMenuRoleMapper;
import cn.lili.modules.member.service.StoreMenuRoleService;
import cn.lili.modules.permission.entity.dos.RoleMenu;
import cn.lili.modules.permission.entity.vo.UserMenuVO;
import cn.lili.modules.permission.mapper.MenuMapper;
import cn.lili.modules.permission.mapper.RoleMenuMapper;
import cn.lili.modules.permission.service.RoleMenuService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import groovy.util.logging.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* 角色菜单业务层实现
*
* @author Chopper
* @since 2020/11/22 11:43
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreMenuRoleServiceImpl extends ServiceImpl<StoreMenuRoleMapper, StoreMenuRole> implements StoreMenuRoleService {
/**
* 菜单
*/
@Resource
private StoreMenuMapper storeMenuMapper;
@Autowired
private Cache<Object> cache;
@Override
public List<StoreMenuRole> findByRoleId(String roleId) {
LambdaQueryWrapper<StoreMenuRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StoreMenuRole::getRoleId, roleId);
return this.baseMapper.selectList(queryWrapper);
}
@Override
public List<StoreUserMenuVO> findAllMenu(String clerkId,String memberId) {
String cacheKey = CachePrefix.STORE_USER_MENU.getPrefix() + memberId;
List<StoreUserMenuVO> menuList = (List<StoreUserMenuVO>) cache.get(cacheKey);
if (menuList == null || menuList.isEmpty()) {
menuList = storeMenuMapper.getUserRoleMenu(clerkId);
cache.put(cacheKey, menuList);
}
return menuList;
}
@Override
public void updateRoleMenu(String roleId, List<StoreMenuRole> roleMenus) {
try {
roleMenus.forEach(role -> {
role.setStoreId(UserContext.getCurrentUser().getStoreId());
});
//删除角色已经绑定的菜单
this.delete(roleId);
//重新保存角色菜单关系
this.saveBatch(roleMenus);
cache.vagueDel(CachePrefix.MENU_USER_ID.getPrefix());
cache.vagueDel(CachePrefix.USER_MENU.getPrefix());
} catch (Exception e) {
log.error("修改用户权限错误", e);
}
}
@Override
public void delete(String roleId) {
//删除
QueryWrapper<StoreMenuRole> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("role_id", roleId);
this.remove(queryWrapper);
cache.vagueDel(CachePrefix.STORE_MENU_USER_ID.getPrefix());
cache.vagueDel(CachePrefix.STORE_USER_MENU.getPrefix());
}
@Override
public void delete(List<String> roleId) {
//删除
QueryWrapper<StoreMenuRole> queryWrapper = new QueryWrapper<>();
queryWrapper.in("role_id", roleId);
this.remove(queryWrapper);
cache.vagueDel(CachePrefix.STORE_MENU_USER_ID.getPrefix());
cache.vagueDel(CachePrefix.STORE_USER_MENU.getPrefix());
}
}

View File

@@ -0,0 +1,178 @@
package cn.lili.modules.member.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.SearchVO;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.dos.StoreMenu;
import cn.lili.modules.member.entity.dos.StoreMenuRole;
import cn.lili.modules.member.entity.vo.StoreMenuVO;
import cn.lili.modules.member.mapper.StoreMenuMapper;
import cn.lili.modules.member.service.ClerkService;
import cn.lili.modules.member.service.StoreMenuRoleService;
import cn.lili.modules.member.service.StoreMenuService;
import cn.lili.modules.permission.entity.dto.MenuSearchParams;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 权限业务层实现
*
* @author Chopper
* @since 2020/11/17 3:49 下午
*/
@Slf4j
@Service
public class StoreMenuServiceImpl extends ServiceImpl<StoreMenuMapper, StoreMenu> implements StoreMenuService {
/**
* 菜单角色
*/
@Autowired
private StoreMenuRoleService storeMenuRoleService;
@Autowired
private Cache<List<StoreMenu>> cache;
/**
* 店员
*/
@Autowired
private ClerkService clerkService;
@Override
public void deleteIds(List<String> ids) {
QueryWrapper<StoreMenuRole> queryWrapper = new QueryWrapper<>();
queryWrapper.in("menu_id", ids);
//如果已有角色绑定菜单,则不能直接删除
if (storeMenuRoleService.count(queryWrapper) > 0) {
throw new ServiceException(ResultCode.PERMISSION_MENU_ROLE_ERROR);
}
this.removeByIds(ids);
}
@Override
public List<StoreMenuVO> findUserTree() {
AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser());
if (Boolean.TRUE.equals(authUser.getIsSuper())) {
return this.tree();
}
//获取当前登录用户的店员信息
Clerk clerk = clerkService.getOne(new LambdaQueryWrapper<Clerk>().eq(Clerk::getMemberId, authUser.getId()));
//获取当前店员角色的菜单列表
List<StoreMenu> userMenus = this.baseMapper.findByUserId(clerk.getId());
return this.tree(userMenus);
}
@Override
public List<StoreMenu> findUserList(String userId) {
String cacheKey = CachePrefix.STORE_MENU_USER_ID.getPrefix() + userId;
List<StoreMenu> menuList = cache.get(cacheKey);
if (menuList == null) {
menuList = this.baseMapper.findByUserId(userId);
cache.put(cacheKey, menuList);
}
return menuList;
}
/**
* 添加更新菜单
*
* @param storeMenu 菜单数据
* @return 是否成功
*/
@Override
public boolean saveOrUpdateMenu(StoreMenu storeMenu) {
if (CharSequenceUtil.isNotEmpty(storeMenu.getId())) {
cache.vagueDel(CachePrefix.STORE_MENU_USER_ID.getPrefix());
}
return this.saveOrUpdate(storeMenu);
}
@Override
public List<StoreMenu> findByRoleIds(String roleId) {
QueryWrapper<StoreMenu> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("role_id", roleId);
return this.list(queryWrapper);
}
@Override
public List<StoreMenu> searchList(MenuSearchParams menuSearchParams) {
//title 需要特殊处理
String title = null;
if (CharSequenceUtil.isNotEmpty(menuSearchParams.getTitle())) {
title = menuSearchParams.getTitle();
menuSearchParams.setTitle(null);
}
QueryWrapper<StoreMenu> queryWrapper = PageUtil.initWrapper(menuSearchParams, new SearchVO());
if (CharSequenceUtil.isNotEmpty(title)) {
queryWrapper.like("title", title);
}
queryWrapper.orderByDesc("sort_order");
return this.baseMapper.selectList(queryWrapper);
}
@Override
public List<StoreMenuVO> tree() {
try {
List<StoreMenu> menus = this.list();
return tree(menus);
} catch (Exception e) {
log.error("菜单树错误", e);
}
return Collections.emptyList();
}
/**
* 传入自定义菜单集合
*
* @param menus 自定义菜单集合
* @return 修改后的自定义菜单集合
*/
private List<StoreMenuVO> tree(List<StoreMenu> menus) {
List<StoreMenuVO> tree = new ArrayList<>();
menus.forEach(item -> {
if (item.getLevel() == 0) {
StoreMenuVO treeItem = new StoreMenuVO(item);
initChild(treeItem, menus);
tree.add(treeItem);
}
});
//对一级菜单排序
tree.sort(Comparator.comparing(StoreMenu::getSortOrder));
return tree;
}
/**
* 递归初始化子树
*
* @param tree 树结构
* @param menus 数据库对象集合
*/
private void initChild(StoreMenuVO tree, List<StoreMenu> menus) {
if (menus == null) {
return;
}
menus.stream()
.filter(item -> (item.getParentId().equals(tree.getId())))
.forEach(child -> {
StoreMenuVO childTree = new StoreMenuVO(child);
initChild(childTree, menus);
tree.getChildren().add(childTree);
});
}
}

View File

@@ -0,0 +1,106 @@
package cn.lili.modules.member.serviceimpl;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.member.entity.dos.StoreRole;
import cn.lili.modules.member.mapper.StoreRoleMapper;
import cn.lili.modules.member.service.StoreClerkRoleService;
import cn.lili.modules.member.service.StoreDepartmentRoleService;
import cn.lili.modules.member.service.StoreMenuRoleService;
import cn.lili.modules.member.service.StoreRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 角色业务层实现
*
* @author Chopper
* @since 2020/11/17 3:50 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreRoleServiceImpl extends ServiceImpl<StoreRoleMapper, StoreRole> implements StoreRoleService {
/**
* 部门角色
*/
@Autowired
private StoreDepartmentRoleService storeDepartmentRoleService;
/**
* 用户权限
*/
@Autowired
private StoreClerkRoleService storeClerkRoleService;
@Autowired
private StoreMenuRoleService storeMenuRoleService;
@Override
public List<StoreRole> findByDefaultRole(Boolean defaultRole) {
QueryWrapper<StoreRole> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("default_role", true);
return baseMapper.selectList(queryWrapper);
}
@Override
public void deleteRoles(List<String> roleIds) {
//校验是否为当前店铺
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", roleIds);
List<StoreRole> roles = this.baseMapper.selectList(queryWrapper);
roles.forEach(role -> {
if (!role.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
});
queryWrapper = new QueryWrapper<>();
queryWrapper.in("role_id", roleIds);
//校验是否绑定店铺部门
if (storeDepartmentRoleService.count(queryWrapper) > 0) {
throw new ServiceException(ResultCode.PERMISSION_DEPARTMENT_ROLE_ERROR);
}
//校验是否绑定店员
if (storeClerkRoleService.count(queryWrapper) > 0) {
throw new ServiceException(ResultCode.PERMISSION_USER_ROLE_ERROR);
}
//删除角色
this.removeByIds(roleIds);
//删除角色与菜单关联
storeMenuRoleService.remove(queryWrapper);
}
@Override
public Boolean update(StoreRole storeRole) {
StoreRole storeRoleTemp = this.getById(storeRole.getId());
//校验店铺角色是否存在
if (storeRoleTemp == null) {
throw new ServiceException(ResultCode.PERMISSION_ROLE_NOT_FOUND_ERROR);
}
//校验店铺角色是否属于当前店铺
if (!storeRoleTemp.getStoreId().equals(UserContext.getCurrentUser().getStoreId())) {
throw new ServiceException(ResultCode.PERMISSION_ROLE_NOT_FOUND_ERROR);
}
return updateById(storeRole);
}
@Override
public Boolean saveStoreRole(StoreRole storeRole) {
storeRole.setStoreId(UserContext.getCurrentUser().getStoreId());
return save(storeRole);
}
@Override
public List<StoreRole> list(List<String> ids) {
QueryWrapper<StoreRole> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", UserContext.getCurrentUser().getStoreId());
queryWrapper.in("id", ids);
return this.baseMapper.selectList(queryWrapper);
}
}

View File

@@ -1,8 +1,12 @@
package cn.lili.modules.member.token;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.enums.PermissionEnum;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.security.token.Token;
import cn.lili.common.security.token.TokenUtil;
@@ -10,10 +14,18 @@ import cn.lili.common.security.token.base.AbstractTokenGenerate;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.lili.modules.member.entity.dos.Clerk;
import cn.lili.modules.member.entity.vo.StoreUserMenuVO;
import cn.lili.modules.member.service.ClerkService;
import cn.lili.modules.member.service.StoreMenuRoleService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 商家token生成
*
@@ -27,16 +39,37 @@ public class StoreTokenGenerate extends AbstractTokenGenerate<Member> {
private StoreService storeService;
@Autowired
private TokenUtil tokenUtil;
@Autowired
private StoreMenuRoleService storeMenuRoleService;
@Autowired
private Cache cache;
@Autowired
private ClerkService clerkService;
@Override
public Token createToken(Member member, Boolean longTerm) {
if (Boolean.FALSE.equals(member.getHaveStore())) {
throw new ServiceException(ResultCode.STORE_NOT_OPEN);
}
LambdaQueryWrapper<Store> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Store::getMemberId, member.getId());
Store store = storeService.getOne(queryWrapper);
AuthUser authUser = new AuthUser(member.getUsername(), member.getId(), member.getNickName(), store.getStoreLogo(), UserEnums.STORE);
//根据会员id查询店员信息
Clerk clerk = clerkService.getClerkByMemberId(member.getId());
if (clerk == null) {
throw new ServiceException(ResultCode.CLERK_NOT_FOUND_ERROR);
}
if (!clerk.getStatus()) {
throw new ServiceException(ResultCode.CLERK_DISABLED_ERROR);
}
//获取当前用户权限
List<StoreUserMenuVO> storeUserMenuVOS = storeMenuRoleService.findAllMenu(clerk.getId(),member.getId());
//缓存权限列表
cache.put(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.STORE) + member.getId(), this.permissionList(storeUserMenuVOS));
//查询店铺信息
Store store = storeService.getById(clerk.getStoreId());
if (store == null) {
throw new ServiceException(ResultCode.STORE_NOT_OPEN);
}
AuthUser authUser = new AuthUser(member.getUsername(), member.getId(), UserEnums.STORE, member.getNickName(), clerk.getIsSuper(), clerk.getId(),store.getStoreLogo());
authUser.setStoreId(store.getId());
authUser.setStoreName(store.getStoreName());
@@ -48,4 +81,79 @@ public class StoreTokenGenerate extends AbstractTokenGenerate<Member> {
return tokenUtil.refreshToken(refreshToken, UserEnums.STORE);
}
/**
* 获取用户权限
*
* @param userMenuVOList
* @return
*/
private Map<String, List<String>> permissionList(List<StoreUserMenuVO> userMenuVOList) {
Map<String, List<String>> permission = new HashMap<>(2);
List<String> superPermissions = new ArrayList<>();
List<String> queryPermissions = new ArrayList<>();
initPermission(superPermissions, queryPermissions);
//循环权限菜单
if (userMenuVOList != null && !userMenuVOList.isEmpty()) {
userMenuVOList.forEach(menu -> {
//循环菜单,赋予用户权限
if (CharSequenceUtil.isNotEmpty(menu.getPermission())) {
//获取路径集合
String[] permissionUrl = menu.getPermission().split(",");
//for循环路径集合
for (String url : permissionUrl) {
//如果是超级权限 则计入超级权限
if (Boolean.TRUE.equals(menu.getSuper())) {
//如果已有超级权限,则这里就不做权限的累加
if (!superPermissions.contains(url)) {
superPermissions.add(url);
}
}
//否则计入浏览权限
else {
//没有权限,则累加。
if (!queryPermissions.contains(url)) {
queryPermissions.add(url);
}
}
}
}
//去除重复的权限
queryPermissions.removeAll(superPermissions);
});
}
permission.put(PermissionEnum.SUPER.name(), superPermissions);
permission.put(PermissionEnum.QUERY.name(), queryPermissions);
return permission;
}
/**
* 初始赋予的权限,查看权限包含首页流量统计权限,
* 超级权限包含个人信息维护,密码修改权限
*
* @param superPermissions 超级权限
* @param queryPermissions 查询权限
*/
void initPermission(List<String> superPermissions, List<String> queryPermissions) {
//菜单管理
superPermissions.add("/store/menu*");
//退出权限
superPermissions.add("/store/passport/login/logout*");
//修改
superPermissions.add("/store/passport/login*");
//店铺设置
queryPermissions.add("/store/settings/storeSettings*");
//文章接口
queryPermissions.add("/store/other/article*");
//首页统计
queryPermissions.add("/store/statistics/index*");
}
}

View File

@@ -204,6 +204,9 @@ public class Order extends BaseEntity {
@ApiModelProperty(value = "使用的平台会员优惠券id")
private String usePlatformMemberCouponId;
@ApiModelProperty(value = "qrCode 实物为提货码 虚拟货物为账号")
private String qrCode;
/**
* 构建订单
*

View File

@@ -43,6 +43,7 @@ public interface OrderService extends IService<Order> {
*/
Order getBySn(String orderSn);
/**
* 订单查询
*
@@ -284,4 +285,5 @@ public interface OrderService extends IService<Order> {
* @return 是否成功
*/
boolean checkFictitiousOrder(String pintuanId, Integer requiredNum, Boolean fictitious);
}

View File

@@ -336,6 +336,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
return this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getSn, orderSn));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void payOrder(String orderSn, String paymentMethod, String receivableNo) {

View File

@@ -74,4 +74,12 @@ public interface PageDataService extends IService<PageData> {
* @return
*/
IPage<PageDataListVO> getPageDataList(PageVO pageVO, PageDataDTO pageDataDTO);
/**
* 获取专题信息
* @param id id
* @return
*/
PageData getSpecial(String id);
}

View File

@@ -1,11 +1,15 @@
package cn.lili.modules.page.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.SystemSettingProperties;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.page.entity.dos.PageData;
import cn.lili.modules.page.entity.dto.PageDataDTO;
@@ -15,6 +19,7 @@ import cn.lili.modules.page.entity.vos.PageDataVO;
import cn.lili.modules.page.mapper.PageDataMapper;
import cn.lili.modules.page.service.PageDataService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -61,9 +66,9 @@ public class PageDataServiceImpl extends ServiceImpl<PageDataMapper, PageData> i
@Transactional(rollbackFor = Exception.class)
public PageData addPageData(PageData pageData) {
//如果页面为发布,则关闭其他页面,开启此页面
//演示站点不可以开启楼层
if (!Boolean.TRUE.equals(systemSettingProperties.getIsDemoSite()) && pageData.getPageShow().equals(SwitchEnum.OPEN.name())) {
if (pageData.getPageShow().equals(SwitchEnum.OPEN.name())) {
LambdaUpdateWrapper<PageData> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getNum,UserContext.getCurrentUser().getStoreId());
lambdaUpdateWrapper.eq(PageData::getPageType, pageData.getPageType());
lambdaUpdateWrapper.eq(PageData::getPageClientType, pageData.getPageClientType());
lambdaUpdateWrapper.set(PageData::getPageShow, SwitchEnum.CLOSE.name());
@@ -84,13 +89,17 @@ public class PageDataServiceImpl extends ServiceImpl<PageDataMapper, PageData> i
lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageType()), PageData::getPageType, pageData.getPageType());
lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageClientType()), PageData::getPageClientType, pageData.getPageClientType());
lambdaUpdateWrapper.set(PageData::getPageShow, SwitchEnum.CLOSE.name());
lambdaUpdateWrapper.set(StrUtil.isNotEmpty(pageData.getNum()), PageData::getNum, SwitchEnum.CLOSE.name());
this.update(lambdaUpdateWrapper);
} else {
pageData.setPageShow(SwitchEnum.CLOSE.name());
}
LambdaUpdateWrapper<PageData> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.set(PageData::getPageData, pageData.getPageData());
lambdaUpdateWrapper.eq(PageData::getId, pageData.getId());
lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getPageType,PageEnum.STORE.name());
lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getNum,UserContext.getCurrentUser().getStoreId());
this.updateById(pageData);
return pageData;
}
@@ -98,8 +107,13 @@ public class PageDataServiceImpl extends ServiceImpl<PageDataMapper, PageData> i
@Override
@Transactional(rollbackFor = Exception.class)
public PageData releasePageData(String id) {
PageData pageData = this.getById(id);
PageData pageData = this.getOne(new LambdaQueryWrapper<PageData>()
.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getPageType,PageEnum.STORE.name())
.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getNum,UserContext.getCurrentUser().getStoreId())
.eq(PageData::getId,id));
if(pageData==null){
throw new ServiceException(ResultCode.PAGE_NOT_EXIST);
}
//如果已经发布,不能重复发布
if (pageData.getPageShow().equals(SwitchEnum.OPEN.name())) {
@@ -128,7 +142,14 @@ public class PageDataServiceImpl extends ServiceImpl<PageDataMapper, PageData> i
@Override
@Transactional(rollbackFor = Exception.class)
public boolean removePageData(String id) {
PageData pageData = this.getById(id);
PageData pageData = this.getOne(new LambdaQueryWrapper<PageData>()
.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getPageType,PageEnum.STORE.name())
.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()),PageData::getNum,UserContext.getCurrentUser().getStoreId())
.eq(PageData::getId,id));
if(pageData==null){
throw new ServiceException(ResultCode.PAGE_NOT_EXIST);
}
//专题则直接进行删除
if (pageData.getPageType().equals(PageEnum.SPECIAL.name())) {
return this.removeById(id);
@@ -179,4 +200,9 @@ public class PageDataServiceImpl extends ServiceImpl<PageDataMapper, PageData> i
return this.baseMapper.getPageDataList(PageUtil.initPage(pageVO), queryWrapper);
}
@Override
public PageData getSpecial(String id) {
return this.getById(id);
}
}

View File

@@ -231,11 +231,11 @@ public class XmlHelper {
}
private static DocumentBuilderFactory getDocumentBuilderFactory() {
return XmlHelper.XmlHelperHolder.documentBuilderFactory;
return XmlHelperHolder.documentBuilderFactory;
}
private static XPathFactory getXpathFactory() {
return XmlHelper.XmlHelperHolder.xPathFactory;
return XmlHelperHolder.xPathFactory;
}
/**
@@ -246,4 +246,4 @@ public class XmlHelper {
private static XPathFactory xPathFactory = XPathFactory.newInstance();
}
}
}

Some files were not shown because too many files have changed in this diff Show More