diff --git a/react-ui/public/assets/images/backup/component-icon-7-Failed.png b/react-ui/public/assets/images/backup/component-icon-7-Failed.png deleted file mode 100644 index 2427996b..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7-Failed.png and /dev/null differ diff --git a/react-ui/public/assets/images/backup/component-icon-7-Omitted.png b/react-ui/public/assets/images/backup/component-icon-7-Omitted.png deleted file mode 100644 index 33a4445e..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7-Omitted.png and /dev/null differ diff --git a/react-ui/public/assets/images/backup/component-icon-7-Pending.png b/react-ui/public/assets/images/backup/component-icon-7-Pending.png deleted file mode 100644 index 12a5aa4e..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7-Pending.png and /dev/null differ diff --git a/react-ui/public/assets/images/backup/component-icon-7-Running.png b/react-ui/public/assets/images/backup/component-icon-7-Running.png deleted file mode 100644 index 0328188f..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7-Running.png and /dev/null differ diff --git a/react-ui/public/assets/images/backup/component-icon-7-Skipped.png b/react-ui/public/assets/images/backup/component-icon-7-Skipped.png deleted file mode 100644 index 33a4445e..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7-Skipped.png and /dev/null differ diff --git a/react-ui/public/assets/images/backup/component-icon-7-Succeeded.png b/react-ui/public/assets/images/backup/component-icon-7-Succeeded.png deleted file mode 100644 index 30676934..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7-Succeeded.png and /dev/null differ diff --git a/react-ui/public/assets/images/backup/component-icon-7.png b/react-ui/public/assets/images/backup/component-icon-7.png deleted file mode 100644 index c0c1087c..00000000 Binary files a/react-ui/public/assets/images/backup/component-icon-7.png and /dev/null differ diff --git a/react-ui/src/app.tsx b/react-ui/src/app.tsx index 10ab35bb..db9ce231 100644 --- a/react-ui/src/app.tsx +++ b/react-ui/src/app.tsx @@ -29,6 +29,8 @@ export async function getInitialState(): Promise<{ loading?: boolean; fetchUserInfo?: () => Promise; }> { + console.log('getInitialState'); + const fetchUserInfo = async () => { try { const response = await getUserInfo({ @@ -133,22 +135,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => { // 增加一个 loading 的状态 childrenRender: (children) => { // if (initialState?.loading) return ; - return ( - <> - {children} - {/* { - setInitialState((preInitialState) => ({ - ...preInitialState, - settings, - })); - }} - /> */} - - ); + return <>{children}; }, ...initialState?.settings, }; diff --git a/react-ui/src/components/HeaderDropdown/index.tsx b/react-ui/src/components/HeaderDropdown/index.tsx index ae560fd2..36153a73 100644 --- a/react-ui/src/components/HeaderDropdown/index.tsx +++ b/react-ui/src/components/HeaderDropdown/index.tsx @@ -17,13 +17,8 @@ const HeaderDropdown: React.FC = ({ overlayClassName: cls, }, }; }); - return ( - target.parentElement || document.body} - {...restProps} - /> - ); + + return ; }; export default HeaderDropdown; diff --git a/react-ui/src/components/RightContent/AvatarDropdown.tsx b/react-ui/src/components/RightContent/AvatarDropdown.tsx index c6c52a92..fca317ef 100644 --- a/react-ui/src/components/RightContent/AvatarDropdown.tsx +++ b/react-ui/src/components/RightContent/AvatarDropdown.tsx @@ -1,13 +1,12 @@ import { clearSessionToken } from '@/access'; -import { PageEnum } from '@/enums/pagesEnums'; import { setRemoteMenu } from '@/services/session'; import { logout } from '@/services/system/auth'; +import { gotoLoginPage } from '@/utils/ui'; import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; import { setAlpha } from '@ant-design/pro-components'; import { useEmotionCss } from '@ant-design/use-emotion-css'; import { history, useModel } from '@umijs/max'; import { Avatar, Spin } from 'antd'; -import { stringify } from 'querystring'; import type { MenuInfo } from 'rc-menu/lib/interface'; import React, { useCallback } from 'react'; import { flushSync } from 'react-dom'; @@ -23,7 +22,7 @@ const Name = () => { const nameClassName = useEmotionCss(({ token }) => { return { - width: '70px', + // width: '70px', height: '48px', overflow: 'hidden', lineHeight: '48px', @@ -64,19 +63,7 @@ const AvatarDropdown: React.FC = ({ menu }) => { await logout(); clearSessionToken(); setRemoteMenu(null); - const { search, pathname } = window.location; - const urlParams = new URL(window.location.href).searchParams; - /** 此方法会跳转到 redirect 参数所在的位置 */ - const redirect = urlParams.get('redirect'); - // Note: There may be security issues, please note - if (window.location.pathname !== PageEnum.LOGIN && !redirect) { - history.replace({ - pathname: PageEnum.LOGIN, - search: stringify({ - redirect: pathname + search, - }), - }); - } + gotoLoginPage(); }; const actionClassName = useEmotionCss(({ token }) => { return { diff --git a/react-ui/src/components/RightContent/index.tsx b/react-ui/src/components/RightContent/index.tsx index c2a4a7bf..6fbfa37c 100644 --- a/react-ui/src/components/RightContent/index.tsx +++ b/react-ui/src/components/RightContent/index.tsx @@ -1,6 +1,5 @@ -import { QuestionCircleOutlined } from '@ant-design/icons'; import { useEmotionCss } from '@ant-design/use-emotion-css'; -import { SelectLang, useModel } from '@umijs/max'; +import { useModel } from '@umijs/max'; import React from 'react'; import Avatar from './AvatarDropdown'; @@ -17,21 +16,21 @@ const GlobalHeaderRight: React.FC = () => { }; }); - const actionClassName = useEmotionCss(({ token }) => { - return { - display: 'flex', - float: 'right', - height: '48px', - marginLeft: 'auto', - overflow: 'hidden', - cursor: 'pointer', - padding: '0 12px', - borderRadius: token.borderRadius, - '&:hover': { - backgroundColor: token.colorBgTextHover, - }, - }; - }); + // const actionClassName = useEmotionCss(({ token }) => { + // return { + // display: 'flex', + // float: 'right', + // height: '48px', + // marginLeft: 'auto', + // overflow: 'hidden', + // cursor: 'pointer', + // padding: '0 12px', + // borderRadius: token.borderRadius, + // '&:hover': { + // backgroundColor: token.colorBgTextHover, + // }, + // }; + // }); const { initialState } = useModel('@@initialState'); @@ -41,15 +40,15 @@ const GlobalHeaderRight: React.FC = () => { return (
- { window.open('https://pro.ant.design/docs/getting-started'); }} > - - + */} + {/* */}
); diff --git a/react-ui/src/overrides.less b/react-ui/src/overrides.less index 1b766517..c65420fb 100644 --- a/react-ui/src/overrides.less +++ b/react-ui/src/overrides.less @@ -1,3 +1,9 @@ +/* + * @Author: 赵伟 + * @Date: 2024-04-28 08:47:43 + * @Description: 覆盖 antd 样式 + */ + // 设置 Table 可以滑动 .vertical-scroll-table { .ant-table-wrapper { @@ -9,7 +15,7 @@ height: 100%; .ant-table { - height: calc(100% - 74px); + height: calc(100% - 74px); // 分页控件的高度 .ant-table-container { height: 100%; diff --git a/react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx b/react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx index 3e58ee26..f5b2bfc4 100644 --- a/react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx +++ b/react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx @@ -144,8 +144,15 @@ function AddExperimentModal({ label="实验描述" name="description" rules={[{ required: true, message: '请输入实验描述' }]} + style={{ marginBottom: '48px' }} > - + { return ( cfg.anchorPoints || [ // 四个 - // [0.5, 0], - // [0.5, 1], - [0, 0.5], - [1, 0.5], + [0.5, 0], + [0.5, 1], + // [0, 0.5], + // [1, 0.5], ] ); }, diff --git a/react-ui/src/requestConfig.ts b/react-ui/src/requestConfig.ts index a742d3cd..501e78c5 100644 --- a/react-ui/src/requestConfig.ts +++ b/react-ui/src/requestConfig.ts @@ -1,13 +1,13 @@ /* * @Author: 赵伟 * @Date: 2024-03-25 13:52:54 - * @Description: + * @Description: 网络请求配置,详情请参考 https://umijs.org/docs/max/request */ import type { RequestConfig } from '@umijs/max'; import { message } from 'antd'; -import { clearSessionToken, getAccessToken, getRefreshToken, getTokenExpireTime } from './access'; - -const checkRegion = 5 * 60 * 1000; +import { clearSessionToken, getAccessToken } from './access'; +import { setRemoteMenu } from './services/session'; +import { gotoLoginPage } from './utils/ui'; /** * Umi Max 网络请求配置 @@ -21,23 +21,25 @@ export const requestConfig: RequestConfig = { const authHeader = headers['Authorization']; const isToken = headers['isToken']; if (!authHeader && isToken !== false) { - const expireTime = getTokenExpireTime(); - if (expireTime) { - const left = Number(expireTime) - new Date().getTime(); - const refreshToken = getRefreshToken(); - if (left < checkRegion && refreshToken) { - if (left < 0) { - clearSessionToken(); - } - } else { - const accessToken = getAccessToken(); - if (accessToken) { - headers['Authorization'] = `Bearer ${accessToken}`; - } - } - } else { - clearSessionToken(); + const accessToken = getAccessToken(); + if (accessToken) { + headers['Authorization'] = `Bearer ${accessToken}`; } + // const expireTime = getTokenExpireTime(); + // if (expireTime) { + // const left = Number(expireTime) - new Date().getTime(); + // const refreshToken = getRefreshToken(); + // if (left < 0 && refreshToken) { + // clearSessionToken(); + // } else { + // const accessToken = getAccessToken(); + // if (accessToken) { + // headers['Authorization'] = `Bearer ${accessToken}`; + // } + // } + // } else { + // clearSessionToken(); + // } } return { url, options }; }, @@ -45,15 +47,19 @@ export const requestConfig: RequestConfig = { responseInterceptors: [ (response: any) => { const { status, data } = response; - // console.log('response', response); - if (status >= 200 && status < 300 && data && (data instanceof Blob || data.code === 200)) { - return response; - } else { - if (data && data.msg) { - message.error(data.msg); + if (status >= 200 && status < 300) { + if (data && (data instanceof Blob || data.code === 200)) { + return response; + } else if (data && data.code === 401) { + clearSessionToken(); + setRemoteMenu(null); + gotoLoginPage(false); } else { - message.error('请求失败'); + message.error(data?.msg ?? '请求失败'); + return Promise.reject(response); } + } else { + message.error('请求失败'); return Promise.reject(response); } }, diff --git a/react-ui/src/services/session.ts b/react-ui/src/services/session.ts index 44861d39..39b0ff84 100644 --- a/react-ui/src/services/session.ts +++ b/react-ui/src/services/session.ts @@ -1,8 +1,7 @@ -import { createIcon } from '@/utils/IconUtil'; import { MenuDataItem } from '@ant-design/pro-components'; import { request } from '@umijs/max'; import React, { lazy } from 'react'; -import { createFromIconfontCN } from '@ant-design/icons'; + let remoteMenu: any = null; export function getRemoteMenu() { @@ -101,7 +100,7 @@ export function convertCompatRouters(childrens: API.RoutersMenuItem[]): any[] { return { path: item.path, // icon:'icon-a-057_fenlei', - icon: 'icon-'+item.meta.icon, + icon: 'icon-' + item.meta.icon, // icon: item.meta.icon, name: item.meta.title, routes: item.children ? convertCompatRouters(item.children) : undefined, diff --git a/react-ui/src/services/system/auth.ts b/react-ui/src/services/system/auth.ts index 031b2ef3..e69e571e 100644 --- a/react-ui/src/services/system/auth.ts +++ b/react-ui/src/services/system/auth.ts @@ -28,8 +28,8 @@ export async function login(body: API.LoginParams, options?: Record /** 退出登录接口 POST /api/login/outLogin */ export async function logout() { - return request>('/api/logout', { - method: 'delete', + return request>('/api/auth/logout', { + method: 'DELETE', }); } diff --git a/react-ui/src/styles/theme.less b/react-ui/src/styles/theme.less index 64b78619..0f93891e 100644 --- a/react-ui/src/styles/theme.less +++ b/react-ui/src/styles/theme.less @@ -1,4 +1,10 @@ -// 全局颜色变量 +/* + * @Author: 赵伟 + * @Date: 2024-04-28 08:47:43 + * @Description: 全局变量,可以直接在 less 文件里使用,无需引入;也可以导入到 js 里使用;为 antd 主题修改提供常量值 + */ + +// 颜色 @primary-color: #1664ff; // 主色调 @primary-color-hover: #69b1ff; @background-color: #f9fafb; // 页面背景颜色 diff --git a/react-ui/src/types.ts b/react-ui/src/types.ts index dcf74581..8e49075e 100644 --- a/react-ui/src/types.ts +++ b/react-ui/src/types.ts @@ -1,3 +1,9 @@ +/* + * @Author: 赵伟 + * @Date: 2024-04-08 09:54:39 + * @Description: 定义全局类型,比如无关联的页面都需要要的类型 + */ + // 流水线全局参数 export type PipelineGlobalParam = { param_name: string; diff --git a/react-ui/src/utils/ui.tsx b/react-ui/src/utils/ui.tsx index 51a74143..ddf83f6f 100644 --- a/react-ui/src/utils/ui.tsx +++ b/react-ui/src/utils/ui.tsx @@ -3,7 +3,9 @@ * @Date: 2024-04-19 14:42:51 * @Description: UI 公共方法 */ +import { PageEnum } from '@/enums/pagesEnums'; import themes from '@/styles/theme.less'; +import { history } from '@umijs/max'; import { Modal, type ModalFuncProps, type UploadFile } from 'antd'; // 自定义 Confirm 弹框 @@ -43,3 +45,17 @@ export const getFileListFromEvent = (e: any) => { return item; }); }; + +// 去登录页面 +export const gotoLoginPage = (toHome: boolean = true) => { + const { pathname, search } = window.location; + const urlParams = new URLSearchParams(); + urlParams.append('redirect', pathname + search); + const newSearch = toHome ? '' : urlParams.toString(); + if (window.location.pathname !== PageEnum.LOGIN) { + history.replace({ + pathname: PageEnum.LOGIN, + search: newSearch, + }); + } +}; diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/model/ModelsController.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/model/ModelsController.java index c754c673..210aefc4 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/model/ModelsController.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/model/ModelsController.java @@ -123,7 +123,7 @@ public class ModelsController extends BaseController { */ @PostMapping @ApiOperation("添加模型") - public GenericsAjaxResult add(@RequestBody Models models) { + public GenericsAjaxResult add(@RequestBody Models models) throws Exception { return genericsSuccess(this.modelsService.insert(models)); } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Models.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Models.java index 87eadc37..f00f189d 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Models.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Models.java @@ -2,6 +2,7 @@ package com.ruoyi.platform.domain; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.ruoyi.platform.annotations.CheckDuplicate; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -22,6 +23,7 @@ public class Models implements Serializable { private Integer id; @ApiModelProperty(value = "模型名称") + @CheckDuplicate private String name; @ApiModelProperty(value = "模型描述") diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetVersionDao.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetVersionDao.java index 19e21651..841f671b 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetVersionDao.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetVersionDao.java @@ -84,7 +84,8 @@ public interface DatasetVersionDao { List queryByDatasetId(Integer datasetId); - DatasetVersion queryByDatasetVersion(@Param("datasetVersion") DatasetVersion datasetVersion); + DatasetVersion + queryByDatasetVersion(@Param("datasetVersion") DatasetVersion datasetVersion); List queryAllByDatasetVersion(@Param("datasetId") Integer datasetId, @Param("version") String version); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelsDao.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelsDao.java index 8919b77a..c787e71a 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelsDao.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelsDao.java @@ -1,10 +1,12 @@ package com.ruoyi.platform.mapper; +import com.ruoyi.platform.domain.Dataset; import com.ruoyi.platform.domain.Models; import org.apache.ibatis.annotations.Param; import org.springframework.data.domain.Pageable; import java.util.List; +import java.util.Map; /** * (Models)表数据库访问层 @@ -22,6 +24,8 @@ public interface ModelsDao { */ Models queryById(Integer id); + Models findByName(@Param("name") String name); + /** * 查询指定行数据 * diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ModelsService.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ModelsService.java index c2522728..c4e5b920 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ModelsService.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/ModelsService.java @@ -2,6 +2,7 @@ package com.ruoyi.platform.service; +import com.ruoyi.platform.domain.Dataset; import com.ruoyi.platform.domain.Models; import com.ruoyi.platform.domain.ModelsVersion; import com.ruoyi.platform.vo.ModelsVo; @@ -45,7 +46,7 @@ public interface ModelsService { * @param models 实例对象 * @return 实例对象 */ - Models insert(Models models); + Models insert(Models models) throws Exception; /** * 修改数据 @@ -81,5 +82,7 @@ public interface ModelsService { String readFileContent(Integer modelsId, String version) throws Exception; + public void checkDeclaredName(Models insert) throws Exception; + List> exportModels(String path, String uuid) throws Exception; } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetServiceImpl.java index 1b89e2c4..c706e6b4 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetServiceImpl.java @@ -240,6 +240,7 @@ public class DatasetServiceImpl implements DatasetService { @Override public List> uploadDataset(MultipartFile[] files, String uuid) throws Exception { List> results = new ArrayList<>(); + for (MultipartFile file:files){ // 构建objectName String username = SecurityUtils.getLoginUser().getUsername(); @@ -259,7 +260,6 @@ public class DatasetServiceImpl implements DatasetService { if (dataset == null) { throw new Exception("数据集不存在,请检查数据集id"); } - DatasetVersion version = datasetVersionService.queryByDatasetVersion(datasetVersion); String url = ""; if (version == null) { diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java index 76d510f5..336776ea 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java @@ -221,7 +221,7 @@ public class ImageServiceImpl implements ImageService { if (imageVersionInsert == null) { throw new Exception("新增镜像版本失败"); } - // 使用CompletableFuture异步执行不同的镜像构建逻辑 + // 使用CompletableFuture异步执行不同的镜像构建逻辑,在构建镜像的同时,更新数据库中的镜像版本状态 CompletableFuture.supplyAsync(() -> { Map resultMap = new HashMap<>(); try { @@ -281,6 +281,7 @@ public class ImageServiceImpl implements ImageService { String pushCmd = "docker push " + imageUrl; String sizeCmd = "docker inspect --format='{{.Size}}' " + imageUrl; String s = k8sClientUtil.executeCommand(pod, tagCmd); + if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, pushCmd))){ resultMap.put("url", imageUrl); //得到镜像文件大小 diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java index 14b1e470..b91fb890 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java @@ -1,7 +1,9 @@ package com.ruoyi.platform.service.impl; import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.platform.annotations.CheckDuplicate; import com.ruoyi.platform.domain.AssetIcon; +import com.ruoyi.platform.domain.Dataset; import com.ruoyi.platform.domain.Models; import com.ruoyi.platform.domain.ModelsVersion; import com.ruoyi.platform.mapper.ModelsDao; @@ -34,6 +36,7 @@ import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.lang.reflect.Field; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; @@ -116,8 +119,9 @@ public class ModelsServiceImpl implements ModelsService { * @return 实例对象 */ @Override - public Models insert(Models models) { + public Models insert(Models models) throws Exception { LoginUser loginUser = SecurityUtils.getLoginUser(); + checkDeclaredName(models); models.setCreateBy(loginUser.getUsername()); models.setUpdateBy(loginUser.getUsername()); models.setUpdateTime(new Date()); @@ -173,8 +177,9 @@ public class ModelsServiceImpl implements ModelsService { if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){ throw new Exception("无权限删除该模型"); } - if (modelsVersionService.queryByModelsId(id).size()>0){ - throw new Exception("请先删除该镜像下的版本文件"); + //判断是否有版本文件 + if (!modelsVersionService.queryByModelsId(id).isEmpty()){ + throw new Exception("请先删除该模型下的版本文件"); } models.setState(0); return this.modelsDao.update(models)>0?"删除成功":"删除失败"; @@ -427,6 +432,31 @@ public class ModelsServiceImpl implements ModelsService { } + @Override + public void checkDeclaredName(Models insert) throws Exception { + Models existingModel = modelsDao.findByName(insert.getName()); + if (existingModel != null) { + // Check if the found models is not the same as the one being inserted + // This is important if you are using this method for both insert and update operations + // You may need an identifier check here, e.g., if 'insert' has an ID and it's the same as 'existingDataset' + if (insert.getId() != null && insert.getId().equals(existingModel.getId())) { + // This is the same dataset, no duplicate name issue for update operation + return; + } + + // Now we know there's another dataset with the same name + Field[] fields = Models.class.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); // Make private fields accessible + if ("name".equals(field.getName()) && field.isAnnotationPresent(CheckDuplicate.class)) { + // If the field is 'name' and is marked with CheckDuplicate annotation + CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class); + throw new Exception("重复的模型名称: " + insert.getName() + ". " + annotation.message()); + } + } + } + } + @Override public List> exportModels(String path, String uuid) throws Exception { List> results = new ArrayList<>(); diff --git a/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/DatasetDaoMapper.xml b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/DatasetDaoMapper.xml index d4bae103..d97f1a3d 100644 --- a/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/DatasetDaoMapper.xml +++ b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/DatasetDaoMapper.xml @@ -31,6 +31,7 @@ from dataset where name = #{name} and state = 1 limit 1 + + + +