25 files added
4 files renamed
13 files modified
8828 ■■■■■ changed files
src/main/java/cc/mrbird/febs/common/utils/OssUtils.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/AdminMallGoodsController.java 140 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/activity/AdminVotesActivityCategoryController.java 208 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/activity/ApiHappyActivityCategoryController.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/activity/ApiHappyActivityController.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/activity/ApiHappyActivityOrderController.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/activity/ViewHappyActivityController.java 141 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/AdminHappyActivityCategoryDto.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/activity/AdminActivityOptionAddDto.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/activity/AdminCategoryAddDto.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/activity/AdminCategoryUpdateDto.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/activity/ApiVoteOptionInPageDto.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/HappyActivity.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/HappyFollow.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/HappyActivityMapper.java 8 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/HappyActivityService.java 3 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IAdminHappyActivityService.java 56 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/AdminHappyActivityServiceImpl.java 346 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/HappyActivityCategoryServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/HappyActivityServiceImpl.java 45 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/ApiActivityOptionListVo.java 7 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/ApiActivityOptionVo.java 14 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/ApiActivityVo.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/activity/ApiCategoryInfoVo.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/activity/VoteActivityVo.java 42 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/HappyActivityOptionMapper.xml 19 ●●●●● patch | view | raw | blame | history
src/main/resources/static/febs/layarea.js 4073 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/add.html 367 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/discountAudit.html 199 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/discountUpdate.html 412 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/groupAdd.html 95 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/groupInfo.html 112 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/groupList.html 236 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/list.html 253 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/optionAdd-bak.html 293 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/optionAdd.html 348 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/optionInfo-bak.html 373 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/optionInfo.html 408 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/optionList.html 243 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/voteRecord.html 55 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/votesActivity/voteoptionDetail.html 177 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/index.html 3 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/utils/OssUtils.java
@@ -11,8 +11,8 @@
public class OssUtils {
    private static String        END_POINT         = "https://oss-cn-hangzhou.aliyuncs.com";
    private static String       ACCESS_KEY_ID     = "LTAI5tCZ5MZT3372gGq4oC62";
    private static String       ACCESS_KEY_SECRET = "IJkBOYotXQrfrv73PyN6OGHg5NNya9";
    private static String       ACCESS_KEY_ID     = "LTAI5tCH5Ld2n72QmF1A2zXm";
    private static String       ACCESS_KEY_SECRET = "RNIf3J90mV1WdbgraesLusjF7TRRb9";
    private static String         bucket_name       = "https://excoin.oss-cn-hangzhou.aliyuncs.com";
    public static boolean uploadFileWithBase64(String base64, String pathName) {
src/main/java/cc/mrbird/febs/mall/controller/AdminMallGoodsController.java
@@ -108,6 +108,7 @@
    // 文件保存目录URL
    @Value("${static.resource.path}")
    private String resourcePath;
    /**
     *  图片上传
     * @return
@@ -115,58 +116,97 @@
    @PostMapping(value = "/uploadFileBase64")
    @ControllerEndpoint(operation = "图片上传", exceptionMessage = "上传失败")
    public Map<String,Object> uploadFileBase64(@RequestBody @Validated MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            new FebsResponse().message("上传文件为空");
        }
        return FileUtil.fileUploadEsc(file,resourceUrl,resourcePath);
//        String base64EncoderImg = "";
//        BASE64Encoder base64Encoder =new BASE64Encoder();
//        List<String> imageFuffixStr = CollUtil.toList(StrUtil.split(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.9f)
//                        .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();
//            }
//        if (file.isEmpty()) {
//            new FebsResponse().message("上传文件为空");
//        }
//        //文件加密
////        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;
//        return FileUtil.fileUploadEsc(file,resourceUrl,resourcePath);
        if (file == null || file.isEmpty()) {
            return new FebsResponse().message("上传文件为空").fail();
        }
        try {
            byte[] fileBytes = file.getBytes();
            String base64Str = java.util.Base64.getEncoder().encodeToString(fileBytes);
            String imageSuffix = "." + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
            String imageNames = System.currentTimeMillis() + IdUtil.simpleUUID() + imageSuffix;
            String imageName = "hc/" + imageNames;
            OssUtils.uploadFileWithBase64(base64Str, 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>();
            map2.put("src",url);//图片url
            map2.put("title",imageNames);//图片名称,这个会显示在输入框里
            map.put("code",0);//0表示成功,1失败
            map.put("msg","上传成功");//提示消息
            map.put("data",map2);
            return map;
        } catch (IOException e) {
            log.error("上传失败: {}", e.getMessage());
            return new FebsResponse().message("上传失败").fail();
        }
    }
//    /**
//     *  图片上传
//     * @return
//     */
//    @PostMapping(value = "/uploadFileBase64")
//    @ControllerEndpoint(operation = "图片上传", exceptionMessage = "上传失败")
//    public Map<String,Object> uploadFileBase64(@RequestBody @Validated MultipartFile file) throws IOException {
//        if (file.isEmpty()) {
//            new FebsResponse().message("上传文件为空");
//        }
//        return FileUtil.fileUploadEsc(file,resourceUrl,resourcePath);
//
////        String base64EncoderImg = "";
////        BASE64Encoder base64Encoder =new BASE64Encoder();
////        List<String> imageFuffixStr = CollUtil.toList(StrUtil.split(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.9f)
////                        .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;
//    }
    public String Base64ImageByMemory(BufferedImage pic) {
        String imgString = "";
src/main/java/cc/mrbird/febs/mall/controller/activity/AdminVotesActivityCategoryController.java
New file
@@ -0,0 +1,208 @@
package cc.mrbird.febs.mall.controller.activity;
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.RedisUtils;
import cc.mrbird.febs.mall.dto.AdminHappyActivityCategoryDto;
import cc.mrbird.febs.mall.dto.activity.AdminActivityOptionAddDto;
import cc.mrbird.febs.mall.dto.activity.AdminCategoryAddDto;
import cc.mrbird.febs.mall.dto.activity.AdminCategoryUpdateDto;
import cc.mrbird.febs.mall.entity.HappyActivity;
import cc.mrbird.febs.mall.entity.HappyActivityOption;
import cc.mrbird.febs.mall.service.IAdminHappyActivityService;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Map;
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/admin/happyActivity")
public class AdminVotesActivityCategoryController extends BaseController {
    private final IAdminHappyActivityService adminHappyActivityService;
    private final RedisUtils redisUtils;
    /**
     * 分类列表
     * @return
     */
    @GetMapping("groupList")
    public FebsResponse groupList(AdminHappyActivityCategoryDto dto, QueryRequest request) {
        Map<String, Object> data = getDataTable(adminHappyActivityService.getGroupList(dto, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 分类-新增
     */
    @PostMapping("addGroup")
    @ControllerEndpoint(operation = "分类-新增", exceptionMessage = "操作失败")
    public FebsResponse addGroup(@RequestBody @Valid AdminCategoryAddDto dto) {
        return adminHappyActivityService.addGroup(dto);
    }
    /**
     * 分类-删除
     */
    @GetMapping("groupDelete/{id}")
    @ControllerEndpoint(operation = "选项-删除", exceptionMessage = "操作失败")
    public FebsResponse groupDelete(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminHappyActivityService.groupDelete(id);
    }
    /**
     * 分类-更新
     */
    @PostMapping("groupUpdate")
    @ControllerEndpoint(operation = "分类-更新", exceptionMessage = "操作失败")
    public FebsResponse groupUpdate(@RequestBody @Valid AdminCategoryUpdateDto dto) {
        return adminHappyActivityService.groupUpdate(dto);
    }
    /**
     * 分类-开启
     */
    @GetMapping("groupState/{id}/{type}")
    @ControllerEndpoint(operation = "分类-开启", exceptionMessage = "操作失败")
    public FebsResponse groupState(
            @NotNull(message = "{required}") @PathVariable Long id,
            @NotNull(message = "{required}") @PathVariable Integer type) {
        return adminHappyActivityService.groupState(id,type);
    }
    /**
     * 获取分类
     * @return
     */
    @GetMapping(value = "/allGroup")
    public FebsResponse allGroup() {
        return new FebsResponse().success().data(adminHappyActivityService.allGroup());
    }
    /**
     * 活动-列表
     */
    @GetMapping("list")
    public FebsResponse getAdminActivityListInPage(HappyActivity dto, QueryRequest request) {
        Map<String, Object> data = getDataTable(adminHappyActivityService.getAdminActivityListInPage(dto, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 活动-新增
     */
    @PostMapping("add")
    @ControllerEndpoint(operation = "新增", exceptionMessage = "操作失败")
    public FebsResponse addActivity(@RequestBody HappyActivity dto) {
        return adminHappyActivityService.addActivity(dto);
    }
    /**
     * 活动-删除
     */
    @GetMapping("delActivity/{id}")
    @ControllerEndpoint(operation = "活动-删除", exceptionMessage = "删除失败")
    public FebsResponse delActivity(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminHappyActivityService.delActivity(id);
    }
    /**
     * 活动-开启
     */
    @GetMapping("changeState/{id}/{state}")
    @ControllerEndpoint(operation = "活动-开启", exceptionMessage = "操作失败")
    public FebsResponse changeState(@NotNull(message = "{required}") @PathVariable Long id
            ,@NotNull(message = "{required}") @PathVariable Integer state) {
        return adminHappyActivityService.changeState(id,state);
    }
    /**
     * 活动-更新
     */
    @PostMapping("activityUpdate")
    @ControllerEndpoint(operation = "活动-更新", exceptionMessage = "操作失败")
    public FebsResponse activityUpdate(@RequestBody HappyActivity dto) {
        return adminHappyActivityService.activityUpdate(dto);
    }
    /**
     * 获取全部活动
     * @return
     */
    @GetMapping(value = "/allActivities")
    public FebsResponse allActivities() {
        return new FebsResponse().success().data(adminHappyActivityService.allActivities());
    }
    /**
     * 选项-列表
     * @return
     */
    @GetMapping("optionList")
    public FebsResponse optionList(HappyActivityOption dto, QueryRequest request) {
        Map<String, Object> data = getDataTable(adminHappyActivityService.getOptionListInPage(dto, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 选项-新增
     */
    @PostMapping("addOption")
    @ControllerEndpoint(operation = "选项-新增", exceptionMessage = "操作失败")
    public FebsResponse addOption(@RequestBody @Valid AdminActivityOptionAddDto dto) {
        return adminHappyActivityService.addOption(dto);
    }
    /**
     * 选项-更新
     */
    @PostMapping("optionUpdate")
    @ControllerEndpoint(operation = "选项-更新", exceptionMessage = "操作失败")
    public FebsResponse optionUpdate(@RequestBody HappyActivityOption dto) {
        return adminHappyActivityService.optionUpdate(dto);
    }
    /**
     * 选项-删除
     */
    @GetMapping("optionDelete/{id}")
    @ControllerEndpoint(operation = "选项-删除", exceptionMessage = "操作失败")
    public FebsResponse optionDelete(@NotNull(message = "{required}") @PathVariable Long id) {
        return adminHappyActivityService.optionDelete(id);
    }
    /**
     * 选项-得票记录
     */
    @GetMapping("voteRecord")
    public FebsResponse voteRecord(QueryRequest request, Integer parentId) {
        HappyActivityOption voteRecord = new HappyActivityOption();
        String existToken = redisUtils.getString("voteRecord");
        if (StrUtil.isNotBlank(existToken)) {
            redisUtils.del(existToken);
        }
        voteRecord.setId(Long.parseLong(existToken));
        Map<String, Object> data = getDataTable(adminHappyActivityService.getFollowVoteInPage(voteRecord,request));
        return new FebsResponse().success().data(data);
    }
}
src/main/java/cc/mrbird/febs/mall/controller/activity/ApiHappyActivityCategoryController.java
File was renamed from src/main/java/cc/mrbird/febs/mall/controller/ApiHappyActivityCategoryController.java
@@ -1,8 +1,8 @@
package cc.mrbird.febs.mall.controller;
package cc.mrbird.febs.mall.controller.activity;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.service.HappyActivityCategoryService;
import cc.mrbird.febs.mall.vo.ApiCategoryInfoVo;
import cc.mrbird.febs.mall.vo.activity.ApiCategoryInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
src/main/java/cc/mrbird/febs/mall/controller/activity/ApiHappyActivityController.java
File was renamed from src/main/java/cc/mrbird/febs/mall/controller/ApiHappyActivityController.java
@@ -1,8 +1,9 @@
package cc.mrbird.febs.mall.controller;
package cc.mrbird.febs.mall.controller.activity;
import cc.mrbird.febs.common.annotation.Limit;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.dto.activity.ApiVoteOptionInPageDto;
import cc.mrbird.febs.mall.service.HappyActivityService;
import cc.mrbird.febs.mall.vo.*;
import io.swagger.annotations.Api;
@@ -56,10 +57,10 @@
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiActivityOptionListVo.class)
    })
    @GetMapping(value = "/voteOptionList/{id}")
    public FebsResponse voteOptionList(@PathVariable("id") Long id) {
    @GetMapping(value = "/voteOptionInPage")
    public FebsResponse voteOptionInPage(@RequestBody @Validated ApiVoteOptionInPageDto dto) {
        return happyActivityService.voteOptionList(id);
        return happyActivityService.voteOptionInPage(dto);
    }
    @ApiOperation(value = "投票活动-选项详情", notes = "投票活动-选项详情")
src/main/java/cc/mrbird/febs/mall/controller/activity/ApiHappyActivityOrderController.java
File was renamed from src/main/java/cc/mrbird/febs/mall/controller/ApiHappyActivityOrderController.java
@@ -1,4 +1,4 @@
package cc.mrbird.febs.mall.controller;
package cc.mrbird.febs.mall.controller.activity;
import cc.mrbird.febs.common.annotation.Limit;
import cc.mrbird.febs.common.entity.FebsResponse;
src/main/java/cc/mrbird/febs/mall/controller/activity/ViewHappyActivityController.java
New file
@@ -0,0 +1,141 @@
package cc.mrbird.febs.mall.controller.activity;
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.common.utils.RedisUtils;
import cc.mrbird.febs.mall.entity.HappyActivity;
import cc.mrbird.febs.mall.entity.HappyActivityCategory;
import cc.mrbird.febs.mall.entity.HappyActivityOption;
import cc.mrbird.febs.mall.mapper.HappyActivityCategoryMapper;
import cc.mrbird.febs.mall.mapper.HappyActivityOptionMapper;
import cc.mrbird.febs.mall.service.IAdminHappyActivityService;
import cn.hutool.core.util.StrUtil;
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("votesActivityView")
@RequestMapping(FebsConstant.VIEW_PREFIX + "modules/votesActivity")
@RequiredArgsConstructor
public class ViewHappyActivityController extends BaseController {
    private final IAdminHappyActivityService iAdminHappyActivityService;
    private final HappyActivityCategoryMapper happyActivityCategoryMapper;
    private final HappyActivityOptionMapper happyActivityOptionMapper;
    private final RedisUtils redisUtils;
    /**
     * 活动分类列表
     */
    @GetMapping("groupList")
    @RequiresPermissions("groupList:view")
    public String groupList() {
        return FebsUtil.view("modules/votesActivity/groupList");
    }
    /**
     * 活动分类新增
     * @return
     */
    @GetMapping(value = "/groupAdd")
    @RequiresPermissions("groupAdd:add")
    public String groupAdd() {
        return FebsUtil.view("modules/votesActivity/groupAdd");
    }
    /**
     * 活动分类编辑
     * @param id
     * @param model
     * @return
     */
    @GetMapping("groupInfo/{id}")
    @RequiresPermissions("groupInfo:view")
    public String groupInfo(@PathVariable long id, Model model) {
        HappyActivityCategory voteActivityGroup = happyActivityCategoryMapper.selectById(id);
        model.addAttribute("voteActivityGroup", voteActivityGroup);
        return FebsUtil.view("modules/votesActivity/groupInfo");
    }
    /**
     * 活动-列表
     */
    @GetMapping("list")
    @RequiresPermissions("list:view")
    public String activityList() {
        return FebsUtil.view("modules/votesActivity/list");
    }
    /**
     * 活动-新增
     */
    @GetMapping("add")
    @RequiresPermissions("add:add")
    public String activityAdd() {
        return FebsUtil.view("modules/votesActivity/add");
    }
    /**
     * 活动-修改
     */
    @GetMapping("votesActivityUpdate/{id}")
    @RequiresPermissions("votesActivityUpdate:update")
    public String votesActivityctivityUpdate(@PathVariable long id, Model model) {
        HappyActivity happyActivity = iAdminHappyActivityService.getBaseMapper().selectById(id);
        model.addAttribute("activity", happyActivity);
        return FebsUtil.view("modules/votesActivity/discountUpdate");
    }
    /**
     * 活动-选项列表
     */
    @GetMapping("optionList")
    @RequiresPermissions("optionList:view")
    public String optionList() {
        return FebsUtil.view("modules/votesActivity/optionList");
    }
    /**
     * 活动-选项新增
     * @return
     */
    @GetMapping(value = "/optionAdd")
    @RequiresPermissions("optionAdd:add")
    public String optionAdd() {
        return FebsUtil.view("modules/votesActivity/optionAdd");
    }
    /**
     * 活动-选项编辑
     * @param id
     * @param model
     * @return
     */
    @GetMapping("optionInfo/{id}")
    @RequiresPermissions("optionInfo:view")
    public String optionInfo(@PathVariable long id, Model model) {
        HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(id);
        model.addAttribute("voteOption", happyActivityOption);
        return FebsUtil.view("modules/votesActivity/optionInfo");
    }
    /**
     * 活动-得票记录
     * @return
     */
    @GetMapping("voteRecord/{id}")
    @RequiresPermissions("voteRecord:view")
    public String moneyFlow(@PathVariable long id, Model model) {
        String existToken = redisUtils.getString("voteRecord");
        if (StrUtil.isNotBlank(existToken)) {
            redisUtils.del(existToken);
        }
        redisUtils.set("voteRecord", id, -1);
        return FebsUtil.view("modules/votesActivity/voteRecord");
    }
}
src/main/java/cc/mrbird/febs/mall/dto/AdminHappyActivityCategoryDto.java
New file
@@ -0,0 +1,10 @@
package cc.mrbird.febs.mall.dto;
import lombok.Data;
@Data
public class AdminHappyActivityCategoryDto {
    private String name;
    private Integer status;
    private Integer hotState;
}
src/main/java/cc/mrbird/febs/mall/dto/activity/AdminActivityOptionAddDto.java
New file
@@ -0,0 +1,39 @@
package cc.mrbird.febs.mall.dto.activity;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class AdminActivityOptionAddDto {
    @NotNull(message = "所属活动不能为空")
    private Long activityId;//投票活动ID
    @NotBlank(message = "选项名称不能为空")
    private String optionName;//佳丽姓名
    private String realName;//注册姓名
    private String image;//投票选项图片 URL
    private String description;//投票活动描述
    private String videoUrl; //视频url
    private String mobilePhone;//手机
    private String sex;//性别
    private String hobby;//兴趣爱好
    private String mcnState;//是否签约MCN机构 0否 1是
    private String address;//地址
    private String province;//省份
    private String city;//城市
    private String email;//邮箱
}
src/main/java/cc/mrbird/febs/mall/dto/activity/AdminCategoryAddDto.java
New file
@@ -0,0 +1,16 @@
package cc.mrbird.febs.mall.dto.activity;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class AdminCategoryAddDto {
    @NotBlank(message = "名称不能为空")
    private String name;
    @NotNull(message = "排序不能为空")
    private Integer orderCnt;
}
src/main/java/cc/mrbird/febs/mall/dto/activity/AdminCategoryUpdateDto.java
New file
@@ -0,0 +1,19 @@
package cc.mrbird.febs.mall.dto.activity;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class AdminCategoryUpdateDto {
    @NotNull(message = "ID不能为空")
    private Long id;
    @NotBlank(message = "名称不能为空")
    private String name;
    @NotNull(message = "排序不能为空")
    private Integer orderCnt;
}
src/main/java/cc/mrbird/febs/mall/dto/activity/ApiVoteOptionInPageDto.java
New file
@@ -0,0 +1,24 @@
package cc.mrbird.febs.mall.dto.activity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(value = "ApiVoteOptionInPageDto", description = "参数")
public class ApiVoteOptionInPageDto {
    @NotNull(message = "页码不能为空")
    @ApiModelProperty(value = "页码", example = "1")
    private Integer pageNow;
    @NotNull(message = "每页数量不能为空")
    @ApiModelProperty(value = "每页数量", example = "10")
    private Integer pageSize;
    @NotNull(message = "活动ID不能为空")
    @ApiModelProperty(value = "活动ID")
    private Long activityId;
}
src/main/java/cc/mrbird/febs/mall/entity/HappyActivity.java
@@ -1,6 +1,7 @@
package cc.mrbird.febs.mall.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@@ -36,8 +37,11 @@
     `back_img` varchar(500) DEFAULT NULL COMMENT '背景图片',
     `DELETE_FLAG` int(11) DEFAULT '0' COMMENT '删除标识 0-未删除 1-已删除',
     `vote_cnt` int(11) DEFAULT NULL COMMENT '投票数量',
     `add_state` int(11) DEFAULT '0' COMMENT '是否允许报名 0-不允许 1-允许',
     */
    private Long categoryId;
    @TableField(exist = false)
    private String categoryName;//
    private String code;
    private String name;
    private Integer type;
@@ -61,6 +65,7 @@
    private String backImg;
    private Integer deleteFlag;
    private Integer voteCnt;
    private Integer addState;
}
src/main/java/cc/mrbird/febs/mall/entity/HappyFollow.java
@@ -1,6 +1,7 @@
package cc.mrbird.febs.mall.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@@ -18,9 +19,21 @@
     `DELETE_FLAG` int(11) DEFAULT '0' COMMENT '删除标识 0-未删除 1-已删除',
     */
    private Long memberId;
    //用户昵称
    @TableField(exist = false)
    private String memberName;
    private Integer sourceType;
    private Long sourceId;
    //活动名称
    @TableField(exist = false)
    private String activityName;
    private Long sourceOptionId;
    //选项名称
    @TableField(exist = false)
    private String optionName;
    private Integer type;
    private Integer deleteFlag;
src/main/java/cc/mrbird/febs/mall/mapper/HappyActivityMapper.java
@@ -1,9 +1,11 @@
package cc.mrbird.febs.mall.mapper;
import cc.mrbird.febs.mall.dto.activity.ApiVoteOptionInPageDto;
import cc.mrbird.febs.mall.entity.HappyActivity;
import cc.mrbird.febs.mall.dto.ApiActivityInfoDto;
import cc.mrbird.febs.mall.vo.ApiActivityInfoVo;
import cc.mrbird.febs.mall.dto.ApiVoteRecordInPageDto;
import cc.mrbird.febs.mall.vo.ApiActivityOptionListVo;
import cc.mrbird.febs.mall.vo.ApiVoteRecordInPageVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -13,5 +15,9 @@
    Page<ApiActivityInfoVo> selectActivityPage(Page<ApiActivityInfoVo> page, @Param("record")ApiActivityInfoDto dto);
    Page<ApiVoteRecordInPageVo> getVoteRecordInPage(Page<ApiActivityInfoVo> page, @Param("record")ApiVoteRecordInPageDto dto);
    Page<ApiVoteRecordInPageVo> getVoteRecordInPage(Page<ApiVoteRecordInPageVo> page, @Param("record")ApiVoteRecordInPageDto dto);
    void updateHappyActivityOptionLikeCnt(@Param("id")Long sourceOptionId);
    Page<ApiActivityOptionListVo> getVoteOptionInPage(Page<ApiActivityOptionListVo> page, @Param("record")ApiVoteOptionInPageDto dto);
}
src/main/java/cc/mrbird/febs/mall/service/HappyActivityService.java
@@ -2,6 +2,7 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.dto.activity.ApiVoteOptionInPageDto;
import cc.mrbird.febs.mall.entity.HappyActivity;
import cc.mrbird.febs.mall.dto.ApiOperateDoDto;
import cc.mrbird.febs.mall.dto.ApiOperateVoteDto;
@@ -14,7 +15,7 @@
    FebsResponse activityInfo(ApiActivityDto dto);
    FebsResponse voteOptionList(Long id);
    FebsResponse voteOptionInPage(ApiVoteOptionInPageDto dto);
    FebsResponse voteOption(Long id);
src/main/java/cc/mrbird/febs/mall/service/IAdminHappyActivityService.java
New file
@@ -0,0 +1,56 @@
package cc.mrbird.febs.mall.service;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.mall.dto.AdminHappyActivityCategoryDto;
import cc.mrbird.febs.mall.dto.activity.AdminActivityOptionAddDto;
import cc.mrbird.febs.mall.dto.activity.AdminCategoryAddDto;
import cc.mrbird.febs.mall.dto.activity.AdminCategoryUpdateDto;
import cc.mrbird.febs.mall.entity.HappyActivity;
import cc.mrbird.febs.mall.entity.HappyActivityCategory;
import cc.mrbird.febs.mall.entity.HappyActivityOption;
import cc.mrbird.febs.mall.entity.HappyFollow;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
public interface IAdminHappyActivityService extends IService<HappyActivity>{
    IPage<HappyActivityCategory> getGroupList(AdminHappyActivityCategoryDto dto, QueryRequest request);
    FebsResponse addGroup(AdminCategoryAddDto dto);
    FebsResponse groupDelete(@NotNull(message = "{required}") Long id);
    FebsResponse groupUpdate(@Valid AdminCategoryUpdateDto dto);
    FebsResponse groupState(@NotNull(message = "{required}") Long id, @NotNull(message = "{required}") Integer type);
    List<HappyActivityCategory> allGroup();
    IPage<HappyActivity> getAdminActivityListInPage(HappyActivity dto, QueryRequest request);
    FebsResponse addActivity(HappyActivity dto);
    FebsResponse delActivity(Long id);
    FebsResponse changeState(Long id, Integer state);
    FebsResponse activityUpdate(HappyActivity dto);
    IPage<HappyActivityOption> getOptionListInPage(HappyActivityOption dto, QueryRequest request);
    List<HappyActivity> allActivities();
    FebsResponse addOption(AdminActivityOptionAddDto dto);
    FebsResponse optionUpdate(HappyActivityOption dto);
    FebsResponse optionDelete(Long id);
    IPage<HappyFollow> getFollowVoteInPage(HappyActivityOption voteRecord, QueryRequest request);
}
src/main/java/cc/mrbird/febs/mall/service/impl/AdminHappyActivityServiceImpl.java
New file
@@ -0,0 +1,346 @@
package cc.mrbird.febs.mall.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.enumerates.StateUpDownEnum;
import cc.mrbird.febs.common.utils.MallUtils;
import cc.mrbird.febs.mall.dto.AdminHappyActivityCategoryDto;
import cc.mrbird.febs.mall.dto.activity.AdminActivityOptionAddDto;
import cc.mrbird.febs.mall.dto.activity.AdminCategoryAddDto;
import cc.mrbird.febs.mall.dto.activity.AdminCategoryUpdateDto;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.IAdminHappyActivityService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class AdminHappyActivityServiceImpl extends ServiceImpl<HappyActivityMapper, HappyActivity> implements IAdminHappyActivityService {
    private final HappyActivityCategoryMapper happyActivityCategoryMapper;
    private final HappyActivityOptionMapper happyActivityOptionMapper;
    private final HappyFollowMapper happyFollowMapper;
    private final MallMemberMapper mallMemberMapper;
    @Override
    public IPage<HappyActivityCategory> getGroupList(AdminHappyActivityCategoryDto dto, QueryRequest request) {
        Page<HappyActivityCategory> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<HappyActivityCategory> voteOptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(StrUtil.isNotEmpty(dto.getName())){
            voteOptionLambdaQueryWrapper.eq(HappyActivityCategory::getName,dto.getName());
        }
        if(ObjectUtil.isNotEmpty(dto.getStatus())){
            voteOptionLambdaQueryWrapper.eq(HappyActivityCategory::getState,dto.getStatus());
        }
        if(ObjectUtil.isNotEmpty(dto.getHotState())){
            voteOptionLambdaQueryWrapper.eq(HappyActivityCategory::getHotState,dto.getHotState());
        }
        voteOptionLambdaQueryWrapper.eq(HappyActivityCategory::getDeleteFlag, StateUpDownEnum.DOWN.getCode());
        voteOptionLambdaQueryWrapper.orderByDesc(HappyActivityCategory::getCreatedTime);
        Page<HappyActivityCategory> adminOptionVoIPage = happyActivityCategoryMapper.selectPage(page, voteOptionLambdaQueryWrapper);
        return adminOptionVoIPage;
    }
    @Override
    public FebsResponse addGroup(AdminCategoryAddDto dto) {
        HappyActivityCategory happyActivityCategory = new HappyActivityCategory();
        happyActivityCategory.setName(dto.getName());
        happyActivityCategory.setOrderCnt(dto.getOrderCnt());
        happyActivityCategoryMapper.insert(happyActivityCategory);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse groupDelete(Long id) {
        HappyActivityCategory happyActivityCategory = happyActivityCategoryMapper.selectById(id);
        happyActivityCategory.setDeleteFlag(StateUpDownEnum.UP.getCode());
        happyActivityCategoryMapper.updateById(happyActivityCategory);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse groupUpdate(AdminCategoryUpdateDto dto) {
        HappyActivityCategory happyActivityCategory = happyActivityCategoryMapper.selectById(dto.getId());
        happyActivityCategory.setName(dto.getName());
        happyActivityCategory.setOrderCnt(dto.getOrderCnt());
        happyActivityCategoryMapper.updateById(happyActivityCategory);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse groupState(Long id, Integer type) {
        HappyActivityCategory happyActivityCategory = happyActivityCategoryMapper.selectById(id);
        if(StateUpDownEnum.UP.getCode() == happyActivityCategory.getDeleteFlag()){
            throw new RuntimeException("该分组已删除,无法操作");
        }
        if(type == 1){
            happyActivityCategory.setHotState(happyActivityCategory.getHotState() == StateUpDownEnum.UP.getCode() ? StateUpDownEnum.DOWN.getCode() : StateUpDownEnum.UP.getCode());
        }
        if(type == 2){
            happyActivityCategory.setState(happyActivityCategory.getState() == StateUpDownEnum.UP.getCode() ? StateUpDownEnum.DOWN.getCode() : StateUpDownEnum.UP.getCode());
        }
        happyActivityCategoryMapper.updateById(happyActivityCategory);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public List<HappyActivityCategory> allGroup() {
        List<HappyActivityCategory> happyActivityCategories =
                happyActivityCategoryMapper.selectList(
                        new LambdaQueryWrapper<HappyActivityCategory>()
                                .eq(HappyActivityCategory::getState, StateUpDownEnum.UP.getCode())
                                .eq(HappyActivityCategory::getDeleteFlag, StateUpDownEnum.DOWN.getCode())
                                .orderByDesc(HappyActivityCategory::getOrderCnt)
                );
        if(CollUtil.isNotEmpty(happyActivityCategories)){
            return happyActivityCategories;
        }
        return Collections.emptyList();
    }
    @Override
    public IPage<HappyActivity> getAdminActivityListInPage(HappyActivity dto, QueryRequest request) {
        Page<HappyActivity> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<HappyActivity> voteActivityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(StrUtil.isNotEmpty(dto.getName())){
            voteActivityLambdaQueryWrapper.like(HappyActivity::getName,dto.getName());
        }
        if(ObjectUtil.isNotEmpty(dto.getState())){
            voteActivityLambdaQueryWrapper.eq(HappyActivity::getState,dto.getState());
        }
        if(ObjectUtil.isNotEmpty(dto.getCategoryId())){
            voteActivityLambdaQueryWrapper.eq(HappyActivity::getCategoryId,dto.getCategoryId());
        }
        voteActivityLambdaQueryWrapper.eq(HappyActivity::getDeleteFlag, StateUpDownEnum.DOWN.getCode());
        voteActivityLambdaQueryWrapper.orderByDesc(HappyActivity::getCreatedTime);
        Page<HappyActivity> voteActivityPage = this.baseMapper.selectPage(page, voteActivityLambdaQueryWrapper);
        List<HappyActivity> records = voteActivityPage.getRecords();
        if(CollUtil.isNotEmpty(records)){
            //stream流获取records的全部categoryId
            Set<Long> categoryIds = records.stream().map(HappyActivity::getCategoryId).collect(Collectors.toSet());
            if(CollUtil.isNotEmpty(categoryIds)){
                //stream流操作categoryIds得到一个Map<categoryId,HappyActivityCategory>的map对象
                List<HappyActivityCategory> happyActivityCategories = happyActivityCategoryMapper.selectList(
                        new LambdaQueryWrapper<HappyActivityCategory>()
                                .select(HappyActivityCategory::getId, HappyActivityCategory::getName)
                                .in(HappyActivityCategory::getId,categoryIds)
                );
                Map<Long, HappyActivityCategory> categoryMap = happyActivityCategories.stream().collect(Collectors.toMap(HappyActivityCategory::getId, happyActivityCategory -> happyActivityCategory));
                for (HappyActivity happyActivity : records){
                    happyActivity.setCategoryName(categoryMap.get(happyActivity.getCategoryId()).getName());
                }
            }
        }
        return voteActivityPage;
    }
    @Override
    public FebsResponse addActivity(HappyActivity dto) {
        String code = MallUtils.getOrderNum("AC");
        HappyActivity happyActivity = new HappyActivity();
        BeanUtil.copyProperties(dto, happyActivity);
        happyActivity.setCode(code);
        this.baseMapper.insert(happyActivity);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse delActivity(Long id) {
        HappyActivity happyActivity = this.baseMapper.selectById(id);
        happyActivity.setDeleteFlag(StateUpDownEnum.UP.getCode());
        this.baseMapper.updateById(happyActivity);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse changeState(Long id, Integer state) {
        HappyActivity happyActivity = this.baseMapper.selectById(id);
        happyActivity.setState(state);
        this.baseMapper.updateById(happyActivity);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse activityUpdate(HappyActivity dto) {
        HappyActivity happyActivity = this.baseMapper.selectById(dto.getId());
        happyActivity.setCategoryId(dto.getCategoryId());
        happyActivity.setName(dto.getName());
        happyActivity.setType(dto.getType());
        happyActivity.setJoinCnt(dto.getJoinCnt());
        happyActivity.setStartTime(dto.getStartTime());
        happyActivity.setEndTime(dto.getEndTime());
        happyActivity.setPhone(dto.getPhone());
        happyActivity.setAddress(dto.getAddress());
        happyActivity.setPayState(dto.getPayState());
        happyActivity.setPayAmount(dto.getPayAmount());
        happyActivity.setTextRemark(dto.getTextRemark());
        happyActivity.setIndexImg(dto.getIndexImg());
        happyActivity.setOrderCnt(dto.getOrderCnt());
        happyActivity.setHotState(dto.getHotState());
        happyActivity.setBackImg(dto.getBackImg());
        happyActivity.setVoteCnt(dto.getVoteCnt());
        happyActivity.setAddState(dto.getAddState());
        this.baseMapper.updateById(happyActivity);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public IPage<HappyActivityOption> getOptionListInPage(HappyActivityOption dto, QueryRequest request) {
        List<HappyActivity> happyActivities = this.baseMapper.selectList(
                new LambdaQueryWrapper<HappyActivity>()
                        .select(HappyActivity::getId)
                        .eq(HappyActivity::getType, StateUpDownEnum.ACTIVITY_TYPE_VOTE.getCode())
        );
        if(CollUtil.isEmpty(happyActivities)){
            return new Page<>();
        }
        //stream流操作happyActivities得到一个set<id>集合
        Set<Long> activityIds = happyActivities.stream().map(HappyActivity::getId).collect(Collectors.toSet());
        Page<HappyActivityOption> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<HappyActivityOption> voteOptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(ObjectUtil.isNotEmpty(dto.getActivityId())){
            voteOptionLambdaQueryWrapper.eq(HappyActivityOption::getActivityId,dto.getActivityId());
        }
        if(ObjectUtil.isNotEmpty(dto.getState())){
            voteOptionLambdaQueryWrapper.eq(HappyActivityOption::getState,dto.getState());
        }
        if(ObjectUtil.isNotEmpty(dto.getOptionName())){
            voteOptionLambdaQueryWrapper.eq(HappyActivityOption::getOptionName,dto.getOptionName());
        }
        voteOptionLambdaQueryWrapper.in(HappyActivityOption::getActivityId,activityIds);
        voteOptionLambdaQueryWrapper.eq(HappyActivityOption::getDeleteFlag, StateUpDownEnum.DOWN.getCode());
        voteOptionLambdaQueryWrapper.orderByDesc(HappyActivityOption::getCreatedTime);
        Page<HappyActivityOption> adminOptionVoIPage = happyActivityOptionMapper.selectPage(page, voteOptionLambdaQueryWrapper);
        return adminOptionVoIPage;
    }
    @Override
    public List<HappyActivity> allActivities() {
        List<HappyActivity> happyActivities = this.baseMapper.selectList(
                new LambdaQueryWrapper<HappyActivity>()
                        .select(HappyActivity::getId, HappyActivity::getName)
                        .eq(HappyActivity::getType, StateUpDownEnum.ACTIVITY_TYPE_VOTE.getCode())
                        .eq(HappyActivity::getDeleteFlag, StateUpDownEnum.DOWN.getCode())
        );
        return happyActivities;
    }
    @Override
    public FebsResponse addOption(AdminActivityOptionAddDto dto) {
        if(ObjectUtil.isEmpty(dto.getActivityId())){
            return new FebsResponse().fail().message("请选择投票活动");
        }
        List<HappyActivityOption> happyActivityOptions = happyActivityOptionMapper.selectList(
                new LambdaQueryWrapper<HappyActivityOption>()
                        .eq(HappyActivityOption::getActivityId, dto.getActivityId())
                        .eq(HappyActivityOption::getDeleteFlag, StateUpDownEnum.DOWN.getCode())
        );
        HappyActivityOption happyActivityOption = new HappyActivityOption();
        BeanUtil.copyProperties(dto, happyActivityOption);
        happyActivityOption.setOrderCnt(CollUtil.isEmpty(happyActivityOptions) ? 1 : happyActivityOptions.size() + 1);
        happyActivityOptionMapper.insert(happyActivityOption);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse optionUpdate(HappyActivityOption dto) {
        HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(dto.getId());
        BeanUtil.copyProperties(dto, happyActivityOption);
        happyActivityOptionMapper.updateById(happyActivityOption);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public FebsResponse optionDelete(Long id) {
        HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(id);
        happyActivityOption.setDeleteFlag(StateUpDownEnum.UP.getCode());
        happyActivityOptionMapper.updateById(happyActivityOption);
        return new FebsResponse().success().message("操作成功");
    }
    @Override
    public IPage<HappyFollow> getFollowVoteInPage(HappyActivityOption voteRecord, QueryRequest request) {
        Long id = voteRecord.getId();
        HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(id);
        if(ObjectUtil.isEmpty(happyActivityOption)){
            return null;
        }
        HappyActivity happyActivity = this.baseMapper.selectById(happyActivityOption.getActivityId());
        if(ObjectUtil.isEmpty(happyActivity)){
            return null;
        }
        //获取活动名称
        String activityName = happyActivity.getName();
        //获取选项名称
        String optionName = happyActivityOption.getOptionName();
        Page<HappyFollow> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<HappyFollow> voteRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        voteRecordLambdaQueryWrapper.eq(HappyFollow::getSourceId, happyActivity.getId());
        voteRecordLambdaQueryWrapper.eq(HappyFollow::getSourceOptionId, happyActivityOption.getId());
        voteRecordLambdaQueryWrapper.eq(HappyFollow::getType,StateUpDownEnum.VOTE.getCode());
        voteRecordLambdaQueryWrapper.orderByDesc(HappyFollow::getCreatedTime);
        Page<HappyFollow> adminIPage = happyFollowMapper.selectPage(page, voteRecordLambdaQueryWrapper);
        if(CollUtil.isNotEmpty(adminIPage.getRecords())){
            List<HappyFollow> records = adminIPage.getRecords();
            //stream流获取records的memberId的set集合
            Set<Long> memberIds = records.stream().map(HappyFollow::getMemberId).collect(Collectors.toSet());
            List<MallMember> mallMembers = mallMemberMapper.selectList(new LambdaQueryWrapper<MallMember>().in(MallMember::getId, memberIds));
            Map<Long, MallMember> mallMemberMap = mallMembers.stream().collect(Collectors.toMap(MallMember::getId, mallMember -> mallMember));
            for(HappyFollow record : records){
                record.setActivityName(activityName);
                record.setOptionName(optionName);
                String memberName = mallMemberMap.get(record.getMemberId()).getName();
                record.setMemberName(StrUtil.isEmpty(memberName) ? "未知用户" : memberName);
            }
        }
        return adminIPage;
    }
}
src/main/java/cc/mrbird/febs/mall/service/impl/HappyActivityCategoryServiceImpl.java
@@ -5,7 +5,7 @@
import cc.mrbird.febs.mall.entity.HappyActivityCategory;
import cc.mrbird.febs.mall.mapper.HappyActivityCategoryMapper;
import cc.mrbird.febs.mall.service.HappyActivityCategoryService;
import cc.mrbird.febs.mall.vo.ApiCategoryInfoVo;
import cc.mrbird.febs.mall.vo.activity.ApiCategoryInfoVo;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
src/main/java/cc/mrbird/febs/mall/service/impl/HappyActivityServiceImpl.java
@@ -7,6 +7,7 @@
import cc.mrbird.febs.common.utils.MallUtils;
import cc.mrbird.febs.common.utils.ShareCodeUtil;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.dto.activity.ApiVoteOptionInPageDto;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.HappyActivityService;
@@ -134,37 +135,11 @@
    }
    @Override
    public FebsResponse voteOptionList(Long id) {
        ArrayList<ApiActivityOptionListVo> apiActivityOptionListVos = new ArrayList<>();
        HappyActivity happyActivity = this.baseMapper.selectById(id);
        if(StateUpDownEnum.ACTIVITY_TYPE_VOTE.getCode() != happyActivity.getType()){
            throw new FebsException("投票活动才可获取投票选项");
        }
        List<HappyActivityOption> happyActivityOptions = happyActivityOptionMapper.selectList(
                new LambdaQueryWrapper<HappyActivityOption>()
                        .select(
                                HappyActivityOption::getId,
                                HappyActivityOption::getOptionName,
                                HappyActivityOption::getRank,
                                HappyActivityOption::getLikesCnt,
                                HappyActivityOption::getImage
                        )
                .eq(HappyActivityOption::getActivityId,id)
                .eq(HappyActivityOption::getState,StateUpDownEnum.VOTE_OPTION_STATE_AUDIT_SUCCESS.getCode())
                .eq(HappyActivityOption::getDeleteFlag,StateUpDownEnum.DOWN.getCode())
                .orderByAsc(HappyActivityOption::getRank)
        );
        if(CollUtil.isNotEmpty(happyActivityOptions)){
            happyActivityOptions.forEach(option -> {
                ApiActivityOptionListVo apiActivityOptionListVo = new ApiActivityOptionListVo();
                BeanUtil.copyProperties(option, apiActivityOptionListVo);
                apiActivityOptionListVos.add(apiActivityOptionListVo);
            });
        }
        return new FebsResponse().success().data(apiActivityOptionListVos);
    public FebsResponse voteOptionInPage(ApiVoteOptionInPageDto dto) {
        // 创建分页对象,传入当前页和每页大小
        Page<ApiActivityOptionListVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        Page<ApiActivityOptionListVo> voteRecordInPage = this.baseMapper.getVoteOptionInPage(page, dto);
        return new FebsResponse().success().data(voteRecordInPage);
    }
    @Override
@@ -252,7 +227,7 @@
        }
        HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(sourceOptionId);
        if (happyActivityOption == null) {
        if (null == happyActivityOption) {
            throw new FebsException("投票对象不存在");
        }
        if (StateUpDownEnum.VOTE_OPTION_STATE_AUDIT_SUCCESS.getCode() != happyActivityOption.getState()) {
@@ -268,17 +243,17 @@
                        .gt(HappyFollow::getCreatedTime, DateUtil.beginOfDay(new Date()))
        );
        if (CollUtil.isNotEmpty(happyFollows) && happyFollows.size() >= happyActivity.getVoteCnt()){
            throw new FebsException("今日已经投票");
            throw new FebsException("今日已经投完票");
        }
        this.baseMapper.updateHappyActivityOptionLikeCnt(sourceOptionId);
        this.operateDoVote(memberId, sourceType, sourceId, sourceOptionId, type);
        this.addLikeCnt(sourceOptionId);
        return new FebsResponse().success();
    }
    @Override
    public FebsResponse voteRecordInPage(ApiVoteRecordInPageDto dto) {
        // 创建分页对象,传入当前页和每页大小
        Page<ApiActivityInfoVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        Page<ApiVoteRecordInPageVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        Page<ApiVoteRecordInPageVo> voteRecordInPage = this.baseMapper.getVoteRecordInPage(page, dto);
        List<ApiVoteRecordInPageVo> records = voteRecordInPage.getRecords();
src/main/java/cc/mrbird/febs/mall/vo/ApiActivityOptionListVo.java
@@ -14,13 +14,10 @@
    @ApiModelProperty(value = "选项名称")
    private String optionName;
    @ApiModelProperty(value = "排名")
    private Integer rank;
    @ApiModelProperty(value = "点赞数量")
    @ApiModelProperty(value = "投票数量")
    private Integer likesCnt;
    @ApiModelProperty(value = "投票选项图片 URL")
    @ApiModelProperty(value = "封面")
    private String image;
}
src/main/java/cc/mrbird/febs/mall/vo/ApiActivityOptionVo.java
@@ -14,23 +14,17 @@
    @ApiModelProperty(value = "选项名称")
    private String optionName;
    @ApiModelProperty(value = "排名")
    private Integer rank;
    @ApiModelProperty(value = "点赞数量")
    @ApiModelProperty(value = "票数")
    private Integer likesCnt;
    @ApiModelProperty(value = "投票选项图片 URL")
    @ApiModelProperty(value = "封面头像")
    private String image;
    @ApiModelProperty(value = "投票选项视频URL")
    @ApiModelProperty(value = "作品")
    private String videoUrl;
    @ApiModelProperty(value = "选项描述")
    private String description;
    @ApiModelProperty(value = "名称")
    private String realName;
    @ApiModelProperty(value = "性别 0-女1-男  2-保密")
    private Integer sex;
@@ -41,6 +35,4 @@
    @ApiModelProperty(value = "是否签约mcn机构 0否 1是")
    private Integer mcnState;
    @ApiModelProperty(value = "投票数量")
    private Integer voteCnt;
}
src/main/java/cc/mrbird/febs/mall/vo/ApiActivityVo.java
@@ -29,6 +29,9 @@
    @ApiModelProperty(value = "状态 0-未开始 1-报名中(进行中) 2-已结束")
    private Integer state;
    @ApiModelProperty(value = "是否允许报名 0-不允许 1-允许")
    private Integer addState;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;
src/main/java/cc/mrbird/febs/mall/vo/activity/ApiCategoryInfoVo.java
File was renamed from src/main/java/cc/mrbird/febs/mall/vo/ApiCategoryInfoVo.java
@@ -1,4 +1,4 @@
package cc.mrbird.febs.mall.vo;
package cc.mrbird.febs.mall.vo.activity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
src/main/java/cc/mrbird/febs/mall/vo/activity/VoteActivityVo.java
New file
@@ -0,0 +1,42 @@
package cc.mrbird.febs.mall.vo.activity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
 * 投票活动表
 */
@Data
public class VoteActivityVo extends BaseEntity {
    private String name;//投票活动名称
    //活动分类ID
    private Long groupId;
    private String coverImage;//活动封面图片 URL
    private String activityType;//活动类型
    private String votesType;//投票类型
    private String isMultiple;//是否多选
    private String introduce;//投票活动描述
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;//投票开始时间;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date endTime;//投票结束时间;
    private String totalVotes;//票数总数
    private String totalParticipants;//参与人数
    private Integer status;//状态 1.未开始 2.已开始
    private Integer proStatus;//进行状态 1.未开始 2.已开始 3.已结束
}
src/main/resources/mapper/modules/HappyActivityOptionMapper.xml
@@ -42,4 +42,23 @@
        order by a.id desc
    </select>
    <update id="updateHappyActivityOptionLikeCnt" >
        update happy_activity_option set likes_cnt = likes_cnt + 1 where id = #{id}
    </update>
    <select id="getVoteOptionInPage" resultType="cc.mrbird.febs.mall.vo.ApiActivityOptionListVo">
        select
            a.id as id,
            a.option_name as optionName,
            a.image as image,
            a.likes_cnt as likesCnt
        from happy_activity_option a
        where
            a.state = 1
          and a.activity_id = #{record.activityId}
          and a.DELETE_FLAG = 1
        order by a.order_cnt asc
    </select>
</mapper>
src/main/resources/static/febs/layarea.js
New file
Diff too large
src/main/resources/templates/febs/views/modules/votesActivity/add.html
New file
@@ -0,0 +1,367 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity-add" lay-title="活动新增">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="activity-add">
                <form class="layui-form" action="" lay-filter="activity-add-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</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">
                                            <div id="activity-group"></div>
                                        </div>
                                    </div>
                                </div>
                                <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="orderCnt" 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="name" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <select name="type" class="activity-type">
                                                <option value="1">普通活动</option>
                                                <option value="2">众筹活动</option>
                                                <option value="3">投票活动</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">推荐首页:</label>
                                        <div class="layui-input-block">
                                            <select name="hotState" class="activity-type">
                                                <option value="0">不推荐</option>
                                                <option value="1">推荐</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <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="phone" 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="address" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <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="voteCnt" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                            <div class="layui-form-mid layui-word-aux">投票活动,单个ID每天投票次数</div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">自主报名:</label>
                                        <div class="layui-input-block">
                                            <select name="hotState" class="activity-type">
                                                <option value="0">不允许</option>
                                                <option value="1">允许</option>
                                            </select>
                                            <div class="layui-form-mid layui-word-aux">投票活动,是否允许用户小程序自主报名</div>
                                        </div>
                                    </div>
                                </div>
                                <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="startTime" id="febs-form-group-date-start" lay-verify="datetime"
                                                   placeholder="yyyy-MM-dd hh:mm:ss" 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="endTime" id="febs-form-group-date-end" lay-verify="datetime"
                                                   placeholder="yyyy-MM-dd hh:mm:ss" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <select name="payState" class="activity-type">
                                                <option value="0">关闭</option>
                                                <option value="1">开启</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <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="joinCnt" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                            <div class="layui-form-mid layui-word-aux">门票总数</div>
                                        </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="payAmount" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                            <div class="layui-form-mid layui-word-aux">门票价格(关闭众筹,或者免费参与,请填写0)</div>
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <div class="layui-upload">
                                                <button type="button" class="layui-btn layui-btn-normal layui-btn" id="test1Max">上传</button>
                                                <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                                                    <div class="layui-upload-list" id="demo1Max"></div>
                                                </blockquote>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <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="testMax">上传</button>
                                                <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                                                    <div class="layui-upload-list" id="demoMax"></div>
                                                </blockquote>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item febs-hide">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">封面链接:</label>
                                        <div class="layui-input-block">
                                            <input type="text" id="indexImg" lay-verify="required" name="indexImg" autocomplete="off" class="layui-input" readonly>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">背景链接:</label>
                                        <div class="layui-input-block">
                                            <input type="text" id="backImg" lay-verify="required" name="backImg" autocomplete="off" class="layui-input" readonly>
                                        </div>
                                    </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" class="toolbar"></div>
                                            <div id="text-container" class="text" style="height: 450px;"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-form-item febs-hide">
                        <button class="layui-btn" lay-submit="" lay-filter="activity-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;
    }
</style>
<!-- 表格操作栏 end -->
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','dropdown', 'laydate', 'layedit', 'upload', 'element', 'table', 'xmSelect','jquery'], 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,
            $view = $('#activity-add'),
            layedit = layui.layedit,
            upload = layui.upload,
            validate = layui.validate,
            element = layui.element;
        form.render();
        const E = window.wangEditor;
        const editor = new E('#toolbar-container', '#text-container'); // 传入两个元素
        editor.config.showLinkImg = false;
        editor.config.uploadFileName = 'file';
        editor.config.customUploadImg = function (files, insertImgFn) {
            // files 是 input 中选中的文件列表
            // insertImgFn 是获取图片 url 后,插入到编辑器的方法
            // 上传图片,返回结果,将图片插入到编辑器中
            for (let i = 0; i < files.length; i++){
                var form = new FormData();
                form.append("file", files[0]);
                $.ajax({
                    url:'/admin/goods/uploadFileBase64',
                    type: "post",
                    processData: false,
                    contentType: false,
                    data: form,
                    dataType: 'json',
                    success(res) {
                        // 上传代码返回结果之后,将图片插入到编辑器中
                        insertImgFn(res.data.src, res.data.title, '')
                    }
                })
            }
        };
        editor.create();
        laydate.render({
            elem: '#febs-form-group-date-start',
            type: 'datetime',   // 选择器类型为日期时间
            format: 'yyyy-MM-dd HH:mm:ss' // 自定义格式
        });
        laydate.render({
            elem: '#febs-form-group-date-end',
            type: 'datetime',   // 选择器类型为日期时间
            format: 'yyyy-MM-dd HH:mm:ss' // 自定义格式
        });
        formSelects.render();
        let activityGroup = xmSelect.render({
            el: '#activity-group',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            tips: '请选择',
            filterable: true,
            radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/happyActivity/allGroup', null, function(res) {
            activityGroup.update({
                data : res.data,
                autoRow: true,
            });
        })
        //图片上传
        upload.render({
            elem: '#test1Max'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,accept: 'file' //普通文件
            ,size: 10240 //限制文件大小,单位 KB
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#demo1Max').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                });
            }
            ,done: function(res){
                $("#indexImg").val(res.data.src);
            }
        });
        //图片上传
        upload.render({
            elem: '#testMax'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,accept: 'file' //普通文件
            ,size: 10240 //限制文件大小,单位 KB
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#demoMax').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                });
            }
            ,done: function(res){
                $("#backImg").val(res.data.src);
            }
        });
        form.on('submit(activity-add-form-submit)', function (data) {
            data.field.categoryId = activityGroup.getValue('valueStr');
            data.field.textRemark = editor.txt.html();
            $.ajax({
                'url':ctx + 'admin/happyActivity/add',
                '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-activity').find('#reset').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/discountAudit.html
New file
@@ -0,0 +1,199 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity" 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="activity-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md10">
                                <div class="layui-form-item">
                                    <div class="layui-inline">
                                        <div class="layui-input-inline">
                                            <input type="hidden" placeholder="activityId" name="activityId"
                                                   autocomplete="off" class="layui-input" id="activityId"
                                                   th:value="${activityId}">
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area" style="display: none;">
                                <button class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain" id="queryAudit">
                                    <i class="layui-icon">&#xe615;</i> 查询
                                </button>
                            </div>
                        </div>
                    </form>
                    <table id="activityAuditTable" lay-filter="activityAuditTable"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/html" id="activityOptionAudit">
    <button class="layui-btn layui-btn-primary layui-btn-sm" type="button" lay-event="activityAuditEvent">审核</button>
    <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" lay-event="activityDetailEvent">查看详情</button>
</script>
<style>
    .layui-form-onswitch {
        background-color: #5FB878 !important;
    }
</style>
<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,
            ctx = '', // 这里需要定义你的 `ctx`
            $view = $('#febs-activity'),
            $query = $('#queryAudit'),
            $searchForm = $view.find('form'),
            sortObject = { field: 'phone', type: null },
            tableIns;
        form.render();
        initTable();
        // 监听表格操作按钮
        table.on('tool(activityAuditTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'activityAuditEvent') {
                febs.modal.confirm('审批', '确认通过审批?', function () {
                    auditAct(data.id, 1);
                });
            } else if (layEvent === 'activityDetailEvent') {
                if (!data.id || !data.activityId) {
                    febs.alert.error('数据异常,无法打开详情页面');
                    return;
                }
                openDetailModal(data.id, data.activityId);
            }
        });
        // 审批
        function auditAct(id, status) {
            febs.get(ctx + 'admin/votesOption/auditOption/' + id + '/' + status, null, function (data) {
                febs.alert.success(data.message);
                tableIns.reload({ page: { curr: 1 } });
            });
        }
        // 删除活动
        function deleteAct(id) {
            febs.get(ctx + 'admin/votesActivity/delActivity/' + id, null, function (data) {
                febs.alert.success(data.message);
                tableIns.reload({ page: { curr: 1 } });
            });
        }
        // 查询按钮点击事件
        $query.on('click', function (e) {
            e.preventDefault();
            var params = getQueryParams();
            params = $.extend(params, { field: sortObject.field, order: sortObject.type });
            tableIns.reload({
                where: params,
                page: { curr: 1 }
            });
        });
        // 初始化表格
        function initTable() {
            tableIns = febs.table.init({
                elem: '#activityAuditTable',
                id: 'activityAuditTable',
                url: ctx + 'admin/votesOption/list/',
                where: getQueryParams(), // 传递查询参数
                page: true,
                cols: [[
                    { field: 'beautyName', title: '名称', minWidth: 150, align: 'left' },
                    { field: 'number', title: '编号', minWidth: 50, align: 'left' },
                    {
                        field: 'image',
                        title: '图片',
                        templet: function (d) {
                            return '<a lay-event="seeImgThumb">' +
                                '<img id="seeImgThumb' + d.id + '" src="' + d.image +
                                '" alt="图片" style="width: 50px; height: 50px; object-fit: cover; border-radius: 5px; cursor: pointer;">' +
                                '</a>';
                        },
                        minWidth: 150,
                        align: 'center'
                    },
                    {
                        field: 'videoUrl',
                        title: '视频',
                        templet: function (d) {
                            return '<a lay-event="seeVideoThumb">' +
                                '<video id="seeVideoThumb' + d.id + '" src="' + d.videoUrl +
                                '" style="width: 100px; height: 100px; object-fit: cover; border-radius: 5px; cursor: pointer;" ' +
                                'muted playsinline></video>' +
                                '</a>';
                        },
                        minWidth: 150,
                        align: 'center'
                    },
                    { field: 'description', title: '描述', minWidth: 200, align: 'left' },
                    {
                        field: 'audit',
                        title: '是否审核',
                        minWidth: 50,
                        align: 'left',
                        templet: function (d) {
                            if (d.audit === 0) {
                                return '未审核';
                            } else if (d.audit === 1) {
                                return '已审核';
                            } else if (d.audit === 2) {
                                return '已拒绝';
                            } else {
                                return '其他';
                            }
                        }
                    },
                    {
                        title: '操作',
                        minWidth: 200,
                        align: 'center',
                        templet: function (d) {
                            var btns = '';
                            if (d.audit === 0) {
                                btns += '<button class="layui-btn layui-btn-primary layui-btn-sm" type="button" lay-event="activityAuditEvent">审核</button>';
                            }
                            btns += '<button class="layui-btn layui-btn-sm layui-btn-normal" type="button" lay-event="activityDetailEvent">查看详情</button>';
                            return btns;
                        }
                    }
                ]]
            });
        }
        // 打开详情页面
        function openDetailModal(id,activityId) {
            var detailUrl = ctx + 'modules/votesActivity/votesoptionDetail/' + encodeURIComponent(id) + '/' + encodeURIComponent(activityId);
            febs.modal.open('详情', detailUrl, {
                area: ['80%', '80%'],
                maxmin: true
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                // activityId: $searchForm.find('input[name="activityId"]').val().trim(),
                activityId: $("#activityId").val().trim(), // 从前端 input 获取值
            };
        }
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/discountUpdate.html
New file
@@ -0,0 +1,412 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity-discount" lay-title="活动设置">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="activity-discount-update">
                <form class="layui-form" action="" lay-filter="activity-discount-update-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</li>
                        </ul>
                        <div class="layui-tab-content">
                            <div class="layui-tab-item layui-show">
                                <blockquote class="layui-elem-quote blue-border">基础信息</blockquote>
                                <!-- 隐藏的 ID 项 -->
                                <div class="layui-form-item febs-hide">
                                    <label class="layui-form-label">ID:</label>
                                    <div class="layui-input-block">
                                        <input type="text" name="id" autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                                <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">
                                            <div id="activity-group"></div>
                                        </div>
                                    </div>
                                </div>
                                <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="orderCnt" 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="name" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <select name="type">
                                                <option value="1">普通活动</option>
                                                <option value="2">众筹活动</option>
                                                <option value="3">投票活动</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">推荐首页:</label>
                                        <div class="layui-input-block">
                                            <select name="hotState">
                                                <option value="0">不推荐</option>
                                                <option value="1">推荐</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <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="phone" 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="address" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <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="voteCnt" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                            <div class="layui-form-mid layui-word-aux">投票活动,单个ID每天投票次数</div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">自主报名:</label>
                                        <div class="layui-input-block">
                                            <select name="addState">
                                                <option value="0">不允许</option>
                                                <option value="1">允许</option>
                                            </select>
                                            <div class="layui-form-mid layui-word-aux">投票活动,是否允许用户小程序自主报名</div>
                                        </div>
                                    </div>
                                </div>
                                <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="startTime" id="febs-form-group-date-start" lay-verify="datetime"
                                                   placeholder="yyyy-MM-dd hh:mm:ss" 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="endTime" id="febs-form-group-date-end" lay-verify="datetime"
                                                   placeholder="yyyy-MM-dd hh:mm:ss" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <select name="payState">
                                                <option value="0">关闭</option>
                                                <option value="1">开启</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <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="joinCnt" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                            <div class="layui-form-mid layui-word-aux">门票总数</div>
                                        </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="payAmount" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                            <div class="layui-form-mid layui-word-aux">门票价格(关闭众筹,或者免费参与,请填写0)</div>
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <div class="layui-upload">
                                                <button type="button" class="layui-btn layui-btn-normal layui-btn" id="test1Max">上传</button>
                                                <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                                                    <div class="layui-upload-list" id="demo1Max"></div>
                                                </blockquote>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <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="testMax">上传</button>
                                                <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                                                    <div class="layui-upload-list" id="demoMax"></div>
                                                </blockquote>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item febs-hide">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">封面链接:</label>
                                        <div class="layui-input-block">
                                            <input type="text" id="indexImg" lay-verify="required" name="indexImg" autocomplete="off" class="layui-input" readonly>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">背景链接:</label>
                                        <div class="layui-input-block">
                                            <input type="text" id="backImg" lay-verify="required" name="backImg" autocomplete="off" class="layui-input" readonly>
                                        </div>
                                    </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" class="toolbar"></div>
                                            <div id="text-container" class="text" style="height: 450px;"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-form-item febs-hide">
                        <button class="layui-btn" lay-submit="" lay-filter="activity-discount-update-form-submit" id="submit">保存</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<style>
    .blue-border {
        border-left-color: #2db7f5;
        font-size: 18px;
    }
</style>
<script type="text/html" id="toolbar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-danger layui-btn-sm" type="button" lay-event="delSku">删除</button>
    </div>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree','dropdown', 'laydate', 'layedit', 'upload', 'element', 'table', 'xmSelect'], 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,
            $view = $('#activity-discount-update'),
            layedit = layui.layedit,
            activity = [[${activity}]],
            upload = layui.upload,
            validate = layui.validate,
            element = layui.element;
        const E = window.wangEditor;
        const editor = new E('#toolbar-container', '#text-container'); // 传入两个元素
        editor.config.showLinkImg = false;
        editor.config.uploadFileName = 'file';
        editor.config.customUploadImg = function (files, insertImgFn) {
            // files 是 input 中选中的文件列表
            // insertImgFn 是获取图片 url 后,插入到编辑器的方法
            // 上传图片,返回结果,将图片插入到编辑器中
            for (let i = 0; i < files.length; i++){
                var form = new FormData();
                form.append("file", files[0]);
                $.ajax({
                    url:'/admin/goods/uploadFileBase64',
                    type: "post",
                    processData: false,
                    contentType: false,
                    data: form,
                    dataType: 'json',
                    success(res) {
                        // 上传代码返回结果之后,将图片插入到编辑器中
                        insertImgFn(res.data.src, res.data.title, '')
                    }
                })
            }
        };
        editor.create();
        laydate.render({
            elem: '#febs-form-group-date-start',
            type: 'datetime',   // 选择器类型为日期时间
            format: 'yyyy-MM-dd HH:mm:ss' // 自定义格式
        });
        laydate.render({
            elem: '#febs-form-group-date-end',
            type: 'datetime',   // 选择器类型为日期时间
            format: 'yyyy-MM-dd HH:mm:ss' // 自定义格式
        });
        formSelects.render();
        let activityGroup = xmSelect.render({
            el: '#activity-group',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            tips: '请选择',
            filterable: true,
            radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/happyActivity/allGroup', null, function(res) {
            activityGroup.update({
                data : res.data,
                autoRow: true,
            });
            initActivityValue();
        })
        //图片上传
        upload.render({
            elem: '#test1Max'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,accept: 'file' //普通文件
            ,size: 10240 //限制文件大小,单位 KB
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#demo1Max').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                });
            }
            ,done: function(res){
                $("#indexImg").val(res.data.src);
            }
        });
        //图片上传
        upload.render({
            elem: '#testMax'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,accept: 'file' //普通文件
            ,size: 10240 //限制文件大小,单位 KB
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#demoMax').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                });
            }
            ,done: function(res){
                $("#backImg").val(res.data.src);
            }
        });
        function initActivityValue() {
            if (!activity) {
                console.warn("activity 数据为空,无法初始化表单!");
                return;
            }
            form.val("activity-discount-update-form", {
                "id": activity.id || '',
                "name": activity.name || '',
                "type": activity.type || '',
                "joinCnt": activity.joinCnt || '',
                "startTime": activity.startTime || '',
                "endTime": activity.endTime || '',
                "phone": activity.phone || '',
                "address": activity.address || '',
                "payState": activity.payState || '',
                "payAmount": activity.payAmount || '',
                "orderCnt": activity.orderCnt || '',
                "hotState": activity.hotState || '',
                "voteCnt": activity.voteCnt || '',
                "addState": activity.addState || ''
            });
            $('#demoMax').append('<img src="' + activity.backImg + '" alt="" class="layui-upload-img single-image" style="width: 130px">')
            $("#backImg").val(activity.backImg);
            $('#demo1Max').append('<img src="' + activity.indexImg + '" alt="" class="layui-upload-img single-image" style="width: 130px">')
            $("#indexImg").val(activity.indexImg);
            var arr = [];
            arr.push(activity.categoryId)
            activityGroup.setValue(arr);
            editor.txt.html(activity.textRemark);
        }
        form.on('submit(activity-discount-update-form-submit)', function (data) {
            data.field.groupId = activityGroup.getValue('valueStr');
            data.field.introduce = editor.txt.html();
            $.ajax({
                'url':ctx + 'admin/happyActivity/activityUpdate',
                '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-activity').find('#reset').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/groupAdd.html
New file
@@ -0,0 +1,95 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-group-add" lay-title="活动分类新增">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
                    <div class="layui-fluid" id="group-add">
                        <form class="layui-form" action="" lay-filter="group-add-form">
                            <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                                <ul class="layui-tab-title">
                                    <li class="layui-this">基础信息</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="orderCnt" 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="name" 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="group-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'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            form = layui.form,
            $view = $('#group-add'),
            validate = layui.validate;
        form.render();
        form.on('submit(group-add-form-submit)', function (data) {
            $.ajax({
                'url':ctx + 'admin/happyActivity/addGroup',
                '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-activity-group').find('#query').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/groupInfo.html
New file
@@ -0,0 +1,112 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-group-info" lay-title="活动分类编辑">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="group-info">
                <form class="layui-form" action="" lay-filter="group-info-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</li>
                        </ul>
                        <div class="layui-tab-content">
                            <input type="text" name="id"
                                   placeholder="" autoComplete="off" class="layui-input febs-hide">
                            <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="orderCnt" 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="name" 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="group-info-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','formSelects', 'table'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            form = layui.form,
            formSelects = layui.formSelects,
            $view = $('#group-info'),
            voteActivityGroup = [[${voteActivityGroup}]],
            validate = layui.validate;
        form.render();
        initVoteActivityGroup();
        formSelects.render();
        function initVoteActivityGroup() {
            console.log("voteActivityGroup:", voteActivityGroup); // 调试信息
            form.val("group-info-form", {
                "id": voteActivityGroup.id,
                "name": voteActivityGroup.name,
                "orderCnt": voteActivityGroup.orderCnt,
            });
        }
        form.on('submit(group-info-form-submit)', function (data) {
            $.ajax({
                'url':ctx + 'admin/happyActivity/groupUpdate',
                '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-activity-group').find('#query').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/groupList.html
New file
@@ -0,0 +1,236 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity-group" 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="activity-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 layui-form-label-sm">名称</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 layui-form-label-sm">审核状态</label>
                                        <div class="layui-input-inline">
                                            <select name="status">
                                                <option value="">请选择</option>
                                                <option value="0">未开启</option>
                                                <option value="1">开启</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">推荐首页</label>
                                        <div class="layui-input-inline">
                                            <select name="hotState">
                                                <option value="">请选择</option>
                                                <option value="0">不推荐</option>
                                                <option value="1">推荐</option>
                                            </select>
                                        </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-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="groupTable" lay-data="{id: 'groupTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="list:view,add:add,votesActivityUpdate:update">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="votesActivityUpdate:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<script type="text/html" id="hotStateSwitch">
    {{# if(d.hotState === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="推荐|不推荐" checked lay-skin="switch" lay-filter="hotStateSwitch">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="推荐|不推荐" lay-skin="switch" lay-filter="hotStateSwitch">
    {{# } }}
</script>
<script type="text/html" id="groupStatusSwitch">
    {{# if(d.state === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="开启|关闭" checked lay-skin="switch" lay-filter="groupStatusSwitch">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="开启|关闭" lay-skin="switch" lay-filter="groupStatusSwitch">
    {{# } }}
</script>
<script type="text/html" id="groupToolbar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="groupAdd:add" lay-event="addGroup">新增分类</button>
    </div>
</script>
<script type="text/html" id="groupOption">
    <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="groupInfo:view" lay-event="groupInfo">编辑</button>
    <button class="layui-btn layui-btn-danger layui-btn-sm" type="button" shiro:hasPermission="groupDelete:delete" lay-event="groupDelete">删除</button>
</script>
<script type="text/html" id="deleteFlag">
    {{#
    var deleteFlag = {
    0: {title: '生效中', color: 'green'},
    1: {title: '已删除', color: 'red'},
    }[d.deleteFlag];
    }}
    <span class="layui-badge febs-bg-{{deleteFlag.color}}">{{ deleteFlag.title }}</span>
</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-activity-group'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initGroupTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(groupTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'groupDelete') {
                febs.modal.confirm('删除', '确认删除?', function () {
                    groupDelete(data.id);
                });
            }
            if (layEvent === 'groupInfo') {
                febs.modal.open('编辑','modules/votesActivity/groupInfo/' + data.id, {
                    btn: ['提交', '取消'],
                    area: ['100%', '100%'],
                    yes: function (index, layero) {
                        $('#febs-group-info').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function groupDelete(id) {
            febs.get(ctx + 'admin/happyActivity/groupDelete/' + id, null, function (data) {
                febs.alert.success(data.message);
                $query.click();
            });
        }
        // 初始化表格操作栏各个按钮功能
        table.on('toolbar(groupTable)', function (obj) {
            let data = obj.data,
                    layEvent = obj.event;
            console.log("触发事件:", obj.event); // 调试信息
            if(layEvent === 'addGroup'){
                febs.modal.open('新增','modules/votesActivity/groupAdd/', {
                    btn: ['提交', '取消'],
                    area: ['100%', '100%'],
                    yes: function (index, layero) {
                        $('#febs-group-add').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function initGroupTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'groupTable',
                url: ctx + 'admin/happyActivity/groupList',
                toolbar:"#groupToolbar",
                defaultToolbar:[],
                cols: [[
                    {type: 'numbers', title: '', width: 80},
                    {title: '操作', toolbar: '#groupOption', minWidth: 200, align: 'center'},
                    {field: 'orderCnt', title: '排序', minWidth: 100,align:'center'},
                    {field: 'name', title: '名称', minWidth: 100,align:'center'},
                    {title: '推荐首页', templet: '#hotStateSwitch', minWidth: 100,align:'center'},
                    {title: '状态', templet: '#groupStatusSwitch', minWidth: 100,align:'center'},
                    {title: '是否删除', templet: '#deleteFlag', minWidth: 100,align:'center'},
                    {field: 'createdTime', title: '创建时间', minWidth: 150,align:'left'}
                ]]
            });
        }
        form.on('switch(hotStateSwitch)', function (data) {
            if (data.elem.checked) {
                groupState(data.value,1);
            } else {
                groupState(data.value,1);
            }
        })
        form.on('switch(groupStatusSwitch)', function (data) {
            if (data.elem.checked) {
                groupState(data.value,2);
            } else {
                groupState(data.value,2);
            }
        })
        function groupState(id,type) {
            febs.get(ctx + 'admin/happyActivity/groupState/' + id+'/' + type, null, function (data) {
                febs.alert.success(data.message);
                $query.click();
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        // 获取查询参数
        function getQueryParams() {
            return {
                name: $searchForm.find('input[name="name"]').val().trim(),
                status: $searchForm.find("select[name='status']").val(),
                hotState: $searchForm.find("select[name='hotState']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/votesActivity/list.html
New file
@@ -0,0 +1,253 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity" 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="activity-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 layui-form-label-sm">活动名称</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 layui-form-label-sm">分类</label>
                                        <div class="layui-input-inline">
                                            <select name="categoryId" class="group-type">
                                                <option value="">请选择</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">状态</label>
                                        <div class="layui-input-inline">
                                            <select name="state">
                                                <option value="">请选择</option>
                                                <option value="0">未开启</option>
                                                <option value="1">已开启</option>
                                                <option value="2">已结束</option>
                                            </select>
                                        </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-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="activityTable" lay-data="{id: 'activityTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="list:view,add:add,votesActivityUpdate:update">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="votesActivityUpdate:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<script type="text/html" id="activityStateSwitch">
    {{# if(d.state === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="开启|关闭" checked lay-skin="switch" lay-filter="activityStateSwitch">
    {{# } else if(d.state === 2) { }}
    <span class="layui-badge febs-bg-red">已结束</span>
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="开启|关闭" lay-skin="switch" lay-filter="activityStateSwitch">
    {{# } }}
</script>
<script type="text/html" id="activityToolbar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="add:add" lay-event="activityAdd">新增活动</button>
    </div>
</script>
<script type="text/html" id="activityOption">
    <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="votesActivityUpdate:update" lay-event="activityUpdateEvent">编辑</button>
    <button class="layui-btn layui-btn-danger layui-btn-sm" type="button" shiro:hasPermission="votesActivityUpdate:update" lay-event="activityDeleteEvent">删除</button>
</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-activity'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        //(下拉框)
        $.get(ctx + 'admin/happyActivity/allGroup', function (res) {
            var data = res.data;
            for (let k in data)
            {
                $(".group-type").append("<option value='" + data[k].id + "'>" + data[k].name + "</option>");
            }
            layui.use('form', function () {
                var form = layui.form;
                form.render();
            });
        });
        // 表格初始化
        initActivityTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(activityTable)', function (obj) {
            console.log("触发事件:", obj.event); // 调试信息
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'activityDeleteEvent') {
                febs.modal.confirm('删除', '确认删除该活动?', function () {
                    delAct(data.id);
                });
            }
            if (layEvent === 'seeImgThumb') {
                var t = $view.find('#seeImgThumb'+data.id+'');
                //页面层
                layer.open({
                    type: 1,
                    title: "图片",
                    skin: 'layui-layer-rim', //加上边框
                    area: ['100%', '100%'], //宽高
                    shadeClose: true, //开启遮罩关闭
                    end: function (index, layero) {
                        return false;
                    },
                    content: '<div style="text-align:center"><img src="' + $(t).attr('src') + '" /></div>'
                });
            }
            if (layEvent === 'activityUpdateEvent') {
                febs.modal.open('编辑','modules/votesActivity/votesActivityUpdate/' + data.id, {
                    btn: ['提交', '取消'],
                    area: ['100%', '100%'],
                    yes: function (index, layero) {
                        $('#febs-activity-discount').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        form.on('switch(activityStateSwitch)', function (data) {
            if (data.elem.checked) {
                changeState(data.value,1);
            } else {
                changeState(data.value,0);
            }
        })
        function changeState(id,state) {
            febs.get(ctx + 'admin/happyActivity/changeState/' + id+'/' + state, null, function (data) {
                febs.alert.success(data.message);
                $query.click();
            });
        }
        function delAct(id) {
            febs.get(ctx + 'admin/happyActivity/delActivity/' + id, null, function (data) {
                febs.alert.success(data.message);
                $query.click();
            });
        }
        // 初始化表格操作栏各个按钮功能
        table.on('toolbar(activityTable)', function (obj) {
            let data = obj.data,
                layEvent = obj.event;
            console.log("触发事件:", obj.event); // 调试信息
            if(layEvent === 'activityAdd'){
                febs.modal.open('新增活动', 'modules/votesActivity/add/', {
                    btn: ['提交', '取消'],
                    area:['100%','100%'],
                    yes: function (index, layero) {
                        $('#febs-activity-add').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function initActivityTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'activityTable',
                url: ctx + 'admin/happyActivity/list',
                toolbar:"#activityToolbar",
                defaultToolbar:[],
                cols: [[
                    {type: 'numbers', title: '', width: 80},
                    {title: '操作', toolbar: '#activityOption', minWidth: 200, align: 'center'},
                    {field: 'name', title: '名称', minWidth: 150,align:'left'},
                    {field: 'categoryName', title: '分类', minWidth: 150,align:'left'},
                    {
                        field: 'indexImg',
                        title: '封面',
                        templet: function (d) {
                            return '<a lay-event="seeImgThumb">' +
                                '<img id="seeImgThumb' + d.id + '" src="' + d.indexImg +
                                '" alt="图片" style="width: 50px; height: 50px; object-fit: cover; border-radius: 5px; cursor: pointer;">' +
                                '</a>';
                        },
                        minWidth: 150,
                        align: 'center'
                    },
                    {field: 'startTime', title: '开始时间', minWidth: 200,align:'left'},
                    {field: 'endTime', title: '结束时间', minWidth: 200,align:'left'},
                    {field: 'state', title: '状态', templet: '#activityStateSwitch', minWidth: 130,align:'center'}
                ]]
            });
        }
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        // 获取查询参数
        function getQueryParams() {
            return {
                name: $searchForm.find('input[name="name"]').val().trim(),
                state: $searchForm.find("select[name='state']").val(),
                categoryId: $searchForm.find("select[name='categoryId']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/votesActivity/optionAdd-bak.html
New file
@@ -0,0 +1,293 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-option-add" lay-title="活动选项新增">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="option-add">
                <form class="layui-form" action="" lay-filter="option-add-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</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">
                                            <div id="activity-option"></div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">序号:</label>
                                        <div class="layui-input-block">
                                            <input type="number" name="number" placeholder="" autocomplete="off" class="layui-input" disabled>
                                        </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="registeredName" lay-verify="required" 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="beautyName" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                </div>
                                <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="mobilePhone" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">性别:</label>
                                        <div class="layui-input-block">
                                            <input type="radio" name="sex" value="1" title="男" />
                                            <input type="radio" name="sex" value="2" title="女" />
                                            <input type="radio" name="sex" value="2" title="保密" checked />
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <div class="layui-form-item" id="area-picker">
                                            <div class="layui-form-label">选择省/市</div>
                                            <div class="layui-input-inline" style="width: 200px;">
                                                <select name="province" class="province-selector" data-value="上海市">
                                                    <option value="">--选择省--</option>
                                                </select>
                                            </div>
                                            <div class="layui-input-inline" style="width: 200px;" >
                                                <select name="city" class="city-selector" data-value="上海市">
                                                    <option value="">--选择市--</option>
                                                </select>
                                            </div>
                                            <!--                                                <div class="layui-input-inline" style="width: 200px;" >-->
                                            <!--                                                    <select name="area" class="county-selector" data-value="浦东新区">-->
                                            <!--                                                        <option value="">&#45;&#45;选择区&#45;&#45;</option>-->
                                            <!--                                                    </select>-->
                                            <!--                                                </div>-->
                                        </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="address" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require" style="white-space: nowrap;">是否签约MCN:</label>
                                        <div class="layui-input-block">
                                            <select name="ismcn" lay-verify="required" class="layui-input">
                                                <option value="0">否</option>
                                                <option value="1">是</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <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>
                                        </div>
                                        <div class="layui-form-item febs-hide">
                                            <label class="layui-form-label">图片链接:</label>
                                            <div class="layui-input-block">
                                                <input type="text" id="image" lay-verify="required" name="image" autocomplete="off" class="layui-input" readonly>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <label class="layui-form-label">爱好:</label>
                                    <div class="layui-input-block">
                                        <label>
                                            <textarea name="hobby" 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 upload" id="upload" style="background-color: #009688; margin-bottom: 2px">上传文件</button>-->
<!--                                        </div>-->
<!--                                    </div>-->
<!--                                </div>-->
<!--                                <div class="layui-form-item">-->
<!--                                    <label class="layui-form-label">视频链接:</label>-->
<!--                                    <div class="layui-input-block">-->
<!--                                        <input type="text" id="videoUrl" lay-verify="required" name="videoUrl" autocomplete="off" class="layui-input" readonly>-->
<!--                                    </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" class="toolbar"></div>-->
<!--                                            <div id="text-container" class="text" style="height: 450px;"></div>-->
<!--                                        </div>-->
<!--                                    </div>-->
<!--                                </div>-->
<!--                            </div>-->
                        </div>
                    </div>
                    <div class="layui-form-item febs-hide">
                        <button class="layui-btn" lay-submit="" lay-filter="option-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', 'formSelects', 'validate', 'laydate', 'layedit', 'upload', 'table', 'xmSelect', 'layarea'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            formSelects = layui.formSelects,
            form = layui.form,
            $view = $('#option-add'),
            layedit = layui.layedit,
            upload = layui.upload,
            layarea = layui.layarea,
            validate = layui.validate;
        form.render();
        formSelects.render();
        let obj1 = layarea.render({
            elem: '#area-picker',
            change: function (res) {
                //选择结果
                console.log(res);
            }
        });
        layarea.render({
            elem: '#area-picker',
            data: {
                province: "上海",
                city: "上海",
                county: "浦东新区",
            },
            change: function (res) {
                //选择结果
                console.log(res);
            }
        });
        let activityOptions = xmSelect.render({
            el: '#activity-option',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            tips: '请选择',
            filterable: true,
            radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/votesActivity/allActivities', null, function(res) {
            activityOptions.update({
                data : res.data,
                autoRow: true,
            });
        })
        //图片上传
        upload.render({
            elem: '#test2'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,accept: 'file' //普通文件
            ,size: 10240 //限制文件大小,单位 KB
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#demo2').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                });
            }
            ,done: function(res){
                $("#image").val(res.data.src);
            }
        });
        form.on('submit(option-add-form-submit)', function (data) {
            data.field.activityId = activityOptions.getValue('valueStr');
            $.ajax({
                'url':ctx + 'admin/votesActivity/addOption',
                '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-activity-option').find('#query').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/optionAdd.html
New file
@@ -0,0 +1,348 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-option-add" lay-title="活动选项新增">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="option-add">
                <form class="layui-form" action="" lay-filter="option-add-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</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">
                                            <div id="activity-option"></div>
                                        </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="optionName" lay-verify="required" 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="realName" lay-verify="required" autocomplete="off" class="layui-input" >
                                            <div class="layui-form-mid layui-word-aux">姓名和选项名称可一致</div>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-form-item" id="area-picker">
                                        <div class="layui-form-label">选择省/市</div>
                                        <div class="layui-input-inline" style="width: 200px;">
                                            <select name="province" class="province-selector" data-value="上海市">
                                                <option value="">--选择省--</option>
                                            </select>
                                        </div>
                                        <div class="layui-input-inline" style="width: 200px;" >
                                            <select name="city" class="city-selector" data-value="上海市">
                                                <option value="">--选择市--</option>
                                            </select>
                                        </div>
                                        <!--                                                <div class="layui-input-inline" style="width: 200px;" >-->
                                        <!--                                                    <select name="area" class="county-selector" data-value="浦东新区">-->
                                        <!--                                                        <option value="">&#45;&#45;选择区&#45;&#45;</option>-->
                                        <!--                                                    </select>-->
                                        <!--                                                </div>-->
                                    </div>
                                </div>
                                <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="address" lay-verify="required" 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="mobilePhone" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">性别:</label>
                                        <div class="layui-input-block">
                                            <input type="radio" name="sex" value="1" title="男" />
                                            <input type="radio" name="sex" value="2" title="女" />
                                            <input type="radio" name="sex" value="2" title="保密" checked />
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">邮箱:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="email" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require" style="white-space: nowrap;">是否签约MCN:</label>
                                        <div class="layui-input-block">
                                            <select name="mcnState" lay-verify="required" class="layui-input">
                                                <option value="0">否</option>
                                                <option value="1">是</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-form-item">
                                    <label class="layui-form-label">爱好:</label>
                                    <div class="layui-input-block">
                                        <label>
                                            <textarea name="hobby" 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>
                                    </div>
                                </div>
                                <div class="layui-form-item febs-hide">
                                    <label class="layui-form-label">图片链接:</label>
                                    <div class="layui-input-block">
                                        <input type="text" id="image" lay-verify="required" name="image" autocomplete="off" class="layui-input" readonly>
                                    </div>
                                </div>
                                <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 upload" id="upload" style="background-color: #009688; margin-bottom: 2px">上传文件</button>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-form-item">
                                    <label class="layui-form-label">作品链接:</label>
                                    <div class="layui-input-block">
                                        <input type="text" id="videoUrl" lay-verify="required" name="videoUrl" autocomplete="off" class="layui-input" readonly>
                                    </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" class="toolbar"></div>
                                            <div id="text-container" class="text" style="height: 450px;"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-form-item febs-hide">
                        <button class="layui-btn" lay-submit="" lay-filter="option-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', 'formSelects', 'validate', 'layedit', 'upload', 'table', 'xmSelect', 'layarea'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            formSelects = layui.formSelects,
            form = layui.form,
            $view = $('#option-add'),
            layedit = layui.layedit,
            upload = layui.upload,
            layarea = layui.layarea,
            validate = layui.validate;
        form.render();
        const E = window.wangEditor;
        const editor = new E('#toolbar-container', '#text-container'); // 传入两个元素
        editor.config.showLinkImg = false;
        editor.config.uploadFileName = 'file';
        editor.config.customUploadImg = function (files, insertImgFn) {
            // files 是 input 中选中的文件列表
            // insertImgFn 是获取图片 url 后,插入到编辑器的方法
            // 上传图片,返回结果,将图片插入到编辑器中
            for (let i = 0; i < files.length; i++){
                var form = new FormData();
                form.append("file", files[0]);
                $.ajax({
                    url:'/admin/goods/uploadFileBase64',
                    type: "post",
                    processData: false,
                    contentType: false,
                    data: form,
                    dataType: 'json',
                    success(res) {
                        // 上传代码返回结果之后,将图片插入到编辑器中
                        insertImgFn(res.data.src, res.data.title, '')
                    }
                })
            }
        };
        editor.create();
        formSelects.render();
        let obj1 = layarea.render({
            elem: '#area-picker',
            change: function (res) {
                //选择结果
                console.log(res);
            }
        });
        layarea.render({
            elem: '#area-picker',
            data: {
                province: "上海",
                city: "上海",
                county: "浦东新区",
            },
            change: function (res) {
                //选择结果
                console.log(res);
            }
        });
        let activityOptions = xmSelect.render({
            el: '#activity-option',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            tips: '请选择',
            filterable: true,
            radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/happyActivity/allActivities', null, function(res) {
            activityOptions.update({
                data : res.data,
                autoRow: true,
            });
        })
        bindUpload();
        function bindUpload() {
            upload.render({
                elem: '.upload'
                ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
                ,accept: 'file'
                ,before: function(obj){
                    layer.msg('上传中', {icon: 16, time: 0});
                }
                ,done: function(res){
                    var item = this.item;
                    //如果上传失败
                    if(res.code !== 0){
                        return layer.msg('上传失败');
                    }
                    $("#videoUrl").val(res.data.src);
                    layer.msg('上传完毕', {icon: 1});
                }
                ,error: function(err){
                    return layer.msg('上传失败');
                }
            });
        }
        //图片上传
        upload.render({
            elem: '#test2'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,accept: 'file' //普通文件
            ,size: 10240 //限制文件大小,单位 KB
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    if ($("#image").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){
                $("#image").val(res.data.src);
            }
        });
        form.on('submit(option-add-form-submit)', function (data) {
            data.field.activityId = activityOptions.getValue('valueStr');
            data.field.description = editor.txt.html();
            console.log(data.field);
            $.ajax({
                'url':ctx + 'admin/happyActivity/addOption',
                '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-activity-option').find('#query').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/optionInfo-bak.html
New file
@@ -0,0 +1,373 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-option-info" lay-title="活动选项编辑">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="option-info">
                <form class="layui-form" action="" lay-filter="option-info-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</li>
                        </ul>
                        <div class="layui-tab-content">
                            <input type="text" name="id"
                                   placeholder="" autoComplete="off" class="layui-input febs-hide">
                            <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="radio" name="audit" value="1" title="待审核" checked />
                                            <input type="radio" name="audit" value="2" title="同意" />
                                            <input type="radio" name="audit" value="3" title="拒绝" />
                                        </div>
                                    </div>
                                    <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">
                                                <div class="layui-upload">
                                                    <button type="button" class="layui-btn layui-btn-normal layui-btn" id="testMaxOption">上传</button>
                                                    <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
                                                        <div class="layui-upload-list" id="demoMaxOption"></div>
                                                    </blockquote>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="layui-col-lg6">
                                            <div class="layui-input-block">
                                                <input type="text" lay-verify="required"  id="image"  name="image" autocomplete="off" class="layui-input" readonly>
                                            </div>
                                            <button type="button" class="layui-btn layui-btn-normal layui-btn" id="openImg">图片审核</button>
                                        </div>
                                    </div>
<!--                                    <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" lay-verify="required" name="videoUrl" autocomplete="off" class="layui-input" readonly>-->
<!--                                            </div>-->
<!--                                        </div>-->
<!--                                        <div class="layui-col-lg6">-->
<!--                                            <button type="button" class="layui-btn layui-btn-normal layui-btn" id="openVideo">视频审核</button>-->
<!--                                        </div>-->
<!--                                    </div>-->
                                </div>
                                <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">
                                            <div id="activity-option"></div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">序号:</label>
                                        <div class="layui-input-block">
                                            <!--                                                    <input type="number" name="number" lay-verify="required" placeholder="" autocomplete="off" class="layui-input" data-value="{$voteOption.number}">-->
                                            <input type="number" name="number" placeholder="" autocomplete="off" class="layui-input" data-value="{$voteOption.number}" disabled>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-form-item">
<!--                                    <div class="layui-col-lg6">-->
<!--                                        <label class="layui-form-label">报名名称:</label>-->
<!--                                        <div class="layui-input-block">-->
<!--                                            <input type="text" name="registeredName" lay-verify="required" autocomplete="off" class="layui-input" >-->
<!--                                        </div>-->
<!--                                    </div>-->
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">姓名:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="beautyName" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                    <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="number" name="voteCount"  autocomplete="off" class="layui-input" >
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <!--                                        <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="province" lay-verify="required" 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="city" lay-verify="required" autocomplete="off" class="layui-input" >-->
                                <!--                                                </div>-->
                                <!--                                            </div>-->
                                <!--                                        </div>-->
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg3">
                                        <label class="layui-form-label febs-form-item-require">省:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="city" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                    <div class="layui-col-lg3">
                                        <label class="layui-form-label febs-form-item-require">市:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="city" 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="address" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                </div>
                                <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="mobilePhone" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">性别:</label>
                                        <div class="layui-input-block">
                                            <input type="radio" name="sex" value="1" title="男" />
                                            <input type="radio" name="sex" value="2" title="女" />
                                            <input type="radio" name="sex" value="3" title="保密" checked />
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require" style="white-space: nowrap;">是否签约MCN:</label>
                                        <div class="layui-input-block">
                                            <select name="ismcn" lay-verify="required" class="layui-input">
                                                <option value="0">否</option>
                                                <option value="1">是</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-form-item">
                                    <label class="layui-form-label">爱好:</label>
                                    <div class="layui-input-block">
                                        <label>
                                            <textarea name="hobby" rows="5" autocomplete="off" class="layui-textarea" ></textarea>
                                        </label>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-form-item febs-hide">
                        <button class="layui-btn" lay-submit="" lay-filter="option-info-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', 'laydate', 'layedit', 'upload', 'table', 'xmSelect', 'layarea'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            formSelects = layui.formSelects,
            form = layui.form,
            $view = $('#option-info'),
            voteOption = [[${voteOption}]],
            layedit = layui.layedit,
            upload = layui.upload,
            layarea = layui.layarea,
            validate = layui.validate;
        form.render();
        formSelects.render();
        let activityOptions = xmSelect.render({
            el: '#activity-option',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            tips: '请选择',
            filterable: true,
            radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/votesActivity/allActivities', null, function(res) {
            activityOptions.update({
                data : res.data,
                autoRow: true,
            });
            initOptionInfo();
        })
        //图片上传
        upload.render({
            elem: '#testMaxOption'
            ,url: ctx + 'admin/goods/uploadFileBase64' //改成您自己的上传接口
            ,multiple: true
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){
                    $('#demoMaxOption').html('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img single-image" style="width: 130px">')
                });
            }
            ,done: function(res){
                $("#image").val(res.data.src);
            }
        });
        // let obj1 = layarea.render({
        //     elem: '#area-picker',
        //     change: function (res) {
        //         //选择结果
        //         console.log(res);
        //     }
        // });
        // layarea.render({
        //     elem: '#area-picker',
        //     data: {
        //         province: "上海",
        //         city: "上海",
        //         county: "浦东新区",
        //     },
        //     change: function (res) {
        //         //选择结果
        //         console.log(res);
        //     }
        // });
        function initOptionInfo() {
            console.log("voteOption:", voteOption); // 调试信息
            form.val("option-info-form", {
                "id": voteOption.id,
                "activityId": voteOption.activityId,
                "beautyName": voteOption.beautyName,
                "registeredName": voteOption.registeredName,
                "description": voteOption.description,
                "voteCount": voteOption.voteCount,
                "rank": voteOption.rank,
                "diffPrevious": voteOption.diffPrevious,
                "number": voteOption.number,
                "mobilePhone": voteOption.mobilePhone,
                "sex": voteOption.sex,
                "hobby": voteOption.hobby,
                "ismcn": voteOption.ismcn,
                "address": voteOption.address,
                "province": voteOption.province,
                "city": voteOption.city,
                "videoUrl": voteOption.videoUrl,
                "audit": voteOption.audit,
                "image": voteOption.image,
                "email": voteOption.email
            });
            var arr = [];
            arr.push(voteOption.activityId)
            activityOptions.setValue(arr);
            $('#demoMaxOption').append('<img src="' + voteOption.image + '" alt="" class="layui-upload-img single-image" style="width: 130px">')
            $("#image").val(voteOption.image);
            // setTimeout(() => {
            //     obj1.reload({
            //         data: {
            //             province: voteOption.province,
            //             city: voteOption.city,
            //         }
            //     });
            // }, 200);
        }
        form.on('submit(option-info-form-submit)', function (data) {
            data.field.activityId = activityOptions.getValue('valueStr');
            console.log(data.field);
            $.ajax({
                'url':ctx + 'admin/votesActivity/optionUpdate',
                '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-activity-option').find('#query').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
        // 添加点击事件监听器
        $('#openImg').on('click', function() {
            let imageUrl = $("#image").val();
            //页面层
            layer.open({
                type: 1,
                title: "图片",
                skin: 'layui-layer-rim', //加上边框
                area: ['100%', '100%'], //宽高
                shadeClose: true, //开启遮罩关闭
                end: function (index, layero) {
                    return false;
                },
                content: '<div style="text-align:center"><img src="' + imageUrl + '" /></div>'
            });
        });
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/optionInfo.html
New file
@@ -0,0 +1,408 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-option-info" lay-title="活动选项编辑">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="option-info">
                <form class="layui-form" action="" lay-filter="option-info-form">
                    <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                        <ul class="layui-tab-title">
                            <li class="layui-this">基础信息</li>
                        </ul>
                        <div class="layui-tab-content">
                            <input type="text" name="id"
                                   placeholder="" autoComplete="off" class="layui-input febs-hide">
                            <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="radio" name="state" value="0" title="待审核" checked />
                                            <input type="radio" name="state" value="1" title="同意" />
                                            <input type="radio" name="state" value="2" title="拒绝" />
                                        </div>
                                    </div>
                                    <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" lay-verify="required" name="image" autocomplete="off" class="layui-input" readonly>
                                            </div>
                                        </div>
                                        <div class="layui-col-lg6">
                                            <button type="button" class="layui-btn layui-btn-normal layui-btn" id="openImg">封面审核</button>
                                        </div>
                                    </div>
                                    <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" lay-verify="required" name="videoUrl" autocomplete="off" class="layui-input" readonly>
                                            </div>
                                        </div>
                                        <div class="layui-col-lg6">
                                            <button type="button" class="layui-btn layui-btn-normal layui-btn" id="openVideo">作品审核</button>
                                        </div>
                                    </div>
                                </div>
                                <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">
                                            <div id="activity-option"></div>
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">序号:</label>
                                        <div class="layui-input-block">
                                            <input type="number" name="orderCnt" placeholder="" autocomplete="off" class="layui-input" data-value="{$voteOption.number}">
                                        </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="optionName" lay-verify="required" 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="realName" lay-verify="required" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">性别:</label>
                                        <div class="layui-input-block">
                                            <input type="radio" name="sex" value="1" title="男" />
                                            <input type="radio" name="sex" value="2" title="女" />
                                            <input type="radio" name="sex" value="3" title="保密" checked />
                                        </div>
                                    </div>
                                    <div class="layui-form-item" id="area-picker">
                                        <div class="layui-form-label">选择省/市</div>
                                        <div class="layui-input-inline" style="width: 200px;">
                                            <select name="province" class="province-selector" >
                                                <option value="">--选择省--</option>
                                            </select>
                                        </div>
                                        <div class="layui-input-inline" style="width: 200px;" >
                                            <select name="city" class="city-selector">
                                                <option value="">--选择市--</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <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="address" lay-verify="required" 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="mobilePhone" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label">邮箱:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="email" autocomplete="off" class="layui-input" >
                                        </div>
                                    </div>
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require" style="white-space: nowrap;">是否签约MCN:</label>
                                        <div class="layui-input-block">
                                            <select name="mcnState" lay-verify="required" class="layui-input">
                                                <option value="0">否</option>
                                                <option value="1">是</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-form-item">
                                    <label class="layui-form-label">爱好:</label>
                                    <div class="layui-input-block">
                                        <label>
                                            <textarea name="hobby" 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" class="toolbar"></div>
                                            <div id="text-container" class="text" style="height: 450px;"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-form-item febs-hide">
                        <button class="layui-btn" lay-submit="" lay-filter="option-info-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', 'laydate', 'layedit', 'table', 'xmSelect', 'layarea'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            layer = layui.layer,
            table = layui.table,
            formSelects = layui.formSelects,
            form = layui.form,
            $view = $('#option-info'),
            voteOption = [[${voteOption}]],
            layedit = layui.layedit,
            layarea = layui.layarea,
            validate = layui.validate;
        form.render();
        const E = window.wangEditor;
        const editor = new E('#toolbar-container', '#text-container'); // 传入两个元素
        editor.config.showLinkImg = false;
        editor.config.uploadFileName = 'file';
        editor.config.customUploadImg = function (files, insertImgFn) {
            // files 是 input 中选中的文件列表
            // insertImgFn 是获取图片 url 后,插入到编辑器的方法
            // 上传图片,返回结果,将图片插入到编辑器中
            for (let i = 0; i < files.length; i++){
                var form = new FormData();
                form.append("file", files[0]);
                $.ajax({
                    url:'/admin/goods/uploadFileBase64',
                    type: "post",
                    processData: false,
                    contentType: false,
                    data: form,
                    dataType: 'json',
                    success(res) {
                        // 上传代码返回结果之后,将图片插入到编辑器中
                        insertImgFn(res.data.src, res.data.title, '')
                    }
                })
            }
        };
        editor.create();
        formSelects.render();
        let activityOptions = xmSelect.render({
            el: '#activity-option',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            tips: '请选择',
            filterable: true,
            radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/happyActivity/allActivities', null, function(res) {
            activityOptions.update({
                data : res.data,
                autoRow: true,
            });
            initOptionInfo();
        })
        let obj1 = layarea.render({
            elem: '#area-picker',
            change: function (res) {
                //选择结果
                console.log(res);
            }
        });
        layarea.render({
            elem: '#area-picker',
            data: {
                province: "上海",
                city: "上海",
                county: "浦东新区",
            },
            change: function (res) {
                //选择结果
                console.log(res);
            }
        });
        function initOptionInfo() {
            console.log("voteOption:", voteOption); // 调试信息
            form.val("option-info-form", {
                "id": voteOption.id,
                "activityId": voteOption.activityId,
                "optionName": voteOption.optionName,
                "realName": voteOption.realName,
                "description": voteOption.description,
                "orderCnt": voteOption.orderCnt,
                "mobilePhone": voteOption.mobilePhone,
                "sex": voteOption.sex,
                "hobby": voteOption.hobby,
                "mcnState": voteOption.mcnState,
                "address": voteOption.address,
                "province": voteOption.province,
                "city": voteOption.city,
                "videoUrl": voteOption.videoUrl,
                "state": voteOption.state,
                "image": voteOption.image,
                "email": voteOption.email
            });
            var arr = [];
            arr.push(voteOption.activityId)
            activityOptions.setValue(arr);
            editor.txt.html(voteOption.description);
            setTimeout(() => {
                obj1.reload({
                    data: {
                        province: voteOption.province,
                        city: voteOption.city,
                    }
                });
            }, 200);
        }
        form.on('submit(option-info-form-submit)', function (data) {
            data.field.activityId = activityOptions.getValue('valueStr');
            data.field.description = editor.txt.html();
            console.log(data.field);
            $.ajax({
                'url':ctx + 'admin/happyActivity/optionUpdate',
                '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-activity-option').find('#query').click();
                    }else{
                        febs.alert.warn(data.message);
                    }
                },
                'error':function () {
                    febs.alert.warn('服务器繁忙');
                }
            })
            return false;
        });
        // 添加点击事件监听器
        $('#openImg').on('click', function() {
            let imageUrl = voteOption.image;
            //页面层
            layer.open({
                type: 1,
                title: "图片",
                skin: 'layui-layer-rim', //加上边框
                area: ['100%', '100%'], //宽高
                shadeClose: true, //开启遮罩关闭
                end: function (index, layero) {
                    return false;
                },
                content: '<div style="text-align:center"><img src="' + imageUrl + '" /></div>'
            });
        });
        // 添加点击事件监听器
        $('#openVideo').on('click', function() {
            let videoUrl = voteOption.videoUrl;
            // 校验视频URL是否有效
            if (!videoUrl || !isVideoUrlValid(videoUrl)) {
                alert('视频地址无效,请检查!');
                return;
            }
            // 使用更安全的方式生成HTML内容
            let videoContent = $('<div>').append(
                $('<video>', {
                    controls: true,
                    autoplay: true,
                    name: 'media',
                    style: "width: 30%;height: 30%;"
                }).append(
                    $('<source>', {
                        src: videoUrl,
                        type: 'video/mp4'
                    })
                )
            ).prop('outerHTML');
            // 页面层
            layer.open({
                type: 1,
                title: "视频",
                skin: 'layui-layer-rim', // 加上边框
                area: ['100%', '100%'],
                shadeClose: true, // 开启遮罩关闭
                content: `<div style="text-align:center">${videoContent}</div>`
            });
        });
        // 视频URL校验函数
        function isVideoUrlValid(url) {
            try {
                const urlObj = new URL(url);
                return urlObj.protocol === 'http:' || urlObj.protocol === 'https:';
            } catch (e) {
                return false;
            }
        }
    });
</script>
src/main/resources/templates/febs/views/modules/votesActivity/optionList.html
New file
@@ -0,0 +1,243 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity-option" 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="activity-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 layui-form-label-sm">选项名称</label>
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="选项名称" name="optionName" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">活动</label>
                                        <div class="layui-input-inline">
                                            <select name="activityId" class="activity-type">
                                                <option value="">请选择</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label layui-form-label-sm">状态</label>
                                        <div class="layui-input-inline">
                                            <select name="state">
                                                <option value="">请选择</option>
                                                <option value="0">待审核</option>
                                                <option value="1">同意</option>
                                                <option value="2">拒绝</option>
                                            </select>
                                        </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-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 class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="export" title="导出">
                                    <i class="layui-icon">&#xe67d;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="optionTable" lay-data="{id: 'optionTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="list:view,add:add,votesActivityUpdate:update">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="votesActivityUpdate:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<script type="text/html" id="optionStateType">
    {{#
    var state = {
    0: {title: '待审核', color: 'blue'},
    1: {title: '同意', color: 'green'},
    2: {title: '拒绝', color: 'red'},
    }[d.state];
    }}
    <span class="layui-badge febs-bg-{{state.color}}">{{ state.title }}</span>
</script>
<script type="text/html" id="optionToolbar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="optionAdd:add" lay-event="addOption">新增活动选项</button>
    </div>
</script>
<script type="text/html" id="optionOption">
    <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="optionInfo:view" lay-event="optionInfo">审核</button>
    <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="voteRecord:view" lay-event="voteRecord">得票记录</button>
    <button class="layui-btn layui-btn-danger layui-btn-sm" type="button" shiro:hasPermission="optionDelete:delete" lay-event="optionDelete">删除</button>
</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-activity-option'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            $export= $view.find('#export'),
            tableIns;
        form.render();
        //(下拉框)
        $.get(ctx + 'admin/happyActivity/allActivities', function (res) {
            var data = res.data;
            for (let k in data)
            {
                $(".activity-type").append("<option value='" + data[k].id + "'>" + data[k].name + "</option>");
            }
            layui.use('form', function () {
                var form = layui.form;
                form.render();
            });
        });
        // 表格初始化
        initOptionTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(optionTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'optionDelete') {
                febs.modal.confirm('删除', '确认删除该选项?', function () {
                    optionDelete(data.id);
                });
            }
            if (layEvent === 'voteRecord') {
                febs.modal.open( '得票记录', 'modules/votesActivity/voteRecord/' + data.id, {
                    maxmin: true,
                });
            }
            if (layEvent === 'optionInfo') {
                febs.modal.open('审核编辑','modules/votesActivity/optionInfo/' + data.id, {
                    btn: ['提交', '取消'],
                    area: ['100%', '100%'],
                    yes: function (index, layero) {
                        $('#febs-option-info').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function optionDelete(id) {
            febs.get(ctx + 'admin/happyActivity/optionDelete/' + id, null, function (data) {
                febs.alert.success(data.message);
                $query.click();
            });
        }
        // 初始化表格操作栏各个按钮功能
        table.on('toolbar(optionTable)', function (obj) {
            let data = obj.data,
                    layEvent = obj.event;
            console.log("触发事件:", obj.event); // 调试信息
            if(layEvent === 'addOption'){
                febs.modal.open('新增','modules/votesActivity/optionAdd/', {
                    btn: ['提交', '取消'],
                    area: ['100%', '100%'],
                    yes: function (index, layero) {
                        $('#febs-option-add').find('#submit').trigger('click');
                    },
                    btn2: function () {
                        layer.closeAll();
                    }
                });
            }
        });
        function changeState(id,state) {
            febs.get(ctx + 'admin/happyActivity/changeOptionState/' + id+'/' + state, null, function (data) {
                febs.alert.success(data.message);
                $query.click();
            });
        }
        function initOptionTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'optionTable',
                url: ctx + 'admin/happyActivity/optionList',
                toolbar:"#optionToolbar",
                defaultToolbar:[],
                cols: [[
                    {type: 'numbers', title: '', width: 80},
                    {title: '操作', toolbar: '#optionOption', minWidth: 200, align: 'center'},
                    {field: 'orderCnt', title: '编号', minWidth: 100,align:'center'},
                    {field: 'optionName', title: '选项名称', minWidth: 200,align:'center'},
                    {title: '审核状态', templet: '#optionStateType', minWidth: 100,align:'center'},
                    {field: 'createdTime', title: '创建时间', minWidth: 150,align:'left'}
                ]]
            });
        }
        form.on('switch(optionAuditSwitch)', function (data) {
            if (data.elem.checked) {
                changeState(data.value,1);
            } else {
                changeState(data.value,0);
            }
        })
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
       // 导出功能
        $export.on('click', function () {
            var params = getQueryParams();
            var queryString = Object.keys(params).map(key => `${key}=${encodeURIComponent(params[key])}`).join('&');
            window.location.href = ctx + 'admin/votesOption/exportOptionList?' + queryString;
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        // 获取查询参数
        function getQueryParams() {
            return {
                optionName: $searchForm.find('input[name="optionName"]').val().trim(),
                activityId: $searchForm.find("select[name='activityId']").val(),
                state: $searchForm.find("select[name='state']").val(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/votesActivity/voteRecord.html
New file
@@ -0,0 +1,55 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-vote-record" 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="voteRecordTable" lay-data="{id: 'voteRecordTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script data-th-inline="none" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'laydate', 'form', 'table', 'febs', 'treeSelect' ,'eleTree'], function () {
        var $ = layui.jquery,
            laydate = layui.laydate,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            treeSelect = layui.treeSelect,
            dropdown = layui.dropdown,
            $view = $('#febs-vote-record'),
            $query = $view.find('#queryChild'),
            $searchForm = $view.find('formChild'),
            sortObject = {field: 'createTime', type: null},
            tableIns,
            createTimeFrom,
            createTimeTo;
        form.render();
        initVoteRecordTable();
        laydate.render({
            elem: '#user-createTime',
            range: true,
            trigger: 'click'
        });
        function initVoteRecordTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'voteRecordTable',
                url: ctx + 'admin/happyActivity/voteRecord?parentId=1',
                cols: [[
                    {field: 'memberName', title: '昵称', minWidth: 150,align:'center'},
                    {field: 'activityName', title: '活动', minWidth: 150,align:'center'},
                    {field: 'optionName', title: '选项', minWidth: 150,align:'center'},
                    {field: 'createdTime', title: '投票时间', minWidth: 150,align:'center'}
                ]]
            });
        }
    })
</script>
src/main/resources/templates/febs/views/modules/votesActivity/voteoptionDetail.html
New file
@@ -0,0 +1,177 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-activity-detail" lay-title="活动详情"
     xmlns="http://www.w3.org/1999/html">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-fluid" id="activity-detail-view">
                <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
                    <ul class="layui-tab-title">
                        <li class="layui-this">详情信息</li>
                    </ul>
                    <div class="layui-tab-content">
                            <div class="layui-form-item">
                                <label class="layui-form-label">选手姓名:</label>
                                <div class="layui-input-block">
                                    <label class="layui-form-mid" id="beautyName" th:text="${votesOption.beautyName}"></label>
                                </div>
                            </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">个人照片:</label>
                            <div class="layui-input-block">
                                <img class="layui-upload-img" id="image" style="width: 100px" th:src="${votesOption.image}" alt="选手照片"/>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">视频链接:</label>
                            <div class="layui-input-block">
                                <video id="videoUrl" style="width: 300px; height: 200px; object-fit: cover; border-radius: 8px;" controls>
                                    <source th:src="${votesOption.videoUrl}" type="video/mp4"/>
                                    您的浏览器不支持视频播放。
                                </video>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">是否审核:</label>
                            <div class="layui-input-block">
                                <label class="layui-form-mid" id="audit">
                                <span th:switch="${votesOption.audit}">
                                <span th:case="1">未审核</span>
                                <span th:case="2">已审核</span>
                                <span th:case="3">已拒绝</span>
                                <span th:case="*">未知状态</span>
                                </span>
                                </label>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">手机:</label>
                            <div class="layui-input-block">
                                <label class="layui-form-mid" id="mobilePhone" th:text="${votesOption.mobilePhone}"></label>
                            </div>
                        </div>
                        <div class="layui-form-item">
                                <label class="layui-form-label">地址:</label>
                                <div class="layui-input-block">
                                    <label class="layui-form-mid" id="address" th:text="${votesOption.address}"></label>
                                </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">性别:</label>
                            <div class="layui-input-block">
                                <label class="layui-form-mid" id="sex" th:text="${votesOption.sex}"></label>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">兴趣爱好:</label>
                            <div class="layui-input-block">
                                <label class="layui-form-mid" id="hobby" th:text="${votesOption.hobby}"></label>
                            </div>
                        </div>
                        <div class="layui-form-item">
                            <label class="layui-form-label">是否签约mcn机构:</label>
                            <div class="layui-input-block">
                                <label class="layui-form-mid" id="ismcn">
                                    <span th:switch="${votesOption.ismcn}">
                                <span th:case="0">否</span>
                                <span th:case="1">是</span>
                                </span>
                                </label>
                            </div>
                        </div>
                            <div class="layui-form-item">
                                <label class="layui-form-label">选手说明:</label>
                                <div class="layui-input-block">
                                    <pre class="layui-form-mid" id="description" th:text="${votesOption.description}" style="white-space: pre-wrap;"></pre>
                                </div>
                            </div>
                        </div>
                    </div>
            </div>
        </div>
    </div>
</div>
<script>
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree', 'dropdown', 'laydate', 'layedit', 'upload', 'element', 'table', 'xmSelect'], 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,
            layedit = layui.layedit,
            upload = layui.upload,
            validate = layui.validate,
            element = layui.element,
            // votesOption = [[${votesOption}]],
            element = layui.element;
        $(document).ready(function() {
            initValue();
        });
        function initValue() {
            // if (!votesOption) {
            //     console.warn("votesOption 数据为空,无法初始化详情页!");
            //     return;
            // }
            // $("#beautyName").text(votesOption.beautyName || '无');
            // $("#image").attr("src", votesOption.image || '');
            // $("#videoUrl").attr("src", votesOption.videoUrl || '');
            // $("#audit").text(getVotesAuditText(votesOption.audit));
            // $("#mobilePhone").text(votesOption.mobilePhone || '无');
            // $("#address").text(votesOption.province + votesOption.city + (votesOption.address || '无'));
            // $("#sex").text(getSexText(votesOption.sex));
            // $("#hobby").text(votesOption.hobby || '无');
            // $("#ismcn").text(getVotesmcnText(votesOption.ismcn));
            // $("#description").text(votesOption.description || '无');
        }
        function getVotesAuditText(type) {
            switch (type) {
                case 0:
                    return '未审核';
                case 1:
                    return '已审核';
                case 2:
                    return '已拒绝';
                default:
                    return '未知状态';
            }
        }
        function getVotesmcnText(type) {
            switch (type) {
                case 0:
                    return '未签约';
                case 1:
                    return '已签约';
                default:
                    return '未知状态';
            }
        }
        function getSexText(sex) {
            if (sex === '0' || sex === 0) {
                return '女';
            } else if (sex === '1' || sex === 1) {
                return '男';
            } else {
                return '未知';
            }
        }
        initValue();
    });
</script>
src/main/resources/templates/index.html
@@ -44,7 +44,8 @@
        treeSelect: 'lay/extends/treeSelect',
        apexcharts: 'lay/extends/apexcharts.min',
        eleTree: 'lay/extends/eleTree',
        xmSelect: 'lay/extends/xm-select'
        xmSelect: 'lay/extends/xm-select',
        layarea: 'layarea',
    }).use(['index']);
</script>
</body>