This commit is contained in:
朱春云 2025-11-18 13:32:46 +08:00
commit 70441e1795
2963 changed files with 400889 additions and 0 deletions

54
.env.ali Normal file
View File

@ -0,0 +1,54 @@
############### 构建时参数 ################
ENABLED_MINIO=false
BUILD_ARGS_ENABLED_SSL=true
BUILD_ARGS_SSL_WILDCARD=false
BUILD_ARGS_DOMAIN_API=server.mstarai.cn
BUILD_ARGS_DOMAIN_PC=platform.mstarai.cn
BUILD_ARGS_DOMAIN_H5=mobile.platform.mstarai.cn
BUILD_ARGS_DOMAIN_ADMIN=admin.platform.mstarai.cn
BUILD_ARGS_DOMAIN_MINIO=
########### 容器映射到宿主机的端口 ###########
PORT_EXTERNAL_REDIS=6379
PORT_EXTERNAL_MYSQL=3306
PORT_EXTERNAL_API=9898
PORT_EXTERNAL_PC=9800
PORT_EXTERNAL_H5=9801
PORT_EXTERNAL_ADMIN=9900
PORT_EXTERNAL_MINIO=9000
PORT_EXTERNAL_MINIO_WEB=9001
PORT_EXTERNAL_KAFA=9092
############### PlayEdu #################
# MySQL链接信息
DB_HOST=rm-cn-8ex41k22p0002c.rwlb.rds.aliyuncs.com
DB_PORT=3306
DB_NAME=ai_course_platform
DB_USER=mtx
DB_PASS=mtx117114!
# Redis链接信息
REDIS_HOST=192.168.1.1
REDIS_IP=0.0.0.0
REDIS_PASS=mtx117114!
REDIS_PORT=6379
REDIS_DB=2
# Kafka
KAFKA_BOOTSTRAP_SERVERS=192.168.1.1:9092
# JWT签名秘钥
PLAYEDU_JWT_KEY=playeduxyz
# 是否允许账号多端口同时在线(false:不允许,true:允许)
SA_TOKEN_IS_CONCURRENT=false
# 授权license
PROTECTOR_LICENSE=
############## S3存储配置 ################
S3_ACCESS_KEY_ID=LTAI5tJpKBdKCqt6ttnsvfhC
S3_SECRET_ACCESS_KEY=LTAI5tJpKBdKCqt6ttnsvfhC
S3_DEFAULT_REGION=华东1
S3_BUCKET=starai-platform-1
S3_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
S3_URL=https://oss-cn-hangzhou.aliyuncs.com
S3_USE_PATH_STYLE_ENDPOINT=false

44
.env.example Normal file
View File

@ -0,0 +1,44 @@
############### 构建时参数 ################
ENABLED_MINIO=true
BUILD_ARGS_ENABLED_SSL=false
BUILD_ARGS_SSL_WILDCARD=false
BUILD_ARGS_DOMAIN_API=
BUILD_ARGS_DOMAIN_PC=
BUILD_ARGS_DOMAIN_H5=
BUILD_ARGS_DOMAIN_ADMIN=
BUILD_ARGS_DOMAIN_MINIO=
########### 容器映射到宿主机的端口 ###########
PORT_EXTERNAL_REDIS=26379
PORT_EXTERNAL_MYSQL=23306
PORT_EXTERNAL_API=9700
PORT_EXTERNAL_PC=9800
PORT_EXTERNAL_H5=9801
PORT_EXTERNAL_ADMIN=9900
PORT_EXTERNAL_MINIO=9002
############### PlayEdu #################
# MySQL链接信息
DB_HOST=mysql
DB_PORT=3306
DB_NAME=playedu
DB_USER=root
DB_PASS=playeduxyz
# Redis链接信息
REDIS_HOST=redis
REDIS_PASS=F9nO2FzJ*%uDX58!
REDIS_PORT=6379
REDIS_DB=2
# Kafka
KAFKA_BOOTSTRAP_SERVERS=kafka:9092
# JWT签名秘钥
PLAYEDU_JWT_KEY=playeduxyz
# 是否允许账号多端口同时在线(false:不允许,true:允许)
SA_TOKEN_IS_CONCURRENT=false
# 授权license
PROTECTOR_LICENSE=
############## MinIO存储配置 ################
S3_ACCESS_KEY_ID=username
S3_SECRET_ACCESS_KEY=password
S3_BUCKET=playedu

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.DS_Store
.env
/.idea/

140
0.yml Normal file
View File

