xgb 12 часов назад
Родитель
Сommit
0dc3c6d623

+ 104 - 0
fs-admin/src/main/java/com/fs/app/controller/AccWorkController.java

@@ -0,0 +1,104 @@
+package com.fs.app.controller;
+
+import java.util.List;
+
+import com.fs.activity.domain.AccWork;
+import com.fs.activity.service.AccWorkService;
+import com.fs.common.utils.poi.ExcelUtil;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 作品Controller
+ *
+ * @author fs
+ * @date 2026-03-09
+ */
+@RestController
+@RequestMapping("/app/acc/work")
+public class AccWorkController extends BaseController
+{
+    @Autowired
+    private AccWorkService accWorkService;
+
+    /**
+     * 查询作品列表
+     */
+    @PreAuthorize("@ss.hasPermi('app:accWork:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(AccWork accWork)
+    {
+        startPage();
+        List<AccWork> list = accWorkService.selectAccWorkList(accWork);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出作品列表
+     */
+    @PreAuthorize("@ss.hasPermi('app:accWork:export')")
+    @Log(title = "作品", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(AccWork accWork)
+    {
+        List<AccWork> list = accWorkService.selectAccWorkList(accWork);
+        ExcelUtil<AccWork> util = new ExcelUtil<AccWork>(AccWork.class);
+        return util.exportExcel(list, "作品数据");
+    }
+
+    /**
+     * 获取作品详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('app:accWork:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(accWorkService.selectAccWorkById(id));
+    }
+
+    /**
+     * 新增作品
+     */
+    @PreAuthorize("@ss.hasPermi('app:accWork:add')")
+    @Log(title = "作品", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody AccWork accWork)
+    {
+        return toAjax(accWorkService.insertAccWork(accWork));
+    }
+
+    /**
+     * 修改作品
+     */
+    @PreAuthorize("@ss.hasPermi('app:accWork:edit')")
+    @Log(title = "作品", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody AccWork accWork)
+    {
+        return toAjax(accWorkService.updateAccWork(accWork));
+    }
+
+    /**
+     * 删除作品
+     */
+    @PreAuthorize("@ss.hasPermi('app:accWork:remove')")
+    @Log(title = "作品", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(accWorkService.deleteAccWorkByIds(ids));
+    }
+}

+ 2 - 2
fs-service/src/main/java/com/fs/activity/domain/AccWork.java

@@ -57,12 +57,12 @@ public class AccWork {
     /**
      * 总投票数
      */
-    private Integer voteCount;
+    private Long voteCount;
 
     /**
      * 观看次数
      */
-    private Integer viewCount;
+    private Long viewCount;
 
     /**
      * 状态:0-待审核 1-已通过 2-已驳回 3-已下架

+ 49 - 0
fs-service/src/main/java/com/fs/activity/mapper/AccWorkMapper.java

@@ -3,6 +3,8 @@ package com.fs.activity.mapper;
 import com.fs.activity.domain.AccWork;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 
+import java.util.List;
+
 /**
 * @author Administrator
 * @description 针对表【acc_work(作品表)】的数据库操作Mapper
@@ -11,6 +13,53 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 */
 public interface AccWorkMapper extends BaseMapper<AccWork> {
 
+    /**
+     * 查询作品
+     *
+     * @param id 作品主键
+     * @return 作品
+     */
+    AccWork selectAccWorkById(Long id);
+
+    /**
+     * 查询作品列表
+     *
+     * @param accWork 作品
+     * @return 作品集合
+     */
+    List<AccWork> selectAccWorkList(AccWork accWork);
+
+    /**
+     * 新增作品
+     *
+     * @param accWork 作品
+     * @return 结果
+     */
+    int insertAccWork(AccWork accWork);
+
+    /**
+     * 修改作品
+     *
+     * @param accWork 作品
+     * @return 结果
+     */
+    int updateAccWork(AccWork accWork);
+
+    /**
+     * 删除作品
+     *
+     * @param id 作品主键
+     * @return 结果
+     */
+    int deleteAccWorkById(Long id);
+
+    /**
+     * 批量删除作品
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteAccWorkByIds(Long[] ids);
 }
 
 

+ 53 - 0
fs-service/src/main/java/com/fs/activity/param/AccVoteRecordRequest.java

@@ -0,0 +1,53 @@
+package com.fs.activity.param;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 投票记录表
+ *
+ */
+@Data
+public class AccVoteRecordRequest {
+
+    /**
+     * 作品ID
+     */
+    private Long workId;
+
+    /**
+     * 活动id
+     */
+    private Long activityId;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 投票日期
+     */
+    private Date voteDate;
+
+    /**
+     * 投票时间
+     */
+    private Date voteTime;
+
+    /**
+     * IP地址
+     */
+    private String ipAddress;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+
+}

+ 24 - 0
fs-service/src/main/java/com/fs/activity/param/AccVoteRecordResponse.java

@@ -0,0 +1,24 @@
+package com.fs.activity.param;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 投票记录表
+ *
+ */
+@Data
+public class AccVoteRecordResponse {
+
+    /**
+     * 作品ID
+     */
+    private Long workId;
+
+    private String workName;
+
+    private Long CurrentVotes;
+
+
+}

+ 3 - 0
fs-service/src/main/java/com/fs/activity/service/AccActivityService.java

@@ -62,4 +62,7 @@ public interface AccActivityService extends IService<AccActivity> {
     int deleteAccActivityById(Long id);
 
     R checkActivitySignUpStatus(Long activityId);
+
+
+    R checkActivityStatus(Long activityId);
 }

+ 61 - 0
fs-service/src/main/java/com/fs/activity/service/AccWorkService.java

@@ -1,7 +1,12 @@
 package com.fs.activity.service;
 
+import com.fs.activity.domain.AccVoteRecord;
 import com.fs.activity.domain.AccWork;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.activity.param.AccVoteRecordRequest;
+import com.fs.common.core.domain.R;
+
+import java.util.List;
 
 /**
 * @author Administrator
@@ -10,4 +15,60 @@ import com.baomidou.mybatisplus.extension.service.IService;
 */
 public interface AccWorkService extends IService<AccWork> {
 
+    /**
+     * 查询作品
+     *
+     * @param id 作品主键
+     * @return 作品
+     */
+    AccWork selectAccWorkById(Long id);
+
+    /**
+     * 查询作品列表
+     *
+     * @param accWork 作品
+     * @return 作品集合
+     */
+    List<AccWork> selectAccWorkList(AccWork accWork);
+
+    /**
+     * 新增作品
+     *
+     * @param accWork 作品
+     * @return 结果
+     */
+    int insertAccWork(AccWork accWork);
+
+    /**
+     * 修改作品
+     *
+     * @param accWork 作品
+     * @return 结果
+     */
+    int updateAccWork(AccWork accWork);
+
+    /**
+     * 批量删除作品
+     *
+     * @param ids 需要删除的作品主键集合
+     * @return 结果
+     */
+    int deleteAccWorkByIds(Long[] ids);
+
+    /**
+     * 删除作品信息
+     *
+     * @param id 作品主键
+     * @return 结果
+     */
+    int deleteAccWorkById(Long id);
+
+
+
+
+
+
+    R uploadVideo(AccWork accWork);
+
+    R castVote(AccVoteRecordRequest accWorkRecord);
 }

+ 21 - 2
fs-service/src/main/java/com/fs/activity/service/impl/AccActivityServiceImpl.java

@@ -107,15 +107,34 @@ public class AccActivityServiceImpl extends ServiceImpl<AccActivityMapper, AccAc
             return R.error("活动未进行");
         }
         // 检测活动时间
-        if(accActivity.getActivityStartTime().getTime()>System.currentTimeMillis()){
+        if(accActivity.getRegistrationStartTime().getTime()>System.currentTimeMillis()){
             return R.error("活动未开始报名");
         }
-        if(accActivity.getActivityEndTime().getTime()<System.currentTimeMillis()){
+        if(accActivity.getRegistrationEndTime().getTime()<System.currentTimeMillis()){
             return R.error("活动报名已结束");
         }
         return R.ok();
     }
 
+    @Override
+    public R checkActivityStatus(Long activityId) {
+        AccActivity accActivity = baseMapper.selectAccActivityById(activityId);
+        if(accActivity==null){
+            return R.error("活动不存在");
+        }
+        if(accActivity.getStatus()!=1){
+            return R.error("活动未进行");
+        }
+        // 检测活动时间
+        if(accActivity.getActivityStartTime().getTime()>System.currentTimeMillis()){
+            return R.error("活动未开始");
+        }
+        if(accActivity.getActivityEndTime().getTime()<System.currentTimeMillis()){
+            return R.error("活动已结束");
+        }
+        return R.ok();
+    }
+
 
 }
 

+ 278 - 0
fs-service/src/main/java/com/fs/activity/service/impl/AccWorkServiceImpl.java

@@ -1,20 +1,298 @@
 package com.fs.activity.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.activity.domain.AccVoteRecord;
 import com.fs.activity.domain.AccWork;
+import com.fs.activity.mapper.AccVoteRecordMapper;
+import com.fs.activity.param.AccVoteRecordRequest;
+import com.fs.activity.param.AccVoteRecordResponse;
+import com.fs.activity.service.AccActivityService;
 import com.fs.activity.service.AccWorkService;
 import com.fs.activity.mapper.AccWorkMapper;
+import com.fs.common.constant.FsConstants;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.exception.ServiceException;
+import com.fs.common.exception.base.BusinessException;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
 /**
 * @author Administrator
 * @description 针对表【acc_work(作品表)】的数据库操作Service实现
 * @createDate 2026-03-05 14:33:08
 */
 @Service
+@Slf4j
 public class AccWorkServiceImpl extends ServiceImpl<AccWorkMapper, AccWork>
     implements AccWorkService{
 
+    private static final String DAILY_VOTE_LIMIT = "vote:daily:limit";
+
+    private static final String VOTE_LOCK_KEY = "vote:lock:";
+
+    private static final String VOTE_COUNT_KEY = "vote:count:";
+
+    private static final String VOTE_RANKING_KEY = "vote:ranking";
+
+
+
+    // 每日最大投票数(可配置)
+    private static final int MAX_VOTES_PER_DAY = 3;
+
+    @Autowired
+    private AccActivityService accActivityService;
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    @Autowired
+    private AccVoteRecordMapper accVoteRecordMapper ;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    /**
+     * 查询作品
+     *
+     * @param id 作品主键
+     * @return 作品
+     */
+    @Override
+    public AccWork selectAccWorkById(Long id)
+    {
+        return baseMapper.selectAccWorkById(id);
+    }
+
+    /**
+     * 查询作品列表
+     *
+     * @param accWork 作品
+     * @return 作品
+     */
+    @Override
+    public List<AccWork> selectAccWorkList(AccWork accWork)
+    {
+        return baseMapper.selectAccWorkList(accWork);
+    }
+
+    /**
+     * 新增作品
+     *
+     * @param accWork 作品
+     * @return 结果
+     */
+    @Override
+    public int insertAccWork(AccWork accWork)
+    {
+        return baseMapper.insertAccWork(accWork);
+    }
+
+    /**
+     * 修改作品
+     *
+     * @param accWork 作品
+     * @return 结果
+     */
+    @Override
+    public int updateAccWork(AccWork accWork)
+    {
+        return baseMapper.updateAccWork(accWork);
+    }
+
+    /**
+     * 批量删除作品
+     *
+     * @param ids 需要删除的作品主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAccWorkByIds(Long[] ids)
+    {
+        return baseMapper.deleteAccWorkByIds(ids);
+    }
+
+    /**
+     * 删除作品信息
+     *
+     * @param id 作品主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAccWorkById(Long id)
+    {
+        return baseMapper.deleteAccWorkById(id);
+    }
+
+    /**
+     * @Description: 上传活动视频
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2026/3/9 10:40
+     */
+    @Override
+    public R uploadVideo(AccWork accWork) {
+
+        accWork.setStatus(0);
+        R r = accActivityService.checkActivityStatus(accWork.getActivityId());
+        if(!r.get("code").equals(200)){
+            return r;
+        }
+
+        // 查询是否上传了视频,已上传更新
+        AccWork work = baseMapper.selectOne(new LambdaQueryWrapper<AccWork>()
+                .eq(AccWork::getActivityId, accWork.getActivityId())
+                .eq(AccWork::getTeamId, accWork.getTeamId()));
+        if(work!=null){
+            accWork.setId(work.getId());
+            if (baseMapper.updateById(accWork)<1){
+                return R.error("更新失败");
+            }
+        }else {
+            if (baseMapper.insert(accWork)<1){
+                return R.error("上传失败");
+            }
+        }
+
+        return R.ok();
+    }
+
+    /**
+     * @Description: 投票
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2026/3/9 11:16
+     */
+    @Override
+    public R castVote(AccVoteRecordRequest request) {
+
+        Long workId = request.getWorkId();
+        Long userId = request.getUserId();
+        Long activityId = request.getActivityId();
+        LocalDate today = LocalDate.now();
+        String todayStr = today.format(DateTimeFormatter.ISO_DATE);
+
+        // 检测活动状态
+        R r = accActivityService.checkActivityStatus(activityId);
+        if(!r.get("code").equals(200)){
+            return r;
+        }
+
+        // 3. 检查用户今日投票次数是否已达上限
+        int todayVoteCount = getUserTodayVoteCount(userId);
+        if (todayVoteCount >= MAX_VOTES_PER_DAY) {
+            throw new ServiceException("今日投票次数已达上限(" + MAX_VOTES_PER_DAY + "次)");
+        }
+
+        // 4. 使用Redis分布式锁防止重复提交
+        String lockKey = VOTE_LOCK_KEY + userId + ":" + workId + ":" + todayStr;
+        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
+        if (Boolean.FALSE.equals(locked)) {
+            throw new ServiceException("请勿重复提交");
+        }
+
+        // 引入 Redisson
+        RLock lock = redissonClient.getLock(lockKey);
+        boolean lockAcquired = false;
+        try {
+            lockAcquired = lock.tryLock(3, 10, TimeUnit.SECONDS);
+            if (lockAcquired) {
+
+                // 5. 检查今日是否已给该作品投票
+                if (accVoteRecordMapper.selectCount(new LambdaQueryWrapper<AccVoteRecord>()
+                        .eq(AccVoteRecord::getUserId, userId)
+                        .eq(AccVoteRecord::getWorkId, workId)
+                        .eq(AccVoteRecord::getVoteDate, today)) > 0) {
+                    throw new ServiceException("今日已给该作品投票");
+                }
+
+                // 6. 创建投票记录
+                AccVoteRecord record = new AccVoteRecord();
+                record.setWorkId(workId);
+                record.setUserId(userId);
+                record.setVoteDate(new Date());
+                record.setIpAddress(request.getIpAddress());
+                if(accVoteRecordMapper.insert(record)<1){
+                    throw new ServiceException("投票失败");
+                }
+
+                AccWork work = new AccWork();
+                work.setId(workId);
+                // 7. 更新作品票数
+                work.setVoteCount(work.getVoteCount() + 1);
+                baseMapper.updateById(work);
+
+                // 8. 更新Redis缓存
+                // 8.1 更新作品票数缓存
+                String countKey = VOTE_COUNT_KEY + workId;
+                redisTemplate.opsForValue().increment(countKey);
+
+                // 8.2 更新排行榜(使用ZSet)
+                redisTemplate.opsForZSet().incrementScore(VOTE_RANKING_KEY, String.valueOf(workId), 1);
+
+
+                // 8.4 更新用户今日投票计数
+                String dailyLimitKey = DAILY_VOTE_LIMIT + activityId +":"+ userId + ":" + todayStr;
+                Long currentVotes = redisTemplate.opsForValue().increment(dailyLimitKey);
+                redisTemplate.expire(dailyLimitKey, 2, TimeUnit.DAYS);
+
+                log.info("用户{}给作品{}投票成功,今日第{}票,当前作品总票数:{}",
+                        userId, workId, currentVotes, work.getVoteCount());
+
+                // 9. 返回结果
+                AccVoteRecordResponse response = new AccVoteRecordResponse();
+                response.setWorkId(workId);
+                response.setWorkName(work.getWorkName());
+                response.setCurrentVotes(work.getVoteCount());
+                return R.ok().put("data", response);
+            }else {
+                throw new ServiceException("服务繁忙,请稍后再试");
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (lockAcquired && lock.isHeldByCurrentThread()) {
+                try {
+                    lock.unlock();
+                } catch (IllegalMonitorStateException e) {
+                    log.warn("尝试释放非当前线程持有的锁");
+                }
+            }
+        }
+
+    }
+
+    /**
+     * 获取用户今日投票数
+     */
+    private int getUserTodayVoteCount(Long userId) {
+        LocalDate today = LocalDate.now();
+        String todayStr = today.format(DateTimeFormatter.ISO_DATE);
+        String dailyLimitKey = DAILY_VOTE_LIMIT + userId + ":" + todayStr;
+
+        Integer count = (Integer) redisTemplate.opsForValue().get(dailyLimitKey);
+        if (count != null) {
+            return count;
+        }
+
+
+        return accVoteRecordMapper.selectCount(new LambdaQueryWrapper<AccVoteRecord>()
+                .eq(AccVoteRecord::getUserId, userId).eq(AccVoteRecord::getVoteDate, todayStr));
+    }
 }
 
 

+ 1 - 1
fs-service/src/main/java/com/fs/store/param/h5/FsUserPageListParam.java

@@ -96,7 +96,7 @@ public class FsUserPageListParam implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date sTime;
 
-    // 0-不是 1-
+    //  1-是 2-不
     private Integer isAppUser;
 
 

+ 91 - 0
fs-service/src/main/resources/mapper/activity/AccWorkMapper.xml

@@ -27,4 +27,95 @@
         description,duration,vote_count,view_count,status,
         audit_remark,audit_time,created_at,updated_at
     </sql>
+
+    <sql id="selectAccWorkVo">
+        select id, team_id, activity_id, work_name, cover_url, video_url, description, duration, vote_count, view_count, status, audit_remark, audit_time, created_at, updated_at from acc_work
+    </sql>
+
+    <select id="selectAccWorkList" parameterType="AccWork" resultMap="BaseResultMap">
+        <include refid="selectAccWorkVo"/>
+        <where>
+            <if test="teamId != null "> and team_id = #{teamId}</if>
+            <if test="activityId != null "> and activity_id = #{activityId}</if>
+            <if test="workName != null  and workName != ''"> and work_name like concat('%', #{workName}, '%')</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="params.beginAuditTime != null and params.beginAuditTime != '' and params.endAuditTime != null and params.endAuditTime != ''"> and audit_time between #{params.beginAuditTime} and #{params.endAuditTime}</if>
+            <if test="params.beginCreatedAt != null and params.beginCreatedAt != '' and params.endCreatedAt != null and params.endCreatedAt != ''"> and created_at between #{params.beginCreatedAt} and #{params.endCreatedAt}</if>
+        </where>
+    </select>
+
+    <select id="selectAccWorkById" parameterType="Long" resultMap="BaseResultMap">
+        <include refid="selectAccWorkVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertAccWork" parameterType="AccWork" useGeneratedKeys="true" keyProperty="id">
+        insert into acc_work
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="teamId != null">team_id,</if>
+            <if test="activityId != null">activity_id,</if>
+            <if test="workName != null">work_name,</if>
+            <if test="coverUrl != null">cover_url,</if>
+            <if test="videoUrl != null">video_url,</if>
+            <if test="description != null">description,</if>
+            <if test="duration != null">duration,</if>
+            <if test="voteCount != null">vote_count,</if>
+            <if test="viewCount != null">view_count,</if>
+            <if test="status != null">status,</if>
+            <if test="auditRemark != null">audit_remark,</if>
+            <if test="auditTime != null">audit_time,</if>
+            <if test="createdAt != null">created_at,</if>
+            <if test="updatedAt != null">updated_at,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="teamId != null">#{teamId},</if>
+            <if test="activityId != null">#{activityId},</if>
+            <if test="workName != null">#{workName},</if>
+            <if test="coverUrl != null">#{coverUrl},</if>
+            <if test="videoUrl != null">#{videoUrl},</if>
+            <if test="description != null">#{description},</if>
+            <if test="duration != null">#{duration},</if>
+            <if test="voteCount != null">#{voteCount},</if>
+            <if test="viewCount != null">#{viewCount},</if>
+            <if test="status != null">#{status},</if>
+            <if test="auditRemark != null">#{auditRemark},</if>
+            <if test="auditTime != null">#{auditTime},</if>
+            <if test="createdAt != null">#{createdAt},</if>
+            <if test="updatedAt != null">#{updatedAt},</if>
+        </trim>
+    </insert>
+
+    <update id="updateAccWork" parameterType="AccWork">
+        update acc_work
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="teamId != null">team_id = #{teamId},</if>
+            <if test="activityId != null">activity_id = #{activityId},</if>
+            <if test="workName != null">work_name = #{workName},</if>
+            <if test="coverUrl != null">cover_url = #{coverUrl},</if>
+            <if test="videoUrl != null">video_url = #{videoUrl},</if>
+            <if test="description != null">description = #{description},</if>
+            <if test="duration != null">duration = #{duration},</if>
+            <if test="voteCount != null">vote_count = #{voteCount},</if>
+            <if test="viewCount != null">view_count = #{viewCount},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="auditRemark != null">audit_remark = #{auditRemark},</if>
+            <if test="auditTime != null">audit_time = #{auditTime},</if>
+            <if test="createdAt != null">created_at = #{createdAt},</if>
+            <if test="updatedAt != null">updated_at = #{updatedAt},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteAccWorkById" parameterType="Long">
+        delete from acc_work where id = #{id}
+    </delete>
+
+    <delete id="deleteAccWorkByIds" parameterType="String">
+        delete from acc_work where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+
 </mapper>

+ 9 - 4
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -233,7 +233,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         fs_user.avatar,
         fs_user.nick_name as nickname,
         fs_user.phone,
-        case when fs_user.app_open_id is null then 0 else 1 end as isAppUser,
+        case when fs_user.app_open_id is null then 2 else 1 end as isAppUser,
         fs_user_course_count.id,
         fs_user_course_count.watch_course_count,
 --         fs_course_watch_log.watch_course_count,
@@ -263,9 +263,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN company_tag ON company_tag.tag_id = upt.tag_id
         LEFT JOIN company_user ON company_user.user_id = fs_user_company_user.company_user_id
         where fs_user.is_del = 0
-        <if test="isAppUser != null">
-            and fs_user.app_open_id is not null
-        </if>
+        <choose>
+            <when test="isAppUser != null and isAppUser == 1">
+                and fs_user.app_open_id is not null
+            </when>
+            <when test="isAppUser != null and isAppUser == 2">
+                and fs_user.app_open_id is null
+            </when>
+        </choose>
         <if test="userId != null and userId!= 0 ">
             and fs_user_company_user.company_user_id = #{userId}
         </if>

+ 43 - 0
fs-user-app/src/main/java/com/fs/app/controller/app/AccActivityController.java

@@ -1,14 +1,21 @@
 package com.fs.app.controller.app;
 
 import com.fs.activity.domain.AccTeam;
+import com.fs.activity.domain.AccVoteRecord;
+import com.fs.activity.domain.AccWork;
 import com.fs.activity.param.AccTeamMemberRequest;
+import com.fs.activity.param.AccVoteRecordRequest;
 import com.fs.activity.service.AccActivityService;
 import com.fs.activity.service.AccTeamMemberService;
 import com.fs.activity.service.AccTeamService;
+import com.fs.activity.service.AccWorkService;
 import com.fs.activity.service.impl.AccTeamMemberServiceImpl;
 import com.fs.app.annotation.Login;
 import com.fs.app.controller.AppBaseController;
 import com.fs.common.core.domain.R;
+import com.fs.course.domain.FsUserTalent;
+import com.fs.course.param.FsUserVideoAddParam;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -30,6 +37,10 @@ public class AccActivityController extends AppBaseController
     @Autowired
     private AccTeamMemberService accTeamMemberService;
 
+
+    @Autowired
+    private AccWorkService accWorkService;
+
     // 活动报名列表
 
     /**
@@ -127,6 +138,38 @@ public class AccActivityController extends AppBaseController
         return accTeamMemberService.deleteTeamMember(accTeam);
     }
 
+    // 上传视频 /app/talent/uploadOSSTalent
+
+    /**
+     * @Description: 上传视频
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2026/3/9 10:11
+     */
+    @Login
+    @PostMapping("/uploadVideo")
+    public R talentVideo(@RequestBody AccWork accWork){
+        return accWorkService.uploadVideo(accWork);
+    }
+
+    /**
+     * @Description: 投票
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2026/3/9 11:07
+     */
+    @Login
+    @PostMapping("/castVote")
+    public R castVote(@RequestBody AccVoteRecordRequest request){
+        request.setUserId(Long.parseLong(getUserId()));
+        return accWorkService.castVote(request);
+    }
+
+
+
+
 
 
 }