Просмотр исходного кода

Update 完成活动上传图片,审核,关闭,置顶,热门

Yue 2 лет назад
Родитель
Сommit
feaa97043f
19 измененных файлов с 241 добавлено и 597 удалено
  1. 22 20
      SERVER/YanZhongXYH/script/sql/XYHSQL.sql
  2. 1 1
      SERVER/YanZhongXYH/xyh-oss/src/main/java/cn/xyh/oss/controller/OssFileController.java
  3. 5 7
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/controller/AmActivityController.java
  4. 0 95
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/controller/AmAttachController.java
  5. 0 55
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/AmAttach.java
  6. 1 1
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/bo/AmActivityBo.java
  7. 0 68
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/bo/AmAttachBo.java
  8. 0 69
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/vo/AmAttachVo.java
  9. 0 17
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/mapper/AmAttachMapper.java
  10. 2 3
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/IAmActivityService.java
  11. 0 50
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/IAmAttachService.java
  12. 2 7
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/impl/AmActivityServiceImpl.java
  13. 0 122
      SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/impl/AmAttachServiceImpl.java
  14. 0 22
      SERVER/YanZhongXYH/xyh-system/src/main/resources/mapper/amActivity/AmAttachMapper.xml
  15. 28 2
      UI/XYH.VUE/src/api/amActivity/_activity.ts
  16. 13 0
      UI/XYH.VUE/src/components/form/VbFormItem.vue
  17. 2 0
      UI/XYH.VUE/src/components/form/models.ts
  18. 57 27
      UI/XYH.VUE/src/components/upload/VbUpload.vue
  19. 108 31
      UI/XYH.VUE/src/views/amActivity/activity/index.vue

+ 22 - 20
SERVER/YanZhongXYH/script/sql/XYHSQL.sql

@@ -217,6 +217,7 @@ create table am_help
     is_head      char(1)      default '0' comment '是否头条(0否 1是)',
     is_hot       char(1)      default '0' comment '是否Hot(0否 1是)',
     is_sys       char(1)      default '0' comment '是否平台发布(0否 1是)',
+    images       varchar(1000) comment '图片短链',
     create_by    varchar(64)  default '' comment '创建者',
     create_time  datetime comment '创建时间',
     update_by    varchar(64)  default '' comment '更新者',
@@ -239,6 +240,7 @@ create table am_comment
     content     text       not null comment '评论内容',
     status      char(4)      default '0' comment '状态(0正常 1异常)',
     is_head     char(1)      default '0' comment '是否头条(0否 1是)',
+    images      varchar(1000) comment '图片短链',
     create_by   varchar(64)  default '' comment '创建者',
     create_time datetime comment '创建时间',
     update_by   varchar(64)  default '' comment '更新者',
@@ -247,26 +249,26 @@ create table am_comment
     primary key (comment_id)
 ) engine = innodb comment = '评论信息';
 
--- ----------------------------
--- 11、图片附件信息
--- ----------------------------
-drop table if exists am_attach;
-create table am_attach
-(
-    att_id      bigint(20)   not null AUTO_INCREMENT comment '附件id',
-    source_id   char(50)     not null comment '源id',
-    source_type char(20)     default '' comment '源类型',
-    file_type   char(1)      not null comment '附件类型(1图片 2视频)',
-    file_path   varchar(255) not null comment '附件路径',
-    file_name   varchar(255) not null comment '附件名称',
-    create_by   varchar(64)  default '' comment '创建者',
-    create_time datetime comment '创建时间',
-    update_by   varchar(64)  default '' comment '更新者',
-    update_time datetime comment '更新时间',
-    remark      varchar(500) default null comment '备注',
-    primary key (att_id)
-) engine = innodb
-  auto_increment = 100 comment = '图片附件信息';
+# -- ----------------------------
+# -- 11、图片附件信息
+# -- ----------------------------
+# drop table if exists am_attach;
+# create table am_attach
+# (
+#     att_id      bigint(20)   not null AUTO_INCREMENT comment '附件id',
+#     source_id   char(50)     not null comment '源id',
+#     source_type char(20)     default '' comment '源类型',
+#     file_type   char(1)      not null comment '附件类型(1图片 2视频)',
+#     file_path   varchar(255) not null comment '附件路径',
+#     file_name   varchar(255) not null comment '附件名称',
+#     create_by   varchar(64)  default '' comment '创建者',
+#     create_time datetime comment '创建时间',
+#     update_by   varchar(64)  default '' comment '更新者',
+#     update_time datetime comment '更新时间',
+#     remark      varchar(500) default null comment '备注',
+#     primary key (att_id)
+# ) engine = innodb
+#   auto_increment = 100 comment = '图片附件信息';
 
 -- ----------------------------
 -- 12、统计信息

+ 1 - 1
SERVER/YanZhongXYH/xyh-oss/src/main/java/cn/xyh/oss/controller/OssFileController.java

@@ -44,7 +44,7 @@ public class OssFileController extends BaseController {
         return R.fail("文件不能获取!");
     }
 
