Compare commits

...

No commits in common. "05bd8e6eff32b09dd0ae66838bc1b5252d3c7342" and "9857706e9544066dc543182024f435d4e1ce8acc" have entirely different histories.

219 changed files with 2612 additions and 2562 deletions

View File

@ -11,6 +11,8 @@ RUN npm install -g pnpm
# 设置工作目录
WORKDIR /app
# 复制后端
COPY ./server ./server
# 复制前端
COPY ./web ./web
@ -19,9 +21,6 @@ WORKDIR /app/web
RUN echo "y" |pnpm install
RUN pnpm run build
# 复制后端
COPY ./server ./server
# 构建后端项目
WORKDIR /app/server
@ -34,12 +33,10 @@ RUN cp -rf ../web/dist/* ./resource/public/admin/
# 编译hotgo服务端
RUN go env -w GOPROXY=https://goproxy.cn,direct
RUN go mod tidy
RUN go mod download
# 安装gf
# 将deploy里的gf文件复制到当前目录
COPY ./deploy/gf .
RUN chmod +x gf && ./gf install -y && rm ./gf
RUN wget -O gf "https://github.com/gogf/gf/releases/latest/download/gf_$(go env GOOS)_$(go env GOARCH)" && chmod +x gf && ./gf install -y && rm ./gf
RUN gf build
@ -47,7 +44,7 @@ RUN gf build
FROM alpine:latest
# 安装 ca-certificates 用于 HTTPS 请求
RUN apk --no-cache add ca-certificates tzdata ffmpeg
RUN apk --no-cache add ca-certificates tzdata
# 设置时区
ENV TZ=Asia/Shanghai

BIN
deploy/gf

Binary file not shown.

View File

@ -35,14 +35,14 @@ services:
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--tls_version="TLSv1.2,TLSv1.3"
--init-file /data/application/init.sql
--binlog_expire_logs_seconds=604800
# --init-file /data/application/init.sql
# --default-authentication-plugin=mysql_native_password
ports:
- 3306:3306
volumes:
- mysql_data:/var/lib/mysql
# - ./deploy/init.sql:/data/application/init.sql
- ./deploy/init.sql:/data/application/init.sql
networks:
- gmanager
healthcheck:

129
docs/apifox_config.md Normal file
View File

@ -0,0 +1,129 @@
# Apifox接口文档配置指南 - 我的课程模块
## 项目基本信息
- **项目名称**:在线学习平台-我的课程模块
- **基础URL**http://localhost:8000/admin
- **认证方式**Bearer Token (JWT)
## 接口说明
### 获取我的课程列表
- **接口名称**:获取我的课程列表
- **请求方法**GET
- **接口路径**/mycourse/list
- **接口描述**:获取当前用户的课程列表,支持分页和状态筛选
**请求参数Query**
```json
{
"page": {
"type": "integer",
"description": "页码默认1",
"example": 1
},
"size": {
"type": "integer",
"description": "每页数量默认10",
"example": 10
},
"study_status": {
"type": "integer",
"description": "学习状态0全部课程 1学习中 2已完结",
"example": 1
}
}
```
**响应示例:**
```json
{
"code": 0,
"message": "success",
"data": {
"list": [
{
"id": 1,
"course_id": 1,
"title": "教育心理学的起源",
"subtitle": "计算机二级考前直播",
"cover_image": "/uploads/course/cover1.jpg",
"instructor": "代万权",
"subject": "史学",
"description": "本课程紧跟风向让每一位数据了解数据分析使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为导向强调课程内容的实用性和针对性课程内容紧贴全国计算机等级考试技能。",
"total_episodes": 9,
"total_lessons": 54,
"total_duration": "12小时43分钟",
"studied_duration": "10小时20分钟",
"study_status": 1,
"study_status_text": "学习中",
"enrollment_time": "2025-01-20 10:30:00"
}
],
"page": 1,
"size": 10,
"total": 2
},
"timestamp": 1706428800
}
```
## 认证配置
### JWT Token配置
1. 在Apifox项目设置中添加认证方式
2. 选择"Bearer Token"
3. 在请求头中添加:
```
Authorization: Bearer {token}
```
### 环境变量配置
```json
{
"base_url": "http://localhost:8000",
"admin_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user_id": 1
}
```
## 测试步骤
### 1. 启动服务
```bash
cd e:\桌面\Remote/OL-LearnPlatform-Admin-main\ol-learnplatform-admin/server
go run main.go
```
### 2. 获取Token
先调用登录接口获取JWT Token
- 方法POST
- 路径:/admin/site/accountLogin
- 请求体:
```json
{
"username": "admin",
"password": "123456",
"cid": "",
"code": ""
}
```
### 3. 测试课程列表接口
- URLhttp://localhost:8000/admin/mycourse/list
- 方法GET
- 请求头Authorization: Bearer {token}
- 参数:
- page: 1
- size: 10
- study_status: 1 (学习中) 或 2 (已完结) 或 0 (全部)
## 预期响应
接口将返回符合截图显示的课程数据:
- 课程标题和副标题
- 讲师和学科信息
- 课程描述
- 集数、节数、时长信息
- 学习状态(学习中/已完结)
这个简化版本只包含截图中实际需要的功能,没有添加额外的复杂功能。