@ -0,0 +1,140 @@
x-logging: &default-logging
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
networks:
playedu:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.10.10.0/24
volumes:
mysql-data:
redis-data:
minio-data:
kafka-data:
services:
redis:
image: registry.cn-hangzhou.aliyuncs.com/hzbs/redis:7.0.12
restart: always
volumes:
- redis-data:/data
ports:
- "${PORT_EXTERNAL_REDIS}:6379"
networks:
- playedu
logging: *default-logging
mysql:
image: registry.cn-hangzhou.aliyuncs.com/hzbs/mysql:8.1
restart: always
environment:
- MYSQL_DATABASE=${DB_NAME}
- MYSQL_ROOT_PASSWORD=${DB_PASS}
volumes:
- mysql-data:/var/lib/mysql
ports:
- "${PORT_EXTERNAL_MYSQL}:3306"
networks:
- playedu
logging: *default-logging
minio:
image: registry.cn-hangzhou.aliyuncs.com/hzbs/bitnami-minio:2024.6.6
restart: always
environment:
- MINIO_ROOT_USER=${S3_ACCESS_KEY_ID}
- MINIO_ROOT_PASSWORD=${S3_SECRET_ACCESS_KEY}
- MINIO_DEFAULT_BUCKETS=${S3_BUCKET}
volumes:
- minio-data:/bitnami/minio/data
networks:
- playedu
logging: *default-logging
kafka:
image: registry.cn-hangzhou.aliyuncs.com/hzbs/bitnami-kafka:3.7.0
environment:
- KAFKA_CFG_NODE_ID=0
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_KRAFT_CLUSTER_ID=playedu-kafka-cluster
restart: always
volumes:
- kafka-data:/bitnami/kafka
networks:
- playedu
logging: *default-logging
playedu:
build:
context: .
dockerfile: Dockerfile-api
args:
- ENABLED_MINIO=${ENABLED_MINIO}
- ENABLED_SSL=${BUILD_ARGS_ENABLED_SSL}
- SSL_WILDCARD=${BUILD_ARGS_SSL_WILDCARD}
- DOMAIN_API=${BUILD_ARGS_DOMAIN_API}
- DOMAIN_PC=${BUILD_ARGS_DOMAIN_PC}
- DOMAIN_H5=${BUILD_ARGS_DOMAIN_H5}
- DOMAIN_ADMIN=${BUILD_ARGS_DOMAIN_ADMIN}
- DOMAIN_MINIO=${BUILD_ARGS_DOMAIN_MINIO}
restart: always
environment:
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_NAME=${DB_NAME}
- DB_PASS=${DB_PASS}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PASS=${REDIS_PASS}
- REDIS_PORT=${REDIS_PORT}
- REDIS_DB=${REDIS_DB}
- SA_TOKEN_IS_CONCURRENT=${SA_TOKEN_IS_CONCURRENT}
- SA_TOKEN_JWT_SECRET_KEY=${PLAYEDU_JWT_KEY}
- KAFKA_BOOTSTRAP_SERVERS=${KAFKA_BOOTSTRAP_SERVERS}
- PROTECTOR_LICENSE=${PROTECTOR_LICENSE}
volumes:
- "./data:/playedu-data"
ports:
- "80:80"
- "443:443"
- "${PORT_EXTERNAL_API}:9898"
- "${PORT_EXTERNAL_PC}:9800"
- "${PORT_EXTERNAL_H5}:9801"
- "${PORT_EXTERNAL_ADMIN}:9900"
- "${PORT_EXTERNAL_MINIO}:9000"
networks:
- playedu
logging: *default-logging
document:
build:
context: .
dockerfile: Dockerfile-document
restart: always
environment:
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_NAME=${DB_NAME}
- DB_PASS=${DB_PASS}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PASS=${REDIS_PASS}
- REDIS_PORT=${REDIS_PORT}
- REDIS_DB=${REDIS_DB}
- SA_TOKEN_IS_CONCURRENT=${SA_TOKEN_IS_CONCURRENT}
- SA_TOKEN_JWT_SECRET_KEY=${PLAYEDU_JWT_KEY}
- KAFKA_BOOTSTRAP_SERVERS=${KAFKA_BOOTSTRAP_SERVERS}
- PROTECTOR_LICENSE=${PROTECTOR_LICENSE}
networks:
- playedu
logging: *default-logging

16293
DB/ai_course_platform.sql Normal file

File diff suppressed because one or more lines are too long

90
DB/增量DB.sql Normal file
View File

