Files
admin aac9f5934d feat: 添加多个功能模块和工具脚本
- 新增websocket客户端和服务端实现
- 添加图片压缩工具和快速压缩脚本
- 实现学生信息处理相关API
- 添加MQTT客户端和消息处理功能
- 更新.gitignore忽略更多文件类型
- 添加数据库操作工具和示例
- 实现多个测试脚本和工具类
2026-04-13 14:47:50 +08:00

15 KiB
Raw Permalink Blame History

In [1]:
from requests import get,post
In [ ]:
from api import randomPic,getShi
In [7]:
token="Bearer f8bdd800-c1d5-4865-901c-0b52925462d6"
headers={
    "Authorization":token,
}
ip = "http://192.168.0.209:9999"
In [3]:
from faker import Faker
import random
from datetime import datetime, timedelta
import json

# 初始化Faker,设置为中文环境
fake = Faker('zh_CN')
def getFengjing():
    data = get("https://api.btstu.cn/sjbz/api.php?lx=fengjing&format=json").json()["imgurl"]
    return data

# ===================== 核心编码映射(对应Java枚举类) =====================
# 学段编码:1=小学,2=初中,3=高中
EDUCATION_STAGE_MAP = {
    1: "小学",
    2: "初中",
    3: "高中"
}
# 年级编码:按学段分组,保证逻辑关联
GRADE_MAP = {
    1: [101, 102, 103, 104, 105, 106],  # 小学:一年级到六年级
    2: [201, 202, 203],                  # 初中:初一到初三
    3: [301, 302, 303]                   # 高中:高一到高三
}
# 年级编码对应中文(可选,用于注释/调试)
GRADE_NAME_MAP = {
    101: "一年级", 102: "二年级", 103: "三年级", 104: "四年级", 105: "五年级", 106: "六年级",
    201: "初一", 202: "初二", 203: "初三",
    301: "高一", 302: "高二", 303: "高三"
}
# 学科编码:1=语文,2=数学,3=英语,4=物理,5=化学,6=生物,7=历史,8=地理,9=政治
SUBJECT_MAP = {
    1: "语文",
    2: "数学",
    3: "英语",
    4: "物理",
    5: "化学",
    6: "生物",
    7: "历史",
    8: "地理",
    9: "政治"
}
# 状态编码:0=草稿,1=发布,2=下架(保持不变)
STATUS_LIST = [0, 1, 2]

def generate_video_info(id_num: int) -> dict:
    """
    生成单条视频信息模拟数据(数字编码版)
    :param id_num: 用于生成唯一ID的序号
    :return: 视频信息字典
    """
    # 随机生成时间(近1年内)
    start_date = datetime.now() - timedelta(days=365)
    create_time = fake.date_time_between(start_date=start_date, end_date="now")
    update_time = create_time if random.random() < 0.3 else fake.date_time_between(start_date=create_time, end_date="now")
    
    # 1. 随机选学段编码(1/2/3
    education_stage_code = random.choice(list(EDUCATION_STAGE_MAP.keys()))
    # 2. 根据学段编码选对应年级编码(保证逻辑一致)
    grade_code = random.choice(GRADE_MAP[education_stage_code])
    # 3. 随机选学科编码(1-9
    subject_code = random.choice(list(SUBJECT_MAP.keys()))
    
    # 生成贴合场景的视频标题(用编码对应中文,让标题更易读)
    grade_name = GRADE_NAME_MAP[grade_code]
    subject_name = SUBJECT_MAP[subject_code]
    title_prefix = [f"{grade_name}{subject_name}", f"{subject_name}同步讲解", f"{subject_name}考点解析", f"{grade_name}{subject_name}易错点总结"]
    title = f"{random.choice(title_prefix)}"
    randomPicUrl = getFengjing()
    return {
        "title": title,
        "coverUrl": randomPicUrl,
        "videoUrl": randomPicUrl,
        "categoryId": random.randint(1, 50),  # 分类ID 1-50
        "teacherId": random.randint(1000, 9999),  # 教师ID 1000-9999
        "subject": subject_code,  # 学科编码(1-9
        "grade": grade_code,      # 年级编码(101/102...303
        "educationStage": education_stage_code,  # 学段编码(1/2/3
        "description": getShi()['content'],  # 5句左右的简介
        "duration": random.randint(300, 3600),  # 时长5分钟到1小时(秒)
        "viewCount": random.randint(0, 1000000),  # 播放量0-100万
        "likeCount": random.randint(0, 100000),  # 点赞数0-10万
        "commentCount": random.randint(0, 10000),  # 评论数0-1万
        "status": random.choice(STATUS_LIST),
        "createTime": create_time.strftime("%Y-%m-%d %H:%M:%S"),  # 适配LocalDateTime格式
        "updateTime": update_time.strftime("%Y-%m-%d %H:%M:%S"),
        "videoUploadUrl": f"https://storage.example.com/videos/{fake.uuid4()}.mp4",
    }