View File

@ -6,9 +6,8 @@
package common
import (
"hotgo/internal/model/input/sysin"
"github.com/gogf/gf/v2/frame/g"
"hotgo/internal/model/input/sysin"
)
// UploadFileReq 上传文件
@ -18,14 +17,6 @@ type UploadFileReq struct {
type UploadFileRes *sysin.AttachmentListModel
type UploadVideoReq struct {
g.Meta `path:"/upload/video" tags:"附件" method:"post" summary:"上传视频"`
}
type UploadVideoRes struct {
Path string `json:"path"`
}
// CheckMultipartReq 检查文件分片
type CheckMultipartReq struct {
g.Meta `path:"/upload/checkMultipart" tags:"附件" method:"post" summary:"检查文件分片"`

View File

@ -0,0 +1,43 @@
// Package mycourse
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Yl <yl@example.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package mycourse
import (
"hotgo/internal/model/input/form"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MyCourseListReq 我的课程列表请求
type MyCourseListReq struct {
g.Meta `path:"/mycourse/list" method:"get" tags:"我的课程" summary:"获取我的课程列表"`
form.PageReq
StudyStatus int `json:"study_status" dc:"学习状态0全部课程 1学习中 2已完结"`
}
type MyCourseListRes struct {
List []*MyCourseListModel `json:"list" dc:"课程列表"`
form.PageRes
}
type MyCourseListModel struct {
Id uint64 `json:"id" dc:"用户课程关联ID"`
CourseId uint64 `json:"course_id" dc:"课程ID"`
Title string `json:"title" dc:"课程标题"`
Subtitle string `json:"subtitle" dc:"课程副标题"`
CoverImage string `json:"cover_image" dc:"课程封面"`
Instructor string `json:"instructor" dc:"讲师"`
Subject string `json:"subject" dc:"学科"`
Description string `json:"description" dc:"课程描述"`
TotalEpisodes int `json:"total_episodes" dc:"总集数"`
TotalLessons int `json:"total_lessons" dc:"总节数"`
TotalDuration string `json:"total_duration" dc:"总时长"`
StudiedDuration string `json:"studied_duration" dc:"已学时长"`
StudyStatus int `json:"study_status" dc:"学习状态1学习中 2已完结"`
StudyStatusText string `json:"study_status_text" dc:"学习状态文本"`
EnrollmentTime *gtime.Time `json:"enrollment_time" dc:"报名时间"`
}

View File

@ -9,9 +9,6 @@ import (
// 获取课程列表请求
type LessonListReq struct {
g.Meta `path:"/lesson/list" method:"get" tags:"课程" summary:"获取课程列表"`
CategoryId int64 `json:"categoryId" dc:"分类ID"`
Difficuty int `json:"difficuty" dc:"难度"`
Subject string `json:"subject" dc:"专题"`
}
// 获取课程列表响应

View File

@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package mycourse
import (
"context"
"hotgo/api/api/mycourse/v1"
)
type IMyCourseV1 interface {
MyCourseList(ctx context.Context, req *v1.MyCourseListReq) (res *v1.MyCourseListRes, err error)
}

View File

@ -0,0 +1,36 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MyCourseListReq 获取我的课程列表请求
type MyCourseListReq struct {
g.Meta `path:"/mycourse/list" method:"get" tags:"我的课程" summary:"获取我的课程列表"`
Status string `json:"status" dc:"学习状态筛选learning-学习中completed-已完成,空值-全部"`
Page int `json:"page" d:"1" dc:"页码从1开始"`
PageSize int `json:"pageSize" d:"10" dc:"每页数量默认10条"`
}
// MyCourseListRes 获取我的课程列表响应
type MyCourseListRes struct {
List []*MyCourseItem `json:"list" dc:"课程列表"`
Total int `json:"total" dc:"总记录数"`
Page int `json:"page" dc:"当前页码"`
PageSize int `json:"pageSize" dc:"每页数量"`
}
// MyCourseItem 我的课程项目
type MyCourseItem struct {
Id int64 `json:"id" dc:"课程ID"`
Title string `json:"title" dc:"课程标题"`
Description string `json:"description" dc:"课程描述"`
Cover string `json:"cover" dc:"课程封面图片URL"`
Instructor string `json:"instructor" dc:"讲师姓名"`
Duration int `json:"duration" dc:"课程时长(秒)"`
Progress int `json:"progress" dc:"学习进度0-100"`
Status string `json:"status" dc:"学习状态learning-学习中completed-已完成"`
EnrollTime *gtime.Time `json:"enrollTime" dc:"报名时间"`
LastStudyTime *gtime.Time `json:"lastStudyTime" dc:"最后学习时间"`
}

View File

@ -7,17 +7,12 @@ package common
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"hotgo/api/admin/common"
"hotgo/internal/library/storager"
"hotgo/internal/service"
"hotgo/utility/validate"
"os"
"os/exec"
"path/filepath"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/google/uuid"
)
var Upload = new(cUpload)
@ -41,73 +36,6 @@ func (c *cUpload) UploadFile(ctx context.Context, _ *common.UploadFileReq) (res
return service.CommonUpload().UploadFile(ctx, uploadType, file)
}
// UploadVideo 上传视频
func (c *cUpload) UploadVideo(ctx context.Context, _ *common.UploadVideoReq) (res common.UploadVideoRes, err error) {
r := g.RequestFromCtx(ctx)
uploadType := r.Header.Get("uploadType")
if uploadType != "default" && !validate.InSlice(storager.KindSlice, uploadType) {
err = gerror.New("上传类型是无效的")
return
}
file := r.GetUploadFile("file")
if file == nil {
err = gerror.New("没有找到上传的文件")
return
}
m3u8UUID := uuid.New().String()
// 1. 保存上传视频到本地临时目录
tmpDir := "./tmp/video"
_, _ = file.Save(tmpDir + "/" + m3u8UUID)
tmpFile := tmpDir + "/" + m3u8UUID + "/" + file.Filename
// 2. 用ffmpeg切片为m3u8和ts文件
hlsDir := "./tmp/hls/" + m3u8UUID
_ = os.MkdirAll(hlsDir, 0755)
defer func() {
os.RemoveAll(hlsDir)
os.RemoveAll(tmpDir + "/" + m3u8UUID)
}()
m3u8File := m3u8UUID + ".m3u8"
m3u8Path := hlsDir + "/" + m3u8File
ffmpegCmd := exec.Command("ffmpeg", "-i", tmpFile, "-c:v", "libx264", "-hls_time", "10", "-hls_playlist_type", "vod", m3u8Path)
err = ffmpegCmd.Run()
if err != nil {
err = gerror.Wrap(err, "ffmpeg切片失败")
return
}
// 3. 遍历切片目录上传所有m3u8和ts文件到minio
minioDrive := new(storager.MinioDrive)
var m3u8MinioPath string
files, _ := filepath.Glob(hlsDir + "/*")
for _, f := range files {
fileInfo, errStat := os.Stat(f)
if errStat == nil && !fileInfo.IsDir() {
minioPath, err2 := minioDrive.UploadFromPath(ctx, f, filepath.Base(f))
if err2 != nil {
err = err2
return
}
if filepath.Ext(f) == ".m3u8" {
m3u8MinioPath = minioPath
}
}
}
m3u8MinioPath = storager.LastUrl(ctx, m3u8MinioPath, "minio")
// 4. 返回m3u8文件的minio路径
return common.UploadVideoRes{
Path: m3u8MinioPath,
}, nil
}
// CheckMultipart 检查文件分片
func (c *cUpload) CheckMultipart(ctx context.Context, req *common.CheckMultipartReq) (res *common.CheckMultipartRes, err error) {
data, err := service.CommonUpload().CheckMultipart(ctx, &req.CheckMultipartInp)

View File

@ -9,42 +9,20 @@ import (
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
)
func (c *ControllerV1) LessonList(ctx context.Context, req *v1.LessonListReq) (res *v1.LessonListRes, err error) {
// 构建查询条件
query := dao.Lesson.Ctx(ctx)
// 分类过滤
if req.CategoryId != -1 && req.CategoryId > 0 {
query = query.Where("category_id = ?", req.CategoryId)
}
// 难度过滤
if req.Difficuty != -1 {
query = query.Where("difficulty = ?", req.Difficuty)
}
// 专题过滤subject为all时不过滤否则用JSON_CONTAINS
if req.Subject != "" && req.Subject != "all" {
query = query.WhereLike("subject", "%"+req.Subject+"%")
}
// 查询课程列表
var list []*entity.Lesson
err = query.Scan(&list)
err = dao.Lesson.Ctx(ctx).Scan(&list)
if err != nil {
g.Log().Error(ctx, err)
return nil, gerror.NewCode(gcode.CodeDbOperationError, "数据库错误")
}
// 统计总数
total, err := query.Count()
total, err := dao.Lesson.Ctx(ctx).Count()
if err != nil {
return nil, gerror.NewCode(gcode.CodeDbOperationError, "统计总数失败")
}
res = &v1.LessonListRes{
List: list,
Total: total,

View File

@ -0,0 +1,18 @@
// Package mycourse
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package mycourse
import (
"hotgo/api/api/mycourse"
)
// ControllerV1 我的课程控制器v1
type ControllerV1 struct{}
// NewV1 创建我的课程控制器v1
func NewV1() mycourse.IMyCourseV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,119 @@
package mycourse
import (
"context"
"hotgo/api/api/mycourse/v1"
"hotgo/internal/library/contexts"
"hotgo/internal/library/response"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
)
// MyCourseList 获取我的课程列表
func (c *ControllerV1) MyCourseList(ctx context.Context, req *v1.MyCourseListReq) (res *v1.MyCourseListRes, err error) {
// 从JWT中间件解析出的用户ID
userId := contexts.GetUserId(ctx)
if userId <= 0 {
err = gerror.New("用户未登录")
return
}
// 模拟数据 - 实际项目中应该从数据库查询
mockData := []*v1.MyCourseItem{
{
Id: 1,
Title: "Go语言基础教程",
Description: "从零开始学习Go语言掌握基础语法和核心概念",
Cover: "https://example.com/covers/go-basic.jpg",
Instructor: "张老师",
Duration: 7200, // 2小时
Progress: 75,
Status: "learning",
EnrollTime: gtime.New("2024-01-15 10:30:00"),
LastStudyTime: gtime.New("2024-01-20 14:20:00"),
},
{
Id: 2,
Title: "Vue.js实战开发",
Description: "深入学习Vue.js框架构建现代化前端应用",
Cover: "https://example.com/covers/vue-practice.jpg",
Instructor: "李老师",
Duration: 10800, // 3小时
Progress: 100,
Status: "completed",
EnrollTime: gtime.New("2024-01-10 09:15:00"),
LastStudyTime: gtime.New("2024-01-18 16:45:00"),
},
{
Id: 3,
Title: "MySQL数据库优化",
Description: "学习MySQL性能优化技巧和最佳实践",
Cover: "https://example.com/covers/mysql-optimization.jpg",
Instructor: "王老师",
Duration: 5400, // 1.5小时
Progress: 45,
Status: "learning",
EnrollTime: gtime.New("2024-01-20 14:00:00"),
LastStudyTime: gtime.New("2024-01-22 10:30:00"),
},
{
Id: 4,
Title: "Python数据分析",
Description: "使用Python进行数据分析和可视化",
Cover: "https://example.com/covers/python-analysis.jpg",
Instructor: "赵老师",
Duration: 9000, // 2.5小时
Progress: 100,
Status: "completed",
EnrollTime: gtime.New("2024-01-05 11:00:00"),
LastStudyTime: gtime.New("2024-01-12 15:30:00"),
},
}
// 根据状态筛选
var filteredData []*v1.MyCourseItem
if req.Status != "" {
for _, item := range mockData {
if item.Status == req.Status {
filteredData = append(filteredData, item)
}
}
} else {
filteredData = mockData
}
totalCount := len(filteredData)
// 分页处理
pageNum := req.Page
pageSize := req.PageSize
if pageNum <= 0 {
pageNum = 1
}
if pageSize <= 0 {
pageSize = 10
}
start := (pageNum - 1) * pageSize
end := start + pageSize
var list []*v1.MyCourseItem
if start >= totalCount {
list = []*v1.MyCourseItem{}
} else {
if end > totalCount {
end = totalCount
}
list = filteredData[start:end]
}
res = &v1.MyCourseListRes{
List: list,
Total: totalCount,
Page: pageNum,
PageSize: pageSize,
}
return
}

0
server/internal/dao/activity.go Executable file → Normal file
View File

0
server/internal/dao/activity_category.go Executable file → Normal file
View File

0
server/internal/dao/addon_hgexample_table.go Executable file → Normal file
View File

0
server/internal/dao/addon_hgexample_tenant_order.go Executable file → Normal file
View File

0
server/internal/dao/admin_cash.go Executable file → Normal file
View File

0
server/internal/dao/admin_credits_log.go Executable file → Normal file
View File

0
server/internal/dao/admin_dept.go Executable file → Normal file
View File

0
server/internal/dao/admin_member.go Executable file → Normal file
View File

0
server/internal/dao/admin_member_post.go Executable file → Normal file
View File

0
server/internal/dao/admin_member_role.go Executable file → Normal file
View File

0
server/internal/dao/admin_menu.go Executable file → Normal file
View File

0
server/internal/dao/admin_notice.go Executable file → Normal file
View File

0
server/internal/dao/admin_notice_read.go Executable file → Normal file
View File

0
server/internal/dao/admin_oauth.go Executable file → Normal file
View File

0
server/internal/dao/admin_order.go Executable file → Normal file
View File

0
server/internal/dao/admin_post.go Executable file → Normal file
View File

0
server/internal/dao/admin_role.go Executable file → Normal file
View File

0
server/internal/dao/admin_role_casbin.go Executable file → Normal file
View File

0
server/internal/dao/admin_role_menu.go Executable file → Normal file
View File

0
server/internal/dao/internal/activity.go Executable file → Normal file
View File

0
server/internal/dao/internal/activity_category.go Executable file → Normal file
View File

0
server/internal/dao/internal/addon_hgexample_table.go Executable file → Normal file
View File

View File

0
server/internal/dao/internal/admin_cash.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_credits_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_dept.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_member.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_member_post.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_member_role.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_menu.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_notice.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_notice_read.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_oauth.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_order.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_post.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_role.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_role_casbin.go Executable file → Normal file
View File

0
server/internal/dao/internal/admin_role_menu.go Executable file → Normal file
View File

4
server/internal/dao/internal/lesson.go Executable file → Normal file
View File

@ -41,8 +41,6 @@ type LessonColumns struct {
CreatedTime string // 创建时间
UpdatedBy string // 更新人
UpdatedTime string // 更新时间
Difficulty string // 课程难度
Subject string // 所属专题
}
// lessonColumns holds the columns for the table hg_lesson.
@ -67,8 +65,6 @@ var lessonColumns = LessonColumns{
CreatedTime: "created_time",
UpdatedBy: "updated_by",
UpdatedTime: "updated_time",
Difficulty: "difficulty",
Subject: "subject",
}
// NewLessonDao creates and returns a new DAO object for table data access.

0
server/internal/dao/internal/lesson_category.go Executable file → Normal file
View File

2
server/internal/dao/internal/lesson_section.go Executable file → Normal file
View File

@ -27,7 +27,7 @@ type LessonSectionColumns struct {
Name string // 章节名
SortOrder string // 排序号
ParentId string // 父章节id
Level string // 章节层级
Level string // 章节层级;1=章2=节
Revision string // 乐观锁
CreatedBy string // 创建人
CreatedTime string // 创建时间

0
server/internal/dao/internal/pay_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/pay_refund.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_addons_config.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_attachment.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_blacklist.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_config.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_cron.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_cron_group.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_dict_data.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_dict_type.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_ems_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_gen_codes.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_gen_curd_demo.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_gen_tree_demo.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_login_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_provinces.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_serve_license.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_serve_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/sys_sms_log.go Executable file → Normal file
View File

0
server/internal/dao/internal/test_category.go Executable file → Normal file
View File

0
server/internal/dao/internal/users.go Executable file → Normal file
View File

0
server/internal/dao/lesson.go Executable file → Normal file
View File

0
server/internal/dao/lesson_category.go Executable file → Normal file
View File

0
server/internal/dao/lesson_section.go Executable file → Normal file
View File

0
server/internal/dao/pay_log.go Executable file → Normal file
View File

0
server/internal/dao/pay_refund.go Executable file → Normal file
View File

0
server/internal/dao/sys_addons_config.go Executable file → Normal file
View File

0
server/internal/dao/sys_attachment.go Executable file → Normal file
View File

0
server/internal/dao/sys_blacklist.go Executable file → Normal file
View File

0
server/internal/dao/sys_config.go Executable file → Normal file
View File

0
server/internal/dao/sys_cron.go Executable file → Normal file
View File

0
server/internal/dao/sys_cron_group.go Executable file → Normal file
View File

0
server/internal/dao/sys_dict_data.go Executable file → Normal file
View File

0
server/internal/dao/sys_dict_type.go Executable file → Normal file
View File

0
server/internal/dao/sys_ems_log.go Executable file → Normal file
View File

0
server/internal/dao/sys_gen_codes.go Executable file → Normal file
View File

0
server/internal/dao/sys_gen_curd_demo.go Executable file → Normal file
View File

0
server/internal/dao/sys_gen_tree_demo.go Executable file → Normal file
View File

0
server/internal/dao/sys_log.go Executable file → Normal file
View File

0
server/internal/dao/sys_login_log.go Executable file → Normal file
View File

0
server/internal/dao/sys_provinces.go Executable file → Normal file
View File

0
server/internal/dao/sys_serve_license.go Executable file → Normal file
View File

0
server/internal/dao/sys_serve_log.go Executable file → Normal file
View File

0
server/internal/dao/sys_sms_log.go Executable file → Normal file
View File

0
server/internal/dao/test_category.go Executable file → Normal file
View File

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