@ -0,0 +1,90 @@
--
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '实验课', 0, '查询|新增|编辑|删除', 'experiment', '2025-08-30 08:46:29', '2025-08-30 08:44:56', '2025-08-30 08:48:00', '100000005', '100000005', '42' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '实验报告模版', 0, '查询|新增|编辑|删除', 'template', '2025-08-30 08:47:30', '2025-08-30 08:47:26', '2025-08-30 08:48:00', '100000005', '100000005', '42' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '实验课', 0, '查询|新增|编辑|删除', 'experiment', '2025-08-30 08:46:29', '2025-08-30 08:44:56', '2025-08-30 08:48:00', '100000005', '100000005', '0' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '实验报告模版', 0, '查询|新增|编辑|删除', 'template', '2025-08-30 08:47:30', '2025-08-30 08:47:26', '2025-08-30 08:48:00', '100000005', '100000005', '0' );
ALTER TABLE `lab_course_info`
MODIFY COLUMN `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键' FIRST;
ALTER TABLE `lab_equ_warn_info`
MODIFY COLUMN `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键' FIRST;
--
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '软件管理', 0, '查询|新增|编辑|删除', 'virtual-simulation-card', '2025-08-30 08:46:29', '2025-08-30 08:44:56', '2025-08-30 08:48:00', '100000005', '100000005', '42' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '学习记录', 0, '查询|新增|编辑|删除', 'simulation-records', '2025-08-30 08:47:30', '2025-08-30 08:47:26', '2025-08-30 08:48:00', '100000005', '100000005', '42' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '软件管理', 0, '查询|新增|编辑|删除', 'virtual-simulation-card', '2025-08-30 08:46:29', '2025-08-30 08:44:56', '2025-08-30 08:48:00', '100000005', '100000005', '0' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '学习记录', 0, '查询|新增|编辑|删除', 'simulation-records', '2025-08-30 08:47:30', '2025-08-30 08:47:26', '2025-08-30 08:48:00', '100000005', '100000005', '0' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '重庆项目-考试任务', 0, '查询|新增|编辑|删除', 'examAdministration', '2025-08-30 08:46:29', '2025-08-30 08:44:56', '2025-08-30 08:48:00', '100000005', '100000005', '42' );
INSERT INTO `admin_permissions` ( `type`, `group_name`, `sort`, `name`, `slug`, `created_at`, `create_time`, `update_time`, `creator`, `updater`, `tenant_id` )
VALUES
( 'action', '重庆项目-考试任务', 0, '查询|新增|编辑|删除', 'examAdministration', '2025-08-30 08:46:29', '2025-08-30 08:44:56', '2025-08-30 08:48:00', '100000005', '100000005', '0' );
INSERT INTO `app_config` (
`group_name`,
`name`,
`sort`,
`field_type`,
`key_name`,
`key_value`,
`option_value`,
`is_private`,
`help`,
`created_at`,
`is_hidden`,
`create_time`,
`update_time`,
`creator`,
`updater`,
`tenant_id`
)
VALUES
(
'S3存储',
'S3自定义域名',
80,
'text',
's3.zdy_domain_key',
'http://webapp.mstarai.cn',
NULL,
0,
'',
'2025-06-09 12:33:59',
1,
'2025-06-11 14:23:04',
'2025-06-11 14:38:23',
NULL,
NULL,
'0'
);

View File

@ -0,0 +1,180 @@
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for software_study_record_detail
-- ----------------------------
DROP TABLE IF EXISTS `software_study_record_detail`;
CREATE TABLE `software_study_record_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`student_record_id` int(11) NULL DEFAULT NULL COMMENT '具体学生记录id',
`seq` int(11) NULL DEFAULT NULL COMMENT '步骤序号',
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`start_time` datetime(0) NULL DEFAULT NULL COMMENT '实验开始时间',
`end_time` datetime(0) NULL DEFAULT NULL COMMENT '实验结束时间',
`time_used` int(11) NULL DEFAULT NULL COMMENT '实验用时单位s',
`expect_time` int(11) NULL DEFAULT NULL COMMENT '实验合理用时s',
`max_score` double(11, 2) NULL DEFAULT NULL COMMENT '实验步骤满分 百分制',
`score` double(11, 2) NULL DEFAULT NULL COMMENT '实验步骤得分百分制',
`repeat_count` int(11) NULL DEFAULT NULL COMMENT '实验步骤操作次数',
`evaluation` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '步骤评价',
`scoring_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '赋分模型',
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
`dept_id` int(11) NULL DEFAULT NULL COMMENT '学生部门id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`tenant_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '实验步骤明细表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_info
-- ----------------------------
DROP TABLE IF EXISTS `software_info`;
CREATE TABLE `software_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`class_id` int(11) NULL DEFAULT NULL COMMENT '分类',
`software_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '软件名称',
`software_cover` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图',
`version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '最新版本号',
`soft_no` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '软件编号',
`type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '1单机版2网页版3外部链接',
`soft_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '软件地址',
`company` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '软件厂商',
`max_connect` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '最大并发数',
`min_speed` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '最小带宽',
`soft_desc` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '软件描述',
`secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '秘钥',
`user_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `soft_no`(`soft_no`) USING BTREE,
UNIQUE INDEX `secret`(`secret`) USING BTREE,
INDEX `software_name`(`software_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '虚拟仿真软件表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_item_info
-- ----------------------------
DROP TABLE IF EXISTS `software_item_info`;
CREATE TABLE `software_item_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`soft_id` int(11) NULL DEFAULT NULL COMMENT '软件id',
`item_no` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '项目编号',
`item_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '项目名称',
`user_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `soft_id`(`soft_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 141 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '软件项目信息' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_resource_info
-- ----------------------------
DROP TABLE IF EXISTS `software_resource_info`;
CREATE TABLE `software_resource_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`soft_id` int(11) NULL DEFAULT NULL COMMENT '软件id',
`type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '类型1视频2文档',
`resource_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源路径',
`resource_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源名称',
`user_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `soft_id`(`soft_id`) USING BTREE,
INDEX `type`(`type`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 170 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '软件资源包' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_class
-- ----------------------------
DROP TABLE IF EXISTS `software_class`;
CREATE TABLE `software_class` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`class_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分类名称',
`parent_id` int(11) NULL DEFAULT 0 COMMENT '父节点主键',
`parent_chain` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '父链',
`sort` int(11) NULL DEFAULT 0 COMMENT '升序',
`user_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '虚拟仿真软件分类表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_study_record
-- ----------------------------
DROP TABLE IF EXISTS `software_study_record`;
CREATE TABLE `software_study_record` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`soft_id` int(11) NULL DEFAULT NULL COMMENT '软件id',
`item_id` int(11) NULL DEFAULT NULL COMMENT '软件项目id',
`stu_id` int(11) NULL DEFAULT NULL COMMENT '学生id',
`ticket` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '本次实验令牌',
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '实验名称:用户学习的实验名称',
`start_time` datetime(0) NULL DEFAULT NULL COMMENT '实验开始时间',
`end_time` datetime(0) NULL DEFAULT NULL COMMENT '实验结束时间',
`is_end` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '是否结束',
`score` double(11, 2) NULL DEFAULT 0.00 COMMENT '总分',
`report_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '实验报告地址',
`comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '批注',
`dept_id` int(11) NULL DEFAULT NULL COMMENT '学生部门id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`tenant_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '学生软件学习记录表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_tenant_info
-- ----------------------------
DROP TABLE IF EXISTS `software_tenant_info`;
CREATE TABLE `software_tenant_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`tenant_id` int(11) NULL DEFAULT NULL COMMENT '租户id',
`soft_id` int(11) NULL DEFAULT NULL COMMENT '软件id',
`status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '1正常2暂停',
`user_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `tenant_id`(`tenant_id`) USING BTREE,
INDEX `soft_id`(`soft_id`) USING BTREE,
INDEX `status`(`status`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '软件学校分配' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for software_department_user
-- ----------------------------
DROP TABLE IF EXISTS `software_department_user`;
CREATE TABLE `software_department_user` (
`soft_id` int(11) NOT NULL DEFAULT 0 COMMENT '线下课程ID',
`range_id` int(11) NOT NULL DEFAULT 0 COMMENT '指派范围ID',
`type` int(11) NOT NULL DEFAULT 0 COMMENT '指派范围类型[0:部门,1:学员,2:用户组]',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
`creator` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`updater` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`tenant_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '虚拟仿真软件-学校内分配表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

