jiangping
2023-09-21 d5bdf4cd56be6bd0e7afa81d75c35a9f15ae2a40
主播接口
已添加25个文件
已修改11个文件
已重命名1个文件
1868 ■■■■■ 文件已修改
.idea/compiler.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/encodings.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/misc.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/company/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/company/src/main/java/com/doumee/config/shiro/ShiroConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/company/src/main/java/com/doumee/config/shiro/ShiroRealm.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/company/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/pom.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/service/src/main/java/com/doumee/service/business/impl/BaseDataServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/service/src/main/java/com/doumee/service/business/impl/BaseGoodsServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/service/src/main/java/com/doumee/service/business/impl/GoodsServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/pom.xml 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/Main.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/ZhuboApplication.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/BaseController.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/business/BrandController.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/business/CateBudgetController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/business/CategoryController.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/business/GoodsController.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/business/WebParamController.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/api/system/SystemController.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCache.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroConfig.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroRealm.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroToken.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerConfig.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/zhubo/src/main/resources/application.yml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.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>
.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>
.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>
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;
    }
    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;
    }
}
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;
    }
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(),"对不起,账号或密码不正确!");
        }
        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)){
server/company/src/main/resources/application.yml
@@ -11,7 +11,7 @@
#  application:
#    name: doumeemes
  profiles:
    active: dev
    active: pro
  # JSON返回配置
  jackson:
server/pom.xml
@@ -13,6 +13,7 @@
    <module>platform</module>
    <module>service</module>
    <module>company</module>
    <module>zhubo</module>
  </modules>
  <parent>
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);
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;
    }
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);
    }
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>
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!");
    }
}
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();
    }
}
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 ä½¿ç”¨","隔开的多个ID
     * @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;
    }
}
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));
    }
}
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));
    }
}
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));
    }
}
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());
    }
}
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("操作成功");
    }
}
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());
    }
}
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;
    }
}
server/zhubo/src/main/java/com/doumee/config/shiro/ShiroAuthFilter2.java
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";
    }
}
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;
/**
 * è‡ªå®šä¹‰Shiro 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;
        }
    }
}
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);
        // åˆ é™¤å¤±æ•ˆçš„session
        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;
    }
}
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());
    }
}
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;
/**
 * è‡ªå®šä¹‰Realm,处理认证和权限
 * @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(),"对不起,账号或密码不正确!");
        }
        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());
    }
}
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;
/**
 * è‡ªå®šä¹‰Shiro 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) {
            // å¯¹SessionId进行验证(可用于防止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;
    }
}
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;
            // ä»Žcookie中获取认证
            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();
                    }
                }
            }
            // ä»Žheader中获取认证
            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);
    }
}
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);
    }
}
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;
/**
 * è‡ªå®šä¹‰Token ï¼Œå¤„理认证和权限
 * @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;
    }
}
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();
        }
    }
}
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("【接口API】")
                .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());
    }
}
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;
    }
}
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");
    }
}
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
  # æŽ’除跟踪的URL正则
  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层的日志设置为debug,方便查看sql
logging:
  level:
    doumeemes.dao: debug
knife4j:
  enable: true
  basic:
    enable: true
    username: admin
    password: 111111