def generate_video_data(count: int) -> list:
    """
    生成指定数量的视频模拟数据(数字编码版)
    :param count: 生成数据的条数
    :return: 视频数据列表
    """
    video_list = []
    for i in range(1, count + 1):
        video_list.append(generate_video_info(i))
    return video_list

# if __name__ == "__main__":
#     # 生成10条测试数据(可自行修改数量)
#     video_data = generate_video_data(1)
    
#     # 打印编码映射说明(方便对照)
#     print("===== 编码映射说明 =====")
#     print(f"学段编码:{EDUCATION_STAGE_MAP}")
#     print(f"年级编码:{GRADE_NAME_MAP}")
#     print(f"学科编码:{SUBJECT_MAP}")
#     print("===== 生成的测试数据 =====")
    
#     # 方式1:打印格式化后的JSON数据
#     print(json.dumps(video_data, ensure_ascii=False, indent=4))
    

#     print("\n数据已保存到 video_info_test_data_code.json 文件")
In [ ]:
for i in range(10):
    video_data = generate_video_data(1)
    post(f"{ip}/video/videoInfo",headers=headers,json=video_data[0]).json()
In [ ]:
# post(f"{ip}/api/video",json=video_data[0])
# video_data
In [8]:
get(f"{ip}/admin/team-org/tree",headers=headers).json()
Out [8]:
{'code': 0,
 'msg': None,
 'data': [{'id': '1',
   'parentId': '0',
   'weight': 1,
   'name': '教研组',
   'isLock': True,
   'createTime': None,
   'children': [{'id': '2',
     'parentId': '1',
     'weight': 1,
     'name': '语文组',
     'isLock': True,
     'createTime': None}]},
  {'id': '3',
   'parentId': '0',
   'weight': 1,
   'name': '行政组',
   'isLock': True,
   'createTime': None}],
 'ok': True}
In [ ]:
get(f"{ip}/video/videoChapter/tree",params={
    "subjectId":"15",
    "deptId":0,
},headers=headers).json()
In [ ]:
get(f"{ip}/video/videoCourse/page",headers=headers,params={
    "current":1,
    "size":10,
}).json()
In [ ]:
post(f"{ip}/video/videoInfo",headers=headers,json={
    "coverUrl": "/api/admin/sys-file/oss/file?fileName=d52e43ce433e44da91d248a5aecaf16e.png",
    "description": "测试课程",
    "gradeId": "102",
    "stageId": "1",
    "subjectId": "19",
    "title": "ces",
	"videoUploadUrl": "http://192.168.0.244:9000/s3demo/video/live/522e4c55fc804decafdd0a62e5a1bf74.mp4"
}).text
In [ ]:
In [7]:
post(f"{ip}/video/videoInfo/uploadImg",headers=headers,files={"file":open("1.png","rb")}).json()
Out [7]:
{'code': 0,
 'msg': None,
 'data': 'http://192.168.0.244:9000/s3demo/video/couer/5ac9f3a8061a4eea938272ce0a34bb3b.png',
 'ok': True}
