xiaoyong931011
2023-07-31 578437af52e1cb25c661efd207273bf49a6e7773
商品、订单
8 files modified
21 files added
2133 ■■■■■ changed files
pom.xml 16 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/FebsShiroApplication.java 36 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/OssUtils.java 32 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/AdminMallGoodsController.java 179 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ViewAdminMallGoodsController.java 80 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/AddMallGoodsDto.java 61 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/MallGoodsUpdateDto.java 59 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/dto/MallOrderInfoDto.java 33 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/MallGoods.java 46 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/MallOrderInfo.java 58 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/MallOrderItem.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/entity/PlatformBanner.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/DappFundFlowDao.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/MallGoodsMapper.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/mapper/MallOrderInfoMapper.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/IAdminMallGoodsService.java 33 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/AdminMallGoodsService.java 144 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/DappMemberServiceImpl.java 9 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/AdminMallMoneyFlowVo.java 27 ●●●●● patch | view | raw | blame | history
src/main/resources/USDT.sol 2 ●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 8 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/DappFundFlowDao.xml 12 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/dapp/MallGoodsMapper.xml 84 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/goods/goodsAddNew.html 271 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/goods/goodsList.html 222 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/goods/goodsUpdateNew.html 300 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/goods/orderList.html 234 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/goods/orderMoneyFlow.html 62 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/index.html 2 ●●●●● patch | view | raw | blame | history
pom.xml
@@ -21,10 +21,24 @@
        <mybatis.plus.version>3.3.1</mybatis.plus.version>
        <swagger.ui>2.9.2</swagger.ui>
        <tomcat.version>9.0.31</tomcat.version>
        <hutool.version>5.3.1</hutool.version>
        <hutool.version>5.7.22</hutool.version>
        <aliyun-oss.version>3.8.0</aliyun-oss.version>
    </properties>
    <dependencies>
        <!--        图片压缩-->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>${aliyun-oss.version}</version>
        </dependency>
        <dependency>
            <groupId>taobao</groupId>
            <artifactId>taobao-sdk</artifactId>