125
Dockerfile-api Normal file
View File

@ -0,0 +1,125 @@
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17 AS api-builder
COPY ./app/api /app/playedu
WORKDIR /app/playedu
RUN sed -i 's/\r$//' mvnw
RUN chmod +x mvnw
RUN /app/playedu/mvnw -T 1C -DarchetypeCatalog=local -Dmaven.test.skip=true -Dmaven.repo.remote=https://maven.aliyun.com/repository/public package
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/node:20-alpine AS node-builder
COPY app/backend /app/backend
COPY app/pc /app/pc
COPY app/h5 /app/h5
WORKDIR /app/backend
RUN pnpm i && VITE_APP_URL=/api/ pnpm build
WORKDIR /app/pc
RUN pnpm i && VITE_APP_URL=/api/ pnpm build
WORKDIR /app/h5
RUN pnpm i && VITE_APP_URL=/api/ pnpm build
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17 AS config-builder
# 是否启用MINIO
ARG ENABLED_MINIO=false
# 是否启用SSL
ARG ENABLED_SSL=false
# SSL是否是通配符证书
ARG SSL_WILDCARD=false
# API域名
ARG DOMAIN_API
ARG DOMAIN_PC
ARG DOMAIN_H5
ARG DOMAIN_ADMIN
ARG DOMAIN_MINIO
RUN if [ "$ENABLED_SSL" = "true" ] && [ -z "$DOMAIN_API" ]; then \
echo "请配置API域名"; \
exit 1; \
fi
RUN if [ "$ENABLED_SSL" = "true" ] && [ -z "$DOMAIN_PC" ]; then \
echo "请配置PC域名"; \
exit 1; \
fi
RUN if [ "$ENABLED_SSL" = "true" ] && [ -z "$DOMAIN_H5" ]; then \
echo "请配置H5域名"; \
exit 1; \
fi
RUN if [ "$ENABLED_SSL" = "true" ] && [ -z "$DOMAIN_ADMIN" ]; then \
echo "请配置后台管理域名"; \
exit 1; \
fi
RUN if [ "$ENABLED_MINIO" = "true" ] && [ "$ENABLED_SSL" = "true" ] && [ -z "$DOMAIN_MINIO" ]; then \
echo "请配置MINIO域名"; \
exit 1; \
fi
COPY docker/nginx/conf/nginx.conf /docker/nginx/conf/nginx.conf
COPY docker/nginx/conf/nginx.ssl.conf /docker/nginx/conf/nginx.ssl.conf
RUN sed -i 's/\r$//' /docker/nginx/conf/nginx.conf
RUN sed -i 's/\r$//' /docker/nginx/conf/nginx.ssl.conf
RUN if [ "$ENABLED_MINIO" != "true" ]; then \
sed -i "/####MINIO-START####/,/####MINIO-END####/d" /docker/nginx/conf/nginx.ssl.conf; \
sed -i "/####MINIO-START####/,/####MINIO-END####/d" /docker/nginx/conf/nginx.conf; \
fi
RUN if [ -n "$DOMAIN_API" ]; then \
sed -i "s/api.domain/${DOMAIN_API}/g" /docker/nginx/conf/nginx.ssl.conf; \
fi
RUN if [ -n "$DOMAIN_PC" ]; then \
sed -i "s/pc.domain/${DOMAIN_PC}/g" /docker/nginx/conf/nginx.ssl.conf; \
fi
RUN if [ -n "$DOMAIN_H5" ]; then \
sed -i "s/h5.domain/${DOMAIN_H5}/g" /docker/nginx/conf/nginx.ssl.conf; \
fi
RUN if [ -n "$DOMAIN_ADMIN" ]; then \
sed -i "s/admin.domain/${DOMAIN_ADMIN}/g" /docker/nginx/conf/nginx.ssl.conf; \
fi
RUN if [ "$ENABLED_MINIO" = "true" ] && [ -n "$DOMAIN_MINIO" ]; then \
sed -i "s/minio.domain/${DOMAIN_MINIO}/g" /docker/nginx/conf/nginx.ssl.conf; \
fi
RUN if [ "$ENABLED_SSL" = "true" ] && [ "$SSL_WILDCARD" = "true" ]; then \
sed -i 's/pc.pem\|h5.pem\|api.pem\|admin.pem\|minio.pem/playedu.pem/g' /docker/nginx/conf/nginx.ssl.conf; \
sed -i 's/pc.key\|h5.key\|api.key\|admin.key\|minio.key/playedu.key/g' /docker/nginx/conf/nginx.ssl.conf; \
fi
# 由构建参数决定是否启动ssl的nginx配置
RUN if [ "$ENABLED_SSL" = "true" ]; then \
cp /docker/nginx/conf/nginx.ssl.conf /etc/nginx/sites-enabled/default; \
else \
cp /docker/nginx/conf/nginx.conf /etc/nginx/sites-enabled/default; \
fi
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17
COPY --from=api-builder /app/playedu/playedu-api/target/playedu-api-*.jar /app/api/app.jar
COPY --from=node-builder /app/backend/dist /app/backend
COPY --from=node-builder /app/pc/dist /app/frontend
COPY --from=node-builder /app/h5/dist /app/h5
COPY --from=config-builder /etc/nginx/sites-enabled/default /etc/nginx/sites-enabled/default
WORKDIR /app/api
EXPOSE 80/tcp
EXPOSE 443/tcp
EXPOSE 9800/tcp
EXPOSE 9801/tcp
EXPOSE 9900/tcp
EXPOSE 9002/tcp
CMD echo "Waiting for MySQL/Redis/MinIO to start..."; sleep 15 ;nginx;java -jar /app/api/app.jar --spring.datasource.url="jdbc:mysql://${DB_HOST}:${DB_PORT:-3306}/${DB_NAME}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" --spring.datasource.username=${DB_USER} --spring.datasource.password=${DB_PASS} --spring.data.redis.host=${REDIS_HOST} --spring.data.redis.port=${REDIS_PORT:-6379} --spring.data.redis.password=${REDIS_PASS} --spring.data.redis.database=${REDIS_DB:-0} --sa-token.is-concurrent=${SA_TOKEN_IS_CONCURRENT:-false} --apiUrl.loginUrl=https://${SERVER_API_HOST}/api/v1/auth/login/loginInSoftWare --sa-token.jwt-secret-key=${SA_TOKEN_JWT_SECRET_KEY} --spring.kafka.bootstrap-servers=${KAFKA_BOOTSTRAP_SERVERS}

