From d5bdf4cd56be6bd0e7afa81d75c35a9f15ae2a40 Mon Sep 17 00:00:00 2001
From: jiangping <jp@doumee.com>
Date: 星期四, 21 九月 2023 09:09:32 +0800
Subject: [PATCH] 主播接口
---
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java | 44 +
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroConfig.java | 153 ++++
server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java | 22
server/service/src/main/java/com/doumee/service/business/impl/BaseGoodsServiceImpl.java | 3
server/zhubo/src/main/java/com/doumee/api/business/CategoryController.java | 106 +++
.idea/encodings.xml | 2
server/zhubo/src/main/java/com/doumee/api/business/GoodsController.java | 71 ++
server/company/src/main/java/com/doumee/config/shiro/ShiroConfig.java | 2
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java | 36 +
server/zhubo/src/main/java/com/doumee/api/business/WebParamController.java | 48 +
.idea/misc.xml | 1
server/zhubo/src/main/java/com/doumee/Main.java | 7
server/zhubo/src/main/java/com/doumee/api/business/BrandController.java | 41 +
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroToken.java | 54 +
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java | 46 +
server/zhubo/src/main/resources/application.yml | 64 ++
server/zhubo/src/main/java/com/doumee/api/business/CateBudgetController.java | 36 +
server/zhubo/pom.xml | 61 +
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroRealm.java | 115 +++
server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java | 45 +
server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java | 111 ---
server/service/src/main/java/com/doumee/service/business/impl/BaseDataServiceImpl.java | 3
server/zhubo/src/main/java/com/doumee/api/BaseController.java | 60 +
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCache.java | 163 +++++
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java | 0
server/zhubo/src/main/java/com/doumee/api/system/SystemController.java | 66 ++
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java | 25
server/company/src/main/resources/application.yml | 2
server/service/src/main/java/com/doumee/service/business/impl/GoodsServiceImpl.java | 18
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java | 144 ++++
server/pom.xml | 1
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java | 85 ++
.idea/compiler.xml | 7
server/zhubo/src/main/java/com/doumee/ZhuboApplication.java | 25
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java | 113 +++
server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerConfig.java | 88 ++
server/company/src/main/java/com/doumee/config/shiro/ShiroRealm.java | 2
37 files changed, 1,752 insertions(+), 118 deletions(-)
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 92917a1..bca72a5 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -6,22 +6,27 @@
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
+ <module name="company" />
+ <module name="zhubo" />
<module name="platform" />
<module name="service" />
- <module name="company" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
+ <module name="company (1)" target="1.8" />
+ <module name="company (2)" target="1.8" />
<module name="pre_select" target="1.8" />
</bytecodeTargetLevel>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="company" options="-parameters" />
+ <module name="company (1)" options="-parameters" />
<module name="platform" options="-parameters" />
<module name="pre_select" options="" />
<module name="preselect" options="-parameters" />
<module name="service" options="-parameters" />
+ <module name="zhubo" options="-parameters" />
</option>
</component>
</project>
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 0956fda..0ce3556 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -9,5 +9,7 @@
<file url="file://$PROJECT_DIR$/server/service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/server/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/server/src/main/resources" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/server/zhubo/src/main/java" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/server/zhubo/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 66c9c8c..a676599 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,6 +5,7 @@
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/server/pom.xml" />
+ <option value="$PROJECT_DIR$/server/zhubo/pom.xml" />
</list>
</option>
</component>
diff --git a/server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java b/server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
index 28b01dc..853e2bb 100644
--- a/server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
+++ b/server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
@@ -27,119 +27,12 @@
*/
public class ShiroAuthFilter extends FormAuthenticationFilter {
- public ShiroAuthFilter(SessionManager sessionManager,ShiroCacheManager shiroCacheManager) {
- super();
- this.sessionManager = (ShiroSessionManager)sessionManager;
- this.cache = shiroCacheManager.getCache("shiro_redis_cache");
- }
- @Override
- protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
- return false;
- }
+ @Override
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
- private int maxSession = 1; //鏈�澶т細璇濇暟閲�
-
- private boolean kickOutAfter = false; //韪㈠嚭鍓嶈�呰繕鏄悗鑰�
- private Cache<String, Deque<Serializable>> cache; //缂撳瓨绠$悊
-
-
- private ShiroSessionManager sessionManager; //浼氳瘽绠$悊
-
- @Override
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
- Subject subject = getSubject(request, response);
- if (!subject.isAuthenticated() && !subject.isRemembered()) { //濡傛灉涓嶆槸璁よ瘉杩囧拰璁颁綇瀵嗙爜鐨勶紝灏辩洿鎺ユ斁琛岃姹傦紝閬垮厤閫犳垚璁块棶杩囨參
- // return Boolean.TRUE;
- }
- Session session = subject.getSession(); //鑾峰彇浼氳瘽session
- Object principal = subject.getPrincipal();
- Serializable sessionId = session.getId();
- LoginUserInfo userInfo = (LoginUserInfo) principal;
- if(userInfo == null ){
- HttpServletResponse servletResponse = (HttpServletResponse) response;
- servletResponse.setHeader("content-type", "application/json;charset=UTF-8");
- servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "鏈櫥褰曟垨鐧诲綍淇℃伅宸茶繃鏈�")));
- return Boolean.FALSE;
-// return super.onAccessDenied(request,response);
- }else if( Constants.equalsInteger(userInfo.getType(), Constants.UserType.COMPANY.getKey()) ){
- return Boolean.TRUE;
-// return super.onAccessDenied(request,response);
- }
-
- String userName = userInfo.getCompanyId() +"_"+ userInfo.getId();
- Deque<Serializable> deque = cache.get(userName);
- if (deque == null) {
- deque = new LinkedList<>();
- }
- if (!deque.contains(sessionId) && session.getAttribute("kickOut") == null) {
- deque.push(sessionId);
- cache.put(userName, deque);
- }
- while (deque.size() > maxSession) {
- Serializable kickOutSessionId;
- if (kickOutAfter) {
- kickOutSessionId = deque.removeFirst();
- cache.put(userName, deque);
- } else {
- kickOutSessionId = deque.removeLast();
- cache.put(userName, deque);
- }
-
- try {
- Session kickOutSession = sessionManager.getSession(new DefaultSessionKey(kickOutSessionId));
- if (kickOutSession != null) {
- kickOutSession.setAttribute("kickOut", Boolean.TRUE);
- }
- } catch (Exception e) {
- e.printStackTrace();
-// log.error("韪㈠嚭寮傚父鏈涪鍑�");
- }
- }
-
- if (session!=null && session.getAttribute("kickOut") != null && (Boolean) session.getAttribute("kickOut") == true) {
- try {
- subject.logout();
- } catch (Exception e) {
- e.printStackTrace();
- }
- saveRequest(request);
HttpServletResponse servletResponse = (HttpServletResponse) response;
servletResponse.setHeader("content-type", "application/json;charset=UTF-8");
servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "鏈櫥褰曟垨鐧诲綍淇℃伅宸茶繃鏈�")));
return Boolean.FALSE;
}
- return Boolean.TRUE;
- }
-
- public int getMaxSession() {
- return maxSession;
- }
-
- public void setMaxSession(int maxSession) {
- this.maxSession = maxSession;
- }
-
- public boolean isKickOutAfter() {
- return kickOutAfter;
- }
-
- public void setKickOutAfter(boolean kickOutAfter) {
- this.kickOutAfter = kickOutAfter;
- }
-
- public Cache<String, Deque<Serializable>> getCache() {
- return cache;
- }
-
- public void setCache(Cache<String, Deque<Serializable>> cache) {
- this.cache = cache;
- }
-
- public ShiroSessionManager getSessionManager() {
- return sessionManager;
- }
-
- public void setSessionManager(ShiroSessionManager sessionManager) {
- this.sessionManager = sessionManager;
- }
}
diff --git a/server/company/src/main/java/com/doumee/config/shiro/ShiroConfig.java b/server/company/src/main/java/com/doumee/config/shiro/ShiroConfig.java
index d9636c8..fdd05c9 100644
--- a/server/company/src/main/java/com/doumee/config/shiro/ShiroConfig.java
+++ b/server/company/src/main/java/com/doumee/config/shiro/ShiroConfig.java
@@ -127,7 +127,7 @@
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
// 娣诲姞璁よ瘉杩囨护鍣�
Map<String, Filter> filters = new LinkedHashMap<>();
- filters.put("authc", new ShiroAuthFilter(this.sessionManager(),shiroCacheManager));
+ filters.put("authc", new ShiroAuthFilter());
shiroFilterFactoryBean.setFilters(filters);
return shiroFilterFactoryBean;
}
diff --git a/server/company/src/main/java/com/doumee/config/shiro/ShiroRealm.java b/server/company/src/main/java/com/doumee/config/shiro/ShiroRealm.java
index 1f3e049..14dfc00 100644
--- a/server/company/src/main/java/com/doumee/config/shiro/ShiroRealm.java
+++ b/server/company/src/main/java/com/doumee/config/shiro/ShiroRealm.java
@@ -88,7 +88,7 @@
if(user == null){
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝璐﹀彿鎴栧瘑鐮佷笉姝g‘锛�");
}
- if(!Constants.equalsInteger(user.getType(),Constants.UserType.COMPANY.getKey()) && !Constants.equalsInteger(user.getType(),Constants.UserType.ZHUBO.getKey())){
+ if(!Constants.equalsInteger(user.getType(),Constants.UserType.COMPANY.getKey())){
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝闈炰紒涓氳处鎴疯韩浠斤紝鏃犳硶鐧诲綍璇ュ钩鍙帮紒锛�");
}
if(!Constants.equalsInteger(user.getStatus(),Constants.ZERO)){
diff --git a/server/company/src/main/resources/application.yml b/server/company/src/main/resources/application.yml
index 6787c56..ac52ad2 100644
--- a/server/company/src/main/resources/application.yml
+++ b/server/company/src/main/resources/application.yml
@@ -11,7 +11,7 @@
# application:
# name: doumeemes
profiles:
- active: dev
+ active: pro
# JSON杩斿洖閰嶇疆
jackson:
diff --git a/server/pom.xml b/server/pom.xml
index be687ef..ab0428b 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -13,6 +13,7 @@
<module>platform</module>
<module>service</module>
<module>company</module>
+ <module>zhubo</module>
</modules>
<parent>
diff --git a/server/service/src/main/java/com/doumee/service/business/impl/BaseDataServiceImpl.java b/server/service/src/main/java/com/doumee/service/business/impl/BaseDataServiceImpl.java
index 03c580a..118f433 100644
--- a/server/service/src/main/java/com/doumee/service/business/impl/BaseDataServiceImpl.java
+++ b/server/service/src/main/java/com/doumee/service/business/impl/BaseDataServiceImpl.java
@@ -384,7 +384,8 @@
}
// goods.setImgurl(getOssImgurl(ossModel,ossModel.getGoodsFolder(), data.getImgurl()));
goods.setImgurl(getOssImgurlFile(ossModel.getGoodsFolder(), data.getImgurl(), data.getId(),Constants.ZERO,fileRecords));
- goods.setPrice(Constants.formatBigdecimal(data.getSaleprice()).multiply(Constants.formatBigdecimal(cModel.getPriceRate())));
+// goods.setPrice(Constants.formatBigdecimal(data.getSaleprice()).multiply(Constants.formatBigdecimal(cModel.getPriceRate())));
+ goods.setPrice(Constants.formatBigdecimal(data.getSaleprice()));
if(model!=null){
//濡傛灉宸茬粡瀛樺湪锛屾洿鏂板晢鍝佹暟鎹�
goods.setEditDate(date);
diff --git a/server/service/src/main/java/com/doumee/service/business/impl/BaseGoodsServiceImpl.java b/server/service/src/main/java/com/doumee/service/business/impl/BaseGoodsServiceImpl.java
index ab87999..7c30b43 100644
--- a/server/service/src/main/java/com/doumee/service/business/impl/BaseGoodsServiceImpl.java
+++ b/server/service/src/main/java/com/doumee/service/business/impl/BaseGoodsServiceImpl.java
@@ -391,6 +391,7 @@
.leftJoin(BaseCategory.class,BaseCategory::getId,BaseGoods::getCategoryId)
.selectAll(BaseGoods.class)
.selectAs(Brand::getName,BaseGoods::getBrandName)
+ .selectAs(BaseCategory::getPriceRate,BaseGoods::getCateRatePrice)
.selectAs(BaseCategory::getName,BaseGoods::getCategoryName)
.eq(BaseGoods::getStatus, Constants.ZERO)
.eq(BaseGoods::getIsdeleted, Constants.ZERO)
@@ -406,6 +407,8 @@
+ systemDictDataBiz.queryByCode(Constants.OSS, Constants.GOODS_IMG).getCode();
pageData.getRecords().forEach(i->{
i.setFullImgUrl(prefixUrl + i.getImgurl());
+ //鍔犱环绯绘暟
+ i.setPrice(Constants.formatBigdecimal(i.getPrice()).multiply(Constants.formatBigdecimal(i.getCateRatePrice())));
});
return pageData;
}
diff --git a/server/service/src/main/java/com/doumee/service/business/impl/GoodsServiceImpl.java b/server/service/src/main/java/com/doumee/service/business/impl/GoodsServiceImpl.java
index 553ced0..02cde3d 100644
--- a/server/service/src/main/java/com/doumee/service/business/impl/GoodsServiceImpl.java
+++ b/server/service/src/main/java/com/doumee/service/business/impl/GoodsServiceImpl.java
@@ -66,6 +66,8 @@
@Autowired
private CategoryMapper categoryMapper;
@Autowired
+ private BaseCategoryMapper baseCategoryMapper;
+ @Autowired
private CateAttrMapper cateAttrMapper;
@Autowired
private CateParamMapper cateParamMapper;
@@ -158,6 +160,11 @@
if(category.getPlatCateId() == null){
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"瀵逛笉璧凤紝璇峰墠寰�銆愮被鍒鐞嗐�戝厛鍏宠仈骞冲彴绫诲埆锛�");
}
+ BaseCategory baseCategory = baseCategoryMapper.selectById(category.getPlatCateId());
+ if(baseCategory == null){
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"瀵逛笉璧凤紝璇峰墠寰�銆愮被鍒鐞嗐�戝厛鍏宠仈骞冲彴绫诲埆锛�");
+ }
+
BaseGoods bp = new BaseGoods();
bp.setCategoryId(category.getPlatCateId());
bp.setIsdeleted(Constants.ZERO);
@@ -185,6 +192,9 @@
try{
for(BaseGoods model : goodsList){
//閬嶅巻骞冲彴鍟嗗搧淇℃伅锛岃繘琛屽晢鍝佷俊鎭悓姝�
+ //鍒嗙被鍔犱环绯绘暟
+
+ model.setCateRatePrice(baseCategory.getPriceRate());
Goods goods = initGoodsPlatParam(user,model,param);
if(goods == null){
continue;
@@ -310,11 +320,11 @@
throw new BusinessException(ResponseStatus.DATA_ERRO.getCode(),"鏁版嵁寮傚父璇峰埛鏂伴噸璇�");
}
//濡傛灉娌℃湁閰嶇疆鍏ユ墜浠凤紝瀹夎鍔犱环绯绘暟鏉ヨ绠�
-// if(model.getCateRatePrice()==null){
-// model.setCateRatePrice(systemDictDataBiz.getGoodsPriceRate());
-// }
+ if(model.getCateRatePrice()==null){
+ model.setCateRatePrice(systemDictDataBiz.getGoodsPriceRate());
+ }
//杩斿洖 .multiply(model.getCateRatePrice())
- return (Constants.formatBigdecimal(model.getPrice()).multiply(param.getRate())).setScale(0,BigDecimal.ROUND_CEILING);
+ return (Constants.formatBigdecimal(model.getPrice()).multiply(model.getCateRatePrice()).multiply(param.getRate())).setScale(0,BigDecimal.ROUND_CEILING);
}
diff --git a/server/zhubo/pom.xml b/server/zhubo/pom.xml
new file mode 100644
index 0000000..7645a85
--- /dev/null
+++ b/server/zhubo/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.doumee</groupId>
+ <artifactId>preselect</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>zhubo</artifactId>
+
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.doumee</groupId>
+ <artifactId>service</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>company</finalName>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <configuration>
+ <fork>true</fork>
+ <mainClass>com.doumee.ZhuboApplication</mainClass>
+ <layout>ZIP</layout>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>-->
+
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/server/zhubo/src/main/java/com/doumee/Main.java b/server/zhubo/src/main/java/com/doumee/Main.java
new file mode 100644
index 0000000..ada0d0d
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/Main.java
@@ -0,0 +1,7 @@
+package com.doumee;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/server/zhubo/src/main/java/com/doumee/ZhuboApplication.java b/server/zhubo/src/main/java/com/doumee/ZhuboApplication.java
new file mode 100644
index 0000000..845163c
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/ZhuboApplication.java
@@ -0,0 +1,25 @@
+package com.doumee;
+
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+/**
+ * 鍚姩绫�
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+@Slf4j
+@SpringBootApplication
+@MapperScan("com.doumee.dao")
+@EnableAsync
+public class ZhuboApplication {
+ public static void main(String[] args) {
+ ApplicationContext context = SpringApplication.run(ZhuboApplication.class);
+ context.getEnvironment();
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/BaseController.java b/server/zhubo/src/main/java/com/doumee/api/BaseController.java
new file mode 100644
index 0000000..c45000d
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/BaseController.java
@@ -0,0 +1,60 @@
+package com.doumee.api;
+
+import com.doumee.core.model.LoginUserInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Controller鍩虹被
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+@Slf4j
+public class BaseController {
+
+ /**
+ * 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+ protected LoginUserInfo getLoginUser () {
+ return (LoginUserInfo)SecurityUtils.getSubject().getPrincipal();
+ }
+
+ /**
+ * 鑾峰彇ID闆嗗悎
+ *
+ * @param ids 浣跨敤","闅斿紑鐨勫涓狪D
+ * @return List<Integer>
+ */
+ protected List<Integer> getIdList (String ids) {
+ String [] idArray = ids.split(",");
+ List<Integer> idList = new ArrayList<>();
+ for (String id : idArray) {
+ idList.add(Integer.valueOf(id));
+ }
+ return idList;
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢瀛楄妭娴�
+ *
+ * @param is 杈撳叆娴�
+ * @return ByteArrayOutputStream
+ */
+ protected ByteArrayOutputStream getOutputStream (InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] bs = new byte[is.available()];
+ int len;
+ while ((len = is.read(bs)) != -1) {
+ baos.write(bs, 0, len);
+ }
+ return baos;
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/business/BrandController.java b/server/zhubo/src/main/java/com/doumee/api/business/BrandController.java
new file mode 100644
index 0000000..586f3f8
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/business/BrandController.java
@@ -0,0 +1,41 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.Brand;
+import com.doumee.service.business.BrandService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/05/12 13:58
+ */
+@Api(tags = "鍝佺墝淇℃伅琛�")
+@RestController
+@RequestMapping("/business/brand")
+public class BrandController extends BaseController {
+
+ @Autowired
+ private BrandService brandService;
+
+ @ApiOperation("鍒楄〃鏌ヨ")
+ @PostMapping("/list")
+ public ApiResponse<List<Brand>> findList (@RequestBody Brand brand) {
+ return ApiResponse.success(brandService.findList(brand));
+ }
+
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/business/CateBudgetController.java b/server/zhubo/src/main/java/com/doumee/api/business/CateBudgetController.java
new file mode 100644
index 0000000..a64325c
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/business/CateBudgetController.java
@@ -0,0 +1,36 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.CateBudget;
+import com.doumee.service.business.CateBudgetService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author 姹熻箘韫�
+ * @since 2023/05/15 17:09
+ */
+@Api(tags = "鍝佺被浠锋牸鍖洪棿琛�")
+@RestController
+@RequestMapping("/business/cateBudget")
+public class CateBudgetController extends BaseController {
+
+ @Autowired
+ private CateBudgetService cateBudgetService;
+
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("business:catebudget:query")
+ public ApiResponse<PageData<CateBudget>> findPage (@RequestBody PageWrap<CateBudget> pageWrap) {
+ return ApiResponse.success(cateBudgetService.findPage(pageWrap));
+ }
+
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/business/CategoryController.java b/server/zhubo/src/main/java/com/doumee/api/business/CategoryController.java
new file mode 100644
index 0000000..508defc
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/business/CategoryController.java
@@ -0,0 +1,106 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.BaseCateParam;
+import com.doumee.dao.business.model.BaseCategory;
+import com.doumee.dao.business.model.Category;
+import com.doumee.service.CateParamSelectService;
+import com.doumee.service.business.BaseCateParamService;
+import com.doumee.service.business.BaseCategoryService;
+import com.doumee.service.business.CategoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.java.Log;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/05/12 13:58
+ */
+@Api(tags = "鍝佺被淇℃伅琛�")
+@RestController
+@RequestMapping("/business/category")
+public class CategoryController extends BaseController {
+
+ @Autowired
+ private CategoryService categoryService;
+
+ @Autowired
+ private BaseCategoryService baseCategoryService;
+
+ @Autowired
+ private BaseCateParamService baseCateParamService;
+ @Autowired
+ private CateParamSelectService cateParamSelectService;
+
+
+ @ApiOperation("鍒楄〃")
+ @PostMapping("/list")
+ public ApiResponse<List<Category>> findList (@RequestBody Category category) {
+ return ApiResponse.success(categoryService.findList(category));
+ }
+
+ @ApiOperation("鍒楄〃 - 鍟嗗搧閫夋嫨")
+ @GetMapping("/findListForGoodsId")
+ public ApiResponse<List<Category>> findListForGoodsId (Integer goodsId) {
+ return ApiResponse.success(categoryService.findListForGoods(goodsId));
+ }
+
+
+ @ApiOperation("浼佷笟閫夋嫨鍒嗙被鍒楄〃 - H5")
+ @PostMapping("/companyFindList")
+ public ApiResponse<List<Category>> companyFindList (@RequestBody Category category) {
+ return ApiResponse.success(categoryService.companyFindList(category));
+ }
+
+ @ApiOperation("骞冲彴鍒嗙被鍒楄〃")
+ @PostMapping("/baseCategoryList")
+ public ApiResponse<List<BaseCategory>> baseCategoryList () {
+ BaseCategory baseCategory = new BaseCategory();
+ baseCategory.setIsdeleted(Constants.ZERO);
+ baseCategory.setStatus(Constants.ZERO);
+ List list = baseCategoryService.findList(baseCategory);
+ return ApiResponse.success(list);
+ }
+
+ @ApiOperation("骞冲彴鍒嗙被璇︽儏")
+ @GetMapping("/baseCategoryDetail")
+ public ApiResponse<BaseCategory> baseCategoryDetail (Integer baseCategoryId) {
+
+ BaseCategory baseCategory = baseCategoryService.findById(baseCategoryId);
+ if(Objects.isNull(baseCategory)){
+ throw new BusinessException(ResponseStatus.DATA_EMPTY);
+ }
+ BaseCateParam baseCateParam = new BaseCateParam();
+ baseCateParam.setIsdeleted(Constants.ZERO);
+ baseCateParam.setStatus(Constants.ZERO);
+ baseCateParam.setCategoryId(baseCategoryId);
+ baseCategory.setBaseCateParamList(
+ baseCateParamService.findList(baseCateParam)
+ );
+ return ApiResponse.success(baseCategory);
+ }
+
+ @ApiOperation("鍒楄〃 - SaaSH5")
+ @PostMapping("/saasList")
+ public ApiResponse<List<Category>> saasList (@RequestBody Category category) {
+ return ApiResponse.success(categoryService.findListSaaS(category));
+ }
+
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/business/GoodsController.java b/server/zhubo/src/main/java/com/doumee/api/business/GoodsController.java
new file mode 100644
index 0000000..f20fdd2
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/business/GoodsController.java
@@ -0,0 +1,71 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.Goods;
+import com.doumee.dao.business.model.dto.BatchDisableDTO;
+import com.doumee.dao.business.model.dto.GoodCreatePlatRequest;
+import com.doumee.dao.business.model.dto.GoodsRequest;
+import com.doumee.service.CateParamSelectService;
+import com.doumee.service.business.GoodsService;
+import io.swagger.annotations.*;
+import lombok.extern.java.Log;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.doumee.core.model.ApiResponse;
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/05/12 13:58
+ */
+@Api(tags = "鍟嗗搧淇℃伅琛�")
+@RestController
+@RequestMapping("/business/goods")
+public class GoodsController extends BaseController {
+
+ @Autowired
+ private GoodsService goodsService;
+ @Autowired
+ private CateParamSelectService cateParamSelectService;
+
+ @ApiOperation("鍒楄〃 - H5")
+ @PostMapping("/list")
+ public ApiResponse<List<Goods>> findList (@RequestBody Goods goods) {
+ LoginUserInfo user = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+ goods.setCompanyId(user.getCompanyId());
+ return ApiResponse.success(goodsService.findList(goods));
+ }
+
+
+ @ApiOperation("鍟嗗搧鍒嗛〉鍒楄〃 - H5")
+ @PostMapping("/goodsPage")
+ public ApiResponse<PageData<Goods>> goodsPage(@RequestBody PageWrap<GoodsRequest> pageWrap) {
+ return ApiResponse.success(goodsService.getGoodsPage(pageWrap));
+ }
+
+ @ApiOperation("鍒楄〃鏌ヨ - H5")
+ @PostMapping("/listForH5")
+ public ApiResponse<List<Goods>> listForH5 (@RequestBody GoodsRequest goodsRequest) {
+ return ApiResponse.success(goodsService.findListForH5(goodsRequest));
+ }
+
+ @ApiOperation("鑾峰彇H5棣栭〉鍥�")
+ @PostMapping("/h5Image")
+ public ApiResponse<String> h5Image () {
+ return ApiResponse.success(goodsService.h5Image());
+ }
+
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/business/WebParamController.java b/server/zhubo/src/main/java/com/doumee/api/business/WebParamController.java
new file mode 100644
index 0000000..47ef372
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/business/WebParamController.java
@@ -0,0 +1,48 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.model.PageData;
+import com.doumee.dao.business.model.WebParam;
+import com.doumee.dao.system.dto.UpdateWebParamDTO;
+import com.doumee.service.business.WebParamService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletResponse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @since 2023/09/12 11:18
+ */
+@Api(tags = "浼佷笟椤甸潰閰嶇疆淇℃伅琛�")
+@RestController
+@RequestMapping("/business/webParam")
+public class WebParamController extends BaseController {
+
+ @Autowired
+ private WebParamService webParamService;
+
+
+ @ApiOperation("鑾峰彇褰撳墠鐧诲綍浼佷笟閰嶇疆淇℃伅")
+ @GetMapping("/getByLogin")
+ public ApiResponse<WebParam> getByLogin() {
+ return ApiResponse.success(webParamService.findOne());
+ }
+
+ @ApiOperation("鏇存柊浼佷笟閰嶇疆淇℃伅")
+ @PostMapping("/renew")
+ public ApiResponse renew(@RequestBody UpdateWebParamDTO updateWebParamDTO) {
+ webParamService.renew(updateWebParamDTO);
+ return ApiResponse.success("鎿嶄綔鎴愬姛");
+ }
+
+}
diff --git a/server/zhubo/src/main/java/com/doumee/api/system/SystemController.java b/server/zhubo/src/main/java/com/doumee/api/system/SystemController.java
new file mode 100644
index 0000000..6e49f7f
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/api/system/SystemController.java
@@ -0,0 +1,66 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemUserBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.system.dto.LoginDTO;
+import com.doumee.dao.system.dto.UpdatePwdDto;
+import com.doumee.dao.system.dto.WebLoginDTO;
+import com.doumee.service.system.SystemLoginService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author Eva.Caesar Liu
+ * @date 2023/03/21 14:49
+ */
+@Api(tags = "绯荤粺鍔熻兘")
+@Trace(exclude = true)
+@Slf4j
+@RestController
+@RequestMapping("/system")
+public class SystemController extends BaseController {
+
+ @Autowired
+ private SystemUserBiz systemUserBiz;
+
+ @Autowired
+ private SystemLoginService systemLoginService;
+
+
+ @PreventRepeat(limit = 10, lockTime = 10000)
+ @ApiOperation("鐧诲綍 - H5")
+ @PostMapping("/loginH5")
+ public ApiResponse<String> loginH5 (@Validated @RequestBody WebLoginDTO dto, HttpServletRequest request) {
+ LoginDTO loginDTO = new LoginDTO();
+ BeanUtils.copyProperties(dto,loginDTO);
+ return ApiResponse.success(systemLoginService.loginByPassword(loginDTO, Constants.TWO, request));
+ }
+
+ @ApiOperation("閫�鍑虹櫥褰�")
+ @PostMapping("/logout")
+ public ApiResponse logout () {
+ Subject subject = SecurityUtils.getSubject();
+ subject.logout();
+ return ApiResponse.success(null);
+ }
+ @ApiOperation("鑾峰彇褰撳墠鐧诲綍鐨勭敤鎴蜂俊鎭�")
+ @GetMapping("/getUserInfo")
+ public ApiResponse<LoginUserInfo> getUserInfo () {
+ return ApiResponse.success(this.getLoginUser());
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
new file mode 100644
index 0000000..6f3cca8
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
@@ -0,0 +1,144 @@
+package com.doumee.config.shiro;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.utils.Constants;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.MapCache;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.DefaultSessionKey;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
+import org.springframework.http.HttpStatus;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Serializable;
+import java.util.Deque;
+import java.util.LinkedList;
+
+/**
+ * Shiro璁よ瘉杩囨护鍣紝澶勭悊鏈璇佹儏鍐电殑鍝嶅簲
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+public class ShiroAuthFilter extends FormAuthenticationFilter {
+
+ public ShiroAuthFilter(SessionManager sessionManager,ShiroCacheManager shiroCacheManager) {
+ super();
+ this.sessionManager = (ShiroSessionManager)sessionManager;
+ this.cache = shiroCacheManager.getCache("shiro_redis_cache");
+ }
+ @Override
+ protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+ return false;
+ }
+
+ private int maxSession = 1; //鏈�澶т細璇濇暟閲�
+
+ private boolean kickOutAfter = false; //韪㈠嚭鍓嶈�呰繕鏄悗鑰�
+ private Cache<String, Deque<Serializable>> cache; //缂撳瓨绠$悊
+
+
+ private ShiroSessionManager sessionManager; //浼氳瘽绠$悊
+
+ @Override
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
+ Subject subject = getSubject(request, response);
+ if (!subject.isAuthenticated() && !subject.isRemembered()) { //濡傛灉涓嶆槸璁よ瘉杩囧拰璁颁綇瀵嗙爜鐨勶紝灏辩洿鎺ユ斁琛岃姹傦紝閬垮厤閫犳垚璁块棶杩囨參
+ // return Boolean.TRUE;
+ }
+ Session session = subject.getSession(); //鑾峰彇浼氳瘽session
+ Object principal = subject.getPrincipal();
+ Serializable sessionId = session.getId();
+ LoginUserInfo userInfo = (LoginUserInfo) principal;
+ if(userInfo == null || !Constants.equalsInteger(userInfo.getType(), Constants.UserType.ZHUBO.getKey()) ){
+ HttpServletResponse servletResponse = (HttpServletResponse) response;
+ servletResponse.setHeader("content-type", "application/json;charset=UTF-8");
+ servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "鏈櫥褰曟垨鐧诲綍淇℃伅宸茶繃鏈�")));
+ return Boolean.FALSE;
+ }
+ String userName = userInfo.getCompanyId() +"_"+ userInfo.getId();
+ Deque<Serializable> deque = cache.get(userName);
+ if (deque == null) {
+ deque = new LinkedList<>();
+ }
+ if (!deque.contains(sessionId) && session.getAttribute("kickOut") == null) {
+ deque.push(sessionId);
+ cache.put(userName, deque);
+ }
+ while (deque.size() > maxSession) {
+ Serializable kickOutSessionId;
+ if (kickOutAfter) {
+ kickOutSessionId = deque.removeFirst();
+ cache.put(userName, deque);
+ } else {
+ kickOutSessionId = deque.removeLast();
+ cache.put(userName, deque);
+ }
+
+ try {
+ Session kickOutSession = sessionManager.getSession(new DefaultSessionKey(kickOutSessionId));
+ if (kickOutSession != null){
+ kickOutSession.setAttribute("kickOut", Boolean.TRUE);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (session!=null && session.getAttribute("kickOut") != null && (Boolean) session.getAttribute("kickOut") == true) {
+ try {
+ subject.logout();
+ if(deque!=null){
+ deque.remove(sessionId);
+ cache.put(userName, deque);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ saveRequest(request);
+ HttpServletResponse servletResponse = (HttpServletResponse) response;
+ servletResponse.setHeader("content-type", "application/json;charset=UTF-8");
+ servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "鏈櫥褰曟垨鐧诲綍淇℃伅宸茶繃鏈�")));
+ return Boolean.FALSE;
+ }
+ return Boolean.TRUE;
+ }
+
+ public int getMaxSession() {
+ return maxSession;
+ }
+
+ public void setMaxSession(int maxSession) {
+ this.maxSession = maxSession;
+ }
+
+ public boolean isKickOutAfter() {
+ return kickOutAfter;
+ }
+
+ public void setKickOutAfter(boolean kickOutAfter) {
+ this.kickOutAfter = kickOutAfter;
+ }
+
+ public Cache<String, Deque<Serializable>> getCache() {
+ return cache;
+ }
+
+ public void setCache(Cache<String, Deque<Serializable>> cache) {
+ this.cache = cache;
+ }
+
+ public ShiroSessionManager getSessionManager() {
+ return sessionManager;
+ }
+
+ public void setSessionManager(ShiroSessionManager sessionManager) {
+ this.sessionManager = sessionManager;
+ }
+}
diff --git a/server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java
similarity index 100%
rename from server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java
rename to server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCache.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCache.java
new file mode 100644
index 0000000..6fe6153
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCache.java
@@ -0,0 +1,163 @@
+package com.doumee.config.shiro;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.context.annotation.Scope;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.SerializationException;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Shiro缂撳瓨
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Scope(value = "prototype")
+@Slf4j
+@Component
+public class ShiroCache implements Cache<Object, Serializable> {
+
+ private String keyPrefix = "ProSelect";
+
+ @Resource(name="sessionRedisTemplate")
+ private RedisTemplate<Object, Serializable> redisTemplate;
+
+ public ShiroCache () {
+ log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
+ }
+
+ public ShiroCache(String keyPrefix) {
+ log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
+ this.keyPrefix = keyPrefix;
+ }
+
+ @Override
+ public Serializable get(Object key) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ return redisTemplate.opsForValue().get(getKey(key));
+ }
+
+ @Override
+ public Serializable put(Object key, Serializable value) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ redisTemplate.opsForValue().set(getKey(key), value);
+ return value;
+ }
+
+ public Serializable put(Object key, Serializable value, int timeout) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ try {
+ redisTemplate.opsForValue().set(getKey(key), value, timeout, TimeUnit.SECONDS);
+ }catch (Exception e){
+
+ }
+ return value;
+ }
+
+ @Override
+ public void clear() throws CacheException {
+ Set<Object> keys = this.keys();
+ redisTemplate.delete(keys);
+ }
+
+ @Override
+ public int size() {
+ return this.keys().size();
+ }
+
+ @Override
+ public Set<Object> keys() {
+ Set<Object> keys = redisTemplate.keys(keyPrefix + "*");
+ if (CollectionUtils.isEmpty(keys)) {
+ return Collections.emptySet();
+ }
+ return keys;
+ }
+
+ @Override
+ public Collection<Serializable> values() {
+ Collection<Serializable> values = new ArrayList<>();
+ Set<Object> keys = this.keys();
+ if (CollectionUtils.isEmpty(keys)) {
+ return values;
+ }
+ for (Object k : keys) {
+ values.add(redisTemplate.opsForValue().get(k));
+ }
+ return values;
+ }
+
+ @Override
+ public Serializable remove(Object key) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ Serializable value = this.get(getKey(key));
+ redisTemplate.delete(getKey(key));
+ return value;
+ }
+
+ private Object getKey (Object key) {
+ if (key instanceof PrincipalCollection) {
+ return this.keyPrefix + getRedisKeyFromPrincipalIdField((PrincipalCollection)key);
+ }
+ return (key instanceof String ? (this.keyPrefix + key) : key);
+ }
+
+ /**
+ * 鑾峰彇redis cache key
+ */
+ private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
+ Object principalObject = key.getPrimaryPrincipal();
+ if (principalObject instanceof String) {
+ return principalObject.toString();
+ } else {
+ Method pincipalIdGetter = this.getPrincipalIdGetter(principalObject);
+ return this.getIdObj(principalObject, pincipalIdGetter);
+ }
+ }
+
+ private Method getPrincipalIdGetter(Object principalObject) {
+ Method pincipalIdGetter;
+ String principalIdMethodName = this.getPrincipalIdMethodName();
+
+ try {
+ pincipalIdGetter = principalObject.getClass().getMethod(principalIdMethodName);
+ return pincipalIdGetter;
+ } catch (NoSuchMethodException e) {
+ throw new SerializationException(e.getMessage(), e);
+ }
+ }
+
+ private String getIdObj(Object principalObject, Method pincipalIdGetter) {
+ try {
+ Object idObj = pincipalIdGetter.invoke(principalObject);
+ String redisKey = idObj.toString();
+ return redisKey;
+ } catch (Exception e) {
+ throw new SerializationException(e.getMessage(), e);
+ }
+ }
+
+ private String getPrincipalIdMethodName() {
+ return "getId";
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java
new file mode 100644
index 0000000..4c11155
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java
@@ -0,0 +1,44 @@
+package com.doumee.config.shiro;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.cache.CacheManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 鑷畾涔塖hiro CacheManager
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Slf4j
+@Component
+public class ShiroCacheManager implements CacheManager {
+
+ private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap();
+
+ private static ApplicationContext applicationContext;
+
+ @Override
+ public <K, V> Cache<K, V> getCache(String name) throws CacheException {
+ log.debug("get cache, name=" + name);
+ Cache cache = this.caches.get(name);
+ if (cache == null) {
+ cache = applicationContext.getBean(ShiroCache.class, "shiro:cache:");
+ this.caches.put(name, cache);
+ }
+ return cache;
+ }
+
+ @Autowired
+ public void setApplicationContext (ApplicationContext applicationContext) {
+ if (ShiroCacheManager.applicationContext == null) {
+ ShiroCacheManager.applicationContext = applicationContext;
+ }
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroConfig.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroConfig.java
new file mode 100644
index 0000000..d9636c8
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroConfig.java
@@ -0,0 +1,153 @@
+package com.doumee.config.shiro;
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import javax.servlet.Filter;
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Shiro閰嶇疆
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Configuration
+public class ShiroConfig {
+
+ @Value("${cache.session.expire}")
+ private int sessionExpireTime;
+
+ @Autowired
+ private ShiroCredentialsMatcher shiroCredentialsMatcher;
+
+ @Autowired
+ private ShiroSessionDAO shiroSessionDAO;
+
+ @Autowired
+ private ShiroCacheManager shiroCacheManager;
+
+ @Autowired
+ private ShiroRealm shiroRealm;
+
+ @Bean("sessionRedisTemplate")
+ public RedisTemplate<Object, Serializable> sessionRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ RedisTemplate<Object, Serializable> redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(redisConnectionFactory);
+ // 榛樿搴忓垪鍖栨柟寮�
+ redisTemplate.setDefaultSerializer(new StringRedisSerializer());
+ // 鍊煎簭鍒楀寲鏂瑰紡
+ ShiroSessionSerializer serializer = new ShiroSessionSerializer();
+ redisTemplate.setValueSerializer(serializer);
+ redisTemplate.setHashValueSerializer(serializer);
+ redisTemplate.afterPropertiesSet();
+ return redisTemplate;
+ }
+
+ @Bean
+ public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+ DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+ autoProxyCreator.setProxyTargetClass(true);
+ return autoProxyCreator;
+ }
+
+ @Bean
+ public SessionManager sessionManager() {
+ ShiroSessionManager sessionManager = new ShiroSessionManager();
+ sessionManager.setSessionDAO(shiroSessionDAO);
+ sessionManager.setGlobalSessionTimeout(sessionExpireTime*1000);
+ // 鍒犻櫎澶辨晥鐨剆ession
+ sessionManager.setDeleteInvalidSessions(true);
+ return sessionManager;
+ }
+
+ @Bean
+ public SecurityManager securityManager() {
+ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+ securityManager.setRealm(shiroRealm);
+ securityManager.setSessionManager(this.sessionManager());
+ securityManager.setCacheManager(shiroCacheManager);
+ return securityManager;
+ }
+
+ @Bean
+ public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
+ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
+ shiroFilterFactoryBean.setSecurityManager(securityManager);
+ Map<String, String> map = new LinkedHashMap<>();
+ // 璺緞鎷︽埅閰嶇疆
+ // 璺緞鎷︽埅閰嶇疆
+// map.put("/system/dictData/companyUserRules","anon");
+// map.put("/system/login", "anon");
+// map.put("/system/logout", "anon");
+// map.put("/common/captcha", "anon");
+// map.put("/business/areas/*", "anon");
+// map.put("/public/uploadPicture","anon");
+// map.put("/public/uploadLocal","anon");
+
+ map.put("/system/dictData/companyUserRules","anon");
+ map.put("/system/login", "anon");
+ map.put("/system/logout", "anon");
+ map.put("/system/loginH5", "anon");
+ map.put("/common/captcha", "anon");
+ map.put("/business/areas/*", "anon");
+ map.put("/public/uploadPicture","anon");
+ map.put("/public/uploadLocal","anon");
+
+
+// map.put("/business/company/register", "anon");
+// map.put("/business/labels/page","anon");
+// map.put("/business/*/list","anon");
+// map.put("/business/goods/goodsPage","anon");
+// map.put("/business/goods/h5Image","anon");
+// map.put("/business/goods/export","anon");
+// map.put("/business/goods/listForH5","anon");
+
+
+ // - 鏀捐swagger
+ map.put("/doc.html", "anon");
+ map.put("/webjars/**", "anon");
+ map.put("/swagger-resources/**", "anon");
+ map.put("/v2/api-docs/**", "anon");
+
+ // - 鍏朵粬鎺ュ彛缁熶竴鎷︽埅
+ map.put("/**", "authc");
+ shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
+ // 娣诲姞璁よ瘉杩囨护鍣�
+ Map<String, Filter> filters = new LinkedHashMap<>();
+ filters.put("authc", new ShiroAuthFilter(this.sessionManager(),shiroCacheManager));
+ shiroFilterFactoryBean.setFilters(filters);
+ return shiroFilterFactoryBean;
+ }
+
+ @Bean
+ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
+ authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
+ return authorizationAttributeSourceAdvisor;
+ }
+
+ @Bean
+ public ShiroSessionDAO getShiroSessionDAO () {
+ shiroSessionDAO.setExpireTime(sessionExpireTime);
+ return shiroSessionDAO;
+ }
+
+ @Bean
+ public ShiroRealm getShiroRealm () {
+ shiroRealm.setCredentialsMatcher(shiroCredentialsMatcher);
+ return shiroRealm;
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java
new file mode 100644
index 0000000..8550e9d
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java
@@ -0,0 +1,46 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.service.system.SystemUserService;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+/**
+ * Shiro瀵嗙爜姣斿澶勭悊
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Component
+public class ShiroCredentialsMatcher extends HashedCredentialsMatcher {
+ @Lazy
+ @Autowired
+ private SystemUserService systemUserService;
+
+ @Override
+ public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
+ UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
+ SystemUser queryUserDto = new SystemUser();
+ queryUserDto.setUsername(usernamePasswordToken.getUsername());
+ queryUserDto.setDeleted(Boolean.FALSE);
+ SystemUser systemUser = systemUserService.findOne(queryUserDto);
+ if (systemUser == null) {
+ return Boolean.FALSE;
+ }
+// if(usernamePasswordToken.getDdLogin()){
+// return Boolean.TRUE;
+// }
+// if(usernamePasswordToken.getWxLogin()){
+// return Boolean.TRUE;
+// }
+ // 鍔犲瘑瀵嗙爜
+ String pwd = Utils.Secure.encryptPassword(new String(usernamePasswordToken.getPassword()), systemUser.getSalt());
+ // 姣旇緝瀵嗙爜
+ return this.equals(pwd, systemUser.getPassword());
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroRealm.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroRealm.java
new file mode 100644
index 0000000..c4cae4d
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroRealm.java
@@ -0,0 +1,115 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.dao.business.model.Company;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.service.business.CompanyService;
+import com.doumee.service.system.SystemDataPermissionService;
+import com.doumee.service.system.SystemPermissionService;
+import com.doumee.service.system.SystemRoleService;
+import com.doumee.service.system.SystemUserService;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 鑷畾涔塕ealm锛屽鐞嗚璇佸拰鏉冮檺
+ * @author Eva.Caesar Liu
+ * @date 2022/03/15 09:54
+ */
+@Component
+public class ShiroRealm extends AuthorizingRealm {
+
+ @Lazy
+ @Autowired
+ private SystemDataPermissionService systemDataPermissionService;
+ @Lazy
+ @Autowired
+ private SystemUserService systemUserService;
+
+ @Lazy
+ @Autowired
+ private SystemRoleService systemRoleService;
+
+ @Lazy
+ @Autowired
+ private SystemPermissionService systemPermissionService;
+
+ @Lazy
+ @Autowired
+ private CompanyService companyService;
+
+ /**
+ * 鏉冮檺澶勭悊
+ * @author Eva.Caesar Liu
+ * @date 2022/03/15 09:54
+ */
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
+ LoginUserInfo loginUserInfo = (LoginUserInfo)principalCollection.getPrimaryPrincipal();
+ // 璁剧疆鐢ㄦ埛瑙掕壊鍜屾潈闄�
+ SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
+ authorizationInfo.addRoles(loginUserInfo.getRoles());
+ authorizationInfo.addStringPermissions(loginUserInfo.getPermissions());
+ return authorizationInfo;
+ }
+
+ /**
+ * 璁よ瘉澶勭悊
+ * @author Eva.Caesar Liu
+ * @date 2022/03/15 09:54
+ */
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException{
+ // 鑾峰彇鐢ㄦ埛鍚�
+ String username = authenticationToken.getPrincipal().toString();
+ // 鏍规嵁鐢ㄦ埛鍚嶆煡璇㈢敤鎴峰璞�
+ SystemUser queryDto = new SystemUser();
+ queryDto.setUsername(username);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemUser user = systemUserService.findOne(queryDto);
+ if(user == null){
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝璐﹀彿鎴栧瘑鐮佷笉姝g‘锛�");
+ }
+ if( !Constants.equalsInteger(user.getType(),Constants.UserType.ZHUBO.getKey())){
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝闈炰富鎾处鎴疯韩浠斤紝濡傛湁鐤戦棶璇疯仈绯荤郴缁熺鐞嗗憳锛侊紒");
+ }
+ if(!Constants.equalsInteger(user.getStatus(),Constants.ZERO)){
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝璐﹀彿淇℃伅宸茶绂佺敤锛屽鏈夌枒闂鑱旂郴绯荤粺绠$悊鍛橈紒");
+ }
+ if(!user.getType().equals(Constants.UserType.SYSTEM)){
+ Company company = companyService.findById(user.getCompanyId());
+ if(company.getStatus().equals(Constants.ONE)){
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝浼佷笟淇℃伅宸茶绂佺敤锛屽鏈夌枒闂鑱旂郴绯荤粺绠$悊鍛橈紒");
+ }
+ if(DateUtil.compareDate(new Date(),DateUtil.addDaysToDate(company.getOepnValidDate(),1))<=Constants.ZERO){
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"浼佷笟璐﹀彿宸茶繃鏈燂紝濡傞渶缁х画浣跨敤锛岃鑱旂郴鎮ㄧ殑涓氬姟缁忕悊");
+ }
+ user.setCompany(company);
+ }
+ // 鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
+ List<SystemRole> roles = systemRoleService.findByUserId(user.getId());
+ List<SystemPermission> permissions = systemPermissionService.findByUserId(user.getId());
+ LoginUserInfo userInfo = LoginUserInfo.from(user, roles, permissions);
+ // 楠岃瘉鐢ㄦ埛
+ return new SimpleAuthenticationInfo(userInfo, user.getPassword(), this.getName());
+ }
+
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java
new file mode 100644
index 0000000..352aaed
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java
@@ -0,0 +1,113 @@
+package com.doumee.config.shiro;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.UnknownSessionException;
+import org.apache.shiro.session.mgt.SimpleSession;
+import org.apache.shiro.session.mgt.eis.SessionDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * 鑷畾涔塖hiro SessionDAO锛屽皢浼氳瘽淇℃伅瀛樺叆缂撳瓨涓�
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Data
+@Slf4j
+@Component
+public class ShiroSessionDAO implements SessionDAO {
+
+ private static final String KEY_PREFIX = "shiro:zhubo:session:";
+
+ @Autowired
+ private ShiroCache shiroCache;
+
+ private int expireTime = 60 * 60 * 24;
+
+ @Autowired
+ private ShiroTokenManager shiroTokenManager;
+
+ @Override
+ public Serializable create(Session session) {
+ if (session == null) {
+ log.error("session is null");
+ throw new UnknownSessionException("session is null");
+ }
+ Serializable sessionId = shiroTokenManager.build();
+ ((SimpleSession)session).setId(sessionId);
+ this.saveSession(session);
+ return sessionId;
+ }
+
+ @Override
+ public Session readSession(Serializable sessionId) throws UnknownSessionException{
+ if (sessionId == null) {
+ log.warn("session id is null");
+ return null;
+ }
+ if (sessionId instanceof String) {
+ // 瀵筍essionId杩涜楠岃瘉锛堝彲鐢ㄤ簬闃叉Session鎹曡幏銆佹毚鍔涙崟鎹夌瓑涓�绯诲垪瀹夊叏闂锛屾渶缁堝畨鍏ㄦ�у彇鍐充簬check濡備綍瀹炵幇锛�
+ shiroTokenManager.check((String) sessionId);
+ }
+ log.debug("read session from cache");
+ Session session = getSessionFromCache(sessionId);
+ if (session == null) {
+ throw new UnknownSessionException("There is no session with id [" + sessionId + "]");
+ }
+ return session;
+ }
+
+ @Override
+ public void update(Session session) throws UnknownSessionException {
+ this.saveSession(session);
+ }
+
+ @Override
+ public void delete(Session session) {
+ if (session != null && session.getId() != null) {
+ shiroCache.remove(KEY_PREFIX + session.getId());
+ }
+ }
+
+ @Override
+ public Collection<Session> getActiveSessions() {
+ Set<Session> sessions = new HashSet<>();
+ Set<Object> keys = shiroCache.keys();
+ if (keys != null && keys.size() > 0) {
+ Iterator iter = keys.iterator();
+ while(iter.hasNext()) {
+ sessions.add((Session) shiroCache.get(iter.next()));
+ }
+ }
+ return sessions;
+ }
+
+ private void saveSession(Session session) throws UnknownSessionException {
+ if (session == null || session.getId() == null) {
+ log.error("session or session id is null");
+ throw new UnknownSessionException("session or session id is null");
+ }
+ shiroCache.put(KEY_PREFIX + session.getId(), (SimpleSession)session, expireTime);
+ }
+
+ private Session getSessionFromCache (Serializable sessionId) {
+ Serializable object = shiroCache.get(KEY_PREFIX + sessionId);
+ Session session = null;
+ if (object != null) {
+ session = (Session)shiroCache.get(KEY_PREFIX + sessionId);
+ }
+ return session;
+ }
+
+ public void setExpireTime (int expireTime) {
+ this.expireTime = expireTime;
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java
new file mode 100644
index 0000000..bb2dd31
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java
@@ -0,0 +1,85 @@
+package com.doumee.config.shiro;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.session.mgt.SessionKey;
+import org.apache.shiro.web.servlet.Cookie;
+import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
+import org.apache.shiro.web.servlet.SimpleCookie;
+import org.apache.shiro.web.session.mgt.WebSessionManager;
+import org.apache.shiro.web.util.WebUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Serializable;
+
+/**
+ * 鑷畾涔変細璇濈鐞嗗櫒
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Slf4j
+public class ShiroSessionManager extends DefaultSessionManager implements WebSessionManager {
+
+ private static final String AUTH_TOKEN = "zhubo-auth-token";
+
+ @Override
+ protected void onStart(Session session, SessionContext context) {
+ super.onStart(session, context);
+ if (!WebUtils.isHttp(context)) {
+ log.debug("SessionContext argument is not Http compatible or does not have an Http request/response pair. No session ID cookie will be set.");
+ return;
+ }
+ HttpServletRequest request = WebUtils.getHttpRequest(context);
+ HttpServletResponse response = WebUtils.getHttpResponse(context);
+ Serializable sessionId = session.getId();
+ this.storeSessionId(sessionId, request, response);
+ request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
+ }
+
+ @Override
+ public Serializable getSessionId(SessionKey key) {
+ Serializable sessionId = super.getSessionId(key);
+ if (sessionId == null && WebUtils.isWeb(key)) {
+ ServletRequest servletRequest = WebUtils.getRequest(key);
+ if (!(servletRequest instanceof HttpServletRequest)) {
+ log.trace("Can not get sessionId from header, the request is not HttpServletRequest");
+ return null;
+ }
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+ // 浠巆ookie涓幏鍙栬璇�
+ javax.servlet.http.Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (javax.servlet.http.Cookie cookie : cookies) {
+ if (AUTH_TOKEN.equals(cookie.getName())) {
+ return cookie.getValue();
+ }
+ }
+ }
+ // 浠巋eader涓幏鍙栬璇�
+ return request.getHeader(AUTH_TOKEN);
+ }
+ return sessionId;
+ }
+ @Override
+ public boolean isServletContainerSessions() {
+ return false;
+ }
+
+ private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
+ if (currentId == null) {
+ String msg = "sessionId cannot be null when persisting for subsequent requests.";
+ throw new IllegalArgumentException(msg);
+ }
+ Cookie cookie = new SimpleCookie(AUTH_TOKEN);
+ cookie.setHttpOnly(false);
+ String idString = currentId.toString();
+ cookie.setValue(idString);
+ cookie.saveTo(request, response);
+ log.trace("Set session ID cookie for session with id {}", idString);
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java
new file mode 100644
index 0000000..d334adf
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java
@@ -0,0 +1,36 @@
+package com.doumee.config.shiro;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.shiro.codec.Base64;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Session搴忓垪鍖�
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+public class ShiroSessionSerializer implements RedisSerializer<Serializable> {
+
+ @Override
+ public byte[] serialize(Serializable obj) throws SerializationException {
+ if (obj == null) {
+ return new byte[0];
+ }
+ String sessionBase64 = Base64.encodeToString(SerializationUtils.serialize(obj));
+ return sessionBase64.getBytes(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public Serializable deserialize(byte[] bytes) throws SerializationException {
+ if (bytes == null || bytes.length == 0) {
+ return null;
+ }
+ String sessionString = new String(bytes, StandardCharsets.UTF_8);
+ byte[] sessionBytes = Base64.decode(sessionString);
+ return SerializationUtils.deserialize(sessionBytes);
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroToken.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroToken.java
new file mode 100644
index 0000000..74c09df
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroToken.java
@@ -0,0 +1,54 @@
+package com.doumee.config.shiro;
+
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鑷畾涔塗oken 锛屽鐞嗚璇佸拰鏉冮檺
+ * @author Eva.Caesar Liu
+ * @date 2022/04/18 18:12
+ */
+@Component
+public class ShiroToken extends UsernamePasswordToken {
+
+ /**
+ * 鍏徃ID
+ */
+ Integer companyId;
+ Boolean isDdLogin;
+ Boolean isWxLogin;
+
+ public ShiroToken() {
+ }
+ public ShiroToken(Integer companyId, String username, String password, boolean isDdLogin, boolean isWxLogin) {
+ super(username, password, false, (String)null);
+ this.companyId = companyId;
+ this.isDdLogin = isDdLogin;
+ this.isWxLogin = isWxLogin;
+ }
+
+ public Boolean getDdLogin() {
+ return isDdLogin;
+ }
+
+ public void setDdLogin(Boolean ddLogin) {
+ isDdLogin = ddLogin;
+ }
+
+
+ public Boolean getWxLogin() {
+ return isWxLogin;
+ }
+
+ public void setWxLogin(Boolean wxLogin) {
+ isWxLogin = wxLogin;
+ }
+
+ public Integer getCompanyId() {
+ return companyId;
+ }
+
+ public void setCompanyId(Integer companyId) {
+ this.companyId = companyId;
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java
new file mode 100644
index 0000000..ba35da6
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java
@@ -0,0 +1,25 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.exception.UnSafeSessionException;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+
+/**
+ * 榛樿Token绠$悊鍣�
+ * @author Eva.Caesar Liu
+ * @date 2023/04/17 12:11
+ */
+@Component
+public class ShiroTokenManager {
+
+ String build() {
+ return UUID.randomUUID().toString();
+ }
+
+ void check(String token) throws UnSafeSessionException {
+ if (token == null || token.length() != 36) {
+ throw new UnSafeSessionException();
+ }
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerConfig.java b/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerConfig.java
new file mode 100644
index 0000000..34caca8
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerConfig.java
@@ -0,0 +1,88 @@
+package com.doumee.config.swagger;
+
+import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.RequestHandler;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+
+import java.util.function.Predicate;
+
+/**
+ * Swagger閰嶇疆
+ * @author Eva.Caesar Liu
+ * @date 2022/03/11 10:24
+ */
+@Configuration
+@EnableOpenApi
+@EnableKnife4j
+public class SwaggerConfig {
+
+ @Value("${swagger.host:}")
+ private String host;
+
+ @Value("${swagger.title:鎺ュ彛鏂囨。}")
+ private String title;
+
+ @Value("${swagger.description:}")
+ private String description;
+
+ @Value("${project.version:}")
+ private String version;
+
+ @Bean
+ public ApiInfo getApiInfo() {
+ return new ApiInfoBuilder()
+ .title(title)
+ .description(description)
+ .version(version)
+ .build();
+ }
+ @Bean
+ public Docket getDocket() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(this.getApiInfo()).groupName("銆愭帴鍙PI銆�")
+ .host(host)
+ .select()
+ .apis( basePackage("com.doumee.api.system;com.doumee.api.business;"))
+ // 璁剧疆闇�瑕佽鎵弿鐨勭被锛岃繖閲岃缃负娣诲姞浜咢Api娉ㄨВ鐨勭被
+// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ /**
+ * 閲嶅啓basePackage鏂规硶锛屼娇鑳藉瀹炵幇澶氬寘璁块棶锛屽鍒惰创涓婂幓
+ * @author teavamc
+ * @date 2019/1/26
+ * @return com.google.common.base.Predicate<springfox.documentation.RequestHandler>
+ */
+ public static Predicate<RequestHandler> basePackage(String basePackage) {
+ return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
+ }
+
+ private static Function<Class<?>, Boolean> handlerPackage(String basePackage) {
+ return input -> {
+ // 寰幆鍒ゆ柇鍖归厤
+ for (String strPackage : basePackage.split(";")) {
+ boolean isMatch = input.getPackage().getName().startsWith(strPackage);
+ if (isMatch) {
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+ private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
+ return Optional.fromNullable(input.declaringClass());
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java b/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java
new file mode 100644
index 0000000..8fd55c6
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java
@@ -0,0 +1,45 @@
+package com.doumee.config.swagger;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Swagger鎷︽埅鍣�
+ * @author Eva.Caesar Liu
+ * @date 2022/04/18 18:12
+ */
+@Slf4j
+@Component
+public class SwaggerInterceptor implements HandlerInterceptor {
+
+ @Value("${swagger.enabled:false}")
+ private Boolean enabledSwagger;
+
+ @Value("${swagger.redirect-uri:/}")
+ private String redirectUri;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ if (!enabledSwagger) {
+ String uri = request.getContextPath();
+ if (StringUtils.isNotBlank(redirectUri))
+ uri = request.getContextPath() + redirectUri;
+ if (StringUtils.isBlank(uri))
+ uri = "/";
+ try {
+ response.sendRedirect(uri);
+ } catch (IOException e) {
+ log.error(String.format("Redirect to '%s' for swagger throw an exception : %s", uri, e.getMessage()), e);
+ }
+ return Boolean.FALSE;
+ }
+ return Boolean.TRUE;
+ }
+}
diff --git a/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java b/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java
new file mode 100644
index 0000000..ca3aa45
--- /dev/null
+++ b/server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java
@@ -0,0 +1,22 @@
+package com.doumee.config.swagger;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Swagger鎷︽埅鍣ㄩ厤缃�
+ * @author Eva.Caesar Liu
+ * @date 2022/04/18 18:12
+ */
+@Configuration
+public class SwaggerInterceptorConfig implements WebMvcConfigurer {
+
+ @Autowired
+ private SwaggerInterceptor swaggerInterceptor;
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(swaggerInterceptor).addPathPatterns("/swagger-ui.html", "/doc.html");
+ }
+}
diff --git a/server/zhubo/src/main/resources/application.yml b/server/zhubo/src/main/resources/application.yml
new file mode 100644
index 0000000..4fb560e
--- /dev/null
+++ b/server/zhubo/src/main/resources/application.yml
@@ -0,0 +1,64 @@
+# 椤圭洰淇℃伅閰嶇疆
+project:
+ name: 棰勯�夋竻鍗曟煡璇�
+ version: 1.0.0
+ env: development
+# env: production
+server:
+ port: 10024
+
+spring:
+# application:
+# name: doumeemes
+ profiles:
+ active: pro
+
+ # JSON杩斿洖閰嶇疆
+ jackson:
+ # 榛樿鏃跺尯
+ time-zone: GMT+8
+ # 榛樿鏃ユ湡鏍煎紡鍖�
+ date-format: yyyy-MM-dd HH:mm:ss
+ servlet:
+ multipart:
+ max-file-size: 200MB
+ max-request-size: 200MB
+ enabled: true
+# MyBatis閰嶇疆
+mybatis-plus:
+ mapper-locations: classpath*:/mappers/**/*.xml
+ configuration:
+ map-underscore-to-camel-case: true
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+# 缂撳瓨鍐呭璁剧疆
+cache:
+ session:
+ # 浼氳瘽杩囨湡鏃堕暱(s)
+ expire: 18000
+ captcha:
+ # 楠岃瘉鐮佽繃鏈熸椂闀�(s)
+ expire: 300
+
+# 璺熻釜鏃ュ織
+trace:
+ # 寮�鍚櫤鑳借窡韪ā寮�
+ smart: true
+ # 鎺掗櫎璺熻釜鐨刄RL姝e垯
+ exclude-patterns: .+/list[a-zA-Z0-9\-\_]*$, .+/tree[a-zA-Z0-9\-\_]*$, .+/page[a-zA-Z0-9\-\_]*$, .+/all[a-zA-Z0-9\-\_]*$, /swagger-resources.*
+
+# 鏃ュ織閰嶇疆
+logback:
+ level: INFO
+ appender: ${project.env}
+# dao灞傜殑鏃ュ織璁剧疆涓篸ebug锛屾柟渚挎煡鐪媠ql
+logging:
+ level:
+ doumeemes.dao: debug
+
+knife4j:
+ enable: true
+ basic:
+ enable: true
+ username: admin
+ password: 111111
\ No newline at end of file
--
Gitblit v1.9.3