xiaoyong931011
2023-07-14 4489b69c7904fdfb4d46e110e178a969bfd82985
服务号初始化
15 files modified
3 files added
451 ■■■■ changed files
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/runner/FebsStartedUpRunner.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/CheckoutUtil.java 85 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallGoods.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/controller/AutoReplyController.java 73 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/util/WechatConfigure.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/util/WechatEventUtil.java 187 ●●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 37 ●●●● patch | view | raw | blame | history
src/main/resources/application.yml 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/error/403.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/error/404.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/error/500.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/layout.html 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/login.html 4 ●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/goods/goodsAddNew.html 5 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/goods/goodsUpdateNew.html 39 ●●●● patch | view | raw | blame | history
src/main/resources/templates/index.html 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -31,5 +31,6 @@
        registration.excludePathPatterns("/api/leader/noLoginLeaderTitle");
        registration.excludePathPatterns("/api/xcxPay/wxpayCallback");
        registration.excludePathPatterns("/api/xcxPay/rechargeCallBack");
        registration.excludePathPatterns("/api/wechat/reply/event");
    }
}
src/main/java/cc/mrbird/febs/common/properties/XcxProperties.java
@@ -14,6 +14,8 @@
    private String xcxAppid;
    private String xcxSecret;
    //微信
    private String wechatToken;
    private String wecharPaynotifyUrl;
