diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/AppCustomRequestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/AppCustomRequestController.java new file mode 100644 index 0000000..cd998eb --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app/AppCustomRequestController.java @@ -0,0 +1,83 @@ +package com.ruoyi.web.controller.app; + +import java.util.List; +import com.ruoyi.app.domain.AppCustomRequest; +import com.ruoyi.app.service.IAppCustomRequestService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 项目定制需求Controller。 + */ +@RestController +@RequestMapping("/app/customRequest") +public class AppCustomRequestController extends BaseController +{ + @Autowired + private IAppCustomRequestService customRequestService; + + @PreAuthorize("isAuthenticated()") + @Log(title = "项目定制需求", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult submit(@RequestBody AppCustomRequest request) + { + return success(customRequestService.submitCustomRequest(request, getUserId())); + } + + @PreAuthorize("isAuthenticated()") + @GetMapping("/my") + public TableDataInfo myList() + { + startPage(); + return getDataTable(customRequestService.selectMyCustomRequestList(getUserId())); + } + + @PreAuthorize("isAuthenticated()") + @GetMapping("/my/{id}") + public AjaxResult myDetail(@PathVariable Long id) + { + AppCustomRequest request = customRequestService.selectAppCustomRequestById(id); + if (request == null || !getUserId().equals(request.getUserId())) + { + return error("定制需求不存在"); + } + return success(request); + } + + @PreAuthorize("@ss.hasPermi('app:customRequest:list')") + @GetMapping("/list") + public TableDataInfo list(AppCustomRequest request) + { + startPage(); + List list = customRequestService.selectAppCustomRequestList(request); + return getDataTable(list); + } + + @PreAuthorize("@ss.hasPermi('app:customRequest:query')") + @GetMapping("/{id}") + public AjaxResult detail(@PathVariable Long id) + { + return success(customRequestService.selectAppCustomRequestById(id)); + } + + @PreAuthorize("@ss.hasPermi('app:customRequest:edit')") + @Log(title = "项目定制需求", businessType = BusinessType.UPDATE) + @PutMapping("/status") + public AjaxResult updateStatus(@RequestBody AppCustomRequest request) + { + request.setUpdateBy(getUsername()); + return toAjax(customRequestService.updateCustomRequestStatus(request)); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/app/domain/AppCustomRequest.java b/ruoyi-system/src/main/java/com/ruoyi/app/domain/AppCustomRequest.java new file mode 100644 index 0000000..7a163f0 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/app/domain/AppCustomRequest.java @@ -0,0 +1,60 @@ +package com.ruoyi.app.domain; + +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 项目定制需求对象 app_custom_request。 + */ +public class AppCustomRequest extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + private Long id; + private String requestNo; + private Long userId; + private String projectName; + private String requirementContent; + private Long techStackId; + /** 保存提交时的技术栈名称,避免后台改名影响历史需求。 */ + private String techStackName; + /** 0待审核 1审核中 2已接单 3开发中 4已完成 5审核未通过 */ + private Integer status; + private String progressNote; + private Integer pointAmount; + /** 0已扣除 1已退回 */ + private Integer pointStatus; + private String rejectReason; + + /** 仅用于后台列表展示与查询。 */ + private String userName; + private String nickName; + + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + public String getRequestNo() { return requestNo; } + public void setRequestNo(String requestNo) { this.requestNo = requestNo; } + public Long getUserId() { return userId; } + public void setUserId(Long userId) { this.userId = userId; } + public String getProjectName() { return projectName; } + public void setProjectName(String projectName) { this.projectName = projectName; } + public String getRequirementContent() { return requirementContent; } + public void setRequirementContent(String requirementContent) { this.requirementContent = requirementContent; } + public Long getTechStackId() { return techStackId; } + public void setTechStackId(Long techStackId) { this.techStackId = techStackId; } + public String getTechStackName() { return techStackName; } + public void setTechStackName(String techStackName) { this.techStackName = techStackName; } + public Integer getStatus() { return status; } + public void setStatus(Integer status) { this.status = status; } + public String getProgressNote() { return progressNote; } + public void setProgressNote(String progressNote) { this.progressNote = progressNote; } + public Integer getPointAmount() { return pointAmount; } + public void setPointAmount(Integer pointAmount) { this.pointAmount = pointAmount; } + public Integer getPointStatus() { return pointStatus; } + public void setPointStatus(Integer pointStatus) { this.pointStatus = pointStatus; } + public String getRejectReason() { return rejectReason; } + public void setRejectReason(String rejectReason) { this.rejectReason = rejectReason; } + public String getUserName() { return userName; } + public void setUserName(String userName) { this.userName = userName; } + public String getNickName() { return nickName; } + public void setNickName(String nickName) { this.nickName = nickName; } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/app/mapper/AppCustomRequestMapper.java b/ruoyi-system/src/main/java/com/ruoyi/app/mapper/AppCustomRequestMapper.java new file mode 100644 index 0000000..89a9897 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/app/mapper/AppCustomRequestMapper.java @@ -0,0 +1,23 @@ +package com.ruoyi.app.mapper; + +import java.util.List; +import com.ruoyi.app.domain.AppCustomRequest; +import org.apache.ibatis.annotations.Param; + +/** + * 项目定制需求Mapper接口。 + */ +public interface AppCustomRequestMapper +{ + AppCustomRequest selectAppCustomRequestById(Long id); + + AppCustomRequest selectAppCustomRequestByIdForUpdate(Long id); + + List selectAppCustomRequestList(AppCustomRequest request); + + List selectMyCustomRequestList(@Param("userId") Long userId); + + int insertAppCustomRequest(AppCustomRequest request); + + int updateAppCustomRequest(AppCustomRequest request); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/app/service/IAppCustomRequestService.java b/ruoyi-system/src/main/java/com/ruoyi/app/service/IAppCustomRequestService.java new file mode 100644 index 0000000..26cad88 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/app/service/IAppCustomRequestService.java @@ -0,0 +1,20 @@ +package com.ruoyi.app.service; + +import java.util.List; +import com.ruoyi.app.domain.AppCustomRequest; + +/** + * 项目定制需求Service接口。 + */ +public interface IAppCustomRequestService +{ + AppCustomRequest selectAppCustomRequestById(Long id); + + List selectAppCustomRequestList(AppCustomRequest request); + + List selectMyCustomRequestList(Long userId); + + AppCustomRequest submitCustomRequest(AppCustomRequest request, Long userId); + + int updateCustomRequestStatus(AppCustomRequest request); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/app/service/impl/AppCustomRequestServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/app/service/impl/AppCustomRequestServiceImpl.java new file mode 100644 index 0000000..cf347a6 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/app/service/impl/AppCustomRequestServiceImpl.java @@ -0,0 +1,171 @@ +package com.ruoyi.app.service.impl; + +import java.util.Date; +import java.util.List; +import com.ruoyi.app.domain.AppCustomRequest; +import com.ruoyi.app.domain.AppIntegralRecord; +import com.ruoyi.app.domain.AppTechStack; +import com.ruoyi.app.mapper.AppCustomRequestMapper; +import com.ruoyi.app.mapper.AppIntegralRecordMapper; +import com.ruoyi.app.mapper.AppTechStackMapper; +import com.ruoyi.app.service.IAppCustomRequestService; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.uuid.IdUtils; +import com.ruoyi.system.mapper.SysUserMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 项目定制需求Service业务层处理。 + */ +@Service +public class AppCustomRequestServiceImpl implements IAppCustomRequestService +{ + private static final int SUBMIT_POINTS = 99; + private static final int STATUS_REJECTED = 5; + private static final int POINT_DEDUCTED = 0; + private static final int POINT_REFUNDED = 1; + + @Autowired + private AppCustomRequestMapper customRequestMapper; + @Autowired + private AppIntegralRecordMapper integralRecordMapper; + @Autowired + private AppTechStackMapper techStackMapper; + @Autowired + private SysUserMapper sysUserMapper; + + @Override + public AppCustomRequest selectAppCustomRequestById(Long id) + { + return customRequestMapper.selectAppCustomRequestById(id); + } + + @Override + public List selectAppCustomRequestList(AppCustomRequest request) + { + return customRequestMapper.selectAppCustomRequestList(request); + } + + @Override + public List selectMyCustomRequestList(Long userId) + { + return customRequestMapper.selectMyCustomRequestList(userId); + } + + @Override + @Transactional + public AppCustomRequest submitCustomRequest(AppCustomRequest request, Long userId) + { + String projectName = StringUtils.trim(request.getProjectName()); + String requirementContent = StringUtils.trim(request.getRequirementContent()); + if (StringUtils.isEmpty(projectName) || projectName.length() < 2 || projectName.length() > 30) + { + throw new ServiceException("项目名称需填写2至30个字"); + } + if (StringUtils.isEmpty(requirementContent) || requirementContent.length() < 20 || requirementContent.length() > 500) + { + throw new ServiceException("项目需求需填写20至500个字"); + } + if (request.getTechStackId() == null) + { + throw new ServiceException("请选择技术栈"); + } + AppTechStack techStack = techStackMapper.selectAppTechStackById(request.getTechStackId()); + if (techStack == null || !"0".equals(techStack.getStatus())) + { + throw new ServiceException("所选技术栈已停用,请重新选择"); + } + if (sysUserMapper.delIntegralByUserId(SUBMIT_POINTS, userId) != 1) + { + throw new ServiceException("积分不足,提交需求需要99积分"); + } + + Date now = DateUtils.getNowDate(); + request.setRequestNo("DZ" + DateUtils.dateTimeNow() + IdUtils.fastSimpleUUID().substring(0, 6).toUpperCase()); + request.setUserId(userId); + request.setProjectName(projectName); + request.setRequirementContent(requirementContent); + request.setTechStackName(techStack.getName()); + request.setStatus(0); + request.setProgressNote("需求已提交,等待平台审核"); + request.setPointAmount(SUBMIT_POINTS); + request.setPointStatus(POINT_DEDUCTED); + request.setRejectReason(null); + request.setCreateBy(String.valueOf(userId)); + request.setCreateTime(now); + request.setUpdateBy(String.valueOf(userId)); + request.setUpdateTime(now); + if (customRequestMapper.insertAppCustomRequest(request) != 1) + { + throw new ServiceException("需求提交失败,请重试"); + } + + insertIntegralRecord(request, 1L, "定制需求提交"); + return request; + } + + @Override + @Transactional + public int updateCustomRequestStatus(AppCustomRequest update) + { + if (update.getId() == null || update.getStatus() == null || update.getStatus() < 0 || update.getStatus() > 5) + { + throw new ServiceException("需求状态不正确"); + } + + AppCustomRequest current = customRequestMapper.selectAppCustomRequestByIdForUpdate(update.getId()); + if (current == null) + { + throw new ServiceException("定制需求不存在"); + } + if (POINT_REFUNDED == current.getPointStatus() && update.getStatus() != STATUS_REJECTED) + { + throw new ServiceException("该需求已退回积分,不能恢复为其他状态"); + } + if (update.getStatus() == STATUS_REJECTED && StringUtils.isEmpty(StringUtils.trim(update.getRejectReason()))) + { + throw new ServiceException("审核不通过时必须填写原因"); + } + + current.setStatus(update.getStatus()); + current.setProgressNote(StringUtils.trim(update.getProgressNote())); + current.setUpdateBy(update.getUpdateBy()); + current.setUpdateTime(DateUtils.getNowDate()); + if (update.getStatus() == STATUS_REJECTED) + { + current.setRejectReason(StringUtils.trim(update.getRejectReason())); + if (POINT_DEDUCTED == current.getPointStatus()) + { + if (sysUserMapper.addIntegralByUserId(current.getPointAmount(), current.getUserId()) != 1) + { + throw new ServiceException("积分退回失败,请重试"); + } + insertIntegralRecord(current, 0L, "定制需求退回"); + current.setPointStatus(POINT_REFUNDED); + } + } + else + { + current.setRejectReason(""); + } + return customRequestMapper.updateAppCustomRequest(current); + } + + private void insertIntegralRecord(AppCustomRequest request, Long isAdd, String source) + { + AppIntegralRecord record = new AppIntegralRecord(); + record.setSource(source); + record.setIsAdd(isAdd); + record.setIntegralNumber(request.getPointAmount().longValue()); + record.setUserId(request.getUserId()); + record.setIntegralTime(new Date()); + if (integralRecordMapper.insertAppIntegralRecord(record) != 1) + { + throw new ServiceException("积分流水记录失败,请重试"); + } + } +} diff --git a/ruoyi-system/src/main/resources/mapper/app/AppCustomRequestMapper.xml b/ruoyi-system/src/main/resources/mapper/app/AppCustomRequestMapper.xml new file mode 100644 index 0000000..5c6d05b --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/app/AppCustomRequestMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select r.id, r.request_no, r.user_id, r.project_name, r.requirement_content, + r.tech_stack_id, r.tech_stack_name, + r.status, r.progress_note, r.point_amount, r.point_status, r.reject_reason, + r.create_by, r.create_time, r.update_by, r.update_time, + u.user_name, u.nick_name + from app_custom_request r + left join sys_user u on u.user_id = r.user_id + + + + + + + + + + + + insert into app_custom_request + (request_no, user_id, project_name, requirement_content, tech_stack_id, tech_stack_name, status, progress_note, + point_amount, point_status, reject_reason, create_by, create_time, update_by, update_time) + values + (#{requestNo}, #{userId}, #{projectName}, #{requirementContent}, #{techStackId}, #{techStackName}, #{status}, #{progressNote}, + #{pointAmount}, #{pointStatus}, #{rejectReason}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}) + + + + update app_custom_request + + status = #{status}, + progress_note = #{progressNote}, + point_status = #{pointStatus}, + reject_reason = #{rejectReason}, + update_by = #{updateBy}, + update_time = #{updateTime} + + where id = #{id} + + diff --git a/ruoyi-ui/src/api/app/customRequest.js b/ruoyi-ui/src/api/app/customRequest.js new file mode 100644 index 0000000..f567cfb --- /dev/null +++ b/ruoyi-ui/src/api/app/customRequest.js @@ -0,0 +1,24 @@ +import request from '@/utils/request' + +export function listCustomRequest(query) { + return request({ + url: '/app/customRequest/list', + method: 'get', + params: query + }) +} + +export function getCustomRequest(id) { + return request({ + url: '/app/customRequest/' + id, + method: 'get' + }) +} + +export function updateCustomRequestStatus(data) { + return request({ + url: '/app/customRequest/status', + method: 'put', + data: data + }) +} diff --git a/ruoyi-ui/src/views/app/customRequest/index.vue b/ruoyi-ui/src/views/app/customRequest/index.vue new file mode 100644 index 0000000..8621557 --- /dev/null +++ b/ruoyi-ui/src/views/app/customRequest/index.vue @@ -0,0 +1,262 @@ + + + + + diff --git a/sql/custom_request.sql b/sql/custom_request.sql new file mode 100644 index 0000000..26cdc97 --- /dev/null +++ b/sql/custom_request.sql @@ -0,0 +1,175 @@ +-- 项目定制需求(99积分提交,审核不通过自动退回) +-- 可重复执行菜单部分;建表仅在表不存在时执行。 + +CREATE TABLE IF NOT EXISTS `app_tech_stack` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(50) NOT NULL COMMENT '技术栈名称', + `sort` int NOT NULL DEFAULT 0 COMMENT '显示排序', + `status` char(1) NOT NULL DEFAULT '0' COMMENT '0启用 1停用', + `remark` varchar(500) DEFAULT NULL COMMENT '备注', + `create_by` varchar(64) DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_app_tech_stack_name` (`name`), + KEY `idx_app_tech_stack_status_sort` (`status`, `sort`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目定制技术栈表'; + +INSERT INTO `app_tech_stack` (`name`, `sort`, `status`, `remark`, `create_by`, `create_time`) +SELECT 'UniApp + Spring Boot', 1, '0', '适合跨端小程序项目', 'admin', NOW() +WHERE NOT EXISTS (SELECT 1 FROM `app_tech_stack` WHERE `name` = 'UniApp + Spring Boot'); + +INSERT INTO `app_tech_stack` (`name`, `sort`, `status`, `remark`, `create_by`, `create_time`) +SELECT 'Vue + Spring Boot', 2, '0', '适合管理系统和Web项目', 'admin', NOW() +WHERE NOT EXISTS (SELECT 1 FROM `app_tech_stack` WHERE `name` = 'Vue + Spring Boot'); + +INSERT INTO `app_tech_stack` (`name`, `sort`, `status`, `remark`, `create_by`, `create_time`) +SELECT '微信小程序原生 + Spring Boot', 3, '0', '适合微信原生小程序项目', 'admin', NOW() +WHERE NOT EXISTS (SELECT 1 FROM `app_tech_stack` WHERE `name` = '微信小程序原生 + Spring Boot'); + +INSERT INTO `app_tech_stack` (`name`, `sort`, `status`, `remark`, `create_by`, `create_time`) +SELECT '其他(请在需求中说明)', 99, '0', '未确定或需要其他技术栈', 'admin', NOW() +WHERE NOT EXISTS (SELECT 1 FROM `app_tech_stack` WHERE `name` = '其他(请在需求中说明)'); + +CREATE TABLE IF NOT EXISTS `app_custom_request` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `request_no` varchar(32) NOT NULL COMMENT '需求单号', + `user_id` bigint NOT NULL COMMENT '用户ID', + `project_name` varchar(30) NOT NULL COMMENT '项目名称', + `requirement_content` varchar(500) NOT NULL COMMENT '项目需求', + `tech_stack_id` bigint DEFAULT NULL COMMENT '技术栈ID', + `tech_stack_name` varchar(50) DEFAULT NULL COMMENT '提交时技术栈名称', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '0待审核 1审核中 2已接单 3开发中 4已完成 5审核未通过', + `progress_note` varchar(300) DEFAULT NULL COMMENT '当前进度说明', + `point_amount` int NOT NULL DEFAULT 99 COMMENT '提交扣除积分', + `point_status` tinyint NOT NULL DEFAULT 0 COMMENT '0已扣除 1已退回', + `reject_reason` varchar(300) DEFAULT NULL COMMENT '审核未通过原因', + `create_by` varchar(64) DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_by` varchar(64) DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_custom_request_no` (`request_no`), + KEY `idx_custom_request_user_time` (`user_id`, `update_time`), + KEY `idx_custom_request_status_time` (`status`, `update_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目定制需求表'; + +-- 兼容已经创建过 app_custom_request 的数据库。 +SET @tech_stack_id_exists := ( + SELECT COUNT(*) FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_custom_request' AND COLUMN_NAME = 'tech_stack_id' +); +SET @tech_stack_id_sql := IF( + @tech_stack_id_exists = 0, + 'ALTER TABLE `app_custom_request` ADD COLUMN `tech_stack_id` bigint DEFAULT NULL COMMENT ''技术栈ID'' AFTER `requirement_content`', + 'SELECT 1' +); +PREPARE tech_stack_id_stmt FROM @tech_stack_id_sql; +EXECUTE tech_stack_id_stmt; +DEALLOCATE PREPARE tech_stack_id_stmt; + +SET @tech_stack_name_exists := ( + SELECT COUNT(*) FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_custom_request' AND COLUMN_NAME = 'tech_stack_name' +); +SET @tech_stack_name_sql := IF( + @tech_stack_name_exists = 0, + 'ALTER TABLE `app_custom_request` ADD COLUMN `tech_stack_name` varchar(50) DEFAULT NULL COMMENT ''提交时技术栈名称'' AFTER `tech_stack_id`', + 'SELECT 1' +); +PREPARE tech_stack_name_stmt FROM @tech_stack_name_sql; +EXECUTE tech_stack_name_stmt; +DEALLOCATE PREPARE tech_stack_name_stmt; + +SET @custom_request_parent_id := COALESCE( + (SELECT parent_id FROM sys_menu WHERE perms = 'app:resource:list' LIMIT 1), + (SELECT parent_id FROM sys_menu WHERE perms = 'app:article:list' LIMIT 1), + 0 +); + +SET @custom_request_order_num := COALESCE( + (SELECT MAX(order_num) + 1 FROM sys_menu WHERE parent_id = @custom_request_parent_id), + 1 +); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT + '项目定制', @custom_request_parent_id, @custom_request_order_num, + 'customRequest', 'app/customRequest/index', '', 1, 0, + 'C', '0', '0', 'app:customRequest:list', 'form', 'admin', NOW(), '', NULL, + '项目定制需求管理' +WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:customRequest:list'); + +SET @custom_request_menu_id := ( + SELECT menu_id FROM sys_menu WHERE perms = 'app:customRequest:list' LIMIT 1 +); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT '定制需求查询', @custom_request_menu_id, 1, '', '', '', 1, 0, + 'F', '0', '0', 'app:customRequest:query', '#', 'admin', NOW(), '', NULL, '' +WHERE @custom_request_menu_id IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:customRequest:query'); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT '定制状态修改', @custom_request_menu_id, 2, '', '', '', 1, 0, + 'F', '0', '0', 'app:customRequest:edit', '#', 'admin', NOW(), '', NULL, '' +WHERE @custom_request_menu_id IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:customRequest:edit'); + +SET @tech_stack_order_num := COALESCE( + (SELECT MAX(order_num) + 1 FROM sys_menu WHERE parent_id = @custom_request_parent_id), + 1 +); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT + '技术栈管理', @custom_request_parent_id, @tech_stack_order_num, + 'techStack', 'app/techStack/index', '', 1, 0, + 'C', '0', '0', 'app:techStack:list', 'tree-table', 'admin', NOW(), '', NULL, + '项目定制技术栈管理' +WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:techStack:list'); + +SET @tech_stack_menu_id := ( + SELECT menu_id FROM sys_menu WHERE perms = 'app:techStack:list' LIMIT 1 +); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT '技术栈查询', @tech_stack_menu_id, 1, '', '', '', 1, 0, + 'F', '0', '0', 'app:techStack:query', '#', 'admin', NOW(), '', NULL, '' +WHERE @tech_stack_menu_id IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:techStack:query'); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT '技术栈新增', @tech_stack_menu_id, 2, '', '', '', 1, 0, + 'F', '0', '0', 'app:techStack:add', '#', 'admin', NOW(), '', NULL, '' +WHERE @tech_stack_menu_id IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:techStack:add'); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT '技术栈修改', @tech_stack_menu_id, 3, '', '', '', 1, 0, + 'F', '0', '0', 'app:techStack:edit', '#', 'admin', NOW(), '', NULL, '' +WHERE @tech_stack_menu_id IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:techStack:edit'); + +INSERT INTO sys_menu + (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, + menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +SELECT '技术栈删除', @tech_stack_menu_id, 4, '', '', '', 1, 0, + 'F', '0', '0', 'app:techStack:remove', '#', 'admin', NOW(), '', NULL, '' +WHERE @tech_stack_menu_id IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:techStack:remove');