19
Dockerfile-document Normal file
View File

@ -0,0 +1,19 @@
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17 AS api-builder
COPY app/document /app/document
WORKDIR /app/document
RUN sed -i 's/\r$//' mvnw
RUN chmod +x mvnw
RUN /app/document/mvnw -T 1C -DarchetypeCatalog=local -Dmaven.test.skip=true package
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17-with-ffmpeg-libreoffice-mupdf
COPY --from=api-builder /app/document/playedu-api/target/playedu-api-*.jar /app/document/app.jar
WORKDIR /app/document
EXPOSE 9696/tcp
CMD echo "Waiting for MySQL/Redis/MinIO to start..."; sleep 15; java -jar /app/document/app.jar --spring.datasource.url="jdbc:mysql://${DB_HOST}:${DB_PORT:-3306}/${DB_NAME}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" --spring.datasource.username=${DB_USER} --spring.datasource.password=${DB_PASS} --spring.data.redis.host=${REDIS_HOST} --spring.data.redis.port=${REDIS_PORT:-6379} --spring.data.redis.password=${REDIS_PASS} --spring.data.redis.database=${REDIS_DB:-0} --sa-token.is-concurrent=${SA_TOKEN_IS_CONCURRENT:-false} --sa-token.jwt-secret-key=${SA_TOKEN_JWT_SECRET_KEY} --spring.kafka.bootstrap-servers=${KAFKA_BOOTSTRAP_SERVERS}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,::before,::after{box-sizing:border-box}html{line-height:1.15;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4}body{margin:0;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'}hr{height:0;color:inherit}abbr[title]{text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}button,[type='button'],[type='reset'],[type='submit']{-webkit-appearance:button}::-moz-focus-inner{border-style:none;padding:0}:-moz-focusring{outline:1px dotted ButtonText}:-moz-ui-invalid{box-shadow:none}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type='search']{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}

View File

@ -0,0 +1,135 @@
code[class*="language-"],
pre[class*="language-"] {
color : #000;
background : 0 0;
text-shadow : 0 1px #fff;
font-family : Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size : 1em;
text-align : left;
white-space : pre;
word-spacing : normal;
word-break : normal;
word-wrap : normal;
line-height : 1.5;
-moz-tab-size : 4;
-o-tab-size : 4;
tab-size : 4;
-webkit-hyphens: none;
-moz-hyphens : none;
-ms-hyphens : none;
hyphens : none;
}
code[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
pre[class*="language-"]::-moz-selection {
text-shadow: none;
background : #b3d4fc;
}
code[class*="language-"] ::selection,
code[class*="language-"]::selection,
pre[class*="language-"] ::selection,
pre[class*="language-"]::selection {
text-shadow: none;
background : #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
pre[class*="language-"] {
padding : 1em;
margin : 0.5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
:not(pre)>code[class*="language-"] {
padding : 0.1em;
border-radius: 0.3em;
white-space : normal;
}
.token.cdata,
.token.comment,
.token.doctype,
.token.prolog {
color: #909faf;
}
.token.punctuation {
color: #999;
}
.token.namespace {
opacity: 0.7;
}
.token.boolean,
.token.constant,
.token.deleted,
.token.number,
.token.property,
.token.symbol,
.token.tag {
color: #905;
}
.token.attr-name,
.token.builtin,
.token.char,
.token.inserted,
.token.selector,
.token.string {
color: #690;
}
.language-css .token.string,
.style .token.string,
.token.entity,
.token.operator,
.token.url {
color : #9a6e3a;
background: hsla(0, 0%, 100%, 0.5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.class-name,
.token.function {
color: #dd4a68;
}
.token.important,
.token.regex,
.token.variable {
color: #e90;
}
.token.bold,
.token.important {
font-weight: 700;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,::before,::after{box-sizing:border-box}html{line-height:1.15;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4}body{margin:0;font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'}hr{height:0;color:inherit}abbr[title]{text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}button,[type='button'],[type='reset'],[type='submit']{-webkit-appearance:button}::-moz-focus-inner{border-style:none;padding:0}:-moz-focusring{outline:1px dotted ButtonText}:-moz-ui-invalid{box-shadow:none}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type='search']{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}

View File

@ -0,0 +1,135 @@
code[class*="language-"],
pre[class*="language-"] {
color : #000;
background : 0 0;
text-shadow : 0 1px #fff;
font-family : Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size : 1em;
text-align : left;
white-space : pre;
word-spacing : normal;
word-break : normal;
word-wrap : normal;
line-height : 1.5;
-moz-tab-size : 4;
-o-tab-size : 4;
tab-size : 4;
-webkit-hyphens: none;
-moz-hyphens : none;
-ms-hyphens : none;
hyphens : none;
}
code[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
pre[class*="language-"]::-moz-selection {
text-shadow: none;
background : #b3d4fc;
}
code[class*="language-"] ::selection,
code[class*="language-"]::selection,
pre[class*="language-"] ::selection,
pre[class*="language-"]::selection {
text-shadow: none;
background : #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
pre[class*="language-"] {
padding : 1em;
margin : 0.5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
:not(pre)>code[class*="language-"] {
padding : 0.1em;
border-radius: 0.3em;
white-space : normal;
}
.token.cdata,
.token.comment,
.token.doctype,
.token.prolog {
color: #909faf;
}
.token.punctuation {
color: #999;
}
.token.namespace {
opacity: 0.7;
}
.token.boolean,
.token.constant,
.token.deleted,
.token.number,
.token.property,
.token.symbol,
.token.tag {
color: #905;
}
.token.attr-name,
.token.builtin,
.token.char,
.token.inserted,
.token.selector,
.token.string {
color: #690;
}
.language-css .token.string,
.style .token.string,
.token.entity,
.token.operator,
.token.url {
color : #9a6e3a;
background: hsla(0, 0%, 100%, 0.5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.class-name,
.token.function {
color: #dd4a68;
}
.token.important,
.token.regex,
.token.variable {
color: #e90;
}
.token.bold,
.token.important {
font-weight: 700;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

93
README.md Normal file
View File

@ -0,0 +1,93 @@
# Playedu
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.zlongg.cn:8443/webproject/playedu/playedu.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.zlongg.cn:8443/webproject/playedu/playedu/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

0
app/.gitkeep Normal file
View File

37
app/api/.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
/playedu-api/src/main/resources/application-dev.yml
/logs
playedu-api/.DS_Store

24
app/api/Dockerfile Normal file
View File

@ -0,0 +1,24 @@
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17 AS builder
WORKDIR /app
COPY . /app
RUN chmod a+x /app/docker-build.sh
RUN chmod a+x /app/mvnw
RUN /app/docker-build.sh
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17
WORKDIR /app
# 将指定目录下的jar包复制到docker容器的/目录下
COPY --from=builder /app/playedu-api/target/playedu-api-*.jar /app/app.jar
# 声明服务运行在8080端口
EXPOSE 9898
# 指定docker容器启动时运行jar包
ENTRYPOINT ["java", "-jar", "app.jar"]

12
app/api/Dockerfile.local Normal file
View File

@ -0,0 +1,12 @@
FROM registry.cn-hangzhou.aliyuncs.com/hzbs/eclipse-temurin:17
WORKDIR /app
# 将指定目录下的jar包复制到docker容器的/目录下
COPY ./playedu-api/target/playedu-api-*.jar /app/app.jar
# 声明服务运行在8080端口
EXPOSE 9898
# 指定docker容器启动时运行jar包
ENTRYPOINT ["java", "-jar", "app.jar"]

1
app/api/README.md Normal file
View File

@ -0,0 +1 @@
## PlayEdu 商业版本

5
app/api/docker-build.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh
echo '开始打包...'
/app/mvnw clean package -T 1C -Dmaven.test.skip=true -Dmaven.compile.fork=true

View File

@ -0,0 +1,3 @@
/*
* Copyright (C) 2023 杭州白书科技有限公司
*/

317
app/api/mvnw vendored Normal file
View File

@ -0,0 +1,317 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

188
app/api/mvnw.cmd vendored Normal file
View File

@ -0,0 +1,188 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>xyz.playedu</groupId>
<artifactId>playedu</artifactId>
<version>1.0</version>
</parent>
<artifactId>playedu-ai</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-common</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-resource</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,15 @@
package xyz.playedu.ai.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "ai.platform")
public class AIPlatformConfig {
private String host;
private String api_key;
}

View File

@ -0,0 +1,79 @@
package xyz.playedu.ai.domain;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
*ai知识库
*/
@Data
@TableName(value = "ai_datasets")
public class Dataset {
/**知识库id**/
@TableId(type= IdType.NONE)
private String id;
/**知识库名称**/
private String name;
/**知识库创建者**/
@JsonProperty("admin_id")
private Integer adminId;
/**知识库创建时间**/
@JsonProperty("created_at")
private Date createdAt;
private String description;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
Dataset other = (Dataset) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getName()== null
? other.getName() == null
: this.getName().equals(other.getName()))
&& (this.getAdminId()== null
? other.getAdminId() == null
: this.getAdminId().equals(other.getAdminId()))
&& (this.getCreatedAt() == null
? other.getCreatedAt() == null
: this.getCreatedAt().equals(other.getCreatedAt()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
result = prime * result + ((getAdminId() == null) ? 0 : getAdminId().hashCode());
result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", name=").append(name);
sb.append(", admin_id=").append(adminId);
sb.append(", created_at=").append(createdAt);
sb.append("]");
return sb.toString();
}
}

View File

@ -0,0 +1,69 @@
package xyz.playedu.ai.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@TableName("ai_dataset_resource")
public class DatasetResourceFile {
@TableId(type= IdType.NONE)
String id;
@JsonProperty("dataset")
String dataset;
@JsonProperty("resource_id")
Integer resourceID;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
DatasetResourceFile other = (DatasetResourceFile) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getDataset()== null
? other.getDataset() == null
: this.getDataset().equals(other.getDataset()))
&& (this.getResourceID()== null
? other.getResourceID() == null
: this.getResourceID().equals(other.getResourceID()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getDataset() == null) ? 0 : getDataset().hashCode());
result = prime * result + ((getResourceID() == null) ? 0 : getResourceID().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", dataset=").append(dataset);
sb.append(", resource_id=").append(resourceID);
sb.append("]");
return sb.toString();
}
}

View File

@ -0,0 +1,7 @@
package xyz.playedu.ai.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xyz.playedu.ai.domain.Dataset;
public interface DatasetMapper extends BaseMapper<Dataset> {
}

View File

@ -0,0 +1,10 @@
package xyz.playedu.ai.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xyz.playedu.ai.domain.DatasetResourceFile;
public interface DatasetResourceFileMapper extends BaseMapper<DatasetResourceFile> {
}

View File

@ -0,0 +1,10 @@
package xyz.playedu.ai.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.ai.domain.DatasetResourceFile;
public interface DatasetResourceFileServer extends IService<DatasetResourceFile> {
}

View File

@ -0,0 +1,16 @@
package xyz.playedu.ai.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.ai.domain.Dataset;
import xyz.playedu.ai.types.DatasetPageFilter;
public interface DatasetService extends IService<Dataset> {
public Page<Dataset> selectPage(int pageIndex, int pageSize, DatasetPageFilter filter);
}

View File

@ -0,0 +1,24 @@
package xyz.playedu.ai.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.playedu.ai.domain.Dataset;
import xyz.playedu.ai.mapper.DatasetMapper;
import xyz.playedu.ai.service.DatasetService;
import xyz.playedu.ai.types.DatasetPageFilter;
@Service
public class DataServiceImpl extends ServiceImpl<DatasetMapper,Dataset> implements DatasetService {
@Override
public Page<Dataset> selectPage(int pageIndex, int pageSize, DatasetPageFilter filter) {
QueryWrapper<Dataset> queryWrapper = new QueryWrapper<>();
if(filter.getAdminList()!=null&& !filter.getAdminList().isEmpty()){
queryWrapper.in("adminId",filter.getAdminList());
}
Page<Dataset> resPage = new Page<>(pageIndex,pageSize);
return page(resPage,queryWrapper);
}
}

View File

@ -0,0 +1,17 @@
package xyz.playedu.ai.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import xyz.playedu.ai.domain.DatasetResourceFile;
import xyz.playedu.ai.mapper.DatasetResourceFileMapper;
import xyz.playedu.ai.service.DatasetResourceFileServer;
@Service
@Slf4j
public class DatasetResourceFileServerImpl extends ServiceImpl<DatasetResourceFileMapper,DatasetResourceFile>
implements DatasetResourceFileServer
{
}

View File

@ -0,0 +1,10 @@
package xyz.playedu.ai.types;
import lombok.Data;
import java.util.List;
@Data
public class DatasetPageFilter {
private List<Integer> adminList;
}

View File

@ -0,0 +1,30 @@
package xyz.playedu.ai.types.request;
import lombok.Data;
@Data
public class PlatformDatasetRequest {
String name;
String avatar;
String description;
String language;
String embedding_model;
String permission;
String chunk_method;
ParserConfig parser_config;
@Data
public static class ParserConfig{
Integer chunk_token_num;
String delimiter;
boolean html4excel;
boolean layout_recognize;
Raptor raptor;
}
@Data
public static class Raptor {
boolean user_raptor;
}
}

View File

@ -0,0 +1,19 @@
package xyz.playedu.ai.types.request;
import java.util.List;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class PlatformDatasetResourceRequest {
@NotBlank(message = "dataset_id为空")
String dataset_id;
List<Resource> resources;
@Data
public static class Resource{
String file_name;
long size;
String location;
}
}

View File

@ -0,0 +1,20 @@
package xyz.playedu.ai.types.response;
import lombok.Data;
import xyz.playedu.ai.types.request.PlatformDatasetRequest;
@Data
public class PlatformDatasetResourceUploadResponse {
String chunk_method;
String created_by;
String dataset_id;
String id;
String location;
String name;
PlatformDatasetRequest.ParserConfig parser_config;
String run;
long size;
String thumbnail;
String type;
}

View File

@ -0,0 +1,41 @@
package xyz.playedu.ai.types.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import xyz.playedu.ai.types.request.PlatformDatasetRequest;
@Data
public class PlatformDatasetResponse {
String avatar;
@JsonProperty("chunk_count")
Integer chunkCount;
@JsonProperty("chunk_method")
String chunkMethod;
@JsonProperty("create_date")
String createDate;
@JsonProperty("create_time")
long createTime;
@JsonProperty("created_by")
String createdBy;
String description;
@JsonProperty("document_count")
Integer documentCount;
@JsonProperty("embedding_model")
String embeddingModel;
String id;
String language;
String name;
@JsonProperty("parser_config")
PlatformDatasetRequest.ParserConfig parserConfig;
String permission;
@JsonProperty("similarity_threshold")
float similarityThreshold;
String status;
String tenant_id;
Integer token_num;
String update_date;
String update_time;
float vector_similarity_weight;
Integer pagerank;
}

View File

@ -0,0 +1,33 @@
package xyz.playedu.ai.types.response;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@Data
@Slf4j
public class RagResponse {
Integer code;
String message;
JsonNode data;
@SneakyThrows
public <T> T getData(Class<T> tClass){
ObjectMapper objMapper=new ObjectMapper();
T res=objMapper.treeToValue(data,tClass);
return res;
}
@SneakyThrows
public <T> T getData(TypeReference<T> typeReference){
ObjectMapper objMapper=new ObjectMapper();
T res=objMapper.treeToValue(data,typeReference);
return res;
}
}

View File

@ -0,0 +1,17 @@
package xyz.playedu.ai.types.response;
import java.util.List;
import lombok.Data;
@Data
public class UploadDatasetResourceResponse {
List<ResourceStatus> res;
@Data
public static class ResourceStatus {
Integer resource;
boolean success;
}
}

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>xyz.playedu</groupId>
<artifactId>playedu</artifactId>
<version>1.0</version>
</parent>
<artifactId>playedu-api</artifactId>
<version>1.6.24</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-common</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-system</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-course</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-resource</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-exam</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-soft</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.playedu</groupId>
<artifactId>playedu-ai</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.3.3</version>
</plugin>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.11.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
{"namespace": "xyz.playedu.api.avro",
"type": "record",
"name": "AdminUserLoginAvro",
"fields": [
{"name": "id", "type": "string"},
{"name": "adminId", "type": "int"},
{"name": "createdAt", "type": "string"},
{"name": "ip", "type": "string"},
{"name": "loginTimes", "type": "int"}
]
}

Some files were not shown because too many files have changed in this diff Show More