src/main/java/cc/mrbird/febs/common/runner/FebsStartedUpRunner.java
@@ -63,7 +63,7 @@
            log.info("/ /`  / / \\ | |\\/| | |_) | |   | |_   | |  | |_  ");
            log.info("\\_\\_, \\_\\_/ |_|  | |_|   |_|__ |_|__  |_|  |_|__ ");
            log.info("                                                      ");
            log.info("钱阿姨 权限系统启动完毕,地址:{}", url);
            log.info("药王谷铺子 权限系统启动完毕,地址:{}", url);
            boolean auto = febsProperties.isAutoOpenBrowser();
            if (auto && StringUtils.equalsIgnoreCase(active, FebsConstant.DEVELOP)) {
src/main/java/cc/mrbird/febs/common/utils/CheckoutUtil.java
New file
@@ -0,0 +1,85 @@
package cc.mrbird.febs.common.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class CheckoutUtil {
    // 与接口配置信息中的Token要一致
    private static String token = "ywgpzfwh";
    /**
     * 验证签名
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[] { token, timestamp, nonce };
        // 将token、timestamp、nonce三个参数进行字典序排序
        // Arrays.sort(arr);
        sort(arr);
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        MessageDigest md = null;
        String tmpStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        content = null;
        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }
    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }
    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        String s = new String(tempArr);
        return s;
    }
    public static void sort(String a[]) {
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[j].compareTo(a[i]) < 0) {
                    String temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }
}
src/main/java/cc/mrbird/febs/mall/entity/MallGoods.java
@@ -70,7 +70,7 @@
    private Integer isSku;
    /**
     * 是否普通商品 1-普通商品 2-套餐
     * 是否普通商品 1-普通商品 2-积分商品 3-双卷商品
     */
    private Integer isNormal;
src/main/java/cc/mrbird/febs/pay/controller/AutoReplyController.java
New file
@@ -0,0 +1,73 @@
package cc.mrbird.febs.pay.controller;
import cc.mrbird.febs.common.properties.XcxProperties;
import cc.mrbird.febs.common.utils.SpringContextHolder;
import cc.mrbird.febs.pay.util.WechatEventUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
 * 微信事件通知 - 控制层
 */
@Slf4j
@RestController
@RequestMapping(value = "/api/wechat/reply")
public class AutoReplyController {
    private final XcxProperties xcxProperties = SpringContextHolder.getBean(XcxProperties.class);
//    @Value("${wechat.appId}")
//    private String wechatAppId;
//
//    @Value("${wechat.appSecret}")
//    private String wechatAppSecret;
//
//    // 这个Token就是微信后台 服务器配置 中的Token
//    @Value("${wechat.token}")
//    private String wechatToken;
    /**
     * 服务器校验
     * @param req 请求
     * @return 校验结果
     */
    @GetMapping("/event")
    public String verification(HttpServletRequest req) {
        return WechatEventUtil.verification(req, xcxProperties.getWechatToken());
    }
    /**
     * 消息事件
     * @param req 请求
     * @return 结果
     */
    @PostMapping("/event")
    public void messageEvent(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        String message = "success";
        PrintWriter out = resp.getWriter();
        try {
            String messageEvent = WechatEventUtil.messageEvent(req);
            if(messageEvent != null) {
                message = messageEvent;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            log.info("消息事件:"+message);
            out.write(message);
            if (out != null) {
                out.close();
            }
        }
    }
}
src/main/java/cc/mrbird/febs/pay/util/WechatConfigure.java
@@ -6,7 +6,7 @@
    public static final String SEND_INFO_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
    public static final String WX_ACCESS_TOKEN_REDIS_KEY = "access_token";
    public static final String WX_ACCESS_TOKEN_REDIS_KEY = "ywgpz_access_token";
    public static final String BAIDU_ACCESS_TOKEN_REDIS_KEY = "bd_access_token";
    public static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
src/main/java/cc/mrbird/febs/pay/util/WechatEventUtil.java
New file
@@ -0,0 +1,187 @@
package cc.mrbird.febs.pay.util;
import org.dom4j.io.SAXReader;
import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import org.dom4j.Document;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.util.*;
/**
 * <pre>
 * 微信消息工具类:事件通知、自动回复、
 * </pre>
 *
 * @author shenshao
 */
public class WechatEventUtil {
    private static Logger log = LoggerFactory.getLogger(WechatEventUtil.class);
    /**
     * 公众号《事件通知》服务器校验
     *
     * @param req 请求
     * @return 校验结果
     */
    public static String verification(HttpServletRequest req, String wechatToken) {
        // 接收微信服务器发送请求时传递过来的参数
        String signature = req.getParameter("signature");
        String timestamp = req.getParameter("timestamp");
        String nonce = req.getParameter("nonce");
        // 将token、timestamp、nonce三个参数进行字典序排序,并拼接为一个字符串
        String sortStr = sort(wechatToken, timestamp, nonce);
        // 字符串进行shal加密
        String mySignature = shal(sortStr);
        // 校验微信服务器传递过来的签名 和  加密后的字符串是否一致, 若一致则签名通过
        if (!"".equals(signature) && !"".equals(mySignature) && signature.equals(mySignature)) {
            log.info("-----签名校验通过-----");
            return req.getParameter("echostr");
        } else {
            log.error("-----校验签名失败-----");
            return "";
        }
    }
    /**
     * 消息事件监控:关注、取消关注等事件
     * @param req
     * @return
     */
    public static String messageEvent(HttpServletRequest req) {
        String result = null;
        Map<String, String> map = xmlToMap(req);
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        String msgType = map.get("MsgType");
        String content = map.get("Content");
        String eventType = map.get("Event");
        log.info("事件处理:event:{}、msgType:{}、toUserName:{}、fromUserName:{}", eventType, msgType, toUserName, fromUserName);
        if ("event".equals(msgType)) {
            if ("subscribe".equals(eventType)) {
                result = imgTextMsg(toUserName, fromUserName, "新用户注册", "仅限上海地区手机号用户", "图片地址", "点击后跳转的路径");
                log.info("新增关注事件:toUserName{}、fromUserName{}", toUserName, fromUserName);
            } else if ("unsubscribe".equals(eventType)) {
                log.info("取消关注事件:toUserName{}、fromUserName{}", toUserName, fromUserName);
            }
        }
        return result;
    }
    /**
     * 组装图文消息(懒得封装对象转XML方法,直接字符串拼装,大伙勿喷)
     * @param toUserName    开发者微信号
     * @param fromUserName  接收人openId
     * @param title         图文消息上的备注
     * @param description   图文消息上的备注
     * @param picUrl        图文消息上的图片
     * @param url           点击图文消息跳转的路径
     * @return
     */
    public static String imgTextMsg(String toUserName, String fromUserName, String title, String description, String picUrl, String url){
        return "<xml>"
                + "<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"
                + "<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"
                + "<CreateTime>"+new Date().getTime()+"</CreateTime>"
                + "<MsgType><![CDATA[news]]></MsgType>"
                + "<ArticleCount>1</ArticleCount>"
                + "<Articles>"
                + "<item>"
                + "<Title><![CDATA["+title+"]]></Title>"
                + "<Description><![CDATA["+description+"]]></Description>"
                + "<PicUrl><![CDATA["+picUrl+"]]></PicUrl>"
                + "<Url><![CDATA["+url+"]]></Url>"
                + "</item>"
                + "</Articles>"
                + "</xml>";
    }
    /**
     * 解析微信发来的请求(XML)
     *
     * @param request 请求
     * @return map
     * @throws Exception 异常
     */
    public static Map<String, String> xmlToMap(HttpServletRequest request) {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<>(16);
        // 从request中取得输入流
        try (InputStream inputStream = request.getInputStream()) {
            System.out.println("获取输入流");
            // 读取输入流
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            // 得到xml根元素
            Element root = document.getRootElement();
            // 得到根元素的所有子节点
            List<Element> elementList = root.elements();
            // 遍历所有子节点
            for (Element e : elementList) {
                System.out.println(e.getName() + " | " + e.getText());
                map.put(e.getName(), e.getText());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
    /**
     * 参数排序
     *
     * @param token     服务器配置,自定义的Token
     * @param timestamp timestamp
     * @param nonce     nonce
     * @return 排序后拼接字符串
     */
    public static String sort(String token, String timestamp, String nonce) {
        String[] strArray = {token, timestamp, nonce};
        Arrays.sort(strArray);
        StringBuilder sb = new StringBuilder();
        for (String str : strArray) {
            sb.append(str);
        }
        return sb.toString();
    }
    /**
     * 字符串进行shal加密
     *
     * @param str 字符串
     * @return 密文
     */
    public static String shal(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            StringBuilder hexString = new StringBuilder();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}
src/main/resources/application-dev.yml
@@ -15,14 +15,14 @@
      datasource:
        # 数据源-1,名称为 base
        base:
#          username: ct_test
#          password: 123456
#          driver-class-name: com.mysql.cj.jdbc.Driver
#          url: jdbc:mysql://120.27.238.55:3306/db_pingtuan?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
          username: db_mall_qianayi
          password: db_mall_qianayi123!@#123
          username: ct_test
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://121.37.162.173:3306/db_mall_qianayi?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
          url: jdbc:mysql://120.27.238.55:3406/db_yaowanggu?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
#          username: db_mall_qianayi
#          password: db_mall_qianayi123!@#123
#          driver-class-name: com.mysql.cj.jdbc.Driver
#          url: jdbc:mysql://121.37.162.173:3306/db_mall_qianayi?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
#          username: db_mall
#          password: mall!@#123
#          driver-class-name: com.mysql.cj.jdbc.Driver
@@ -30,13 +30,13 @@
  redis:
    # Redis数据库索引(默认为 0)
    database: 8
    database: 11
    # Redis服务器地址
    host: 121.37.162.173
    host: 120.27.238.55
    # Redis服务器连接端口
    port: 6379
    port: 6479
    # Redis 密码
    password: d32ncxe@i3#!dV
    password: d3y6dsdl;f.327
    lettuce:
      pool:
        # 连接池中的最小空闲连接
@@ -50,10 +50,10 @@
    # 连接超时时间(毫秒)
    timeout: 5000
  rabbitmq:
    host: 121.37.162.173
    host: 120.27.238.55
    port: 5672
    username: hibit
    password: hibit123
    username: ct_rabbit
    password: 123456
    publisher-confirm-type: correlated
pay:
@@ -69,16 +69,17 @@
xcx:
  wechar_login_url: https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
  xcx_appid: wxfb1acf504eb9d058
  xcx_secret: 7ee226a964b1be7cfb96f5e0dc739c44
  xcx_appid: wx052716b1a388b13c
  xcx_secret: e7cf355e7234f035d8fea6a3a19513b9
  debug: false
  wecharPaynotifyUrl: http://qianayi.csxuncong.com/api/xcxPay/wxpayCallback
  wecharRechargePaynotifyUrl: http://qianayi.csxuncong.com/api/xcxPay/rechargeCallBack
  wecharPaynotifyUrl: http://ywgpz.csxuncong.com/api/xcxPay/wxpayCallback
  wecharRechargePaynotifyUrl: http://ywgpz.csxuncong.com/api/xcxPay/rechargeCallBack
  certLocalPath: /home/qianayiCert/apiclient_cert.p12
  wecharpayMchid: 1638095860
  wecharpaySecret: QIANAYIZONGZI1234567899876543212
  gaodeKey: 95ede7157929f5f6b6c758971be924b1
  serviceName: yiyuanshucai
  wechatToken:ywgpzfwh
system:
  job: true
src/main/resources/application.yml
@@ -1,5 +1,5 @@
server:
  port: 8085
  port: 8184
  tomcat:
    uri-encoding: utf-8
src/main/resources/templates/error/403.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>钱阿姨 权限系统</title>
    <title>药王谷铺子 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
src/main/resources/templates/error/404.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>钱阿姨 权限系统</title>
    <title>药王谷铺子 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
src/main/resources/templates/error/500.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>钱阿姨 权限系统</title>
    <title>药王谷铺子 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
src/main/resources/templates/febs/views/layout.html
@@ -64,7 +64,7 @@
        <div class="layui-side-scroll">
            <div class="layui-logo" style="cursor: pointer">
                <img data-th-src="@{febs/images/logo.png}">
                <span>钱阿姨 权限系统</span>
                <span>药王谷铺子 权限系统</span>
            </div>
            <script
                    type="text/html"
src/main/resources/templates/febs/views/login.html
@@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>钱阿姨 权限系统</title>
    <title>药王谷铺子 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
@@ -19,7 +19,7 @@
        <div class="layui-container">
            <div class="layui-row">
                <div class="layui-col-xs12 layui-col-lg4 layui-col-lg-offset4 febs-tc">
                    <div class="layui-logo"><span><b>钱阿姨</b> 权限系统</span></div>
                    <div class="layui-logo"><span><b>药王谷铺子</b> 权限系统</span></div>
                </div>
                <div class="layui-col-xs12 layui-col-lg4 layui-col-lg-offset4" id="login-div">
                    <div class="layui-form" lay-filter="login-form">
src/main/resources/templates/febs/views/modules/goods/goodsAddNew.html
@@ -97,8 +97,9 @@
                                            <label class="layui-form-label febs-form-item-require">商品类型</label>
                                            <div class="layui-input-block">
                                                <select name="isNormal" class="goods-type" lay-filter="goods-type-select">
                                                    <option value="1">普通商品区</option>
<!--                                                    <option value="2">套餐区</option>-->
                                                    <option value="1">普通商品</option>
                                                    <option value="2">积分商品</option>
                                                    <option value="2">双卷商品</option>
                                                </select>
                                            </div>
                                        </div>
src/main/resources/templates/febs/views/modules/goods/goodsUpdateNew.html
@@ -106,30 +106,31 @@
                                            <div class="layui-input-block">
                                                <select name="isNormal" class="goods-type"
                                                        lay-filter="goods-type-select">
                                                    <option value="1">普通商品区</option>
<!--                                                    <option value="2">套餐区</option>-->
                                                    <option value="1">普通商品</option>
                                                    <option value="2">积分商品</option>
                                                    <option value="2">双卷商品</option>
                                                </select>
                                            </div>
                                        </div>
                                        <div class="layui-form-item febs-hide tc-set">
                                            <label class="layui-form-label">静态倍数</label>
                                            <div class="layui-input-block">
                                                <input type="text" name="staticMulti" placeholder="请输入静态倍数"
                                                       autoComplete="off" class="layui-input">
                                                <div class="layui-form-mid layui-word-aux">支付后,赠送(购买金额*静态倍数)的赠送积分
                                                </div>
                                            </div>
                                        </div>
<!--                                        <div class="layui-form-item febs-hide tc-set">-->
<!--                                            <label class="layui-form-label">静态倍数</label>-->
<!--                                            <div class="layui-input-block">-->
<!--                                                <input type="text" name="staticMulti" placeholder="请输入静态倍数"-->
<!--                                                       autoComplete="off" class="layui-input">-->
<!--                                                <div class="layui-form-mid layui-word-aux">支付后,赠送(购买金额*静态倍数)的赠送积分-->
<!--                                                </div>-->
<!--                                            </div>-->
<!--                                        </div>-->
                                        <div class="layui-form-item febs-hide tc-set">
                                            <label class="layui-form-label">静态占比(%)</label>
                                            <div class="layui-input-block">
                                                <input type="text" name="staticProp" placeholder="请输入静态占比"
                                                       autoComplete="off" class="layui-input">
                                                <div class="layui-form-mid layui-word-aux">所有套餐静态占比相加应等于100%</div>
                                            </div>
                                        </div>
<!--                                        <div class="layui-form-item febs-hide tc-set">-->
<!--                                            <label class="layui-form-label">静态占比(%)</label>-->
<!--                                            <div class="layui-input-block">-->
<!--                                                <input type="text" name="staticProp" placeholder="请输入静态占比"-->
<!--                                                       autoComplete="off" class="layui-input">-->
<!--                                                <div class="layui-form-mid layui-word-aux">所有套餐静态占比相加应等于100%</div>-->
<!--                                            </div>-->
<!--                                        </div>-->
                                    </div>
                                    <div class="layui-tab-item">
src/main/resources/templates/index.html
@@ -3,7 +3,7 @@
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="utf-8">
    <title>钱阿姨 权限系统</title>
    <title>药王谷铺子 权限系统</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">