In [12]:
get("http://192.168.0.244:18081/api/common/channel/play?channelId=1",headers={"api-key":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjNlNzk2NDZjNGRiYzQwODM4M2E5ZWVkMDlmMmI4NWFlIn0.eyJqdGkiOiIzRjFJQ2xhRzNscm9zVEdZTUlNanZRIiwiaWF0IjoxNzcyNjA1NzA5LCJuYmYiOjE3NzI2MDU3MDksInN1YiI6ImxvZ2luIiwiYXVkIjoiQXVkaWVuY2UiLCJ1c2VyTmFtZSI6ImFkbWluIiwiYXBpS2V5SWQiOjF9.YxFVDE6czLSqUZtLXnW7mWzkk0EG6lfHgJpykP_eZ_-COve8_tfLLRs_Gqip64EiGrAWTuw98TRToIzF2TKAqOHYD3XtaTlzcrCUWXHT-d70DYz9qniStrXimwIqeyuYKzgyweiGkkbmkn6y6SRrvGkQmGZWltHNLtp_Iy9DToBQr6adA8Jt23mGazZDueewJEofp54FeirB7Uorwb8XXFX-u9X33HbB3RIX5GS3AmOCchWOwhaBH4ZyeZDCJO7W1ziD_UPzzo4GG1GIc7sAnjGO0poGXs3-oCyBJ0gwsapJcSB6n-S8qW_JvIp7qk0GGo8KyBLE2ILRHX6BYULiww"}).text
Out [12]:
'{"code":0,"msg":"成功","data":{"app":"rtp","stream":"34020000001320000002_34020000001320000002","ip":null,"flv":"http://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002.live.flv?originTypeStr=rtp_push","https_flv":"https://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002.live.flv?originTypeStr=rtp_push","ws_flv":"ws://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002.live.flv?originTypeStr=rtp_push","wss_flv":"wss://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002.live.flv?originTypeStr=rtp_push","fmp4":"http://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002.live.mp4?originTypeStr=rtp_push","https_fmp4":"https://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002.live.mp4?originTypeStr=rtp_push","ws_fmp4":"ws://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002.live.mp4?originTypeStr=rtp_push","wss_fmp4":"wss://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002.live.mp4?originTypeStr=rtp_push","hls":"http://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002/hls.m3u8?originTypeStr=rtp_push","https_hls":"https://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002/hls.m3u8?originTypeStr=rtp_push","ws_hls":"ws://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002/hls.m3u8?originTypeStr=rtp_push","wss_hls":"wss://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002/hls.m3u8?originTypeStr=rtp_push","ts":"http://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002.live.ts?originTypeStr=rtp_push","https_ts":"https://192.168.0.244:443/rtp/34020000001320000002_34020000001320000002.live.ts?originTypeStr=rtp_push","ws_ts":"ws://192.168.0.244:85/rtp/34020000001320000002_34020000001320000002.live.ts?originTypeStr=rtp_push","wss_ts":null,"rtmp":"rtmp://192.168.0.244:1935/rtp/34020000001320000002_34020000001320000002?originTypeStr=rtp_push","rtmps":null,"rtsp":"rtsp://192.168.0.244:554/rtp/34020000001320000002_34020000001320000002?originTypeStr=rtp_push","rtsps":null,"rtc":"http://192.168.0.244:85/index/api/webrtc?app=rtp&stream=34020000001320000002_34020000001320000002&type=play&originTypeStr=rtp_push","rtcs":"https://192.168.0.244:443/index/api/webrtc?app=rtp&stream=34020000001320000002_34020000001320000002&type=play&originTypeStr=rtp_push","mediaServerId":"zlmediakit-local","mediaInfo":{"app":"rtp","stream":"34020000001320000002_34020000001320000002","mediaServer":{"id":"zlmediakit-local","ip":"192.168.0.244","hookIp":"127.0.0.1","sdpIp":"192.168.0.244","streamIp":"192.168.0.244","httpPort":85,"httpSSlPort":443,"rtmpPort":1935,"flvPort":0,"flvSSLPort":443,"mp4Port":0,"wsFlvPort":0,"wsFlvSSLPort":443,"rtmpSSlPort":0,"rtpProxyPort":10000,"jttProxyPort":0,"rtspPort":554,"rtspSSLPort":0,"autoConfig":false,"secret":"TWSYFgYJOQWB4ftgeYut8DW4wbs7pQnj","hookAliveInterval":10.0,"rtpEnable":true,"status":true,"rtpPortRange":"40000,45000","sendRtpPortRange":"50000,55000","recordAssistPort":0,"createTime":"2026-01-04 17:59:07","updateTime":"2026-03-04 14:45:29","lastKeepaliveTime":null,"defaultServer":true,"recordDay":7,"recordPath":"","type":"zlm","transcodeSuffix":null,"serverId":"000000"},"schema":"rtsp","readerCount":0,"videoCodec":"H264","width":1920,"height":1080,"fps":null,"loss":null,"audioCodec":null,"audioChannels":null,"audioSampleRate":null,"duration":null,"online":true,"originType":3,"originTypeStr":"rtp_push","originUrl":"rtp://__defaultVhost__/rtp/34020000001320000002_34020000001320000002","aliveSecond":0,"bytesSpeed":0,"callId":"e6e72138756dfd276b888202879d70b1@192.168.0.244","paramMap":{},"serverId":"000000"},"startTime":null,"endTime":null,"duration":null,"downLoadFilePath":null,"transcodeStream":null,"progress":0.0,"key":null}}'
In [ ]: