模型库
This commit is contained in:
		| @ -11,9 +11,6 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; | ||||
| public class GlobalExceptionHandler { | ||||
|     @ExceptionHandler(Exception.class) | ||||
|     public ApiResponse handleException(Exception e) { | ||||
|         if (!e.getMessage().contains("No static resource")) { | ||||
|             log.error("全局异常处理:{}", e.getMessage()); | ||||
|         } | ||||
|         return ApiResponse.failure(e.getMessage()); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -23,10 +23,10 @@ public class SaTokenConfig implements WebMvcConfigurer { | ||||
|         excludePathPatterns.add("/v3/api-docs/**"); | ||||
|         excludePathPatterns.add("/fileInfo/download/**"); | ||||
|         excludePathPatterns.add("/fileInfo/preview/**"); | ||||
|         excludePathPatterns.add("/fileInfo/previewLocal/**"); | ||||
|         excludePathPatterns.add("/data/clt/**"); | ||||
|         excludePathPatterns.add("/data/mbtiles/**"); | ||||
|         excludePathPatterns.add("/data/pak/**"); | ||||
|         excludePathPatterns.add("/**"); | ||||
|  | ||||
|         // 注册 Sa-Token 拦截器 | ||||
|         registry.addInterceptor(new SaInterceptor(handle -> { | ||||
|  | ||||
| @ -44,7 +44,6 @@ public class ServerInitService { | ||||
|  | ||||
|     public void checkDefaultData() { | ||||
|         checkDefaultUserAndRole(); | ||||
|         checkDefaultSource(); | ||||
|     } | ||||
|  | ||||
|     public void checkDefaultUserAndRole() { | ||||
| @ -73,98 +72,4 @@ public class ServerInitService { | ||||
|             userService.save(user); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void checkDefaultSource() { | ||||
|         if(sourceService.count() == 0) { | ||||
|             // 查询管理员角色 | ||||
|             Role adminRole = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleName, "管理员")); | ||||
|             log.info("初始化默认资源数据"); | ||||
|             Source source1 = new Source(); | ||||
|             source1.setId(UUID.fastUUID().toString(true)); | ||||
|             source1.setSourceName("倾斜模型"); | ||||
|             source1.setSourceType("directory"); | ||||
|             source1.setTreeIndex(0); | ||||
|             source1.setIsShow(1); | ||||
|             sourceService.save(source1); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source1.getId()); | ||||
|  | ||||
|             Source source2 = new Source(); | ||||
|             source2.setId(UUID.fastUUID().toString(true)); | ||||
|             source2.setSourceName("人工模型"); | ||||
|             source2.setSourceType("directory"); | ||||
|             source2.setTreeIndex(0); | ||||
|             source2.setIsShow(1); | ||||
|             sourceService.save(source2); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source2.getId()); | ||||
|  | ||||
|             Source source3 = new Source(); | ||||
|             source3.setId(UUID.fastUUID().toString(true)); | ||||
|             source3.setSourceName("卫星底图"); | ||||
|             source3.setSourceType("directory"); | ||||
|             source3.setTreeIndex(0); | ||||
|             source3.setIsShow(1); | ||||
|             sourceService.save(source3); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source3.getId()); | ||||
|  | ||||
|             Source source4 = new Source(); | ||||
|             source4.setId(UUID.fastUUID().toString(true)); | ||||
|             source4.setSourceName("地形"); | ||||
|             source4.setSourceType("directory"); | ||||
|             source4.setTreeIndex(0); | ||||
|             source4.setIsShow(1); | ||||
|             sourceService.save(source4); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source4.getId()); | ||||
|  | ||||
|             Source source5 = new Source(); | ||||
|             source5.setId(UUID.fastUUID().toString(true)); | ||||
|             source5.setSourceName("在线图源"); | ||||
|             source5.setSourceType("directory"); | ||||
|             source5.setTreeIndex(0); | ||||
|             source5.setIsShow(1); | ||||
|             sourceService.save(source5); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source5.getId()); | ||||
|  | ||||
|             Source source6 = new Source(); | ||||
|             source6.setId(UUID.fastUUID().toString(true)); | ||||
|             source6.setSourceName("卫星图"); | ||||
|             source6.setSourceType("arcgisWximagery"); | ||||
|             source6.setParentId(source5.getId()); | ||||
|             source6.setTreeIndex(0); | ||||
|             source6.setIsShow(1); | ||||
|             sourceService.save(source6); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source6.getId()); | ||||
|  | ||||
|             Source source7 = new Source(); | ||||
|             source7.setId(UUID.fastUUID().toString(true)); | ||||
|             source7.setSourceName("暗黑地图"); | ||||
|             source7.setSourceType("arcgisBlueImagery"); | ||||
|             source7.setParentId(source5.getId()); | ||||
|             source7.setTreeIndex(0); | ||||
|             source7.setIsShow(1); | ||||
|             sourceService.save(source7); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source7.getId()); | ||||
|  | ||||
|             Source source8 = new Source(); | ||||
|             source8.setId(UUID.fastUUID().toString(true)); | ||||
|             source8.setSourceName("路网图"); | ||||
|             source8.setSourceType("gdlwImagery"); | ||||
|             source8.setParentId(source5.getId()); | ||||
|             source8.setTreeIndex(0); | ||||
|             source8.setIsShow(1); | ||||
|             sourceService.save(source8); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source8.getId()); | ||||
|  | ||||
|             Source source9 = new Source(); | ||||
|             source9.setId(UUID.fastUUID().toString(true)); | ||||
|             source9.setSourceName("矢量图"); | ||||
|             source9.setSourceType("gdslImagery"); | ||||
|             source9.setParentId(source5.getId()); | ||||
|             source9.setTreeIndex(0); | ||||
|             source9.setIsShow(1); | ||||
|             sourceService.save(source9); | ||||
|             roleSourceService.addRoleSource(adminRole.getId(), source9.getId()); | ||||
|  | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -34,7 +34,7 @@ public class CodeUtil { | ||||
|         } | ||||
|  | ||||
|         // 传入需要生成代码的表名 | ||||
|         Generation("model"); | ||||
|         Generation("business_config"); | ||||
|     } | ||||
|  | ||||
|     public static void Generation(String... tableName) { | ||||
|  | ||||
							
								
								
									
										28
									
								
								src/main/java/com/yj/earth/common/util/FileUtil.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/main/java/com/yj/earth/common/util/FileUtil.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| package com.yj.earth.common.util; | ||||
|  | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.mock.web.MockMultipartFile; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.IOException; | ||||
|  | ||||
| public class FileUtil { | ||||
|  | ||||
|     /** | ||||
|      * 将本地文件转换为 MultipartFile | ||||
|      */ | ||||
|     public static MultipartFile convertToMultipartFile(File file) { | ||||
|         try (FileInputStream inputStream = new FileInputStream(file)) { | ||||
|             return new MockMultipartFile( | ||||
|                     "files", | ||||
|                     file.getName(), | ||||
|                     MediaType.APPLICATION_OCTET_STREAM_VALUE, | ||||
|                     inputStream | ||||
|             ); | ||||
|         } catch (IOException e) { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -47,4 +47,43 @@ public class JsonUtil { | ||||
|             return new HashMap<>(0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 将 JSON 字符串转换为指定类型的对象 | ||||
|      */ | ||||
|     public static <T> T jsonToObject(String json, Class<T> clazz) { | ||||
|         if (json == null || json.trim().isEmpty()) { | ||||
|             return null; | ||||
|         } | ||||
|         return objectMapper.convertValue(json, clazz); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 将 Map 转换为指定类型的对象 | ||||
|      */ | ||||
|     public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) { | ||||
|         if (map == null || clazz == null) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // 使用ObjectMapper将Map转换为指定类型对象 | ||||
|             return objectMapper.convertValue(map, clazz); | ||||
|         } catch (IllegalArgumentException e) { | ||||
|             log.error("Map转对象失败、目标类型: {}, Map内容: {}", clazz.getName(), map, e); | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 将任意 Object 转化为 JSON | ||||
|      */ | ||||
|     public static String toJson(Object obj) { | ||||
|         try { | ||||
|             return objectMapper.writeValueAsString(obj); | ||||
|         } catch (JsonProcessingException e) { | ||||
|             log.error("对象转JSON失败", e); | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										334
									
								
								src/main/java/com/yj/earth/common/util/SQLiteUtil.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								src/main/java/com/yj/earth/common/util/SQLiteUtil.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,334 @@ | ||||
| package com.yj.earth.common.util; | ||||
|  | ||||
| import java.sql.*; | ||||
| import java.util.*; | ||||
| import java.lang.reflect.*; | ||||
| import java.util.Date; | ||||
| import java.time.LocalDateTime; // 新增导入 | ||||
| import java.time.format.DateTimeFormatter; // 新增导入 | ||||
| import java.time.format.DateTimeParseException; // 新增导入 | ||||
|  | ||||
| public class SQLiteUtil { | ||||
|  | ||||
|     // 加载 SQLite JDBC 驱动 | ||||
|     static { | ||||
|         try { | ||||
|             Class.forName("org.sqlite.JDBC"); | ||||
|         } catch (ClassNotFoundException e) { | ||||
|             throw new RuntimeException("无法加载SQLite JDBC驱动", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // 统一日期格式(匹配数据库TEXT字段存储的格式:yyyy-MM-dd'T'HH:mm:ss.SSS) | ||||
|     private static final DateTimeFormatter LOCAL_DATE_TIME_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME; | ||||
|  | ||||
|     /** | ||||
|      * 根据数据库文件绝对路径获取连接 | ||||
|      */ | ||||
|     public static Connection getConnection(String dbFilePath) throws SQLException { | ||||
|         String url = "jdbc:sqlite:" + dbFilePath; | ||||
|         return DriverManager.getConnection(url); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行查询并返回单个对象 | ||||
|      */ | ||||
|     public static <T> T queryForObject(String dbFilePath, String sql, List<Object> params, Class<T> clazz) throws SQLException, IllegalAccessException, InstantiationException { | ||||
|         List<T> results = queryForList(dbFilePath, sql, params, clazz); | ||||
|         return results.isEmpty() ? null : results.get(0); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行查询并返回对象列表 | ||||
|      */ | ||||
|     public static <T> List<T> queryForList(String dbFilePath, String sql, List<Object> params, Class<T> clazz) | ||||
|             throws SQLException, IllegalAccessException, InstantiationException { | ||||
|         List<T> resultList = new ArrayList<>(); | ||||
|  | ||||
|         // 使用try-with-resources确保资源自动关闭 | ||||
|         try (Connection conn = getConnection(dbFilePath); | ||||
|              PreparedStatement pstmt = createPreparedStatement(conn, sql, params)) { | ||||
|  | ||||
|             // 执行查询 | ||||
|             try (ResultSet rs = pstmt.executeQuery()) { | ||||
|                 ResultSetMetaData metaData = rs.getMetaData(); | ||||
|                 int columnCount = metaData.getColumnCount(); | ||||
|  | ||||
|                 // 处理结果集 | ||||
|                 while (rs.next()) { | ||||
|                     T obj = clazz.newInstance(); | ||||
|                     for (int i = 1; i <= columnCount; i++) { | ||||
|                         String columnName = metaData.getColumnName(i); | ||||
|                         Object value = rs.getObject(i); | ||||
|  | ||||
|                         // 设置对象属性(自动处理类型转换) | ||||
|                         setFieldValue(obj, columnName, value); | ||||
|                     } | ||||
|                     resultList.add(obj); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return resultList; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行增删改SQL语句 | ||||
|      */ | ||||
|     public static int executeUpdate(String dbFilePath, String sql, List<Object> params) throws SQLException { | ||||
|         try (Connection conn = getConnection(dbFilePath); | ||||
|              PreparedStatement pstmt = createPreparedStatement(conn, sql, params)) { | ||||
|             return pstmt.executeUpdate(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建并设置参数化的PreparedStatement(关键:处理LocalDateTime转String) | ||||
|      */ | ||||
|     private static PreparedStatement createPreparedStatement(Connection conn, String sql, List<Object> params) | ||||
|             throws SQLException { | ||||
|         PreparedStatement pstmt = conn.prepareStatement(sql); | ||||
|  | ||||
|         if (params != null && !params.isEmpty()) { | ||||
|             int index = 1; | ||||
|             for (Object value : params) { | ||||
|                 // 新增:LocalDateTime类型转为String、适配SQLite的TEXT字段 | ||||
|                 if (value instanceof LocalDateTime) { | ||||
|                     String dateStr = ((LocalDateTime) value).format(LOCAL_DATE_TIME_FORMATTER); | ||||
|                     pstmt.setObject(index++, dateStr); | ||||
|                 } | ||||
|                 // 新增:byte[]类型显式指定为BLOB(避免SQLite自动转换异常) | ||||
|                 else if (value instanceof byte[]) { | ||||
|                     pstmt.setBytes(index++, (byte[]) value); | ||||
|                 } else { | ||||
|                     pstmt.setObject(index++, value); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return pstmt; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 通过反射设置对象的字段值 | ||||
|      */ | ||||
|     private static void setFieldValue(Object obj, String columnName, Object value) { | ||||
|         try { | ||||
|             Field field = findField(obj.getClass(), columnName); | ||||
|             if (field != null) { | ||||
|                 field.setAccessible(true); | ||||
|                 Object convertedValue = convertValue(field.getType(), value); | ||||
|                 field.set(obj, convertedValue); | ||||
|             } | ||||
|         } catch (IllegalAccessException e) { | ||||
|             System.err.println("警告: 无法设置字段 " + columnName + " 的值 - " + e.getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查找字段、支持下划线命名转驼峰命名(如created_at → createdAt) | ||||
|      */ | ||||
|     private static Field findField(Class<?> clazz, String columnName) { | ||||
|         // 1. 直接匹配字段名(如数据库列名与字段名一致) | ||||
|         try { | ||||
|             return clazz.getDeclaredField(columnName); | ||||
|         } catch (NoSuchFieldException e) { | ||||
|             // 2. 下划线转驼峰后匹配(如created_at → createdAt) | ||||
|             String camelCaseName = underscoreToCamelCase(columnName); | ||||
|             try { | ||||
|                 return clazz.getDeclaredField(camelCaseName); | ||||
|             } catch (NoSuchFieldException e1) { | ||||
|                 // 3. 递归查找父类(支持继承场景) | ||||
|                 if (clazz.getSuperclass() != null) { | ||||
|                     return findField(clazz.getSuperclass(), columnName); | ||||
|                 } | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 下划线命名转驼峰命名(工具方法) | ||||
|      */ | ||||
|     private static String underscoreToCamelCase(String str) { | ||||
|         if (str == null || str.isEmpty()) { | ||||
|             return str; | ||||
|         } | ||||
|         StringBuilder sb = new StringBuilder(); | ||||
|         boolean nextUpperCase = false; | ||||
|         for (char c : str.toCharArray()) { | ||||
|             if (c == '_') { | ||||
|                 nextUpperCase = true; | ||||
|             } else { | ||||
|                 if (nextUpperCase) { | ||||
|                     sb.append(Character.toUpperCase(c)); | ||||
|                     nextUpperCase = false; | ||||
|                 } else { | ||||
|                     // 修正:首字母小写(如CREATED_AT → createdAt、而非CreatedAt) | ||||
|                     sb.append(Character.toLowerCase(c)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return sb.toString(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 核心:类型转换(新增LocalDateTime解析、优化BLOB适配) | ||||
|      */ | ||||
|     private static Object convertValue(Class<?> targetType, Object value) { | ||||
|         if (value == null) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         // 类型已匹配、直接返回 | ||||
|         if (targetType.isInstance(value)) { | ||||
|             return value; | ||||
|         } | ||||
|  | ||||
|         // 1. 数字类型转换(int/long/double等) | ||||
|         if (targetType == Integer.class || targetType == int.class) { | ||||
|             return ((Number) value).intValue(); | ||||
|         } else if (targetType == Long.class || targetType == long.class) { | ||||
|             return ((Number) value).longValue(); | ||||
|         } else if (targetType == Double.class || targetType == double.class) { | ||||
|             return ((Number) value).doubleValue(); | ||||
|         } else if (targetType == Float.class || targetType == float.class) { | ||||
|             return ((Number) value).floatValue(); | ||||
|         } | ||||
|  | ||||
|         // 2. 布尔类型转换(支持数字/字符串转布尔) | ||||
|         else if (targetType == Boolean.class || targetType == boolean.class) { | ||||
|             if (value instanceof Number) { | ||||
|                 return ((Number) value).intValue() != 0; | ||||
|             } else if (value instanceof String) { | ||||
|                 return "true".equalsIgnoreCase((String) value); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 3. 字符串类型转换(所有类型转String) | ||||
|         else if (targetType == String.class) { | ||||
|             return value.toString(); | ||||
|         } | ||||
|  | ||||
|         // 4. 日期类型转换(java.util.Date) | ||||
|         else if (targetType == Date.class) { | ||||
|             if (value instanceof Timestamp) { | ||||
|                 return new Date(((Timestamp) value).getTime()); | ||||
|             } else if (value instanceof LocalDateTime) { | ||||
|                 // 支持LocalDateTime转Date(如需) | ||||
|                 return Date.from(((LocalDateTime) value).atZone(java.time.ZoneId.systemDefault()).toInstant()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 5. 新增:LocalDateTime类型转换(SQLite TEXT → Java LocalDateTime) | ||||
|         else if (targetType == LocalDateTime.class) { | ||||
|             if (value instanceof String) { | ||||
|                 try { | ||||
|                     // 解析数据库存储的ISO格式字符串(如"2025-09-18T17:30:27.143") | ||||
|                     return LocalDateTime.parse((String) value, LOCAL_DATE_TIME_FORMATTER); | ||||
|                 } catch (DateTimeParseException e) { | ||||
|                     System.err.println("警告: 日期解析失败、字符串=" + value + "、格式应为yyyy-MM-dd'T'HH:mm:ss.SSS - " + e.getMessage()); | ||||
|                     return null; | ||||
|                 } | ||||
|             } else if (value instanceof Timestamp) { | ||||
|                 // 兼容Timestamp类型(如其他数据库迁移场景) | ||||
|                 return ((Timestamp) value).toLocalDateTime(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 6. 新增:byte[]类型转换(SQLite BLOB → Java byte[]) | ||||
|         else if (targetType == byte[].class && value instanceof Blob) { | ||||
|             Blob blob = (Blob) value; | ||||
|             try { | ||||
|                 return blob.getBytes(1, (int) blob.length()); | ||||
|             } catch (SQLException e) { | ||||
|                 System.err.println("警告: BLOB转byte[]失败 - " + e.getMessage()); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 无法转换时返回原始值(避免崩溃、打印警告) | ||||
|         System.err.println("警告: 不支持的类型转换、目标类型=" + targetType.getName() + "、原始值类型=" + value.getClass().getName()); | ||||
|         return value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行DDL语句(CREATE, ALTER, DROP等) | ||||
|      */ | ||||
|     private static void executeDDL(String dbFilePath, String sql, List<Object> params) throws SQLException { | ||||
|         try (Connection conn = getConnection(dbFilePath); | ||||
|              PreparedStatement pstmt = createPreparedStatement(conn, sql, params)) { | ||||
|             pstmt.execute(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行无参数的DDL语句 | ||||
|      */ | ||||
|     public static void executeDDL(String dbFilePath, String sql) { | ||||
|         try { | ||||
|             executeDDL(dbFilePath, sql, null); | ||||
|         } catch (SQLException e) { | ||||
|             throw new RuntimeException("执行DDL语句失败、SQL=" + sql, e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行查询并返回count结果 | ||||
|      */ | ||||
|     public static int queryForCount(String dbFilePath, String sql, List<Object> params) throws SQLException { | ||||
|         try (Connection conn = getConnection(dbFilePath); | ||||
|              PreparedStatement pstmt = createPreparedStatement(conn, sql, params); | ||||
|              ResultSet rs = pstmt.executeQuery()) { | ||||
|  | ||||
|             if (rs.next()) { | ||||
|                 return rs.getInt(1); | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 执行无参数的查询并返回count结果 | ||||
|      */ | ||||
|     public static int queryForCount(String dbFilePath, String sql) throws SQLException { | ||||
|         return queryForCount(dbFilePath, sql, null); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 初始化数据库表(model_type + model) | ||||
|      */ | ||||
|     public static void initialization(String modelPath) { | ||||
|         // 创建模型类型表 | ||||
|         String sql = """ | ||||
|                     CREATE TABLE "model_type" ( | ||||
|                       "id" TEXT, | ||||
|                       "name" TEXT, | ||||
|                       "parent_id" TEXT, | ||||
|                       "created_at" TEXT, | ||||
|                       "updated_at" TEXT, | ||||
|                       PRIMARY KEY ("id") | ||||
|                     ); | ||||
|                 """; | ||||
|         executeDDL(modelPath, sql); | ||||
|  | ||||
|         // 创建模型表 | ||||
|         sql = """ | ||||
|                   CREATE TABLE "model" ( | ||||
|                     "id" TEXT, | ||||
|                     "model_type_id" TEXT, | ||||
|                     "model_name" TEXT, | ||||
|                     "model_type" TEXT, | ||||
|                     "poster_type" TEXT, | ||||
|                     "poster" TEXT, | ||||
|                     "data" TEXT, | ||||
|                     "view" TEXT, | ||||
|                     "created_at" TEXT, | ||||
|                     "updated_at" TEXT, | ||||
|                     PRIMARY KEY ("id") | ||||
|                   ); | ||||
|                 """; | ||||
|         executeDDL(modelPath, sql); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 ZZX9599
					ZZX9599