src/main/java/cc/mrbird/febs/FebsShiroApplication.java
@@ -43,24 +43,24 @@
                .run(args);
    }
    @PostConstruct
    public void systemConstantsInit() {
        DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                DataDictionaryEnum.FEE_ADDRESS_KEY.getType(),
                DataDictionaryEnum.FEE_ADDRESS_KEY.getCode());
        String key = dataDictionaryCustom.getCode();
        key = StrUtil.toCamelCase(key);
        String value = dataDictionaryCustom.getValue();
        try {
            Field field = systemConstants.getClass().getDeclaredField(key);
            field.set(systemConstants, value);
            AppContants.FEE_ADDRESS_KEY.put("feeAddressKey",systemConstants.getFeeAddressKey());
            dataDictionaryCustom.setValue("isReady");
            dataDictionaryCustomMapper.updateById(dataDictionaryCustom);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//    @PostConstruct
//    public void systemConstantsInit() {
//        DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
//                DataDictionaryEnum.FEE_ADDRESS_KEY.getType(),
//                DataDictionaryEnum.FEE_ADDRESS_KEY.getCode());
//        String key = dataDictionaryCustom.getCode();
//        key = StrUtil.toCamelCase(key);
//        String value = dataDictionaryCustom.getValue();
//        try {
//            Field field = systemConstants.getClass().getDeclaredField(key);
//            field.set(systemConstants, value);
//            AppContants.FEE_ADDRESS_KEY.put("feeAddressKey",systemConstants.getFeeAddressKey());
//            dataDictionaryCustom.setValue("isReady");
//            dataDictionaryCustomMapper.updateById(dataDictionaryCustom);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//    @PostConstruct
src/main/java/cc/mrbird/febs/common/utils/OssUtils.java
New file
@@ -0,0 +1,32 @@
package cc.mrbird.febs.common.utils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Decoder;
import java.io.ByteArrayInputStream;
@Slf4j
public class OssUtils {
    private static String        END_POINT         = "https://oss-cn-hangzhou.aliyuncs.com";
    private static String       ACCESS_KEY_ID     = "LTAI4GBuydqbJ5bTsDP97Lpd";
    private static String       ACCESS_KEY_SECRET = "vbCjQtPxABWjqtUlQfzjlA0qAY96fh";
    private static String         bucket_name       = "https://excoin.oss-cn-hangzhou.aliyuncs.com";
    public static boolean uploadFileWithBase64(String base64, String pathName) {
        ByteArrayInputStream stream = null;
        try {
            OSS ossClient = new OSSClientBuilder().build(END_POINT, ACCESS_KEY_ID,ACCESS_KEY_SECRET);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(base64);
            stream = new ByteArrayInputStream(bytes);
            ossClient.putObject("excoin", pathName, stream);
            return true;
        } catch (Exception e) {
            log.error("#上传失败:{}#", e);
            return false;
        }
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/AdminMallGoodsController.java
New file
@@ -0,0 +1,179 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.annotation.ControllerEndpoint;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.utils.OssUtils;
import cc.mrbird.febs.dapp.dto.AddMallGoodsDto;
import cc.mrbird.febs.dapp.dto.MallGoodsUpdateDto;
import cc.mrbird.febs.dapp.dto.MallOrderInfoDto;
import cc.mrbird.febs.dapp.entity.MallGoods;
import cc.mrbird.febs.dapp.entity.MallOrderInfo;
import cc.mrbird.febs.dapp.service.IAdminMallGoodsService;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/admin/goods")
public class AdminMallGoodsController extends BaseController {
    private final IAdminMallGoodsService adminMallGoodsService;
    /**
     *  图片上传
     * @return
     */
    @PostMapping(value = "/uploadFileBase64")
    @ControllerEndpoint(operation = "图片上传", exceptionMessage = "上传失败")
    public Map<String,Object> uploadFileBase64(@RequestBody @Validated MultipartFile file) {
        if (file.isEmpty()) {
            new FebsResponse().message("上传文件为空");
        }
        String base64EncoderImg = "";
        BASE64Encoder base64Encoder =new BASE64Encoder();
        List<String> imageFuffixStr = StrUtil.splitTrim(file.getOriginalFilename(), ".");
        String imageFuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        if("jpg".equals(imageFuffixStr.get(1))){
            try {
                //输出到BufferedImage
                BufferedImage bufferedImage = Thumbnails.of(file.getInputStream())
                        // 图片大小(长宽)压缩比例 从0-1,1表示原图
                        .scale(1f)
                        // 图片质量压缩比例 从0-1,越接近1质量越好
                        .outputQuality(0.5f)
                        .asBufferedImage();
                //对内存中的图片文件进行Base64处理
                ByteArrayOutputStream newBaos = new ByteArrayOutputStream();//io流
                ImageIO.write(bufferedImage, "jpg", newBaos);//写入流中
                byte[] bytes = newBaos.toByteArray();//转换成字节
                base64EncoderImg = base64Encoder.encode(bytes);
//            base64EncoderImg = URLEncoder.encode(new BASE64Encoder().encode(bytes), "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            try {
                base64EncoderImg = base64Encoder.encode(file.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //文件加密
//        String imageFuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
//      String imageFuffix = ".png";
        String imageNames = System.currentTimeMillis() + IdUtil.simpleUUID() + imageFuffix;
        String imageName = "uploadeFile/" + imageNames;
        OssUtils.uploadFileWithBase64(base64EncoderImg, imageName);
        String bucket_name ="https://excoin.oss-cn-hangzhou.aliyuncs.com";
        String url = bucket_name + "/" + imageName;
        Map<String,Object> map = new HashMap<String,Object>();
        Map<String,Object> map2 = new HashMap<String,Object>();
        map.put("code",0);//0表示成功,1失败
        map.put("msg","上传成功");//提示消息
        map.put("data",map2);
        map2.put("src",url);//图片url
        map2.put("title",imageNames);//图片名称,这个会显示在输入框里
        return map;
    }
    /**
     * 商品列表
     * @param mallGoods
     * @param request
     * @return
     */
    @GetMapping("goodsList")
    public FebsResponse getGoodsList(MallGoods mallGoods, QueryRequest request) {
        Map<String, Object> data = getDataTable(adminMallGoodsService.getCategoryListInPage(mallGoods, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 商品-新增
     */
    @PostMapping("addMallGoods")
    @ControllerEndpoint(operation = " 商品-新增", exceptionMessage = "新增失败")
    public FebsResponse addMallGoods(@RequestBody @Valid AddMallGoodsDto addMallGoodsDto) {
        return adminMallGoodsService.addMallGoods(addMallGoodsDto);
    }
    /**
     * 商品-上架
     */
    @GetMapping("upMallGoods/{id}")
    @ControllerEndpoint(operation = " 商品-上架", exceptionMessage = "上架失败")
    public FebsResponse upMallGoods(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminMallGoodsService.upMallGoods(id);
    }
    /**
     * 商品-下架
     */
    @GetMapping("downMallGoods/{id}")
    @ControllerEndpoint(operation = " 商品-下架", exceptionMessage = "下架失败")
    public FebsResponse downMallGoods(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminMallGoodsService.downMallGoods(id);
    }
    /**
     * 商品-删除
     */
    @GetMapping("delMallGoods/{id}")
    @ControllerEndpoint(operation = " 商品-删除", exceptionMessage = "删除失败")
    public FebsResponse delMallGoods(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminMallGoodsService.delMallGoods(id);
    }
    /**
     * 商品-编辑
     */
    @PostMapping("updateMallGoods")
    @ControllerEndpoint(operation = "商品-编辑", exceptionMessage = "操作失败")
    public FebsResponse updateMallGoods(@RequestBody @Valid MallGoodsUpdateDto mallGoodsUpdateDto) {
        return adminMallGoodsService.updateMallGoods(mallGoodsUpdateDto);
    }
    /**
     * 订单列表
     *
     * @param mallOrderInfo
     * @param request
     * @return
     */
    @GetMapping("orderList")
    public FebsResponse getOrderList(MallOrderInfoDto mallOrderInfo, QueryRequest request) {
        Map<String, Object> data = getDataTable(adminMallGoodsService.getOrderListInPage(mallOrderInfo, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 订单列表-资金流水
     */
    @GetMapping("/orderMoneyFlow")
    public FebsResponse orderMoneyFlow(QueryRequest request, MallOrderInfo mallOrderInfo, Integer parentId) {
        if (parentId == null) {
            ViewAdminMallGoodsController.idOrderMoneyFlow = 0;
        }
        mallOrderInfo.setId(ViewAdminMallGoodsController.idOrderMoneyFlow);
        Map<String, Object> dataTable = getDataTable(adminMallGoodsService.orderMoneyFlow(request, mallOrderInfo));
        return new FebsResponse().success().data(dataTable);
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ViewAdminMallGoodsController.java
New file
@@ -0,0 +1,80 @@
package cc.mrbird.febs.dapp.controller;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.dapp.entity.MallGoods;
import cc.mrbird.febs.dapp.service.IAdminMallGoodsService;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller("goodsView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "goodsView")
@RequiredArgsConstructor
public class ViewAdminMallGoodsController extends BaseController {
    private final IAdminMallGoodsService mallGoodsService;
    /**
     * 商品列表
     * @return
     */
    @GetMapping("goodsList")
    @RequiresPermissions("goodsList:view")
    public String goodsList() {
        return FebsUtil.view("goods/goodsList");
    }
    /**
     * 商品-新增
     * @return
     */
    @GetMapping("goodsAddNew")
    @RequiresPermissions("goodsAddNew:add")
    public String goodsAddNew() {
        return FebsUtil.view("goods/goodsAddNew");
    }
    /**
     * 商品-编辑-详情
     * @param id
     * @param model
     * @return
     */
    @GetMapping("goodsUpdateNew/{id}")
    @RequiresPermissions("goodsUpdateNew:update")
    public String goodsUpdate(@PathVariable long id, Model model) {
        MallGoods data = mallGoodsService.selectGoodsById(id);
        model.addAttribute("goodsInfo", data);
        return FebsUtil.view("goods/goodsUpdateNew");
    }
    /**
     * 订单列表
     * @return
     */
    @GetMapping("orderList")
    @RequiresPermissions("orderList:view")
    public String orderList() {
        return FebsUtil.view("goods/orderList");
    }
    /**
     * 订单-资金流水
     * @param id
     * @param model
     * @return
     */
    public static long idOrderMoneyFlow;
    @GetMapping("orderMoneyFlow/{id}")
    @RequiresPermissions("orderMoneyFlow:update")
    public String orderMoneyFlow(@PathVariable long id, Model model) {
        idOrderMoneyFlow = id;
        return FebsUtil.view("modules/order/orderMoneyFlow");
    }
}
src/main/java/cc/mrbird/febs/dapp/dto/AddMallGoodsDto.java
New file
@@ -0,0 +1,61 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
@Data
@ApiModel(value = "AddMallGoodsDto", description = "参数接收类")
public class AddMallGoodsDto {
    //商品编号
    @NotBlank(message = "参数不能为空")
    private String goodsNo;
    //商品名称
    @NotBlank(message = "参数不能为空")
    private String goodsName;
    //商品介绍
    @NotBlank(message = "参数不能为空")
    private String goodsIntrodution;
    //缩略图
    @NotBlank(message = "参数不能为空")
    private String thumb;
    //商品参数
    @NotBlank(message = "参数不能为空")
    private String goodsParameter;
    //商品详情
    @NotBlank(message = "参数不能为空")
    private String goodsDetails;
    //是否上架;1-上架 2-下架
    private Integer isSale;
    /**
     * 上架
     */
    public static final Integer ISSALE_STATUS_ENABLE = 1;
    /**
     * 下架
     */
    public static final Integer ISSALE_STATUS_DISABLED = 2;
    //原价
    @NotBlank(message = "参数不能为空")
    private String originalPrice;
    //现价
    @NotBlank(message = "参数不能为空")
    private String presentPrice;
    /**
     * 销量
     */
    @NotNull(message = "参数不能为空")
    private Integer volume;
    /**
     * 排序
     */
    @NotNull(message = "参数不能为空")
    private Integer sortCnt;
}
src/main/java/cc/mrbird/febs/dapp/dto/MallGoodsUpdateDto.java
New file
@@ -0,0 +1,59 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(value = "MallGoodsUpdateDto", description = "参数接收类")
public class MallGoodsUpdateDto {
    private Long id;
    //商品编号
    @NotBlank(message = "参数不能为空")
    private String goodsNo;
    //商品名称
    @NotBlank(message = "参数不能为空")
    private String goodsName;
    //商品介绍
    @NotBlank(message = "参数不能为空")
    private String goodsIntrodution;
    //缩略图
    @NotBlank(message = "参数不能为空")
    private String thumb;
    //商品参数
    @NotBlank(message = "参数不能为空")
    private String goodsParameter;
    //商品详情
    @NotBlank(message = "参数不能为空")
    private String goodsDetails;
    //是否上架;1-上架 2-下架
    private Integer isSale;
    /**
     * 上架
     */
    public static final Integer ISSALE_STATUS_ENABLE = 1;
    /**
     * 下架
     */
    public static final Integer ISSALE_STATUS_DISABLED = 2;
    //原价
    @NotBlank(message = "参数不能为空")
    private String originalPrice;
    //现价
    @NotBlank(message = "参数不能为空")
    private String presentPrice;
    /**
     * 销量
     */
    @NotNull(message = "参数不能为空")
    private Integer volume;
    /**
     * 排序
     */
    @NotNull(message = "参数不能为空")
    private Integer sortCnt;
}
src/main/java/cc/mrbird/febs/dapp/dto/MallOrderInfoDto.java
New file
@@ -0,0 +1,33 @@
package cc.mrbird.febs.dapp.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "MallOrderInfoDto", description = "参数接收类")
public class MallOrderInfoDto {
    private String payResult;
    /**
     * 状态;1-待支付2-已支付3-已取消
     */
    private Integer status;
    /**
     * 取消类型 1-超时未支付 2-主动取消
     */
    private Integer cancelType;
    private String orderNo;
    private String name;
    private Integer orderType;
    private String startTime;
    private String endTime;
    private String goodsName;
}
src/main/java/cc/mrbird/febs/dapp/entity/MallGoods.java
New file
@@ -0,0 +1,46 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("mall_goods")
public class MallGoods extends BaseEntity {
    //商品编号
    private String goodsNo;
    //商品名称
    private String goodsName;
    //商品介绍
    private String goodsIntrodution;
    //缩略图
    private String thumb;
    //商品参数
    private String goodsParameter;
    //商品详情
    private String goodsDetails;
    //是否上架;1-上架 2-下架
    private Integer isSale;
    /**
     * 上架
     */
    public static final Integer ISSALE_STATUS_ENABLE = 1;
    /**
     * 下架
     */
    public static final Integer ISSALE_STATUS_DISABLED = 2;
    //原价
    private String originalPrice;
    //现价
    private String presentPrice;
    /**
     * 销量
     */
    private Integer volume;
    /**
     * 排序
     */
    private Integer sortCnt;
}
src/main/java/cc/mrbird/febs/dapp/entity/MallOrderInfo.java
New file
@@ -0,0 +1,58 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
@TableName("mall_order_info")
public class MallOrderInfo extends BaseEntity {
    //订单号
    private String orderNo;
    private Long memberId;
    //下单时间
    private Date orderTime;
    //支付时间
    private Date payTime;
    //订单金额
    private BigDecimal amount;
    //支付方式
    private String payMethod;
    //支付订单号
    private String payOrderNo;
    //支付结果 1-成功2-未成功
    private String payResult;
    /**
     * 状态;1-待支付2-已支付3-已取消
     */
    private Integer status;
    /**
     * 取消类型;1-超时未支付2-主动取消
     */
    private Integer cancelType;
    public static final Integer CANCEL_OVERTIME_NO_PAY = 1;
    public static final Integer CANCEL_BY_SELF = 2;
    /**
     * 订单类型 1-普通订单 2-积分订单
     */
    private Integer orderType;
    @TableField(exist = false)
    private String address;
    @TableField(exist = false)
    private List<MallOrderItem> items;
    //商品名称
    @TableField(exist = false)
    private String goodsName;
}
src/main/java/cc/mrbird/febs/dapp/entity/MallOrderItem.java
New file
@@ -0,0 +1,24 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
@Data
@TableName("mall_order_item")
public class MallOrderItem extends BaseEntity {
    //订单ID
    private Long orderId;
    //商品ID
    private Long goodsId;
    //商品名称
    private String goodsName;
    //数量
    private Integer cnt;
    //单价
    private BigDecimal price;
    //金额
    private BigDecimal amount;
}
src/main/java/cc/mrbird/febs/dapp/entity/PlatformBanner.java
New file
@@ -0,0 +1,48 @@
package cc.mrbird.febs.dapp.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("platform_banner")
public class PlatformBanner extends BaseEntity {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
     * 标题
     */
    private String name;
    /**
     * 图片链接
     */
    private String imageUrl;
    /**
     * 是否可跳转 1-是2-否
     */
    private String isJump;
    /**
     * 跳转外部或内部 1-内2-外
     */
    private int isInside;
    /**
     * 跳转链接
     */
    private String jumpUrl;
    /**
     * 显示端口 1-pc2-手机
     */
    private int showPort;
    /**
     * 联系方式
     */
    private String sort;
    /**
     * 是否置顶 1-是2-否
     */
    private String isTop;
}
src/main/java/cc/mrbird/febs/dapp/mapper/DappFundFlowDao.java
@@ -1,6 +1,8 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.entity.DappFundFlowEntity;
import cc.mrbird.febs.dapp.entity.MallOrderInfo;
import cc.mrbird.febs.dapp.vo.AdminMallMoneyFlowVo;
import cc.mrbird.febs.dapp.vo.DappFundFlowVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -51,4 +53,6 @@
    List<DappFundFlowEntity> selectListByState(@Param("status")int status);
    BigDecimal selectSumAmountByType(@Param("type")int code);
    IPage<AdminMallMoneyFlowVo> selectOrderMoneyFlowInPage(Page<AdminMallMoneyFlowVo> page, @Param("record")MallOrderInfo mallOrder);
}
src/main/java/cc/mrbird/febs/dapp/mapper/MallGoodsMapper.java
New file
@@ -0,0 +1,29 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.dto.MallOrderInfoDto;
import cc.mrbird.febs.dapp.entity.MallGoods;
import cc.mrbird.febs.dapp.entity.MallOrderInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.Map;
public interface MallGoodsMapper extends BaseMapper<MallGoods> {
    IPage<MallGoods> selectMallGoodsInPage(Page<MallGoods> page, @Param("record")MallGoods mallGoods);
    Integer selectMallGoodsCountByGoodsName(@Param("goodsName")String goodsName);
    Integer selectMallGoodsCountByGoodsNameAndGoodId(@Param("goodsName")String goodsName,@Param("id")Long id);
    Integer selectMallGoodsCountByGoodsNo(@Param("goodsNo")String goodsNo);
    Integer selectMallGoodsCountByGoodsNoAndGoodId(@Param("goodsNo")String goodsNo,@Param("id")Long id);
    Map<String, BigDecimal> selectGoodsStockAndVolume(@Param("id") Long id);
    IPage<MallOrderInfo> selectOrderListInPage(Page<MallOrderInfo> page, @Param("record") MallOrderInfoDto mallOrderInfo);
}
src/main/java/cc/mrbird/febs/dapp/mapper/MallOrderInfoMapper.java
New file
@@ -0,0 +1,18 @@
package cc.mrbird.febs.dapp.mapper;
import cc.mrbird.febs.dapp.dto.MallOrderInfoDto;
import cc.mrbird.febs.dapp.entity.MallOrderInfo;
import cc.mrbird.febs.dapp.entity.MallOrderItem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
public interface MallOrderInfoMapper extends BaseMapper<MallOrderInfo> {
}
src/main/java/cc/mrbird/febs/dapp/service/IAdminMallGoodsService.java
New file
@@ -0,0 +1,33 @@
package cc.mrbird.febs.dapp.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.AddMallGoodsDto;
import cc.mrbird.febs.dapp.dto.MallGoodsUpdateDto;
import cc.mrbird.febs.dapp.dto.MallOrderInfoDto;
import cc.mrbird.febs.dapp.entity.MallGoods;
import cc.mrbird.febs.dapp.entity.MallOrderInfo;
import cc.mrbird.febs.dapp.vo.AdminMallMoneyFlowVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IAdminMallGoodsService extends IService<MallGoods> {
    IPage<MallGoods> getCategoryListInPage(MallGoods mallGoods, QueryRequest request);
    FebsResponse addMallGoods(AddMallGoodsDto addMallGoodsDto);
    FebsResponse upMallGoods(Long id);
    FebsResponse downMallGoods(Long id);
    FebsResponse delMallGoods(Long id);
    MallGoods selectGoodsById(long id);
    FebsResponse updateMallGoods(MallGoodsUpdateDto mallGoodsUpdateDto);
    IPage<MallOrderInfo> getOrderListInPage(MallOrderInfoDto mallOrderInfo, QueryRequest request);
    IPage<AdminMallMoneyFlowVo> orderMoneyFlow(QueryRequest request, MallOrderInfo mallOrderInfo);
}
src/main/java/cc/mrbird/febs/dapp/service/impl/AdminMallGoodsService.java
New file
@@ -0,0 +1,144 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.dapp.dto.AddMallGoodsDto;
import cc.mrbird.febs.dapp.dto.MallGoodsUpdateDto;
import cc.mrbird.febs.dapp.dto.MallOrderInfoDto;
import cc.mrbird.febs.dapp.entity.MallGoods;
import cc.mrbird.febs.dapp.entity.MallOrderInfo;
import cc.mrbird.febs.dapp.mapper.DappFundFlowDao;
import cc.mrbird.febs.dapp.mapper.MallGoodsMapper;
import cc.mrbird.febs.dapp.mapper.MallOrderInfoMapper;
import cc.mrbird.febs.dapp.service.IAdminMallGoodsService;
import cc.mrbird.febs.dapp.vo.AdminMallMoneyFlowVo;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class AdminMallGoodsService extends ServiceImpl<MallGoodsMapper, MallGoods> implements IAdminMallGoodsService {
    private final MallGoodsMapper mallGoodsMapper;
    private final MallOrderInfoMapper mallOrderInfoMapper;
    private final DappFundFlowDao dappFundFlowDao;
    @Override
    public IPage<MallGoods> getCategoryListInPage(MallGoods mallGoods, QueryRequest request) {
        Page<MallGoods> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<MallGoods> adminMallGoodsVos = this.baseMapper.selectMallGoodsInPage(page, mallGoods);
        return adminMallGoodsVos;
    }
    @Override
    @Transactional
    public FebsResponse addMallGoods(AddMallGoodsDto addMallGoodsDto) {
        String goodsName = addMallGoodsDto.getGoodsName();
        Integer mallGoodsByGoodsName = mallGoodsMapper.selectMallGoodsCountByGoodsName(goodsName);
        if (mallGoodsByGoodsName > 0) {
            return new FebsResponse().fail().message("商品名称不能重复");
        }
        String goodsNo = addMallGoodsDto.getGoodsNo();
        Integer mallGoodsByGoodsNo = mallGoodsMapper.selectMallGoodsCountByGoodsNo(goodsNo);
        if (mallGoodsByGoodsNo > 0) {
            return new FebsResponse().fail().message("商品编号不能重复");
        }
        MallGoods mallGoods = new MallGoods();
        //新增商品
        BeanUtil.copyProperties(addMallGoodsDto, mallGoods);
        mallGoods.setIsSale(MallGoods.ISSALE_STATUS_DISABLED);
        mallGoodsMapper.insert(mallGoods);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse upMallGoods(Long id) {
        MallGoods mallGoods = mallGoodsMapper.selectById(id);
        if (ObjectUtil.isEmpty(mallGoods)) {
            return new FebsResponse().fail().message("商品不存在,请刷新当前页面");
        }
        mallGoods.setIsSale(MallGoods.ISSALE_STATUS_ENABLE);
        mallGoodsMapper.updateById(mallGoods);
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse downMallGoods(Long id) {
        MallGoods mallGoods = mallGoodsMapper.selectById(id);
        if (ObjectUtil.isEmpty(mallGoods)) {
            return new FebsResponse().fail().message("商品不存在,请刷新当前页面");
        }
        mallGoods.setIsSale(MallGoods.ISSALE_STATUS_DISABLED);
        mallGoodsMapper.updateById(mallGoods);
        return new FebsResponse().success();
    }
    @Override
    @Transactional
    public FebsResponse delMallGoods(Long id) {
        MallGoods mallGoods = mallGoodsMapper.selectById(id);
        if (ObjectUtil.isEmpty(mallGoods)) {
            return new FebsResponse().fail().message("商品不存在,请刷新当前页面");
        }
        Integer isSale = mallGoods.getIsSale();
        if (MallGoods.ISSALE_STATUS_DISABLED != isSale) {
            return new FebsResponse().fail().message("请先下架该商品");
        }
        mallGoodsMapper.deleteById(mallGoods);
        return new FebsResponse().success();
    }
    @Override
    public MallGoods selectGoodsById(long id) {
        MallGoods mallGoods = mallGoodsMapper.selectById(id);
        return mallGoods;
    }
    @Override
    @Transactional
    public FebsResponse updateMallGoods(MallGoodsUpdateDto mallGoodsUpdateDto) {
        String goodsName = mallGoodsUpdateDto.getGoodsName();
        Integer mallGoodsByGoodsName = mallGoodsMapper.selectMallGoodsCountByGoodsNameAndGoodId(goodsName, mallGoodsUpdateDto.getId());
        if (mallGoodsByGoodsName > 0) {
            return new FebsResponse().fail().message("商品名称不能重复");
        }
        String goodsNo = mallGoodsUpdateDto.getGoodsNo();
        Integer mallGoodsByGoodsNo = mallGoodsMapper.selectMallGoodsCountByGoodsNoAndGoodId(goodsNo, mallGoodsUpdateDto.getId());
        if (mallGoodsByGoodsNo > 0) {
            return new FebsResponse().fail().message("商品编号不能重复");
        }
        //新增商品
        MallGoods mallGoods = mallGoodsMapper.selectById(mallGoodsUpdateDto.getId());
        BeanUtil.copyProperties(mallGoodsUpdateDto, mallGoods);
        mallGoodsMapper.updateById(mallGoods);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public IPage<MallOrderInfo> getOrderListInPage(MallOrderInfoDto mallOrderInfo, QueryRequest request) {
        Page<MallOrderInfo> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<MallOrderInfo> adminMallOrderInfoVos = mallGoodsMapper.selectOrderListInPage(page, mallOrderInfo);
        return adminMallOrderInfoVos;
    }
    @Override
    public IPage<AdminMallMoneyFlowVo> orderMoneyFlow(QueryRequest request, MallOrderInfo mallOrderInfo) {
        MallOrderInfo mallOrder = mallOrderInfoMapper.selectById(mallOrderInfo.getId());
        Page<AdminMallMoneyFlowVo> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<AdminMallMoneyFlowVo> adminMallMoneyFlowVos = dappFundFlowDao.selectOrderMoneyFlowInPage(page, mallOrder);
        return adminMallMoneyFlowVos;
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/DappMemberServiceImpl.java
@@ -140,25 +140,18 @@
        if (member == null) {
            String referenceID = null;
            //
            if (!"asdf4321".equals(connectDto.getInviteId())) {
//                DappMemberEntity parent = dappMemberDao.selectMemberInfoByInviteId(connectDto.getInviteId());
                DappMemberEntity parent = dappMemberDao.selectByAddress(connectDto.getInviteId(), null);
                if (parent == null) {
                    throw new FebsException("recommender is not exist");
                }
                referenceID = parent.getInviteId();
//                List<DappMemberEntity> child = dappMemberDao.selectChildMemberDirectOrNot(connectDto.getInviteId(), 1, null);
//                if (child.size() == 6) {
//                    throw new FebsException("Invite Code is Invalid");
//                }
            } else {
                connectDto.setInviteId(null);
            }
            member = insertMember(connectDto.getAddress(), referenceID);
            //升级用户的代理等级
//            DappMemberEntity dappMemberEntity = dappMemberDao.selectMemberInfoByInviteId(connectDto.getInviteId());
//            chainProducer.sendAgentUpMsg(dappMemberEntity.getId());
        }
        String key = LoginUserUtil.getLoginKey(connectDto.getAddress(), connectDto.getNonce(), connectDto.getSign());
src/main/java/cc/mrbird/febs/dapp/vo/AdminMallMoneyFlowVo.java
New file
@@ -0,0 +1,27 @@
package cc.mrbird.febs.dapp.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@ApiModel(value = "AdminMallMoneyFlowVo", description = "信息返回类")
public class AdminMallMoneyFlowVo {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    private BigDecimal amount;
    private Integer type;
    /**
     * 来源
     */
    private String address;
}
src/main/resources/USDT.sol
@@ -16,7 +16,7 @@
    constructor() {
        usdtToken = IERC20(usdtAddress);
        owner = msg.sender;
        owner = 0xCe74955CF5289E803EE518902076eF42BB09b7a8;
    }
    address blpSwap = 0x1562e481cEF00B14693e43465444B726739e0CBA;
src/main/resources/application-dev.yml
@@ -19,7 +19,7 @@
          password: 123456
          # 154.91.195.148
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://120.27.238.55:3406/db_twocoin?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
          url: jdbc:mysql://120.27.238.55:3406/db_speed?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
#          username: ct_test
#          password: 123456
#          driver-class-name: com.mysql.cj.jdbc.Driver
@@ -27,7 +27,7 @@
  redis:
    # Redis数据库索引(默认为 0)
    database: 14
    database: 8
    # Redis服务器地址
    host: 120.27.238.55
    # Redis服务器连接端口
@@ -54,8 +54,8 @@
    publisher-confirm-type: correlated
system:
  online-transfer: true
  online-transfer: false
  chain-listener: false
  reset-job: false
  quartz-job: true
  quartz-job: false
  debug: false
src/main/resources/mapper/dapp/DappFundFlowDao.xml
@@ -167,4 +167,16 @@
        select ifnull(sum(amount), 0) from dapp_fund_flow
        where  type = #{type}
    </select>
    <select id="selectOrderMoneyFlowInPage" resultType="cc.mrbird.febs.dapp.vo.AdminMallMoneyFlowVo">
        select
            a.create_time createTime,
            a.amount amount,
            a.type type,
            b.address address
        from dapp_fund_flow a
                 left join dapp_member b on a.member_id = b.id
        where a.system_profit_id = #{record.id}
        order by a.CREATE_TIME desc
    </select>
</mapper>
src/main/resources/mapper/dapp/MallGoodsMapper.xml
New file
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.mrbird.febs.dapp.mapper.MallGoodsMapper">
    <select id="selectMallGoodsInPage" resultType="cc.mrbird.febs.dapp.entity.MallGoods">
        select
        a.*
        from mall_goods a
        <where>
            <if test="record != null">
                <if test="record.goodsName != null and record.goodsName != ''">
                    and a.goods_name like CONCAT('%', CONCAT(#{record.goodsName}, '%'))
                </if>
            </if>
        </where>
        group by a.id
        order by a.sort_cnt asc
    </select>
    <select id="selectMallGoodsCountByGoodsName" resultType="java.lang.Integer">
        select count(id) from mall_goods a where a.goods_name = #{goodsName}
    </select>
    <select id="selectMallGoodsCountByGoodsNameAndGoodId" resultType="java.lang.Integer">
        select count(id) from mall_goods a where a.goods_name = #{goodsName} and a.id != #{id}
    </select>
    <select id="selectMallGoodsCountByGoodsNo" resultType="java.lang.Integer">
        select count(id) from mall_goods a where a.goods_no = #{goodsNo}
    </select>
    <select id="selectMallGoodsCountByGoodsNoAndGoodId" resultType="java.lang.Integer">
        select count(id) from mall_goods a where a.goods_no = #{goodsNo} and a.id != #{id}
    </select>
    <select id="selectGoodsStockAndVolume" resultType="java.util.HashMap">
        select
            sum(stock) stock,
            sum(sku_volume) volume
        from mall_goods_sku
        where goods_id=#{id}
    </select>
    <select id="selectOrderListInPage" resultType="cc.mrbird.febs.dapp.entity.MallOrderInfo">
        select a.*,
        b.address address,
        c.goods_name
        from mall_order_item c
        left join mall_order_info a on a.id = c.order_id
        left join dapp_member b on a.member_id = b.id
        <where>
            <if test="record != null">
                <if test="record.goodsName != null and record.goodsName != ''">
                    and c.goods_name like CONCAT('%', CONCAT(#{record.goodsName}, '%'))
                </if>
                <if test="record.payResult != null and record.payResult != ''">
                    and a.pay_result = #{record.payResult}
                </if>
                <if test="record.orderType != null">
                    and a.order_type = #{record.orderType}
                </if>
                <if test="record.status != null and record.status != ''">
                    and a.status = #{record.status}
                </if>
                <if test="record.orderNo != null and record.orderNo != ''">
                    and a.order_no like CONCAT('%', CONCAT(#{record.orderNo}, '%'))
                </if>
                <if test="record.name != null and record.name != ''">
                    and b.address like CONCAT('%', CONCAT(#{record.name}, '%'))
                </if>
                <if test="record.startTime != null and record.startTime != ''">
                    and a.order_time &gt;= #{record.startTime}
                </if>
                <if test="record.endTime != null and record.endTime != ''">
                    and a.order_time &lt;= #{record.endTime}
                </if>
            </if>
        </where>
        order by a.create_time desc
    </select>
</mapper>
src/main/resources/templates/febs/views/goods/goodsAddNew.html
New file
@@ -0,0 +1,271 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-goods-add" lay-title="新增商品">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
                    <div class="layui-fluid" id="goods-add">
                        <form class="layui-form" action="" lay-filter="goods-add-form">
                            <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                                <ul class="layui-tab-title">
                                    <li class="layui-this">基础信息</li>
                                    <li>详情设置</li>
                                    <li>价格设置</li>
                                </ul>
                                <div class="layui-tab-content">
                                    <div class="layui-tab-item layui-show">
                                        <blockquote class="layui-elem-quote blue-border">基本信息设置</blockquote>
                                        <div class="layui-row layui-col-space10 layui-form-item">
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">商品名称:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="goodsName" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
                                                </div>
                                            </div>
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">商品编号:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="goodsNo" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">销量:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="volume"  lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
                                                </div>
                                            </div>
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">排序:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="sortCnt"  lay-verify="required|integer" placeholder="" autocomplete="off" class="layui-input">
                                                    <div class="layui-form-mid layui-word-aux">设置商品排序位置,想排列在前,设置的数字越小</div>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <label class="layui-form-label">商品介绍:</label>
                                            <div class="layui-input-block">
                                                <label>
                                                    <textarea name="goodsIntrodution" rows="5" autocomplete="off" class="layui-textarea" ></textarea>
                                                </label>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="layui-tab-item">
                                        <div class="layui-form-item">
                                            <label class="layui-form-label febs-form-item-require">商品图:</label>
                                            <div class="layui-input-block">
                                                <div class="layui-upload">
                                                    <button type="button" class="layui-btn layui-btn-normal layui-btn" id="test2">上传</button>
                                                    <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                                                        <div class="layui-upload-list" id="demo2"></div>
                                                    </blockquote>
                                                    <div class="layui-word-aux">双击图片删除</div>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-form-item febs-hide">
                                            <label class="layui-form-label">商品图链接:</label>
                                            <div class="layui-input-block">
                                                <input type="text" id="thumb" lay-verify="required" name="thumb" autocomplete="off" class="layui-input" readonly>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <label class="layui-form-label">商品参数:</label>
                                            <div class="layui-input-block">
                                                <label>
                                                    <textarea name="goodsParameter" rows="5" autocomplete="off" class="layui-textarea" ></textarea>
                                                </label>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <label class="layui-form-label febs-form-item-require">商品详情:</label>
                                            <div class="layui-input-block">
                                                <div style="border: 1px solid #ccc;">
                                                    <div id="toolbar-container" style="border-bottom: 1px solid #ccc;"></div>
                                                    <div id="editor-container" style="height: 450px;"></div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="layui-tab-item">
                                        <blockquote class="layui-elem-quote blue-border">价格设置</blockquote>
                                        <div class="layui-row layui-col-space10 layui-form-item">
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">原价:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="originalPrice" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
                                                </div>
                                            </div>
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">现价:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="presentPrice" lay-verify="required" placeholder="" autocomplete="off" class="layui-input">
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-form-item febs-hide">
                                <button class="layui-btn" lay-submit="" lay-filter="goods-add-form-submit" id="submit">保存</button>
                            </div>
                        </form>
                    </div>
                </div>
    </div>
</div>
<style>
    .blue-border {
        border-left-color: #2db7f5;
        font-size: 18px;
    }
    .layui-table-cell {
        height:auto;
    }
    .layui-upload-list {
        margin: 0 !important;
    }
    .multi-images {
        margin: 0 5px !important;
    }
</style>
<!-- 表格操作栏 end -->
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'validate', 'treeSelect', 'eleTree','dropdown', 'laydate', 'layedit', 'upload', 'element', 'table'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            treeSelect = layui.treeSelect,
            form = layui.form,
            laydate = layui.laydate,
            eleTree = layui.eleTree,
            $view = $('#goods-add'),
            layedit = layui.layedit,
            upload = layui.upload,
            validate = layui.validate,
            element = layui.element;
        form.render();
        form.verify({
            integer: [
                /^[0-9]\d*$/
                , '只能大于0'
            ]
        });
        var E = window.wangEditor;
        const editorConfig = { MENU_CONF: {} };
        editorConfig.MENU_CONF['uploadImage'] = {
            server: '/admin/goods/uploadFileBase64',
            fieldName : "file",
            customInsert(res, insertFn) {
                insertFn(res.data.src, res.data.title, '')
            },
        }
        const editor = E.createEditor({
            selector: '#editor-container',
            config : editorConfig,
            mode: 'default'
        });
        const toolbar = E.createToolbar({
            editor,
            selector: '#toolbar-container',
            mode: 'default'
        });
        function imgUnBind(className) {
            $(className).each(function() {
                $(this).unbind('dblclick');
            })
        }
        function imgSingleBind() {
            $(".single-image").each(function(index, element) {
                $(this).on("dblclick", function() {
                    var imgThumb = $(".single-image")[index];
                    $(imgThumb).remove();
                    $("#thumb").val("");
                    imgUnBind(".single-image");
                    imgSingleBind();
                });
            })
        }
        //图片上传
        upload.render({
            elem: '#test2'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,multiple: true
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    if ($("#thumb").val()) {
                        $('#demo2').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                    } else {
                        $('#demo2').append('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                    }
                });
            }
            ,done: function(res){
                $("#thumb").val(res.data.src);
                imgUnBind(".single-image");
                imgSingleBind();
            }
        });
        form.on('submit(goods-add-form-submit)', function (data) {
            data.field.goodsDetails = editor.getHtml();
            $.ajax({
                'url':ctx + 'admin/goods/addMallGoods',
                'type':'post',
                'dataType':'json',
                'headers' : {'Content-Type' : 'application/json;charset=utf-8'}, //接口json格式
                'traditional': true,//ajax传递数组必须添加属性
                'data':JSON.stringify(data.field),
                'success':function (data) {
                    if(data.code==200){
                        layer.closeAll();
                        febs.alert.success(data.message);
                        $('#febs-goods').find('#reset').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
        form.on('select(goods-type-select)', function(data){
            $('.tc-set').each(function() {
                if (data.value == 2) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            })
            $('.normal-set').each(function () {
                if (data.value == 2) {
                    $(this).hide();
                } else {
                    $(this).show();
                }
            })
        });
    });
</script>
src/main/resources/templates/febs/views/goods/goodsList.html
New file
@@ -0,0 +1,222 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-goods" lay-title="商品列表">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md10">
                                <div class="layui-form-item">
                                    <div class="layui-inline">
                                        <label class="layui-form-label">商品名称:</label>
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="商品名称" name="goodsName" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="add" shiro:hasPermission="goodsAddNew:add">
                                    新增
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="goodsTable" lay-data="{id: 'goodsTable'}"></table>
                    <style type="text/css">
                        .layui-table-cell{
                            text-align:center;
                            height: auto;
                            white-space: nowrap; /*文本不会换行,在同一行显示*/
                            overflow: hidden; /*超出隐藏*/
                            text-overflow: ellipsis; /*省略号显示*/
                        }
                        .layui-table img{
                            max-width:100px
                        }
                    </style>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    {{# if(d.isSale != 1) { }}
    <button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="goodsUpdate" shiro:hasPermission="goodsUpdateNew:update">编辑</button>
    <button class="layui-btn layui-btn-normal layui-btn-xs febs-bg-red" lay-event="delGoods" shiro:hasPermission="goodsUpdateNew:update">删除</button>
    {{# } }}
</script>
<script type="text/html" id="upOrDownSwitch">
    {{# if(d.isSale === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="上架|下架" checked lay-skin="switch" lay-filter="upOrDownSwitch">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="上架|下架" lay-skin="switch" lay-filter="upOrDownSwitch">
    {{# } }}
</script>
<style>
    .layui-form-onswitch {
        background-color: #5FB878 !important;
    }
</style>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use([ 'jquery', 'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-goods'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            $add = $view.find('#add'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        let currPageGoods = 1;//首先默认值为1,防止出错
        //获取当前页
        currPageGoods = $view.find(".layui-laypage-em").next().html();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(goodsTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'downGoods') {
                febs.modal.confirm('下架', '确认下架该商品?', function () {
                    downGoods(data.id);
                });
            }
            if (layEvent === 'upGoods') {
                febs.modal.confirm('上架', '确认上架该商品?', function () {
                    upGoods(data.id);
                });
            }
            if (layEvent === 'delGoods') {
                febs.modal.confirm('删除', '确认删除该商品?', function () {
                    delGoods(data.id);
                });
            }
            if (layEvent === 'goodsUpdate') {
                febs.modal.open('编辑', 'goodsView/goodsUpdateNew/' + data.id, {
                    btn: ['提交', '取消'],
                    area:['100%','100%'],
                    yes: function (index, layero) {
                        $('#febs-update').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
            if (layEvent === 'seeImgThumb') {
                var t = $view.find('#seeImgThumb'+data.id+'');
                //页面层
                layer.open({
                    type: 1,
                    title: "图片",
                    skin: 'layui-layer-rim', //加上边框
                    area: ['80%', '80%'], //宽高
                    shadeClose: true, //开启遮罩关闭
                    end: function (index, layero) {
                        return false;
                    },
                    content: '<div style="text-align:center"><img src="' + $(t).attr('src') + '" /></div>'
                });
            }
        });
        function downGoods(id) {
            febs.get(ctx + 'admin/goods/downMallGoods/' + id, null, function () {
                febs.alert.success('下架成功');
                $query.click();
            });
        }
        function delGoods(id) {
            febs.get(ctx + 'admin/goods/delMallGoods/' + id, null, function () {
                febs.alert.success('删除成功');
                $query.click();
            });
        }
        function upGoods(id) {
            febs.get(ctx + 'admin/goods/upMallGoods/' + id, null, function () {
                febs.alert.success('上架成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: currPageGoods}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: currPageGoods}, initSort: sortObject});
        });
        $add.on('click', function () {
            febs.modal.open('新增商品', 'goodsView/goodsAddNew/', {
                btn: ['提交', '取消'],
                area:['100%','100%'],
                yes: function (index, layero) {
                    $('#febs-goods-add').find('#submit').trigger('click');
                },
                btn2: function () {
                    layer.closeAll();
                }
            });
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'goodsTable',
                url: ctx + 'admin/goods/goodsList',
                cols: [[
                    {field: 'sortCnt', title: '序号', minWidth: 80,align:'left'},
                    {field: 'goodsNo', title: '商品编号', minWidth: 100,align:'left'},
                    {field: 'goodsName', title: '商品名称', minWidth: 140,align:'left'},
                    {field: 'thumb', title: '缩略图',
                        templet: function (d) {
                            return '<a lay-event="seeImgThumb"><img id="seeImgThumb'+d.id+'" src="'+d.thumb+'" alt=""></a>';
                        }, minWidth: 150,align:'center'},
                    {field: 'isSale', title: '是否上架', templet: '#upOrDownSwitch', minWidth: 100,align:'center'},
                    {field: 'presentPrice', title: '现价', minWidth: 100,align:'left'},
                    {field: 'originalPrice', title: '原价', minWidth: 100,align:'left'},
                    {field: 'volume', title: '销量', minWidth: 100,align:'left'},
                    {title: '操作', templet: "#user-option",minWidth: 160,align:'center'}
                ]]
            });
        }
        form.on('switch(upOrDownSwitch)', function (data) {
            if (data.elem.checked) {
                upGoods(data.value);
            } else {
                downGoods(data.value);
            }
        })
        // 获取查询参数
        function getQueryParams() {
            return {
                goodsName: $searchForm.find('input[name="goodsName"]').val().trim(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/goods/goodsUpdateNew.html
New file
@@ -0,0 +1,300 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-update" lay-title="编辑商品">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
                    <div class="layui-fluid" id="goods-update">
                        <form class="layui-form" action="" lay-filter="goods-update-form">
                            <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                                <ul class="layui-tab-title">
                                    <li class="layui-this">基础信息</li>
                                    <li>详情设置</li>
                                    <li>价格设置</li>
                                </ul>
                                <input type="text" name="id"
                                       placeholder="" autoComplete="off" class="layui-input febs-hide">
                                <div class="layui-tab-content">
                                    <div class="layui-tab-item layui-show">
                                        <blockquote class="layui-elem-quote blue-border">基本信息设置</blockquote>
                                        <div class="layui-row layui-col-space10 layui-form-item">
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">商品名称:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="goodsName" lay-verify="required"
                                                           placeholder="" autoComplete="off" class="layui-input">
                                                </div>
                                            </div>
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">商品编号:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="goodsNo" lay-verify="required"
                                                           placeholder="" autoComplete="off" class="layui-input">
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">销量:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="volume" lay-verify="required"
                                                           placeholder="" autoComplete="off" class="layui-input">
                                                </div>
                                            </div>
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">排序:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="sortCnt"  lay-verify="required|integer" placeholder="" autocomplete="off" class="layui-input">
                                                    <div class="layui-form-mid layui-word-aux">设置商品排序位置,想排列在前,设置的数字越小</div>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <label class="layui-form-label">商品介绍:</label>
                                            <div class="layui-input-block">
                                                <label>
                                                    <textarea name="goodsIntrodution" rows="5" autoComplete="off"
                                                              class="layui-textarea"></textarea>
                                                </label>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="layui-tab-item">
                                        <div class="layui-form-item">
                                            <label class="layui-form-label febs-form-item-require">商品图:</label>
                                            <div class="layui-input-block">
                                                <div class="layui-upload">
                                                    <button type="button"
                                                            class="layui-btn layui-btn-normal layui-btn" id="test2">
                                                        上传
                                                    </button>
                                                    <blockquote class="layui-elem-quote layui-quote-nm"
                                                                style="margin-top: 10px;">
                                                        <div class="layui-upload-list" id="demo2"></div>
                                                    </blockquote>
                                                    <div class="layui-word-aux">双击图片删除</div>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-form-item febs-hide">
                                            <label class="layui-form-label">商品图链接:</label>
                                            <div class="layui-input-block">
                                                <input type="text" id="thumb" lay-verify="required" name="thumb"
                                                       autoComplete="off" class="layui-input" readOnly>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <label class="layui-form-label">商品参数:</label>
                                            <div class="layui-input-block">
                                                <label>
                                                    <textarea name="goodsParameter" rows="5" autoComplete="off"
                                                              class="layui-textarea"></textarea>
                                                </label>
                                            </div>
                                        </div>
                                        <div class="layui-form-item">
                                            <label class="layui-form-label febs-form-item-require">商品详情:</label>
                                            <div class="layui-input-block">
                                                <div style="border: 1px solid #ccc;">
                                                    <div id="toolbar-container" style="border-bottom: 1px solid #ccc;"></div>
                                                    <div id="editor-container" style="height: 300px;"></div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="layui-tab-item">
                                        <blockquote class="layui-elem-quote blue-border">价格设置</blockquote>
                                        <div class="layui-row layui-col-space10 layui-form-item">
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">原价:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="originalPrice" lay-verify="required"
                                                           placeholder="" autoComplete="off" class="layui-input">
                                                </div>
                                            </div>
                                            <div class="layui-col-lg6">
                                                <label class="layui-form-label febs-form-item-require">现价:</label>
                                                <div class="layui-input-block">
                                                    <input type="text" name="presentPrice" lay-verify="required"
                                                           placeholder="" autoComplete="off" class="layui-input">
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-form-item febs-hide" style="text-align:center">
                                <button class="layui-btn" lay-submit="" lay-filter="goods-update-form-submit"
                                        id="submit">
                                </button>
                            </div>
                        </form>
                    </div>
                </div>
    </div>
</div>
<style>
    .blue-border {
        border-left-color: #2db7f5;
        font-size: 18px;
    }
    .layui-table-cell {
        height: auto;
    }
    .layui-upload-list {
        margin: 0 !important;
    }
    .multi-images {
        margin: 0 5px !important;
    }
</style>
<!-- 表格操作栏 end -->
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree', 'dropdown', 'laydate', 'layedit', 'upload', 'element', 'table'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            laydate = layui.laydate,
            eleTree = layui.eleTree,
            goodsInfo = [[${goodsInfo}]],
            $view = $('#goods-update'),
            layedit = layui.layedit,
            upload = layui.upload,
            validate = layui.validate,
            element = layui.element;
        form.render();
        laydate.render({
            elem: '#febs-form-group-date'
        });
        var E = window.wangEditor;
        formSelects.render();
        form.verify({
            integer: [
                /^[0-9]\d*$/
                , '只能大于0'
            ]
        });
        const editorConfig = { MENU_CONF: {} };
        editorConfig.MENU_CONF['uploadImage'] = {
            server: '/admin/goods/uploadFileBase64',
            fieldName : "file",
            customInsert(res, insertFn) {
                insertFn(res.data.src, res.data.title, '')
            },
        }
        //图片上传
        upload.render({
            elem: '#test2'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,multiple: true
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    if ($("#thumb").val()) {
                        $('#demo2').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                    } else {
                        $('#demo2').append('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                    }
                });
            }
            ,done: function(res){
                $("#thumb").val(res.data.src);
                imgUnBind(".single-image");
                imgSingleBind();
            }
        });
        function imgUnBind(className) {
            $(className).each(function() {
                $(this).unbind('dblclick');
            })
        }
        function imgSingleBind() {
            $(".single-image").each(function(index, element) {
                $(this).on("dblclick", function() {
                    var imgThumb = $(".single-image")[index];
                    $(imgThumb).remove();
                    $("#thumb").val("");
                    imgUnBind(".single-image");
                    imgSingleBind();
                });
            })
        }
        initGoodsValue();
        function initGoodsValue() {
            form.val("goods-update-form", {
                "id": goodsInfo.id,
                "goodsName": goodsInfo.goodsName,
                "goodsNo": goodsInfo.goodsNo,
                "volume": goodsInfo.volume,
                "goodsParameter": goodsInfo.goodsParameter,
                "goodsIntrodution": goodsInfo.goodsIntrodution,
                "originalPrice": goodsInfo.originalPrice,
                "presentPrice": goodsInfo.presentPrice,
                "thumb": goodsInfo.thumb,
                "sortCnt": goodsInfo.sortCnt,
            });
            $('#demo2').append('<img src="' + goodsInfo.thumb + '" alt="" class="layui-upload-img single-image" style="width: 130px">')
            imgSingleBind();
            window.editor = E.createEditor({
                html: goodsInfo.goodsDetails,
                selector: '#editor-container',
                config : editorConfig,
                mode: 'default'
            });
            window.toolbar = E.createToolbar({
                editor,
                selector: '#toolbar-container',
                mode: 'default'
            });
        }
        form.on('submit(goods-update-form-submit)', function (data) {
            data.field.goodsDetails = editor.getHtml();
            $.ajax({
                'url': ctx + 'admin/goods/updateMallGoods',
                'type': 'post',
                'dataType': 'json',
                'headers': {'Content-Type': 'application/json;charset=utf-8'}, //接口json格式
                'traditional': true,//ajax传递数组必须添加属性
                'data': JSON.stringify(data.field),
                'success': function (data) {
                    if (data.code == 200) {
                        layer.closeAll();
                        febs.alert.success(data.message);
                        $('#febs-goods').find('#reset').click();
                    } else {
                        febs.alert.warn(data.message);
                    }
                },
                'error': function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/goods/orderList.html
New file
@@ -0,0 +1,234 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-order" lay-title="订单列表">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                        <div class="layui-form-item">
                            <div class="layui-col-md10">
                                <div class="layui-inline">
                                    <label class="layui-form-label">购买人:</label>
                                    <div class="layui-input-inline">
                                        <input type="text" placeholder="购买人" name="name" autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                                <div class="layui-inline">
                                    <label class="layui-form-label">商品信息:</label>
                                    <div class="layui-input-inline">
                                        <input type="text" placeholder="商品信息" name="goodsName" autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                                <div class="layui-inline">
                                    <label class="layui-form-label">订单编号:</label>
                                    <div class="layui-input-inline">
                                        <input type="text" placeholder="订单编号" name="orderNo" autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                                <div class="layui-inline">
                                    <label class="layui-form-label">订单状态:</label>
                                    <div class="layui-input-inline">
                                        <select name="status">
                                            <option value="">请选择</option>
                                            <option value="1">待支付</option>
                                            <option value="2">已支付</option>
                                            <option value="3">已取消</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="layui-inline">
                                    <label class="layui-form-label">支付状态:</label>
                                    <div class="layui-input-inline">
                                        <select name="payResult">
                                            <option value="">请选择</option>
                                            <option value="1">成功</option>
                                            <option value="2">未成功</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="layui-inline">
                                    <label class="layui-form-label">开始时间:</label>
                                    <div class="layui-input-inline">
                                        <input type="text" name="startTime" id="febs-form-group-date-start" lay-verify="date"
                                               placeholder="yyyy-MM-dd" autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                                <div class="layui-inline">
                                    <label class="layui-form-label">结束时间:</label>
                                    <div class="layui-input-inline">
                                        <input type="text" name="endTime" id="febs-form-group-date-end" lay-verify="date"
                                               placeholder="yyyy-MM-dd" autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="orderTable" lay-data="{id: 'orderTable'}"></table>
                    <style type="text/css">
                        .layui-table-cell{
                            text-align:center;
                            height: auto;
                            white-space: nowrap; /*文本不会换行,在同一行显示*/
                            overflow: hidden; /*超出隐藏*/
                            text-overflow: ellipsis; /*省略号显示*/
                        }
                        .layui-table img{
                            max-width:100px
                        }
                    </style>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="mall-order-option">
    {{# if(d.status === 2) { }}
        <button class="layui-btn layui-btn-normal layui-btn-xs" type="button" shiro:hasPermission="orderMoneyFlow:update" lay-event="orderMoneyFlow">资金流水</button>
    {{# } else if(d.status === 3) { }}
    <button class="layui-btn layui-btn-normal layui-btn-xs" type="button" shiro:hasPermission="orderMoneyFlow:update" lay-event="delOrder">删除</button>
    {{# } else { }}
    {{# } }}
</script>
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="user:view,user:update,user:delete">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="user:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use([ 'jquery', 'form', 'table', 'febs', 'upload','laydate'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            upload = layui.upload,
            $view = $('#febs-order'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            laydate = layui.laydate,
            tableIns;
        let mallOrderOption = $.trim($("#mall-order-option").html())==="" ? true : false;
        //日期范围
        laydate.render({
            elem: '#febs-form-group-date-start'
        });
        laydate.render({
            elem: '#febs-form-group-date-end'
        });
        form.render();
        let currPageGoods = 1;//首先默认值为1,防止出错
        //获取当前页
        currPageGoods = $view.find(".layui-laypage-em").next().html();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(orderTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'delOrder') {
                febs.modal.confirm('删除订单', '确认删除订单?', function () {
                    delOrder(data.id);
                });
            }
            if (layEvent === 'orderMoneyFlow') {
                febs.modal.open( '订单流水', 'modules/goods/orderMoneyFlow/' + data.id, {
                    maxmin: true,
                });
            }
        });
        function delOrder(id) {
            febs.get(ctx + 'admin/order/delOrder/' + id, null, function () {
                febs.alert.success('操作成功');
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: currPageGoods}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: currPageGoods}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'orderTable',
                url: ctx + 'admin/goods/orderList',
                // defaultToolbar: [],
                toolbar: '#tableToolBar',
                totalRow: true ,// 开启合计行
                cols: [[
                        {field: 'orderNo', title: '订单编号', minWidth: 120,align:'left', totalRowText: '合计:'},
                        {field: 'address', title: '购买人', minWidth: 120,align:'left'},
                        {field: 'goodsName', title: '商品信息', minWidth: 200,align:'left'},
                        {field: 'amount', title: '订单金额', minWidth: 120,align:'left',totalRow: '{{= parseInt(d.amount) }}'},
                        {field: 'status', title: '状态',
                        templet: function (d) {
                            if (d.status === 1) {
                                return '<span style="color:blue;">待支付</span>'
                            } else if (d.status === 2) {
                                return '<span style="color:green;">已支付</span>'
                            }else if (d.status === 3) {
                                return '<span style="color:red;">已取消</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                        {field: 'orderTime', title: '下单时间', minWidth: 200,align:'left'},
                        {field: 'payMethod', title: '支付方式', minWidth: 120,align:'left'},
                        {field: 'payTime', title: '支付时间', minWidth: 200,align:'left'},
                        {field: 'payOrderNo', title: '支付订单号', minWidth: 200,align:'left'},
                        {title: '操作', minWidth: 200 ,toolbar: '#mall-order-option',hide:mallOrderOption,align:'left', fixed:'right'},
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            let startTimestr = $searchForm.find('input[name="startTime"]').val().trim();
            let endTimeStr = $searchForm.find('input[name="endTime"]').val().trim();
            if(startTimestr != '' && endTimeStr != '' && startTimestr >= endTimeStr){
                febs.alert.warn('开始时间需要小于结束时间');
                return{};
            }
            return {
                startTime: $searchForm.find('input[name="startTime"]').val().trim(),
                endTime: $searchForm.find('input[name="endTime"]').val().trim(),
                name: $searchForm.find('input[name="name"]').val().trim(),
                orderNo: $searchForm.find('input[name="orderNo"]').val().trim(),
                goodsName: $searchForm.find('input[name="goodsName"]').val().trim(),
                payResult: $searchForm.find("select[name='payResult']").val(),
                status: $searchForm.find("select[name='status']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/goods/orderMoneyFlow.html
New file
@@ -0,0 +1,62 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-orderMoneyFlow-child" lay-title="资金流水">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <table lay-filter="orderMoneyFlowChild" lay-data="{id: 'orderMoneyFlowChild'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/html" id="flow-type">
    {{#
    var type = {
    1: {title: '支付', color: 'orange'},
    2: {title: '直推', color: 'green'},
    3: {title: '赠送积分', color: 'blue'},
    4: {title: '市场拓展奖', color: 'orange'},
    5: {title: '团队静态收益', color: 'green'},
    6: {title: '个人静态收益', color: 'blue'},
    7: {title: '积分奖励', color: 'orange'},
    }[d.type];
    }}
    <span class="layui-badge febs-bg-{{type.color}}">{{ type.title }}</span>
</script>
<script data-th-inline="none" type="text/javascript">
    layui.use([ 'jquery', 'laydate', 'form', 'table', 'febs', 'treeSelect' ,'eleTree'], function () {
        var $ = layui.jquery,
            laydate = layui.laydate,
            febs = layui.febs,
            form = layui.form,
            table = layui.table
            $view = $('#febs-orderMoneyFlow-child')
            tableIns;
        form.render();
        initTable();
        laydate.render({
            elem: '#user-createTime',
            range: true,
            trigger: 'click'
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'orderMoneyFlowChild',
                url: ctx + 'admin/goods/orderMoneyFlow',
                cols: [[
                    {field: 'address', title: '用户', minWidth: 80,align:'center'},
                    {field: 'amount', title: '金额', minWidth: 80,align:'center'},
                    {title: '类型', minWidth: 100,templet: '#flow-type',align:'center'},
                    {field: 'createdTime', title: '时间', minWidth: 150,align:'left'}
                ]]
            });
        }
    })
</script>
src/main/resources/templates/index.html
@@ -16,6 +16,8 @@
    <link rel="stylesheet" th:href="@{febs/css/formSelects-v4.css}" media="all">
    <!-- 高德地图,key为演示作用,请勿滥用-->
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=0e8a587317998a5e03cf608649b229d6&plugin=AMap.Autocomplete"></script>
    <link href="https://unpkg.com/@wangeditor/editor@5.0.1/dist/css/style.css" rel="stylesheet">
    <script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>
    <link rel="icon" th:href="@{febs/images/favicon.ico}" type="image/x-icon"/>
</head>
<body>