() {{
+ add(new FileVO() {{
+ setUrl(key);
+ }});
+ }};
+ }
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/controller/WorkController.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/controller/WorkController.java
new file mode 100644
index 000000000..61af74d28
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/controller/WorkController.java
@@ -0,0 +1,175 @@
+package org.dromara.system.saas.controller;
+
+
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.luban.api.convert.WorkConvert;
+import com.luban.api.dto.WorkCreateDTO;
+import com.luban.api.dto.WorkQueryDTO;
+import com.luban.api.dto.WorkUpdateDTO;
+import com.luban.api.entity.Work;
+import com.luban.api.service.WorkService;
+import com.luban.api.vo.WorkVO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * 前端控制器
+ *
+ *
+ * 由于业务都非常简单,并没有把业务代码下沉到 service 层
+ *
+ * @author WeiHongBin
+ */
+@RestController
+@RequestMapping("/works")
+@Tag(name = "作品管理", description = "作品管理")
+@Slf4j
+public class WorkController {
+
+
+ private final WorkService workService;
+
+ public WorkController(WorkService workService) {
+ this.workService = workService;
+ }
+
+
+ @Operation(summary = "根据workId查询")
+ @GetMapping("/has-forms")
+ public List hasForms() {
+ return WorkConvert.toVO(workService.list());
+ }
+
+ @Operation(summary = "根据workId查询")
+ @GetMapping("/{id}")
+ public WorkVO findWorkById(@PathVariable Long id) {
+ return WorkConvert.toVO(workService.getById(id));
+ }
+
+ @Operation(summary = "查询所有work")
+ @GetMapping
+ public List listAllWorks(@Valid WorkQueryDTO dto) {
+ WorkVO vo = new WorkVO();
+ vo.setTemplate(Boolean.parseBoolean(dto.getIs_template()));
+ BeanUtils.copyProperties(dto, vo);
+ return workService.list(new QueryWrapper<>(WorkConvert.toEntity(vo))).stream().map(WorkConvert::toVO).collect(Collectors.toList());
+ }
+
+
+ @Operation(summary = "分页查询works")
+ @GetMapping("/pageable")
+ public IPage listWorks(@Valid WorkQueryDTO dto) {
+ WorkVO vo = new WorkVO();
+ vo.setTemplate(Boolean.parseBoolean(dto.getIs_template()));
+ BeanUtils.copyProperties(dto, vo);
+ IPage page = workService.page(new Page<>(dto.getCurrent(), dto.getSize()), new LambdaQueryWrapper<>(WorkConvert.toEntity(vo)).orderByDesc(Work::getCreateTime));
+ List voList = page.getRecords().stream().map(WorkConvert::toVO).collect(Collectors.toList());
+ return new Page(page.getCurrent(), page.getSize(), page.getTotal()).setPages(page.getPages()).setRecords(voList);
+ }
+
+ @Operation(summary = "创建work")
+ @PostMapping
+ public WorkVO createWork(@RequestBody @Valid WorkCreateDTO dto) {
+ WorkVO vo = new WorkVO();
+ BeanUtils.copyProperties(dto, vo);
+ Work work = WorkConvert.toEntity(vo);
+ workService.save(work);
+ return WorkConvert.toVO(work);
+ }
+
+ @Operation(summary = "更新work")
+ @PutMapping("/{id}")
+ public WorkVO updateWork(@PathVariable Long id, @RequestBody @Valid WorkUpdateDTO dto) {
+ Work work = workService.getById(id);
+ if (!StringUtils.isEmpty(dto.getTitle())) {
+ work.setTitle(dto.getTitle());
+ }
+ if (!StringUtils.isEmpty(dto.getDescription())) {
+ work.setDescription(dto.getDescription());
+ }
+ if (!StringUtils.isEmpty(dto.getCoverImageUrl())) {
+ work.setCoverImageUrl(dto.getCoverImageUrl());
+ }
+ if (!CollectionUtils.isEmpty(dto.getPages())) {
+ work.setPages(JSONUtil.toJsonStr(dto.getPages()));
+ }
+ work.setIsTemplate(dto.isTemplate());
+ work.setIsPublish(dto.isPublish());
+ work.setWidth(dto.getWidth());
+ work.setHeight(dto.getWidth());
+ work.setPageMode(dto.getWidth());
+
+ work.setUpdateTime(LocalDateTime.now());
+ workService.saveOrUpdate(work);
+ return WorkConvert.toVO(work);
+ }
+
+
+ @Operation(summary = "删除work")
+ @DeleteMapping("/{id}")
+ public void deleteWorkById(@PathVariable Long id) {
+ workService.removeById(id);
+ }
+
+ @Operation(summary = "设为模板")
+ @PostMapping("/set-as-template/{id}")
+ public WorkVO markWorkAsTemplate(@PathVariable Long id) {
+ Work work = workService.getById(id);
+ work.setIsTemplate(true);
+ work.setUpdateTime(LocalDateTime.now());
+ workService.updateById(work);
+ return WorkConvert.toVO(work);
+ }
+
+ @Operation(summary = "统计作品总数")
+ @GetMapping("/count")
+ public long countWork() {
+ return workService.count();
+ }
+
+ @Operation(summary = "使用模板")
+ @PostMapping("/use-template/{id}")
+ public WorkVO useTemplate(@PathVariable Long id) {
+ Work work = workService.getById(id);
+ work.setId(null);
+ work.setIsTemplate(false);
+ work.setIsPublish(false);
+ workService.save(work);
+ return WorkConvert.toVO(work);
+ }
+
+ @Operation(summary = "使用模板")
+ @GetMapping("/preview/{id}")
+ public ModelAndView useTemplate(@PathVariable Long id, @RequestParam(value = "view_mode", required = false) String viewMode) {
+ Work work = workService.getById(id);
+
+ // 非预览模式, 查看不到内容
+ boolean canRender = "preview".equals(viewMode) || work.getIsPublish();
+
+ if (!canRender) {
+ work.setPages("[]");
+ }
+ ModelAndView mv = new ModelAndView("engine");
+ //TODO 后端处理前端,这种方式不是很好,最后改成纯前端处理
+ mv.addObject("workString", JSONUtil.toJsonStr(WorkConvert.toVO(work)));
+ mv.addObject("work", work);
+ return mv;
+ }
+}
+
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/controller/WorkFormsController.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/controller/WorkFormsController.java
new file mode 100644
index 000000000..f6ae9b0d8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/controller/WorkFormsController.java
@@ -0,0 +1,20 @@
+package org.dromara.system.saas.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * 前端控制器
+ *
+ *
+ * @author WeiHongBin
+ * @since 2019-11-26
+ */
+@RestController
+@RequestMapping("/work-forms")
+public class WorkFormsController {
+
+}
+
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/convert/ScriptsConvert.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/convert/ScriptsConvert.java
new file mode 100644
index 000000000..baf04df8e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/convert/ScriptsConvert.java
@@ -0,0 +1,21 @@
+package org.dromara.system.saas.convert;
+
+import com.luban.api.entity.Scripts;
+import com.luban.api.vo.ScriptsVO;
+import org.springframework.beans.BeanUtils;
+
+/**
+ * Scripts 转换器
+ *
+ * @author WeiHongBin
+ */
+public class ScriptsConvert {
+
+
+ public static ScriptsVO toVO(Scripts entity) {
+ ScriptsVO vo = new ScriptsVO();
+ BeanUtils.copyProperties(entity, vo);
+ return vo;
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/convert/WorkConvert.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/convert/WorkConvert.java
new file mode 100644
index 000000000..ff69bb98d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/convert/WorkConvert.java
@@ -0,0 +1,49 @@
+package org.dromara.system.saas.convert;
+
+import cn.hutool.json.JSONUtil;
+import com.luban.api.entity.Work;
+import com.luban.api.vo.WorkVO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Work 转换器
+ *
+ * @author WeiHongBin
+ */
+public class WorkConvert {
+
+
+ public static WorkVO toVO(Work entity) {
+ WorkVO vo = new WorkVO();
+ BeanUtils.copyProperties(entity, vo);
+ if (!StringUtils.isEmpty(entity.getPages())) {
+ vo.setPages(JSONUtil.parseArray(entity.getPages()));
+ }
+ return vo;
+ }
+
+
+ public static List toVO(List entitys) {
+ List workVOS = new ArrayList<>();
+ for (Work entity : entitys) {
+ workVOS.add(toVO(entity));
+ }
+ return workVOS;
+ }
+
+ public static Work toEntity(WorkVO vo) {
+ Work work = new Work();
+ BeanUtils.copyProperties(vo, work);
+ if (!CollectionUtils.isEmpty(vo.getPages())) {
+ work.setPages(JSONUtil.toJsonStr(vo.getPages()));
+ }
+ return work;
+ }
+
+
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/ScriptsDao.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/ScriptsDao.java
new file mode 100644
index 000000000..4a2d33892
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/ScriptsDao.java
@@ -0,0 +1,16 @@
+package org.dromara.system.saas.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.luban.api.entity.Scripts;
+
+/**
+ *
+ * 作品 Mapper 接口
+ *
+ *
+ * @author lizhengwei
+ * @since 2024-06-21
+ */
+public interface ScriptsDao extends BaseMapper {
+
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/WorkDao.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/WorkDao.java
new file mode 100644
index 000000000..77c29325b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/WorkDao.java
@@ -0,0 +1,16 @@
+package org.dromara.system.saas.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.luban.api.entity.Work;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author WeiHongBin
+ * @since 2019-11-26
+ */
+public interface WorkDao extends BaseMapper {
+
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/WorkFormsDao.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/WorkFormsDao.java
new file mode 100644
index 000000000..2bb466687
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dao/WorkFormsDao.java
@@ -0,0 +1,16 @@
+package org.dromara.system.saas.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.luban.api.entity.WorkForms;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author WeiHongBin
+ * @since 2019-11-26
+ */
+public interface WorkFormsDao extends BaseMapper {
+
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/PageDtoBase.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/PageDtoBase.java
new file mode 100644
index 000000000..0673309b1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/PageDtoBase.java
@@ -0,0 +1,37 @@
+package org.dromara.system.saas.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 分页基类
+ *
+ * @author admin
+ */
+@Data
+public class PageDtoBase {
+ /**
+ * 每页行数
+ */
+ @Schema(title = "每页行数")
+ protected Integer size = 10;
+
+ /**
+ * 页码
+ */
+ @Schema(title = "页码")
+ protected Integer current = 1;
+
+
+ public void setSize(Integer size) {
+ if (size != null) {
+ this.size = size;
+ }
+ }
+
+ public void setCurrent(Integer current) {
+ if (current != null) {
+ this.current = current;
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/ScriptsQueryDTO.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/ScriptsQueryDTO.java
new file mode 100644
index 000000000..00f1cc387
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/ScriptsQueryDTO.java
@@ -0,0 +1,15 @@
+package org.dromara.system.saas.dto;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@EqualsAndHashCode
+@Accessors(chain = true)
+@Schema(title = "WorkQueryDTO")
+public class ScriptsQueryDTO {
+ private Integer _limit;
+}
diff --git a/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/WorkCreateDTO.java b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/WorkCreateDTO.java
new file mode 100644
index 000000000..54097861e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-h5-saas/src/main/java/org/dromara/system/saas/dto/WorkCreateDTO.java
@@ -0,0 +1,35 @@
+package org.dromara.system.saas.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author WeiHongBin
+ */
+@Data
+@EqualsAndHashCode
+@Accessors(chain = true)
+@Schema(title = "WorkCreateDTO")
+public class WorkCreateDTO {
+
+ private String title;
+
+ private String description;
+
+ private String coverImageUrl;
+
+ private List