-    @GetMapping("/upload/{path}")
+    @PostMapping("/upload/{path}")
     public R<UploadFileVo> upload(@RequestPart("file") MultipartFile file, @PathVariable(name = "path", required = false) String path) {
         if (path.isEmpty()) {
             path = "common";

+ 5 - 7
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/controller/AmActivityController.java

@@ -23,7 +23,6 @@ import cn.xyh.system.utils.AuditStatusEnum;
 import lombok.RequiredArgsConstructor;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.constraints.NotEmpty;
@@ -85,13 +84,13 @@ public class AmActivityController extends BaseController {
     @Log(title = "活动信息", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping("/add")
-    public R<Void> add(@RequestPart("files") MultipartFile[] files, @Validated(AddGroup.class) AmActivityBo bo) {
+    public R<Void> add(@RequestBody @Validated(AddGroup.class) AmActivityBo bo) {
         if (isAlumnus()) {
             bo.setIsSys("0");
         } else {
             bo.setIsSys("1");
         }
-        return toAjax(amActivityService.insertByBo(files, bo));
+        return toAjax(amActivityService.insertByBo(bo));
     }
 
     /**
@@ -101,13 +100,13 @@ public class AmActivityController extends BaseController {
     @Log(title = "活动信息", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PostMapping("/update")
-    public R<Void> edit(@RequestPart("files") MultipartFile[] files, @Validated(EditGroup.class) AmActivityBo bo) {
+    public R<Void> edit(@RequestBody @Validated(EditGroup.class) AmActivityBo bo) {
         if (isAlumnus()) {
             bo.setIsSys("0");
         } else {
             bo.setIsSys("1");
         }
-        return toAjax(amActivityService.updateByBo(files, bo));
+        return toAjax(amActivityService.updateByBo(bo));
     }
 
     /**
@@ -118,8 +117,7 @@ public class AmActivityController extends BaseController {
     @SaCheckPermission(PermissionName.AmActivityActivityRemove)
     @Log(title = "活动信息", businessType = BusinessType.DELETE)
     @DeleteMapping("/{activityIds}")
-    public R<Void> remove(@NotEmpty(message = "主键不能为空")
-                          @PathVariable String[] activityIds) {
+    public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable String[] activityIds) {
         return toAjax(amActivityService.deleteWithValidByIds(Arrays.asList(activityIds), true));
     }
 

+ 0 - 95
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/controller/AmAttachController.java

@@ -1,95 +0,0 @@
-package cn.xyh.amActivity.controller;
-
-import cn.xyh.amActivity.domain.bo.AmAttachBo;
-import cn.xyh.amActivity.domain.vo.AmAttachVo;
-import cn.xyh.amActivity.service.IAmAttachService;
-import cn.xyh.common.annotation.Log;
-import cn.xyh.common.annotation.RepeatSubmit;
-import cn.xyh.common.config.VberConfig;
-import cn.xyh.common.core.controller.BaseController;
-import cn.xyh.common.core.domain.R;
-import cn.xyh.common.enums.BusinessType;
-import cn.xyh.common.exception.file.InvalidExtensionException;
-import cn.xyh.common.utils.file.FileUploadUtils;
-import cn.xyh.common.utils.file.MimeTypeUtils;
-import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 图片附件
- *
- * @author Yue
- * @date 2024-01-19
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/amActivity/attach")
-public class AmAttachController extends BaseController {
-
-    private final IAmAttachService amAttachService;
-
-    /**
-     * 获取图片附件详细信息
-     *
-     * @param sourceId
-     */
-    @GetMapping("source/{sourceType}/{sourceId}")
-    public R<List<AmAttachVo>> getInfosBySource(@NotNull(message = "源类型不能为空") @PathVariable String sourceType, @NotNull(message = "源Id不能为空") @PathVariable String sourceId) {
-        return R.ok(amAttachService.queryBySource(sourceType, sourceId));
-    }
-
-    /**
-     * 新增图片附件
-     */
-    @Log(title = "图片附件", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/upload/{sourceType}/{sourceId}")
-    public R<Map<String, Object>> add(@RequestPart("avatarfile") MultipartFile file, @PathVariable String sourceId, @PathVariable String sourceType)
-            throws IOException, InvalidExtensionException {
-        if (file.isEmpty()) {
-            return R.fail("文件不能为空");
-        }
-
-        AmAttachBo bo = new AmAttachBo();
-        bo.setSourceId(sourceId);
-        bo.setSourceType(sourceType);
-        String url = FileUploadUtils.upload(VberConfig.getActivityPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
-        bo.setFilePath(url);
-
-        bo.setFileName(file.getOriginalFilename());
-        bo.setFileType("1");
-        if (amAttachService.insertByBo(bo)) {
-            Map<String, Object> map = new HashMap<>();
-            //map.put("url", url);
-            map.put("fileName", url);
-            //map.put("newFileName", FileUtils.getName(fileName));
-            map.put("originalFilename", file.getOriginalFilename());
-            return R.ok(map);
-        } else {
-            return R.fail("上传失败");
-        }
-    }
-
-    /**
-     * 删除图片附件
-     *
-     * @param attIds 主键串
-     */
-    @Log(title = "图片附件", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{attIds}")
-    public R<Void> remove(@NotEmpty(message = "主键不能为空")
-                          @PathVariable Long[] attIds) {
-        return toAjax(amAttachService.deleteWithValidByIds(Arrays.asList(attIds), true));
-    }
-}

+ 0 - 55
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/AmAttach.java

@@ -1,55 +0,0 @@
-package cn.xyh.amActivity.domain;
-
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.math.BigDecimal;
-
-import cn.xyh.common.core.domain.BaseEntity;
-
-/**
- * 图片附件对象 am_attach
- *
- * @author Yue
- * @date 2024-01-19
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("am_attach")
-public class AmAttach extends BaseEntity {
-
-private static final long serialVersionUID = 1L;
-
-    /**
-     * 附件id
-     */
-    private Long attId;
-    /**
-     * 源id
-     */
-    private String sourceId;
-    /**
-     * 源类型
-     */
-    private String sourceType;
-    /**
-     * 附件类型(1图片 2视频)
-     */
-    private String fileType;
-    /**
-     * 附件路径
-     */
-    private String filePath;
-    /**
-     * 附件名称
-     */
-    private String fileName;
-    /**
-     * 备注
-     */
-    private String remark;
-
-}

+ 1 - 1
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/bo/AmActivityBo.java

@@ -93,5 +93,5 @@ public class AmActivityBo extends BaseEntity {
      */
     private String isSys;
 
-
+    private String images;
 }

+ 0 - 68
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/bo/AmAttachBo.java

@@ -1,68 +0,0 @@
-package cn.xyh.amActivity.domain.bo;
-
-import cn.xyh.common.core.domain.BaseEntity;
-import cn.xyh.common.core.validate.AddGroup;
-import cn.xyh.common.core.validate.EditGroup;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-
-/**
- * 图片附件业务对象 am_attach
- *
- * @author Yue
- * @date 2024-01-19
- */
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-
-public class AmAttachBo extends BaseEntity {
-
-    
-    /**
-     * 附件id
-     */
-    @NotNull(message = "附件id不能为空", groups = {EditGroup.class})
-    private Long attId;
-
-    /**
-     * 源id
-     */
-    @NotBlank(message = "源id不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String sourceId;
-
-    /**
-     * 源类型
-     */
-    @NotBlank(message = "源类型不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String sourceType;
-
-    /**
-     * 附件类型(1图片 2视频)
-     */
-    @NotBlank(message = "附件类型(1图片 2视频)不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String fileType;
-
-    /**
-     * 附件路径
-     */
-    @NotBlank(message = "附件路径不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String filePath;
-
-    /**
-     * 附件名称
-     */
-    @NotBlank(message = "附件名称不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String fileName;
-
-    /**
-     * 备注
-     */
-    @NotBlank(message = "备注不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String remark;
-
-
-}

+ 0 - 69
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/domain/vo/AmAttachVo.java

@@ -1,69 +0,0 @@
-package cn.xyh.amActivity.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import cn.xyh.common.annotation.ExcelDictFormat;
-import cn.xyh.common.convert.ExcelDictConvert;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.Date;
-
-
-/**
- * 图片附件视图对象 am_attach
- *
- * @author Yue
- * @date 2024-01-19
- */
-@Data
-@ExcelIgnoreUnannotated
-public class AmAttachVo implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-            /**
-             * 附件id
-             */
-            @ExcelProperty(value = "附件id")
-        private Long attId;
-
-            /**
-             * 源id
-             */
-            @ExcelProperty(value = "源id")
-        private String sourceId;
-
-            /**
-             * 源类型
-             */
-            @ExcelProperty(value = "源类型")
-        private String sourceType;
-
-            /**
-             * 附件类型(1图片 2视频)
-             */
-            @ExcelProperty(value = "附件类型", converter = ExcelDictConvert.class)
-            @ExcelDictFormat(readConverterExp = "1=图片,2=视频")
-        private String fileType;
-
-            /**
-             * 附件路径
-             */
-            @ExcelProperty(value = "附件路径")
-        private String filePath;
-
-            /**
-             * 附件名称
-             */
-            @ExcelProperty(value = "附件名称")
-        private String fileName;
-
-            /**
-             * 备注
-             */
-            @ExcelProperty(value = "备注")
-        private String remark;
-
-
-}

+ 0 - 17
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/mapper/AmAttachMapper.java

@@ -1,17 +0,0 @@
-package cn.xyh.amActivity.mapper;
-
-import cn.xyh.amActivity.domain.AmAttach;
-import cn.xyh.amActivity.domain.vo.AmAttachVo;
-import cn.xyh.common.core.mapper.BaseMapperPlus;
-import org.springframework.stereotype.Repository;
-
-/**
- * 图片附件Mapper接口
- *
- * @author Yue
- * @date 2024-01-19
- */
-@Repository
-public interface AmAttachMapper extends BaseMapperPlus<AmAttachMapper, AmAttach, AmAttachVo> {
-
-}

+ 2 - 3
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/IAmActivityService.java

@@ -4,7 +4,6 @@ import cn.xyh.amActivity.domain.bo.AmActivityBo;
 import cn.xyh.amActivity.domain.vo.AmActivityVo;
 import cn.xyh.common.core.domain.PageQuery;
 import cn.xyh.common.core.page.TableDataInfo;
-import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Collection;
 import java.util.List;
@@ -35,12 +34,12 @@ public interface IAmActivityService {
     /**
      * 新增活动信息
      */
-    Boolean insertByBo(MultipartFile[] files, AmActivityBo bo);
+    Boolean insertByBo(AmActivityBo bo);
 
     /**
      * 修改活动信息
      */
-    Boolean updateByBo(MultipartFile[] files, AmActivityBo bo);
+    Boolean updateByBo(AmActivityBo bo);
 
     /**
      * 校验并批量删除活动信息信息

+ 0 - 50
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/IAmAttachService.java

@@ -1,50 +0,0 @@
-package cn.xyh.amActivity.service;
-
-import cn.xyh.amActivity.domain.bo.AmAttachBo;
-import cn.xyh.amActivity.domain.vo.AmAttachVo;
-import cn.xyh.common.core.domain.PageQuery;
-import cn.xyh.common.core.page.TableDataInfo;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 图片附件Service接口
- *
- * @author Yue
- * @date 2024-01-19
- */
-public interface IAmAttachService {
-
-    /**
-     * 查询图片附件
-     */
-    AmAttachVo queryById(Long attId);
-
-    /**
-     * 查询图片附件列表
-     */
-    TableDataInfo<AmAttachVo> queryPageList(AmAttachBo bo, PageQuery pageQuery);
-
-    /**
-     * 查询图片附件列表
-     */
-    List<AmAttachVo> queryList(AmAttachBo bo);
-
-    /**
-     * 新增图片附件
-     */
-    Boolean insertByBo(AmAttachBo bo);
-
-    /**
-     * 修改图片附件
-     */
-    Boolean updateByBo(AmAttachBo bo);
-
-    /**
-     * 校验并批量删除图片附件信息
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-    List<AmAttachVo> queryBySource(String sourceType, String sourceId);
-}

+ 2 - 7
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/impl/AmActivityServiceImpl.java

@@ -121,13 +121,11 @@ public class AmActivityServiceImpl implements IAmActivityService {
      * 新增活动信息
      */
     @Override
-    public Boolean insertByBo(MultipartFile[] files, AmActivityBo bo) {
+    public Boolean insertByBo(AmActivityBo bo) {
 
         AmActivity add = BeanUtil.toBean(bo, AmActivity.class);
         add.setActivityId(getActivityId());
         validEntityBeforeSave(add);
-        saveActivityImages(files, add);
-        //saveActivityImages(files, add.getActivityId());
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setActivityId(add.getActivityId());
@@ -143,12 +141,9 @@ public class AmActivityServiceImpl implements IAmActivityService {
      * 修改活动信息
      */
     @Override
-    public Boolean updateByBo(MultipartFile[] files, AmActivityBo bo) {
+    public Boolean updateByBo(AmActivityBo bo) {
         AmActivity update = BeanUtil.toBean(bo, AmActivity.class);
         validEntityBeforeSave(update);
-        saveActivityImages(files, update);
-
-        //saveActivityImages(files, update.getActivityId());
         return baseMapper.updateById(update) > 0;
     }
 

+ 0 - 122
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/amActivity/service/impl/AmAttachServiceImpl.java

@@ -1,122 +0,0 @@
-package cn.xyh.amActivity.service.impl;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.xyh.amActivity.domain.AmAttach;
-import cn.xyh.amActivity.domain.bo.AmAttachBo;
-import cn.xyh.amActivity.domain.vo.AmAttachVo;
-import cn.xyh.amActivity.mapper.AmAttachMapper;
-import cn.xyh.amActivity.service.IAmAttachService;
-import cn.xyh.common.core.domain.PageQuery;
-import cn.xyh.common.core.page.TableDataInfo;
-import cn.xyh.common.utils.StringUtils;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 图片附件Service业务层处理
- *
- * @author Yue
- * @date 2024-01-19
- */
-@RequiredArgsConstructor
-@Service
-public class AmAttachServiceImpl implements IAmAttachService {
-
-    private final AmAttachMapper baseMapper;
-
-    /**
-     * 查询图片附件
-     */
-    @Override
-    public AmAttachVo queryById(Long attId) {
-        return baseMapper.selectVoById(attId);
-    }
-
-    /**
-     * 查询图片附件列表
-     */
-    @Override
-    public TableDataInfo<AmAttachVo> queryPageList(AmAttachBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<AmAttach> lqw = buildQueryWrapper(bo);
-        Page<AmAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    /**
-     * 查询图片附件列表
-     */
-    @Override
-    public List<AmAttachVo> queryList(AmAttachBo bo) {
-        LambdaQueryWrapper<AmAttach> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<AmAttach> buildQueryWrapper(AmAttachBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<AmAttach> lqw = Wrappers.lambdaQuery();
-        lqw.eq(StringUtils.isNotBlank(bo.getSourceId()), AmAttach::getSourceId, bo.getSourceId());
-        lqw.eq(StringUtils.isNotBlank(bo.getSourceType()), AmAttach::getSourceType, bo.getSourceType());
-        lqw.eq(StringUtils.isNotBlank(bo.getFileType()), AmAttach::getFileType, bo.getFileType());
-        lqw.eq(StringUtils.isNotBlank(bo.getFilePath()), AmAttach::getFilePath, bo.getFilePath());
-        lqw.like(StringUtils.isNotBlank(bo.getFileName()), AmAttach::getFileName, bo.getFileName());
-        return lqw;
-    }
-
-    /**
-     * 新增图片附件
-     */
-    @Override
-    public Boolean insertByBo(AmAttachBo bo) {
-        AmAttach add = BeanUtil.toBean(bo, AmAttach.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setAttId(add.getAttId());
-        }
-        return flag;
-    }
-
-    /**
-     * 修改图片附件
-     */
-    @Override
-    public Boolean updateByBo(AmAttachBo bo) {
-        AmAttach update = BeanUtil.toBean(bo, AmAttach.class);
-        validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 保存前的数据校验
-     */
-    private void validEntityBeforeSave(AmAttach entity) {
-        //TODO 做一些数据校验,如唯一约束
-    }
-
-    /**
-     * 批量删除图片附件
-     */
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            //TODO 做一些业务上的校验,判断是否需要校验
-        }
-        return baseMapper.deleteBatchIds(ids) > 0;
-    }
-
-    @Override
-    public List<AmAttachVo> queryBySource(String sourceType, String sourceId) {
-        LambdaQueryWrapper<AmAttach> lqw = new LambdaQueryWrapper<AmAttach>()
-                .eq(AmAttach::getSourceType, sourceType)
-                .eq(AmAttach::getSourceId, sourceId)
-                .select(AmAttach::getAttId, AmAttach::getFilePath, AmAttach::getFileName, AmAttach::getFileType);
-        return baseMapper.selectVoList(lqw);
-    }
-}

+ 0 - 22
SERVER/YanZhongXYH/xyh-system/src/main/resources/mapper/amActivity/AmAttachMapper.xml

@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.xyh.amActivity.mapper.AmAttachMapper">
-
-    <resultMap type="cn.xyh.amActivity.domain.AmAttach" id="AmAttachResult">
-        <result property="attId" column="att_id"/>
-        <result property="sourceId" column="source_id"/>
-        <result property="sourceType" column="source_type"/>
-        <result property="fileType" column="file_type"/>
-        <result property="filePath" column="file_path"/>
-        <result property="fileName" column="file_name"/>
-        <result property="createBy" column="create_by"/>
-        <result property="createTime" column="create_time"/>
-        <result property="updateBy" column="update_by"/>
-        <result property="updateTime" column="update_time"/>
-        <result property="remark" column="remark"/>
-    </resultMap>
-
-
-</mapper>

+ 28 - 2
UI/XYH.VUE/src/api/amActivity/_activity.ts

@@ -43,7 +43,6 @@ class activityApi {
 		return Rs.post({
 			url: "/amActivity/activity/add",
 			data: data,
-			contentType: "multipart/form-data",
 			successAlert: false
 		})
 	}
@@ -52,7 +51,6 @@ class activityApi {
 	updateActivity = (data: any) => {
 		return Rs.post({
 			url: "/amActivity/activity/update",
-			contentType: "multipart/form-data",
 			data: data,
 			successAlert: false
 		})
@@ -64,6 +62,34 @@ class activityApi {
 			url: "/amActivity/activity/" + activityId
 		})
 	}
+
+	auditActivity = (activityId: string, status: string) => {
+		return Rs.post({
+			url: `/amActivity/activity/audit/${activityId}/${status}`,
+			successAlert: true
+		})
+	}
+
+	topActivity = (activityId: string, status: string) => {
+		return Rs.post({
+			url: `/amActivity/activity/top/${activityId}/${status}`,
+			successAlert: false
+		})
+	}
+
+	hotActivity = (activityId: string, status: string) => {
+		return Rs.post({
+			url: `/amActivity/activity/hot/${activityId}/${status}`,
+			successAlert: false
+		})
+	}
+
+	closeActivity = (activityId: string) => {
+		return Rs.post({
+			url: `/amActivity/activity/close/${activityId}`,
+			successAlert: false
+		})
+	}
 }
 
 export default activityApi

+ 13 - 0
UI/XYH.VUE/src/components/form/VbFormItem.vue

@@ -182,6 +182,19 @@ onMounted(() => {
 					v-bind="item.props"
 					v-on="item.listeners"></vb-select>
 			</template>
+			<template v-else-if="checkComponent('VU') || checkComponent('VbUpload')">
+				<vb-upload
+					v-model="data[item.field]"
+					:id="itemId"
+					:required="item.required"
+					:class="item.class"
+					:style="item.style"
+					:placeholder="item.placeholder ?? item.label"
+					:size="item.size"
+					:data="itemData"
+					v-bind="item.props"
+					v-on="item.listeners"></vb-upload>
+			</template>
 			<template v-else-if="checkComponent('Dict') || checkComponent('DictSelect')">
 				<dict-select
 					v-model="data[item.field]"

+ 2 - 0
UI/XYH.VUE/src/components/form/models.ts

@@ -21,6 +21,8 @@ export interface VbFormItem {
 		| "VbSelect"
 		| "VE" // VbEditor
 		| "VbEditor"
+		| "VU" // VbUpload
+		| "VbUpload"
 		| "Dict" // DictSelect
 		| "DictSelect"
 		| "VS" // VbSelect

+ 57 - 27
UI/XYH.VUE/src/components/upload/VbUpload.vue

@@ -2,6 +2,7 @@
 const props = withDefaults(
 	defineProps<{
 		modelValue: string | any[]
+		prefixUrl?: string
 		uploadType?: "image" | "file"
 		uploadUrl?: string
 		limit?: number // 图片数量限制
@@ -25,11 +26,11 @@ const emits = defineEmits<{
 const imageUploadRef = ref()
 const number = ref(0)
 const uploadList = ref<any[]>([])
-const dialogImageUrl = ref("")
-const dialogVisible = ref(false)
+const showViewer = ref(false)
+const viewerInitialIndex = ref(0)
 const baseUrl = import.meta.env.VITE_APP_BASE_API
 const uploadImgUrl = ref(
-	props.uploadUrl ? props.uploadUrl : import.meta.env.VITE_APP_BASE_API + "/common/upload"
+	import.meta.env.VITE_APP_BASE_API + (props.uploadUrl ? props.uploadUrl : "/common/upload")
 ) // 上传的图片服务器地址
 const headers = ref({ Authorization: "Bearer " + getToken() })
 const fileList = ref<any[]>([])
@@ -37,7 +38,11 @@ const isImage = computed(() => {
 	return props.uploadType == "image"
 })
 const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize))
-
+const imageUrls = computed(() => {
+	return fileList.value.map((v) => {
+		return v.url
+	})
+})
 // 上传前校检格式和大小
 function handleBeforeUpload(file: any) {
 	let flag = false
@@ -83,8 +88,16 @@ function handleUploadError() {
 
 // 上传成功回调
 function handleUploadSuccess(res: any, file: any) {
-	if (res.code === 200) {
-		uploadList.value.push({ name: res.fileName, url: res.fileName })
+	console.log("RES", res, file)
+	if (res.code === 200 && res.data.url) {
+		let url = `${baseUrl}/${props.prefixUrl ? props.prefixUrl : ""}/${res.data.url}`
+		url = url
+			.replace("https://", "$$$$")
+			.replace("http://", "@@@@")
+			.replace(/\/\//g, "/")
+			.replace("$$$$", "https://")
+			.replace("@@@@", "http://")
+		uploadList.value.push({ name: res.data.url, url })
 		uploadedSuccessfully()
 	} else {
 		number.value--
@@ -126,8 +139,10 @@ function uploadedSuccessfully() {
 
 // 预览
 function handlePictureCardPreview(file: any) {
-	dialogImageUrl.value = file.url
-	dialogVisible.value = true
+	//dialogImageUrl.value = file.url
+	console.log("---", file)
+	viewerInitialIndex.value = file.index //fileList.value.map((f) => f.url).indexOf(file.url)
+	showViewer.value = true
 }
 
 // 获取文件名称
@@ -141,30 +156,41 @@ function getFileName(name: string) {
 
 // 对象转成指定字符串分隔
 function listToString(list: any[], separator?: string) {
-	let strs = ""
+	let str = ""
 	separator = separator ?? ","
 	list.forEach((v) => {
 		if (undefined !== v.url && v.url.indexOf("blob:") !== 0) {
-			strs += v.url.replace(baseUrl, "") + separator
+			str += v.name + separator
 		}
 	})
-	return strs != "" ? strs.substring(0, strs.length - 1) : ""
+	return str != "" ? str.substring(0, str.length - 1) : ""
 }
 
 watch(
 	() => props.modelValue,
 	(val) => {
 		if (val) {
-			let temp = 1
+			let temp = 0
 			// 首先将值转为数组
 			const list = Array.isArray(val) ? val : (props.modelValue as string)?.split(",")
 			// 然后将数组转为对象数组
 			fileList.value = list.map((item) => {
 				if (typeof item === "string") {
 					if (!item.includes(baseUrl)) {
-						item = { name: baseUrl + item, url: baseUrl + item }
+						let url = `${baseUrl}/${props.prefixUrl ? props.prefixUrl : ""}/${item}`
+						url = url
+							.replace("https://", "$$$$")
+							.replace("http://", "@@@@")
+							.replace(/\/\//g, "/")
+							.replace("$$$$", "https://")
+							.replace("@@@@", "http://")
+						item = {
+							name: item,
+							url,
+							index: temp
+						}
 					} else {
-						item = { name: item, url: item }
+						item = { name: item, url: item, index: temp }
 					}
 					item.uid = item.uid || new Date().getTime() + temp++
 				}
@@ -202,12 +228,19 @@ onMounted(init)
 			:headers="headers"
 			:on-preview="isImage ? handlePictureCardPreview : undefined"
 			:class="{ hide: fileList.length >= limit, 'upload-file-uploader': !isImage }">
-			<el-icon v-if="isImage" class="avatar-uploader-icon"><plus /></el-icon>
+			<el-icon v-if="isImage" class="avatar-uploader-icon">
+				<VbIcon icon-name="plus-square"></VbIcon>
+			</el-icon>
 			<el-button v-else type="primary">选取文件</el-button>
 		</el-upload>
 		<!-- 上传提示 -->
 		<div class="el-upload__tip" v-if="showTip">
-			请上传
+			<template v-if="limit">
+				最多可上传
+				<b style="color: #f56c6c">{{ limit }}</b>
+				{{ isImage ? "张" : "个" }}
+			</template>
+			<span v-else>请上传</span>
 			<template v-if="fileSize">
 				大小不超过
 				<b style="color: #f56c6c">{{ fileSize }}MB</b>
@@ -216,20 +249,17 @@ onMounted(init)
 				格式为
 				<b style="color: #f56c6c">{{ fileType.join("/") }}</b>
 			</template>
-			的文件。
-			<template v-if="limit">
-				(最多可上传
-				<b style="color: #f56c6c">{{ limit }}</b>
-				{{ isImage ? "张图片" : "个文件" }})
-			</template>
+			的{{ isImage ? "图片" : "文件" }}。
 		</div>
-
-		<el-dialog v-if="isImage" v-model="dialogVisible" title="预览" width="800px" append-to-body>
-			<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
-		</el-dialog>
+		<el-image-viewer
+			v-if="isImage && showViewer"
+			:url-list="imageUrls"
+			:initial-index="viewerInitialIndex"
+			:teleported="true"
+			@close="() => (showViewer = false)" />
 		<!-- 文件列表 -->
 		<transition-group
-			v-else
+			v-if="!isImage"
 			class="upload-file-list el-upload-list el-upload-list--text"
 			name="el-fade-in-linear"
 			tag="ul">

+ 108 - 31
UI/XYH.VUE/src/views/amActivity/activity/index.vue

@@ -18,9 +18,11 @@ const opts = reactive({
 		{ field: "peopleMax", name: "人数上限", visible: true, width: 80 },
 		{ field: "activityDate", name: "活动日期", visible: true, width: 120 },
 		{ field: "expiryDate", name: "截止日期", visible: true, width: 120 },
-		{ field: "area", name: "活动区域", visible: true, width: 80 },
+		// { field: "area", name: "活动区域", visible: true, width: 80 },
 		{ field: "address", name: "活动地点", visible: true },
-		{ field: "auditStatus", name: "状态", visible: true, width: 100 },
+		{ field: "auditStatus", name: "审核状态", visible: true, width: 100 },
+		{ field: "isHead", name: "置顶", visible: true, width: 80 },
+		{ field: "isHot", name: "热门", visible: true, width: 80 },
 		{ field: "actions", name: `操作`, width: 150 }
 	],
 	queryParams: {
@@ -284,10 +286,15 @@ const opts = reactive({
 			}
 		},
 		{
-			field: "file",
+			field: "images",
 			label: "图片上传",
 			class: "w-100",
-			component: "slot"
+			component: "VU",
+			props: {
+				uploadUrl: "/oss/upload/activity",
+				prefixUrl: "/oss/preview/",
+				limit: 8
+			}
 		}
 	] as any,
 	resetForm: () => {
@@ -345,6 +352,13 @@ const detailModalTitle = computed(() => {
 const detailData = ref({})
 const auditStatus = ref("1")
 
+/** 提交按钮 */
+function submitForm() {
+	apis.amActivity.activityApi.addOrUpdateActivity(form.value).then(() => {
+		handleQuery()
+	})
+}
+
 function handleAudit(row: any) {
 	detailType.value = "A"
 	apis.amActivity.activityApi.getActivity(row.activityId).then((res) => {
@@ -371,25 +385,74 @@ function submitDetail() {
 		return
 	}
 	if (detailType.value === "A") {
+		apis.amActivity.activityApi
+			.auditActivity(detailData.value.activityId, auditStatus.value)
+			.then(() => {
+				detailModalRef.value.hide()
+				handleQuery()
+			})
 	}
 }
 
-/** 提交按钮 */
-function submitForm() {
-	const formData = new FormData()
-	fileList.value.forEach((file) => {
-		formData.append("files", file.raw)
-	})
-	const data: any = {}
-	Object.keys(emptyFormData.value).forEach((v) => {
-		data[v] = form.value[v]
-		formData.append(v, form.value[v])
-	})
-	//formData.append("form", JSON.stringify(data))
-	apis.amActivity.activityApi.addOrUpdateActivity(formData, !!form.value.activityId).then(() => {
-		handleQuery()
-	})
+function handleClose(row: any) {
+	message
+		.confirm("是否确认关闭 [" + row.title + "] 的活动?")
+		.then(() => {
+			apis.amActivity.activityApi.closeActivity(row.activityId).then(() => {
+				handleQuery()
+				message.msgSuccess("关闭成功")
+			})
+		})
+		.catch(() => {
+			//
+		})
 }
+function handleTop(row: any) {
+	if (row.auditStatus == "2") {
+		message.msgWarning("活动未审核通过")
+		return
+	}
+	if (row.auditStatus == "3") {
+		message.msgWarning("活动已关闭")
+		return
+	}
+	const text = row.isHead === "0" ? "取消置顶" : "置顶"
+	message
+		.confirm("确认要" + text + " [" + row.title + "] 的活动?")
+		.then(() => {
+			apis.amActivity.activityApi.topActivity(row.activityId, row.isHead).then(() => {
+				message.msgSuccess(text + "成功")
+				handleQuery()
+			})
+		})
+		.catch(() => {
+			row.isHead = row.isHead === "0" ? "1" : "0"
+		})
+}
+
+function handleHot(row: any) {
+	if (row.auditStatus == "2") {
+		message.msgWarning("活动未审核通过")
+		return
+	}
+	if (row.auditStatus == "3") {
+		message.msgWarning("活动已关闭")
+		return
+	}
+	const text = row.isHot === "0" ? "取消热门" : "热门"
+	message
+		.confirm("确认要" + text + " [" + row.title + "] 的活动?")
+		.then(() => {
+			apis.amActivity.activityApi.topActivity(row.activityId, row.isHot).then(() => {
+				message.msgSuccess(text + "成功")
+				handleQuery()
+			})
+		})
+		.catch(() => {
+			row.isHead = row.isHot === "0" ? "1" : "0"
+		})
+}
+
 function loadCategory() {
 	apis.system.categoryApi.getActivityCategory().then((res) => {
 		categoryColumns.value = []
@@ -442,6 +505,24 @@ onMounted(init)
 					{{ dayjs(row.expiryDate).format("YYYY-MM-DD") }}
 				</span>
 			</template>
+			<template #address="{ row }">
+				<span v-if="row.area == '线上活动'" class="text-info">{{ row.area }}</span>
+				<span v-else>{{ row.address }}</span>
+			</template>
+			<template #isHead="{ row }">
+				<el-switch
+					v-model="row.isHead"
+					active-value="1"
+					inactive-value="0"
+					@change="handleTop(row)"></el-switch>
+			</template>
+			<template #isHot="{ row }">
+				<el-switch
+					v-model="row.isHot"
+					active-value="1"
+					inactive-value="0"
+					@change="handleHot(row)"></el-switch>
+			</template>
 			<template #actions="{ row }">
 				<vb-tooltip
 					v-if="row.auditStatus != 0 && row.auditStatus != 2"
@@ -479,7 +560,7 @@ onMounted(init)
 						</template>
 					</el-button>
 				</vb-tooltip>
-				<vb-tooltip content="修改" placement="top">
+				<vb-tooltip v-if="row.auditStatus != 3" content="修改" placement="top">
 					<el-button
 						link
 						type="primary"
@@ -490,7 +571,10 @@ onMounted(init)
 						</template>
 					</el-button>
 				</vb-tooltip>
-				<vb-tooltip content="删除" placement="top">
+				<vb-tooltip
+					v-if="row.auditStatus == 0 || row.auditStatus == 3"
+					content="删除"
+					placement="top">
 					<el-button
 						link
 						type="primary"
@@ -510,14 +594,7 @@ onMounted(init)
 			:form-items="opts.formItems"
 			:label-width="opts.labelWidth"
 			append-to-body
-			@confirm="submitForm">
-			<template #file_form>
-				<div>
-					<VbUpload2 ref="uploadRef" v-model="fileList"></VbUpload2>
-				</div>
-			</template>
-		</VbModal>
-
+			@confirm="submitForm"></VbModal>
 		<VbModal
 			modalBodyClass="detail-modal"
 			v-model:modal="detailModalRef"
@@ -580,9 +657,9 @@ onMounted(init)
 						</dl>
 					</el-col>
 				</el-row>
-				<el-row :gutter="20" v-if="detailData.images">
+				<div class="d-flex justify-content-center my-3" v-if="detailData.images">
 					<VbImagePreview :src="detailData.images" :prefixSrc="'/oss/preview/'"></VbImagePreview>
-				</el-row>
+				</div>
 				<div v-if="detailType == 'A'" class="d-flex justify-content-center">
 					<vb-select
 						v-model="auditStatus"