refactor: 后端标识统一为 FruitShorts,并落地 05 离线下载
为什么: 1) 产品已定名 FruitShorts,但后端仍是 reelshort 系列标识 —— Java 包 com.reelshort、 模块名与 jar 名 reelshort-*、spring.application.name、配置前缀 reelshort.*, 这些会出现在启动日志、命令行和 IDE 里,与产品名不一致。本次整体替换为 fruitshorts, 数据库连接名上一轮已改名,保持不变。 2) 第一阶段下一批第 1 步(05 离线下载)要求把下载授权(设备绑定/有效期/吊销)、 下载任务与断点续传、配额与过期清理、仅 Wi-Fi 规则做成完整接口,本提交一并落地。 3) 顺带修复:schema-phase1.sql 里 playback_ticket / order_event 仍按普通表定义唯一索引, 表分区化之后重跑脚本必定报错(分区表的唯一索引必须包含分区键)。改为在本脚本里就 按分区表定义,并验证脚本可重复执行。
This commit is contained in:
1 parent
a4aa749cc6
commit
b3179fc836
251 files changed
+7261
-767
No files matched your search
@@ -0,0 +1,14 @@
|
||||
package com.fruitshorts;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.fruitshorts.**.dal.mapper")
|
||||
public class FruitShortsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FruitShortsApplication.class, args);
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.system.service.AdminUserService;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.system.vo.AdminUserPageReqVO;
|
||||
import com.fruitshorts.system.vo.AdminUserRespVO;
|
||||
import com.fruitshorts.system.vo.AdminUserSaveReqVO;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/admin-users")
|
||||
@RequiredArgsConstructor
|
||||
public class AdminUserController {
|
||||
|
||||
private final AdminUserService adminUserService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
public Result<PageResult<AdminUserRespVO>> page(AdminUserPageReqVO req) {
|
||||
return Result.ok(adminUserService.page(req));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
public Result<AdminUserRespVO> get(@PathVariable Long id) {
|
||||
return Result.ok(adminUserService.get(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
@OperationLog(module = "后台管理", action = "新增管理员")
|
||||
public Result<Long> create(@Valid @RequestBody AdminUserSaveReqVO req) {
|
||||
return Result.ok(adminUserService.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
@OperationLog(module = "后台管理", action = "编辑管理员")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody AdminUserSaveReqVO req) {
|
||||
adminUserService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
@OperationLog(module = "后台管理", action = "删除管理员")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
adminUserService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping("/{id}/status")
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
@OperationLog(module = "后台管理", action = "修改管理员状态")
|
||||
public Result<Void> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
|
||||
adminUserService.updateStatus(id, status);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping("/{id}/password")
|
||||
@PreAuthorize("@ss.hasPermission('system:admin-user')")
|
||||
@OperationLog(module = "后台管理", action = "重置管理员密码")
|
||||
public Result<Void> resetPassword(@PathVariable Long id, @RequestBody Map<String, String> body) {
|
||||
adminUserService.resetPassword(id, body.get("password"));
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.admin.vo.AppUserWatchHistoryVO;
|
||||
import com.fruitshorts.content.dal.entity.Drama;
|
||||
import com.fruitshorts.content.dal.entity.DramaEpisode;
|
||||
import com.fruitshorts.content.enums.ContentStatus;
|
||||
import com.fruitshorts.content.service.DramaService;
|
||||
import com.fruitshorts.content.service.EpisodeService;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.playback.dal.entity.WatchHistory;
|
||||
import com.fruitshorts.playback.service.WatchProgressService;
|
||||
import com.fruitshorts.user.dal.entity.AppUserBanRecord;
|
||||
import com.fruitshorts.user.service.AppUserAdminService;
|
||||
import com.fruitshorts.user.vo.AppUserQueryReqVO;
|
||||
import com.fruitshorts.user.vo.AppUserAdminRespVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** 后台用户管理。 */
|
||||
@RestController
|
||||
@RequestMapping("/admin/app-users")
|
||||
@RequiredArgsConstructor
|
||||
public class AppUserAdminController {
|
||||
|
||||
private final AppUserAdminService appUserAdminService;
|
||||
private final WatchProgressService watchProgressService;
|
||||
private final DramaService dramaService;
|
||||
private final EpisodeService episodeService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('app-user:list')")
|
||||
public Result<PageResult<AppUserAdminRespVO>> page(AppUserQueryReqVO req) {
|
||||
return Result.ok(appUserAdminService.page(req));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('app-user:list')")
|
||||
public Result<AppUserAdminRespVO> detail(@PathVariable Long id) {
|
||||
return Result.ok(appUserAdminService.detail(id));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/ban-records")
|
||||
@PreAuthorize("@ss.hasPermission('app-user:list')")
|
||||
public Result<List<AppUserBanRecord>> banRecords(@PathVariable Long id) {
|
||||
return Result.ok(appUserAdminService.banRecords(id));
|
||||
}
|
||||
|
||||
/** 观看流水明细:客服核对"用户说看了但没记录"这类问题时用,带上剧名与集号。 */
|
||||
@GetMapping("/{id}/watch-history")
|
||||
@PreAuthorize("@ss.hasPermission('app-user:list')")
|
||||
public Result<List<AppUserWatchHistoryVO>> watchHistory(@PathVariable Long id,
|
||||
@RequestParam(defaultValue = "50") int limit) {
|
||||
List<WatchHistory> rows = watchProgressService.history(id, limit);
|
||||
if (rows.isEmpty()) {
|
||||
return Result.ok(List.of());
|
||||
}
|
||||
// 批量取剧名与集号:一屏 50 行逐条查库就是 100 次往返
|
||||
Map<Long, Drama> dramas = dramaService
|
||||
.listByIds(rows.stream().map(WatchHistory::getDramaId).distinct().toList())
|
||||
.stream().collect(Collectors.toMap(Drama::getId, item -> item, (a, b) -> a));
|
||||
Map<Long, DramaEpisode> episodes = episodeService
|
||||
.listByIds(rows.stream().map(WatchHistory::getEpisodeId).distinct().toList())
|
||||
.stream().collect(Collectors.toMap(DramaEpisode::getId, item -> item, (a, b) -> a));
|
||||
return Result.ok(rows.stream().map(row -> toVo(row, dramas, episodes)).toList());
|
||||
}
|
||||
|
||||
private AppUserWatchHistoryVO toVo(WatchHistory row, Map<Long, Drama> dramas,
|
||||
Map<Long, DramaEpisode> episodes) {
|
||||
AppUserWatchHistoryVO vo = new AppUserWatchHistoryVO();
|
||||
vo.setId(row.getId());
|
||||
vo.setDramaId(row.getDramaId());
|
||||
vo.setEpisodeId(row.getEpisodeId());
|
||||
vo.setPositionMs(row.getPositionMs());
|
||||
vo.setDurationMs(row.getDurationMs());
|
||||
vo.setSource(row.getSource());
|
||||
vo.setDeviceId(row.getDeviceId());
|
||||
vo.setWatchedAt(row.getWatchedAt());
|
||||
long position = row.getPositionMs() == null ? 0L : row.getPositionMs();
|
||||
long duration = row.getDurationMs() == null ? 0L : row.getDurationMs();
|
||||
vo.setFinished(duration > 0 && position + 1000L >= duration);
|
||||
Drama drama = dramas.get(row.getDramaId());
|
||||
if (drama != null) {
|
||||
vo.setDramaTitle(drama.getTitle());
|
||||
vo.setDramaPublished(ContentStatus.PUBLISHED.getCode().equals(drama.getStatus()));
|
||||
} else {
|
||||
vo.setDramaPublished(false);
|
||||
}
|
||||
DramaEpisode episode = episodes.get(row.getEpisodeId());
|
||||
if (episode != null) {
|
||||
vo.setEpisodeNo(episode.getEpNo());
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
/** 状态处置:normal/limited/banned。封禁会立即吊销该用户全部会话。 */
|
||||
@PutMapping("/{id}/status")
|
||||
@PreAuthorize("@ss.hasPermission('app-user:update')")
|
||||
@OperationLog(module = "用户管理", action = "修改用户状态")
|
||||
public Result<Void> updateStatus(@PathVariable Long id,
|
||||
@RequestParam String status,
|
||||
@RequestParam(required = false) String reason) {
|
||||
appUserAdminService.updateStatus(id, status, reason, SecurityUtils.getUserId());
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.framework.web.WebUtils;
|
||||
import com.fruitshorts.system.service.AuthService;
|
||||
import com.fruitshorts.system.vo.LoginReqVO;
|
||||
import com.fruitshorts.system.vo.LoginRespVO;
|
||||
import com.fruitshorts.system.vo.MenuVO;
|
||||
import com.fruitshorts.system.vo.PasswordChangeReqVO;
|
||||
import com.fruitshorts.system.vo.ProfileRespVO;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/auth")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthController {
|
||||
|
||||
private final AuthService authService;
|
||||
|
||||
@PostMapping("/login")
|
||||
@OperationLog(module = "认证", action = "登录")
|
||||
public Result<LoginRespVO> login(@Valid @RequestBody LoginReqVO req, HttpServletRequest request) {
|
||||
return Result.ok(authService.login(req, WebUtils.getClientIp(request)));
|
||||
}
|
||||
|
||||
/** 当前用户的菜单路由树,结构与前端 element-plus-admin 的动态路由一致。 */
|
||||
@GetMapping("/menus")
|
||||
public Result<List<MenuVO>> menus() {
|
||||
return Result.ok(authService.listMenus(SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/profile")
|
||||
public Result<ProfileRespVO> profile() {
|
||||
return Result.ok(authService.profile(SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
/** JWT 无状态,登出由前端清除 token 即可。 */
|
||||
@PostMapping("/logout")
|
||||
@OperationLog(module = "认证", action = "退出登录")
|
||||
public Result<Void> logout() {
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/password")
|
||||
@OperationLog(module = "认证", action = "修改密码")
|
||||
public Result<Void> changePassword(@Valid @RequestBody PasswordChangeReqVO req) {
|
||||
authService.changePassword(SecurityUtils.getUserId(), req.getOldPassword(), req.getNewPassword());
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.content.service.BannerService;
|
||||
import com.fruitshorts.content.vo.BannerRespVO;
|
||||
import com.fruitshorts.content.vo.BannerSaveReqVO;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/banners")
|
||||
@RequiredArgsConstructor
|
||||
public class BannerController {
|
||||
|
||||
private final BannerService bannerService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('banner:list')")
|
||||
public Result<PageResult<BannerRespVO>> page(@RequestParam(required = false) String position,
|
||||
@RequestParam(required = false) Integer status,
|
||||
@RequestParam(defaultValue = "1") Integer pageIndex,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize) {
|
||||
return Result.ok(bannerService.page(position, status, pageIndex, pageSize));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('banner:list')")
|
||||
public Result<BannerRespVO> get(@PathVariable Long id) {
|
||||
return Result.ok(bannerService.get(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('banner:create')")
|
||||
@OperationLog(module = "内容管理", action = "新增轮播图")
|
||||
public Result<Long> create(@Valid @RequestBody BannerSaveReqVO req) {
|
||||
return Result.ok(bannerService.create(req, SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('banner:update')")
|
||||
@OperationLog(module = "内容管理", action = "编辑轮播图")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody BannerSaveReqVO req) {
|
||||
bannerService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('banner:delete')")
|
||||
@OperationLog(module = "内容管理", action = "删除轮播图")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
bannerService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping("/{id}/status")
|
||||
@PreAuthorize("@ss.hasPermission('banner:update')")
|
||||
@OperationLog(module = "内容管理", action = "修改轮播图状态")
|
||||
public Result<Void> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
|
||||
bannerService.updateStatus(id, status);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping("/sort")
|
||||
@PreAuthorize("@ss.hasPermission('banner:update')")
|
||||
public Result<Void> sort(@RequestBody Map<String, List<Long>> body) {
|
||||
bannerService.updateSort(body.getOrDefault("ids", List.of()));
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.system.service.ConfigService;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.system.vo.ConfigItemVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/configs")
|
||||
@RequiredArgsConstructor
|
||||
public class ConfigController {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("@ss.hasAnyPermission('system:role','system:menu')")
|
||||
public Result<List<ConfigItemVO>> list() {
|
||||
return Result.ok(configService.list());
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
@OperationLog(module = "后台管理", action = "修改系统设置")
|
||||
public Result<Void> update(@RequestBody Map<String, String> values) {
|
||||
configService.update(values);
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.content.enums.ContentStatus;
|
||||
import com.fruitshorts.content.service.DramaCategoryService;
|
||||
import com.fruitshorts.content.vo.DramaCategoryRespVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典接口:题材、内容状态等下拉数据。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/dicts")
|
||||
@RequiredArgsConstructor
|
||||
public class DictController {
|
||||
|
||||
private final DramaCategoryService dramaCategoryService;
|
||||
|
||||
@GetMapping("/drama-category")
|
||||
@PreAuthorize("@ss.hasPermission('drama:list')")
|
||||
public Result<List<DramaCategoryRespVO>> dramaCategories() {
|
||||
return Result.ok(dramaCategoryService.list());
|
||||
}
|
||||
|
||||
@GetMapping("/content-status")
|
||||
@PreAuthorize("@ss.hasPermission('drama:list')")
|
||||
public Result<List<Map<String, String>>> contentStatus() {
|
||||
return Result.ok(Arrays.stream(ContentStatus.values())
|
||||
.map(status -> Map.of("code", status.getCode(), "text", status.getText()))
|
||||
.toList());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.playback.service.DownloadService;
|
||||
import com.fruitshorts.playback.vo.DownloadLicenseRespVO;
|
||||
import com.fruitshorts.playback.vo.DownloadQueryReqVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/** 后台下载授权管理。 */
|
||||
@RestController
|
||||
@RequestMapping("/admin/downloads")
|
||||
@RequiredArgsConstructor
|
||||
public class DownloadAdminController {
|
||||
|
||||
private final DownloadService downloadService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('download:list')")
|
||||
public Result<PageResult<DownloadLicenseRespVO>> page(DownloadQueryReqVO req) {
|
||||
return Result.ok(downloadService.page(req));
|
||||
}
|
||||
|
||||
@GetMapping("/stats")
|
||||
@PreAuthorize("@ss.hasPermission('download:list')")
|
||||
public Result<Map<String, Object>> stats() {
|
||||
return Result.ok(downloadService.stats());
|
||||
}
|
||||
|
||||
/** 吊销单条授权:用户侧下次联网即失效。 */
|
||||
@PutMapping("/{id}/revoke")
|
||||
@PreAuthorize("@ss.hasPermission('download:revoke')")
|
||||
@OperationLog(module = "下载管理", action = "吊销下载授权")
|
||||
public Result<Void> revoke(@PathVariable Long id) {
|
||||
downloadService.adminRevoke(id);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/** 手动触发过期清理,正常情况下由定时任务每天执行。 */
|
||||
@PostMapping("/cleanup")
|
||||
@PreAuthorize("@ss.hasPermission('download:revoke')")
|
||||
@OperationLog(module = "下载管理", action = "清理过期下载授权")
|
||||
public Result<Integer> cleanup() {
|
||||
return Result.ok(downloadService.expireLicenses());
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.content.service.DramaCategoryService;
|
||||
import com.fruitshorts.content.vo.DramaCategoryRespVO;
|
||||
import com.fruitshorts.content.vo.DramaCategorySaveReqVO;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短剧类型管理。类型属于短剧域,权限沿用 drama:*,不再单开权限点。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/drama-categories")
|
||||
@RequiredArgsConstructor
|
||||
public class DramaCategoryController {
|
||||
|
||||
private final DramaCategoryService dramaCategoryService;
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("@ss.hasPermission('drama:list')")
|
||||
public Result<List<DramaCategoryRespVO>> list() {
|
||||
return Result.ok(dramaCategoryService.list());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('drama:create')")
|
||||
@OperationLog(module = "内容管理", action = "新增短剧类型")
|
||||
public Result<Long> create(@Valid @RequestBody DramaCategorySaveReqVO req) {
|
||||
return Result.ok(dramaCategoryService.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('drama:update')")
|
||||
@OperationLog(module = "内容管理", action = "编辑短剧类型")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody DramaCategorySaveReqVO req) {
|
||||
dramaCategoryService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('drama:delete')")
|
||||
@OperationLog(module = "内容管理", action = "删除短剧类型")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
dramaCategoryService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.content.dal.entity.DramaReviewRecord;
|
||||
import com.fruitshorts.content.service.DramaService;
|
||||
import com.fruitshorts.content.vo.DramaPageReqVO;
|
||||
import com.fruitshorts.content.vo.DramaRespVO;
|
||||
import com.fruitshorts.content.vo.DramaSaveReqVO;
|
||||
import com.fruitshorts.content.vo.DramaStatusReqVO;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/dramas")
|
||||
@RequiredArgsConstructor
|
||||
public class DramaController {
|
||||
|
||||
private final DramaService dramaService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('drama:list')")
|
||||
public Result<PageResult<DramaRespVO>> page(DramaPageReqVO req) {
|
||||
return Result.ok(dramaService.page(req));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('drama:list')")
|
||||
public Result<DramaRespVO> get(@PathVariable Long id) {
|
||||
return Result.ok(dramaService.get(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('drama:create')")
|
||||
@OperationLog(module = "内容管理", action = "新建短剧")
|
||||
public Result<Long> create(@Valid @RequestBody DramaSaveReqVO req) {
|
||||
return Result.ok(dramaService.create(req, SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('drama:update')")
|
||||
@OperationLog(module = "内容管理", action = "编辑短剧")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody DramaSaveReqVO req) {
|
||||
dramaService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('drama:delete')")
|
||||
@OperationLog(module = "内容管理", action = "删除短剧")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
dramaService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/** 提交审核:内容运营即可操作。 */
|
||||
@PostMapping("/{id}/submit")
|
||||
@PreAuthorize("@ss.hasAnyPermission('drama:review','drama:update')")
|
||||
@OperationLog(module = "内容管理", action = "提交审核")
|
||||
public Result<Void> submit(@PathVariable Long id, @RequestBody(required = false) DramaStatusReqVO req) {
|
||||
changeStatus(id, "SUBMIT", req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/approve")
|
||||
@PreAuthorize("@ss.hasPermission('drama:review')")
|
||||
@OperationLog(module = "内容管理", action = "审核通过")
|
||||
public Result<Void> approve(@PathVariable Long id, @RequestBody(required = false) DramaStatusReqVO req) {
|
||||
changeStatus(id, "APPROVE", req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/reject")
|
||||
@PreAuthorize("@ss.hasPermission('drama:review')")
|
||||
@OperationLog(module = "内容管理", action = "驳回短剧")
|
||||
public Result<Void> reject(@PathVariable Long id, @RequestBody(required = false) DramaStatusReqVO req) {
|
||||
changeStatus(id, "REJECT", req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/publish")
|
||||
@PreAuthorize("@ss.hasPermission('drama:review')")
|
||||
@OperationLog(module = "内容管理", action = "短剧上线")
|
||||
public Result<Void> publish(@PathVariable Long id, @RequestBody(required = false) DramaStatusReqVO req) {
|
||||
changeStatus(id, "PUBLISH", req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/offline")
|
||||
@PreAuthorize("@ss.hasPermission('drama:review')")
|
||||
@OperationLog(module = "内容管理", action = "短剧下线")
|
||||
public Result<Void> offline(@PathVariable Long id, @RequestBody(required = false) DramaStatusReqVO req) {
|
||||
changeStatus(id, "OFFLINE", req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/review-records")
|
||||
@PreAuthorize("@ss.hasPermission('drama:list')")
|
||||
public Result<List<DramaReviewRecord>> reviewRecords(@PathVariable Long id) {
|
||||
return Result.ok(dramaService.listReviewRecords(id));
|
||||
}
|
||||
|
||||
private void changeStatus(Long id, String action, DramaStatusReqVO req) {
|
||||
dramaService.changeStatus(id, action, req == null ? null : req.getReason(),
|
||||
SecurityUtils.getUserId(), SecurityUtils.getUsername());
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.content.service.EpisodeService;
|
||||
import com.fruitshorts.content.vo.EpisodeRespVO;
|
||||
import com.fruitshorts.content.vo.EpisodeSaveReqVO;
|
||||
import com.fruitshorts.content.vo.EpisodeSortReqVO;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/episodes")
|
||||
@RequiredArgsConstructor
|
||||
public class EpisodeController {
|
||||
|
||||
private final EpisodeService episodeService;
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("@ss.hasPermission('episode:list')")
|
||||
public Result<List<EpisodeRespVO>> list(@RequestParam Long dramaId,
|
||||
@RequestParam(required = false) String status) {
|
||||
return Result.ok(episodeService.listByDrama(dramaId, status));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('episode:upload')")
|
||||
@OperationLog(module = "内容管理", action = "新增剧集")
|
||||
public Result<Long> create(@Valid @RequestBody EpisodeSaveReqVO req) {
|
||||
return Result.ok(episodeService.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('episode:upload')")
|
||||
@OperationLog(module = "内容管理", action = "编辑剧集")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody EpisodeSaveReqVO req) {
|
||||
episodeService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('episode:upload')")
|
||||
@OperationLog(module = "内容管理", action = "删除剧集")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
episodeService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping("/sort")
|
||||
@PreAuthorize("@ss.hasPermission('episode:sort')")
|
||||
@OperationLog(module = "内容管理", action = "调整剧集顺序")
|
||||
public Result<Void> sort(@Valid @RequestBody EpisodeSortReqVO req) {
|
||||
episodeService.updateSort(req.getIds());
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.framework.security.SecurityUtils;
|
||||
import com.fruitshorts.media.service.MediaService;
|
||||
import com.fruitshorts.media.vo.MediaAssetRespVO;
|
||||
import com.fruitshorts.media.vo.UploadCompleteReqVO;
|
||||
import com.fruitshorts.media.vo.UploadInitReqVO;
|
||||
import com.fruitshorts.media.vo.UploadInitRespVO;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 媒资上传(本地存储版):init 建会话 → chunk 传分片 → complete 合并出地址。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/media")
|
||||
@RequiredArgsConstructor
|
||||
public class MediaController {
|
||||
|
||||
private final MediaService mediaService;
|
||||
|
||||
@PostMapping("/upload/init")
|
||||
@PreAuthorize("@ss.hasAnyPermission('cover:upload','episode:upload')")
|
||||
public Result<UploadInitRespVO> init(@Valid @RequestBody UploadInitReqVO req) {
|
||||
return Result.ok(mediaService.init(req, SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
@PostMapping("/upload/chunk")
|
||||
@PreAuthorize("@ss.hasAnyPermission('cover:upload','episode:upload')")
|
||||
public Result<Integer> uploadChunk(@RequestParam String uploadId,
|
||||
@RequestParam int index,
|
||||
@RequestParam("file") MultipartFile file) {
|
||||
mediaService.saveChunk(uploadId, index, file);
|
||||
return Result.ok(index);
|
||||
}
|
||||
|
||||
@PostMapping("/upload/complete")
|
||||
@PreAuthorize("@ss.hasAnyPermission('cover:upload','episode:upload')")
|
||||
public Result<MediaAssetRespVO> complete(@Valid @RequestBody UploadCompleteReqVO req) {
|
||||
return Result.ok(mediaService.complete(req));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasAnyPermission('cover:upload','episode:upload')")
|
||||
public Result<MediaAssetRespVO> get(@PathVariable Long id) {
|
||||
return Result.ok(mediaService.get(id));
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.system.service.MenuService;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.system.vo.MenuSaveReqVO;
|
||||
import com.fruitshorts.system.vo.MenuVO;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/menus")
|
||||
@RequiredArgsConstructor
|
||||
public class MenuController {
|
||||
|
||||
private final MenuService menuService;
|
||||
|
||||
@GetMapping("/tree")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu')")
|
||||
public Result<List<MenuVO>> tree() {
|
||||
return Result.ok(menuService.listAll());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:menu')")
|
||||
@OperationLog(module = "后台管理", action = "新增菜单")
|
||||
public Result<Long> create(@Valid @RequestBody MenuSaveReqVO req) {
|
||||
return Result.ok(menuService.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu')")
|
||||
@OperationLog(module = "后台管理", action = "编辑菜单")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody MenuSaveReqVO req) {
|
||||
menuService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu')")
|
||||
@OperationLog(module = "后台管理", action = "删除菜单")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
menuService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.system.service.OperationLogService;
|
||||
import com.fruitshorts.system.vo.OperationLogPageReqVO;
|
||||
import com.fruitshorts.system.vo.OperationLogRespVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/operation-logs")
|
||||
@RequiredArgsConstructor
|
||||
public class OperationLogController {
|
||||
|
||||
private final OperationLogService operationLogService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('log:list')")
|
||||
public Result<PageResult<OperationLogRespVO>> page(OperationLogPageReqVO req) {
|
||||
return Result.ok(operationLogService.page(req));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('log:list')")
|
||||
public Result<OperationLogRespVO> get(@PathVariable Long id) {
|
||||
return Result.ok(operationLogService.get(id));
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.system.service.PermissionService;
|
||||
import com.fruitshorts.system.vo.PermissionGroupVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/permissions")
|
||||
@RequiredArgsConstructor
|
||||
public class PermissionController {
|
||||
|
||||
private final PermissionService permissionService;
|
||||
|
||||
/** 按分组返回权限点,直接喂给前端的角色权限配置页。 */
|
||||
@GetMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
public Result<List<PermissionGroupVO>> groups() {
|
||||
return Result.ok(permissionService.listGroups());
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.system.service.RoleCategoryService;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.system.vo.RoleCategoryRespVO;
|
||||
import com.fruitshorts.system.vo.RoleCategorySaveReqVO;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/role-categories")
|
||||
@RequiredArgsConstructor
|
||||
public class RoleCategoryController {
|
||||
|
||||
private final RoleCategoryService roleCategoryService;
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:role-category')")
|
||||
public Result<List<RoleCategoryRespVO>> list() {
|
||||
return Result.ok(roleCategoryService.list());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:role-category')")
|
||||
@OperationLog(module = "后台管理", action = "新增角色分类")
|
||||
public Result<Long> create(@Valid @RequestBody RoleCategorySaveReqVO req) {
|
||||
return Result.ok(roleCategoryService.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:role-category')")
|
||||
@OperationLog(module = "后台管理", action = "编辑角色分类")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody RoleCategorySaveReqVO req) {
|
||||
roleCategoryService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:role-category')")
|
||||
@OperationLog(module = "后台管理", action = "删除角色分类")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
roleCategoryService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package com.fruitshorts.admin.controller;
|
||||
|
||||
import com.fruitshorts.common.pojo.PageResult;
|
||||
import com.fruitshorts.common.pojo.Result;
|
||||
import com.fruitshorts.system.service.RoleService;
|
||||
import com.fruitshorts.framework.log.OperationLog;
|
||||
import com.fruitshorts.system.vo.RolePermissionSaveReqVO;
|
||||
import com.fruitshorts.system.vo.RoleRespVO;
|
||||
import com.fruitshorts.system.vo.RoleSaveReqVO;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/roles")
|
||||
@RequiredArgsConstructor
|
||||
public class RoleController {
|
||||
|
||||
private final RoleService roleService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
public Result<PageResult<RoleRespVO>> page(@RequestParam(required = false) String keyword,
|
||||
@RequestParam(defaultValue = "1") Integer pageIndex,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize) {
|
||||
return Result.ok(roleService.page(keyword, pageIndex, pageSize));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public Result<List<RoleRespVO>> list() {
|
||||
return Result.ok(roleService.listAll());
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
public Result<RoleRespVO> get(@PathVariable Long id) {
|
||||
return Result.ok(roleService.get(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
@OperationLog(module = "后台管理", action = "新增角色")
|
||||
public Result<Long> create(@Valid @RequestBody RoleSaveReqVO req) {
|
||||
return Result.ok(roleService.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
@OperationLog(module = "后台管理", action = "编辑角色")
|
||||
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody RoleSaveReqVO req) {
|
||||
roleService.update(id, req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
@OperationLog(module = "后台管理", action = "删除角色")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
roleService.delete(id);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/permissions")
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
public Result<List<String>> permissions(@PathVariable Long id) {
|
||||
return Result.ok(roleService.listCodesByRoleId(id));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}/permissions")
|
||||
@PreAuthorize("@ss.hasPermission('system:role')")
|
||||
@OperationLog(module = "后台管理", action = "修改角色权限")
|
||||
public Result<Void> updatePermissions(@PathVariable Long id,
|
||||
@Valid @RequestBody RolePermissionSaveReqVO req) {
|
||||
roleService.updatePermissions(id, req.getPermissions());
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.fruitshorts.admin.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 后台观看流水行。
|
||||
*
|
||||
* <p>比原始流水多了剧名与集号:客服核对问题时看「闪婚后 · 第 3 集」比看
|
||||
* 「dramaId=5 / episodeId=9」有用得多。剧已下架时仍然显示剧名,只标注状态。
|
||||
*/
|
||||
@Data
|
||||
public class AppUserWatchHistoryVO {
|
||||
|
||||
private Long id;
|
||||
private Long dramaId;
|
||||
private String dramaTitle;
|
||||
/** 短剧当前是否已上线,用于识别"用户说看了但剧已下线"的情况 */
|
||||
private Boolean dramaPublished;
|
||||
private Long episodeId;
|
||||
private Integer episodeNo;
|
||||
private Long positionMs;
|
||||
private Long durationMs;
|
||||
/** 是否已看完(进度到达片尾 1 秒内) */
|
||||
private Boolean finished;
|
||||
private String source;
|
||||
private String deviceId;
|
||||
private LocalDateTime watchedAt;
|
||||
}
|
||||
Reference in new issue
Block a user