├── i18n ├── .gitkeep └── zh-CN │ ├── common.toml │ └── app.toml ├── .gitattributes ├── web ├── src │ ├── store │ │ └── index.js │ ├── components │ │ ├── ParentView │ │ │ └── index.vue │ │ ├── IconSelect │ │ │ └── requireIcons.js │ │ ├── Git │ │ │ └── index.vue │ │ ├── SvgIcon │ │ │ ├── svgicon.js │ │ │ └── index.vue │ │ ├── Screenfull │ │ │ └── index.vue │ │ └── iFrame │ │ │ └── index.vue │ ├── assets │ │ ├── logo │ │ │ └── logo.png │ │ ├── 401_images │ │ │ └── 401.gif │ │ ├── 404_images │ │ │ ├── 404.png │ │ │ └── 404_cloud.png │ │ ├── images │ │ │ ├── profile.jpg │ │ │ └── login-background.jpg │ │ ├── icons │ │ │ └── svg │ │ │ │ ├── chart.svg │ │ │ │ ├── size.svg │ │ │ │ ├── link.svg │ │ │ │ ├── guide.svg │ │ │ │ ├── money.svg │ │ │ │ ├── email.svg │ │ │ │ ├── drag.svg │ │ │ │ ├── documentation.svg │ │ │ │ ├── fullscreen.svg │ │ │ │ ├── download.svg │ │ │ │ ├── user.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── excel.svg │ │ │ │ ├── example.svg │ │ │ │ ├── fonts.svg │ │ │ │ ├── exit-fullscreen.svg │ │ │ │ ├── star.svg │ │ │ │ ├── slider.svg │ │ │ │ ├── table.svg │ │ │ │ ├── search.svg │ │ │ │ ├── education.svg │ │ │ │ ├── tab.svg │ │ │ │ ├── message.svg │ │ │ │ ├── switch.svg │ │ │ │ ├── theme.svg │ │ │ │ ├── cookie.svg │ │ │ │ ├── code.svg │ │ │ │ ├── druid.svg │ │ │ │ ├── peoples.svg │ │ │ │ ├── input.svg │ │ │ │ ├── server.svg │ │ │ │ ├── textarea.svg │ │ │ │ ├── time.svg │ │ │ │ ├── edit.svg │ │ │ │ ├── nested.svg │ │ │ │ ├── row.svg │ │ │ │ ├── monitor.svg │ │ │ │ ├── tree-table.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── build.svg │ │ │ │ ├── clock-history.svg │ │ │ │ ├── clipboard.svg │ │ │ │ ├── list.svg │ │ │ │ ├── icon.svg │ │ │ │ ├── international.svg │ │ │ │ ├── question.svg │ │ │ │ ├── wechat.svg │ │ │ │ ├── skill.svg │ │ │ │ ├── people.svg │ │ │ │ └── post.svg │ │ └── styles │ │ │ └── transition.scss │ ├── utils │ │ ├── errorCode.js │ │ ├── auth.js │ │ ├── dynamicTitle.js │ │ └── dict.js │ ├── api │ │ ├── menu.js │ │ ├── monitor │ │ │ ├── server.js │ │ │ ├── cache.js │ │ │ ├── online.js │ │ │ ├── jobLog.js │ │ │ ├── operlog.js │ │ │ └── logininfor.js │ │ ├── live │ │ │ ├── file.js │ │ │ ├── download.js │ │ │ ├── daily.js │ │ │ ├── cookie.js │ │ │ ├── manage.js │ │ │ ├── author.js │ │ │ ├── parse.js │ │ │ └── history.js │ │ ├── system │ │ │ ├── notice.js │ │ │ ├── push.js │ │ │ ├── sys_config.js │ │ │ ├── sys_dict_type.js │ │ │ ├── dict_data.js │ │ │ ├── config.js │ │ │ └── menu.js │ │ └── login.js │ ├── layout │ │ └── components │ │ │ ├── index.js │ │ │ ├── InnerLink │ │ │ └── index.vue │ │ │ ├── IframeToggle │ │ │ └── index.vue │ │ │ ├── Sidebar │ │ │ └── Link.vue │ │ │ └── AppMain.vue │ ├── directive │ │ ├── index.js │ │ └── permission │ │ │ ├── hasRole.js │ │ │ └── hasPermi.js │ ├── views │ │ ├── redirect │ │ │ └── index.vue │ │ └── docs │ │ │ ├── support.vue │ │ │ └── media.vue │ ├── App.vue │ ├── plugins │ │ └── index.js │ └── settings.js ├── public │ └── favicon.ico ├── vite │ └── plugins │ │ ├── setup-extend.js │ │ ├── auto-import.js │ │ ├── svg-icon.js │ │ ├── index.js │ │ └── compression.js ├── .env.development ├── .env.staging ├── .env.production ├── .gitignore └── nginx.conf ├── manifest ├── docker │ ├── entrypoint.sh │ └── docker.sh ├── migrate │ └── 6_parseImages.up.sql └── config │ ├── config_docker.yaml │ └── config.yaml.example ├── resource └── assets │ ├── profile │ └── profile.jpg │ └── screenshots │ ├── index.jpg │ ├── roomAdd.jpg │ ├── mediaParse.jpg │ └── followerTrend.jpg ├── README.md ├── internal ├── pkg │ ├── download │ │ ├── douyin │ │ │ └── douyin_consts.go │ │ └── bilibili │ │ │ └── bilibili_consts.go │ ├── interfaces │ │ └── interfaces.go │ ├── params │ │ └── goja.go │ ├── utils │ │ ├── utils_test.go │ │ ├── context.go │ │ ├── err.go │ │ └── env.go │ ├── message_push │ │ └── gotify │ │ │ └── gotify_test.go │ ├── events │ │ └── events.go │ ├── listeners │ │ └── live_status.go │ ├── media_parser │ │ ├── parser_test.go │ │ ├── douyin │ │ │ └── douyin_consts.go │ │ └── bilibili │ │ │ ├── bilibili_models.go │ │ │ └── bilibili_consts.go │ ├── parser │ │ └── parser.go │ └── lives │ │ └── lives.go ├── app │ ├── live │ │ ├── model │ │ │ ├── room_info.go │ │ │ ├── file_info.go │ │ │ ├── stat_daily.go │ │ │ ├── live_history.go │ │ │ ├── do │ │ │ │ ├── live_history.go │ │ │ │ ├── live_cookie.go │ │ │ │ ├── download_record.go │ │ │ │ ├── room_info.go │ │ │ │ ├── push_channel.go │ │ │ │ ├── push_channel_email.go │ │ │ │ ├── author_info_history.go │ │ │ │ ├── stat_daily.go │ │ │ │ ├── author_info.go │ │ │ │ ├── live_manage.go │ │ │ │ └── media_parse.go │ │ │ └── entity │ │ │ │ ├── live_history.go │ │ │ │ ├── live_cookie.go │ │ │ │ ├── download_record.go │ │ │ │ └── room_info.go │ │ ├── consts │ │ │ └── live_i18n.go │ │ ├── logic │ │ │ └── logic.go │ │ ├── controller │ │ │ ├── file_manage.go │ │ │ └── media_download.go │ │ ├── dao │ │ │ ├── room_info.go │ │ │ ├── stat_daily.go │ │ │ ├── author_info.go │ │ │ ├── live_cookie.go │ │ │ ├── live_manage.go │ │ │ ├── media_parse.go │ │ │ ├── live_history.go │ │ │ ├── push_channel.go │ │ │ ├── download_record.go │ │ │ ├── push_channel_email.go │ │ │ └── author_info_history.go │ │ └── service │ │ │ └── file_manage.go │ ├── admin │ │ ├── consts │ │ │ ├── consts.go │ │ │ ├── consts_routes.go │ │ │ └── system_i18n.go │ │ ├── model │ │ │ ├── sys_push.go │ │ │ ├── entity │ │ │ │ ├── sys_role_menu.go │ │ │ │ ├── sys_user_role.go │ │ │ │ ├── push_message_log.go │ │ │ │ ├── push_channel.go │ │ │ │ ├── sys_job_log.go │ │ │ │ └── sys_dict_type.go │ │ │ ├── do │ │ │ │ ├── sys_role_menu.go │ │ │ │ ├── sys_user_role.go │ │ │ │ ├── push_message_log.go │ │ │ │ ├── push_channel.go │ │ │ │ ├── sys_job_log.go │ │ │ │ ├── sys_dict_type.go │ │ │ │ ├── push_channel_email.go │ │ │ │ ├── sys_config.go │ │ │ │ ├── sys_logininfor.go │ │ │ │ ├── sys_notice.go │ │ │ │ ├── stat_daily.go │ │ │ │ ├── push_channel_web.go │ │ │ │ ├── sys_dict_data.go │ │ │ │ ├── sys_job.go │ │ │ │ └── sys_role.go │ │ │ └── sys_role.go │ │ ├── dao │ │ │ ├── sys_job.go │ │ │ ├── sys_menu.go │ │ │ ├── sys_role.go │ │ │ ├── sys_user.go │ │ │ ├── sys_config.go │ │ │ ├── sys_job_log.go │ │ │ ├── sys_notice.go │ │ │ ├── push_channel.go │ │ │ ├── sys_dict_data.go │ │ │ ├── sys_dict_type.go │ │ │ ├── sys_role_menu.go │ │ │ ├── sys_user_role.go │ │ │ ├── sys_logininfor.go │ │ │ ├── push_channel_web.go │ │ │ ├── push_message_log.go │ │ │ └── push_channel_email.go │ │ ├── logic │ │ │ └── logic.go │ │ └── service │ │ │ └── sys_role_menu.go │ ├── common │ │ ├── consts │ │ │ ├── consts_gtoken.go │ │ │ ├── consts.go │ │ │ ├── consts_i18n.go │ │ │ ├── consts_system.go │ │ │ └── consts_openapi.go │ │ ├── model │ │ │ ├── context.go │ │ │ └── redis.go │ │ ├── logic │ │ │ └── logic.go │ │ ├── service │ │ │ ├── captcha.go │ │ │ ├── middleware.go │ │ │ └── session.go │ │ └── controller │ │ │ └── captcha.go │ └── monitor │ │ ├── controller │ │ ├── server.go │ │ └── oper_log.go │ │ ├── logic │ │ └── logic.go │ │ ├── model │ │ ├── do │ │ │ ├── sys_job_log.go │ │ │ └── sys_job.go │ │ ├── server_info.go │ │ └── entity │ │ │ └── sys_job_log.go │ │ ├── dao │ │ ├── sys_job.go │ │ ├── sys_job_log.go │ │ └── sys_oper_log.go │ │ └── service │ │ ├── server.go │ │ └── sys_oper_log.go ├── cmd │ ├── cmd_rod.go │ ├── cmd_job.go │ └── cmd_init.go └── drivers │ ├── drivers.go │ └── mysql.go ├── .dockerignore ├── api └── v1 │ ├── common │ └── req.go │ ├── monitor │ ├── server.go │ └── oper_log.go │ ├── tool │ └── captcha.go │ └── live │ ├── file_manage.go │ └── media_download.go ├── .gitignore ├── main.go ├── docker-compose.yaml.example ├── CHANGELOG.md ├── Makefile ├── LICENSE └── hack └── config.yaml.example /i18n/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-language=GO -------------------------------------------------------------------------------- /web/src/store/index.js: -------------------------------------------------------------------------------- 1 | const store = createPinia() 2 | 3 | export default store -------------------------------------------------------------------------------- /web/src/components/ParentView/index.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /manifest/docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec sh -c /LiveDog/main & nginx -g 'daemon off;' 4 | -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/public/favicon.ico -------------------------------------------------------------------------------- /web/src/assets/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/src/assets/logo/logo.png -------------------------------------------------------------------------------- /manifest/docker/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This shell is executed before docker build. 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /web/src/assets/401_images/401.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/src/assets/401_images/401.gif -------------------------------------------------------------------------------- /web/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/src/assets/404_images/404.png -------------------------------------------------------------------------------- /web/src/assets/images/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/src/assets/images/profile.jpg -------------------------------------------------------------------------------- /resource/assets/profile/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/resource/assets/profile/profile.jpg -------------------------------------------------------------------------------- /resource/assets/screenshots/index.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/resource/assets/screenshots/index.jpg -------------------------------------------------------------------------------- /resource/assets/screenshots/roomAdd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/resource/assets/screenshots/roomAdd.jpg -------------------------------------------------------------------------------- /web/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

Live Dog

3 | 项目已迁移至新仓库: [Gowlive](https://github.com/shichen437/Gowlive) 4 |
-------------------------------------------------------------------------------- /resource/assets/screenshots/mediaParse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/resource/assets/screenshots/mediaParse.jpg -------------------------------------------------------------------------------- /web/src/assets/images/login-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/web/src/assets/images/login-background.jpg -------------------------------------------------------------------------------- /resource/assets/screenshots/followerTrend.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shichen437/live-dog/HEAD/resource/assets/screenshots/followerTrend.jpg -------------------------------------------------------------------------------- /web/src/utils/errorCode.js: -------------------------------------------------------------------------------- 1 | export default { 2 | '401': '认证失败,无法访问系统资源', 3 | '403': '当前操作没有权限', 4 | '404': '访问资源不存在', 5 | 'default': '系统未知错误,请反馈给管理员' 6 | } 7 | -------------------------------------------------------------------------------- /web/vite/plugins/setup-extend.js: -------------------------------------------------------------------------------- 1 | import setupExtend from 'vite-plugin-vue-setup-extend' 2 | 3 | export default function createSetupExtend() { 4 | return setupExtend() 5 | } 6 | -------------------------------------------------------------------------------- /internal/pkg/download/douyin/douyin_consts.go: -------------------------------------------------------------------------------- 1 | package douyin 2 | 3 | var ( 4 | platform = "douyin" 5 | randomStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 6 | ) 7 | -------------------------------------------------------------------------------- /web/src/api/menu.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 获取路由 4 | export const getRouters = () => { 5 | return request({ 6 | url: '/getRouters', 7 | method: 'get' 8 | }) 9 | } -------------------------------------------------------------------------------- /web/src/assets/icons/svg/chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/api/monitor/server.js: -------------------------------------------------------------------------------- 1 | import request from "@/utils/request"; 2 | 3 | // 获取服务信息 4 | export function getServer() { 5 | return request({ 6 | url: "/monitor/server", 7 | method: "get", 8 | }); 9 | } -------------------------------------------------------------------------------- /internal/pkg/interfaces/interfaces.go: -------------------------------------------------------------------------------- 1 | package interfaces 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type Module interface { 8 | Start(ctx context.Context) error 9 | Close(ctx context.Context) 10 | } 11 | -------------------------------------------------------------------------------- /web/.env.development: -------------------------------------------------------------------------------- 1 | # 页面标题 2 | VITE_APP_TITLE = LiveDog 监控平台 3 | 4 | # 开发环境配置 5 | VITE_APP_ENV = 'development' 6 | 7 | # LiveDog管理系统/开发环境 8 | VITE_APP_BASE_API = '/dev-api' 9 | 10 | VITE_APP_VERSION = '0.0.9' -------------------------------------------------------------------------------- /web/src/api/monitor/cache.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 查询缓存详细 4 | export function getCache() { 5 | return request({ 6 | url: '/monitor/cache', 7 | method: 'get' 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /internal/pkg/params/goja.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/dop251/goja" 7 | ) 8 | 9 | var vmPool = sync.Pool{ 10 | New: func() interface{} { 11 | return goja.New() 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/size.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/app/live/model/room_info.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "github.com/shichen437/live-dog/internal/app/live/model/entity" 4 | 5 | type RoomInfo struct { 6 | *entity.RoomInfo 7 | Recording bool `json:"recording" description:"录制状态"` 8 | } 9 | -------------------------------------------------------------------------------- /web/src/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as AppMain } from './AppMain' 2 | export { default as Navbar } from './Navbar' 3 | export { default as Settings } from './Settings' 4 | export { default as TagsView } from './TagsView/index.vue' 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .hgignore.swp 3 | .project 4 | .orig 5 | .swp 6 | .idea/ 7 | .settings/ 8 | .vscode/ 9 | bin/ 10 | **/.DS_Store 11 | resource/ 12 | Makefile 13 | README.md 14 | web/node_modules 15 | web/src 16 | manifest/config/config.yaml -------------------------------------------------------------------------------- /internal/app/live/model/file_info.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type FileInfo struct { 4 | Filename string `json:"filename"` 5 | Size int64 `json:"size"` 6 | IsFolder bool `json:"isFolder"` 7 | LastModified int64 `json:"lastModified"` 8 | } 9 | -------------------------------------------------------------------------------- /api/v1/common/req.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type PageReq struct { 4 | PageNum int `p:"pageNum"` 5 | PageSize int `p:"pageSize"` 6 | OrderBy string `p:"orderBy"` //排序方式 7 | Params map[string]string `p:"params"` //时间范围 8 | } 9 | -------------------------------------------------------------------------------- /internal/app/live/model/stat_daily.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "github.com/shichen437/live-dog/internal/app/live/model/entity" 4 | 5 | type StatDailyRes struct { 6 | *entity.StatDaily 7 | } 8 | 9 | type StatDailyList struct { 10 | *entity.StatDaily 11 | } 12 | -------------------------------------------------------------------------------- /web/.env.staging: -------------------------------------------------------------------------------- 1 | # 页面标题 2 | VITE_APP_TITLE = LiveDog 监控平台 3 | 4 | # 生产环境配置 5 | VITE_APP_ENV = 'staging' 6 | 7 | # LiveDog管理系统/生产环境 8 | VITE_APP_BASE_API = '/stage-api' 9 | 10 | # 是否在打包时开启压缩,支持 gzip 和 brotli 11 | VITE_BUILD_COMPRESS = gzip 12 | 13 | VITE_APP_VERSION = '0.0.9' -------------------------------------------------------------------------------- /internal/app/admin/consts/consts.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | SysConfigStatusOk = "0" 5 | SysConfigStatusNo = "1" 6 | 7 | SysDictTypeStatusOk = "0" 8 | SysDictTypeStatusNo = "1" 9 | ) 10 | 11 | var PushChannelType = []string{"email", "gotify", "webhook", "bark"} 12 | -------------------------------------------------------------------------------- /web/.env.production: -------------------------------------------------------------------------------- 1 | # 页面标题 2 | VITE_APP_TITLE = LiveDog 监控平台 3 | 4 | # 生产环境配置 5 | VITE_APP_ENV = 'production' 6 | 7 | # LiveDog管理系统/生产环境 8 | VITE_APP_BASE_API = '/prod-api' 9 | 10 | # 是否在打包时开启压缩,支持 gzip 和 brotli 11 | VITE_BUILD_COMPRESS = gzip 12 | 13 | VITE_APP_VERSION = '0.0.9' -------------------------------------------------------------------------------- /web/src/components/IconSelect/requireIcons.js: -------------------------------------------------------------------------------- 1 | let icons = [] 2 | const modules = import.meta.glob('./../../assets/icons/svg/*.svg'); 3 | for (const path in modules) { 4 | const p = path.split('assets/icons/svg/')[1].split('.svg')[0]; 5 | icons.push(p); 6 | } 7 | 8 | export default icons -------------------------------------------------------------------------------- /manifest/migrate/6_parseImages.up.sql: -------------------------------------------------------------------------------- 1 | SET FOREIGN_KEY_CHECKS = 0; 2 | 3 | ALTER TABLE `media_parse` 4 | ADD COLUMN `images_url` text NULL COMMENT '图集 url' AFTER `music_cover_url`, 5 | ADD COLUMN `images_cover_url` varchar(1000) NULL COMMENT '图集封面 url' AFTER `images_url`; 6 | 7 | SET FOREIGN_KEY_CHECKS = 1; -------------------------------------------------------------------------------- /web/src/assets/icons/svg/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/components/Git/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /internal/app/common/consts/consts_gtoken.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | LocalCache = 1 5 | // 是否支持多端登录 6 | MultiLogin = true 7 | TokenType = "Bearer" 8 | ServerName = "LiveDog Monitor Platform" 9 | //超时时间 10 * 24 * 60 * 60 10 | Timeout = 86400 11 | GTokenAdminPrefix = "SYS-USER-" 12 | ) 13 | -------------------------------------------------------------------------------- /internal/pkg/download/bilibili/bilibili_consts.go: -------------------------------------------------------------------------------- 1 | package bilibili 2 | 3 | var ( 4 | platform = "bilibili" 5 | randomStr = "abcdefghijklmnopqrstuvwxyz0123456789" 6 | userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.51" 7 | ) 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .project 3 | .settings/ 4 | .swp 5 | .vscode/ 6 | **/.DS_Store 7 | bin/ 8 | hack/config.yaml 9 | manifest/output/ 10 | manifest/config/config.yaml 11 | main 12 | main.exe 13 | main.exe~ 14 | output/ 15 | resource/log/ 16 | **/*/resource/log/ 17 | resource/file/ 18 | temp/ 19 | docker-compose.yaml 20 | -------------------------------------------------------------------------------- /web/vite/plugins/auto-import.js: -------------------------------------------------------------------------------- 1 | import autoImport from 'unplugin-auto-import/vite' 2 | 3 | export default function createAutoImport() { 4 | return autoImport({ 5 | imports: [ 6 | 'vue', 7 | 'vue-router', 8 | 'pinia' 9 | ], 10 | dts: false 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /web/src/directive/index.js: -------------------------------------------------------------------------------- 1 | import hasRole from './permission/hasRole' 2 | import hasPermi from './permission/hasPermi' 3 | import copyText from './common/copyText' 4 | 5 | export default function directive(app){ 6 | app.directive('hasRole', hasRole) 7 | app.directive('hasPermi', hasPermi) 8 | app.directive('copyText', copyText) 9 | } -------------------------------------------------------------------------------- /web/src/assets/icons/svg/guide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/cmd/cmd_rod.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/gogf/gf/v2/frame/g" 5 | "github.com/gogf/gf/v2/os/gctx" 6 | "github.com/shichen437/live-dog/internal/pkg/utils" 7 | ) 8 | 9 | func InitBrowserPool() { 10 | g.Log().Info(gctx.New(), "初始化浏览器池") 11 | utils.InitBrowserPool(1) 12 | g.Log().Info(gctx.New(), "初始化浏览器池完成") 13 | } 14 | -------------------------------------------------------------------------------- /web/src/components/SvgIcon/svgicon.js: -------------------------------------------------------------------------------- 1 | import * as components from '@element-plus/icons-vue' 2 | 3 | export default { 4 | install: (app) => { 5 | for (const key in components) { 6 | const componentConfig = components[key]; 7 | app.component(componentConfig.name, componentConfig); 8 | } 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /internal/pkg/utils/utils_test.go: -------------------------------------------------------------------------------- 1 | package utils_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gogf/gf/os/gctx" 7 | "github.com/gogf/gf/v2/frame/g" 8 | "github.com/shichen437/live-dog/internal/pkg/utils" 9 | ) 10 | 11 | func TestPush(t *testing.T) { 12 | ok := utils.IsTimeRange("21:00", "00:00") 13 | g.Log().Info(gctx.New(), ok) 14 | } 15 | -------------------------------------------------------------------------------- /web/src/utils/auth.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const TokenKey = 'Admin-Token' 4 | 5 | export function getToken() { 6 | return Cookies.get(TokenKey) 7 | } 8 | 9 | export function setToken(token) { 10 | return Cookies.set(TokenKey, token) 11 | } 12 | 13 | export function removeToken() { 14 | return Cookies.remove(TokenKey) 15 | } 16 | -------------------------------------------------------------------------------- /web/src/views/redirect/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/app/live/consts/live_i18n.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | MonitorTimeEmpty = `{#monitor-time-empty}` 5 | MonitorTimeSame = `{#monitor-time-same}` 6 | MonitorTimeShort = `{#monitor-time-short}` 7 | RoomUrlEmpty = `{#room-url-empty}` 8 | RoomUrlParseF = `{#room-url-parse-failed}` 9 | RoomUrlNotAllowed = `{#room-url-not-allowed}` 10 | ) 11 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | **/*.log 8 | 9 | tests/**/coverage/ 10 | tests/e2e/reports 11 | selenium-debug.log 12 | 13 | # Editor directories and files 14 | .idea 15 | .vscode 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | *.local 21 | 22 | package-lock.json 23 | yarn.lock 24 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/drag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/vite/plugins/svg-icon.js: -------------------------------------------------------------------------------- 1 | import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' 2 | import path from 'path' 3 | 4 | export default function createSvgIcon(isBuild) { 5 | return createSvgIconsPlugin({ 6 | iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')], 7 | symbolId: 'icon-[dir]-[name]', 8 | svgoOptions: isBuild 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /web/src/api/live/file.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function listFile(query) { 4 | return request({ 5 | url: '/file/manage/list', 6 | method: 'get', 7 | params: query 8 | }) 9 | } 10 | 11 | export function delFile(query) { 12 | return request({ 13 | url: '/file/manage', 14 | method: 'delete', 15 | params: query 16 | }) 17 | } -------------------------------------------------------------------------------- /web/src/components/Screenfull/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /i18n/zh-CN/common.toml: -------------------------------------------------------------------------------- 1 | err-login-fail-msg = "用户名或密码错误" 2 | err-login-code-fail-msg = "验证码错误" 3 | err-auth-fail-msg = "没有授权或请求超时" 4 | success = "操作成功" 5 | 6 | add-failed = "数据添加失败" 7 | delete-failed = "数据删除失败" 8 | get-failed = "数据获取失败" 9 | list-failed = "数据列表获取失败" 10 | update-failed = "数据修改失败" 11 | 12 | data-code-empty = "数据编码不能为空" 13 | data-not-found = "数据不存在" 14 | id-empty = "数据ID不能为空" 15 | -------------------------------------------------------------------------------- /internal/app/common/model/context.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/gogf/gf/v2/net/ghttp" 5 | ) 6 | 7 | type Context struct { 8 | Session *ghttp.Session // Session in context. 9 | User *ContextUser // User in context. 10 | } 11 | 12 | type ContextUser struct { 13 | Id int64 // User ID. 14 | UserName string // User UserName. 15 | Nickname string // User nickname. 16 | } 17 | -------------------------------------------------------------------------------- /web/src/api/monitor/online.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 查询在线用户列表 4 | export function list(query) { 5 | return request({ 6 | url: '/monitor/online/list', 7 | method: 'get', 8 | params: query 9 | }) 10 | } 11 | 12 | // 强退用户 13 | export function forceLogout(tokenId) { 14 | return request({ 15 | url: '/monitor/online/' + tokenId, 16 | method: 'delete' 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /web/src/api/monitor/jobLog.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 查询调度日志列表 4 | export function listJobLog(query) { 5 | return request({ 6 | url: '/monitor/jobLog/list', 7 | method: 'get', 8 | params: query 9 | }) 10 | } 11 | 12 | // 删除调度日志 13 | export function delJobLog(jobLogId) { 14 | return request({ 15 | url: '/monitor/jobLog/' + jobLogId, 16 | method: 'delete' 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /internal/pkg/message_push/gotify/gotify_test.go: -------------------------------------------------------------------------------- 1 | package gotify_test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/gogf/gf/v2/frame/g" 8 | ) 9 | 10 | func TestPush(t *testing.T) { 11 | url := "http://192.168.3.16:36073/message?token=AqgRo24hjfzUqtp" 12 | c := g.Client() 13 | data := g.Map{ 14 | "title": "开播通知", 15 | "message": "你关注的主播已开播", 16 | } 17 | c.Post(context.Background(), url, data) 18 | } 19 | -------------------------------------------------------------------------------- /internal/app/admin/model/sys_push.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/shichen437/live-dog/internal/app/admin/model/entity" 5 | 6 | "github.com/gogf/gf/v2/frame/g" 7 | ) 8 | 9 | type PushChannel struct { 10 | g.Meta `orm:"table:push_channel" desc:"消息推送渠道"` 11 | *entity.PushChannel 12 | Email *entity.PushChannelEmail `json:"email" desc:"邮箱信息"` 13 | Web *entity.PushChannelWeb `json:"web" desc:"web 信息"` 14 | } 15 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/documentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/fullscreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/drivers/drivers.go: -------------------------------------------------------------------------------- 1 | package drivers 2 | 3 | import ( 4 | "github.com/shichen437/live-dog/internal/pkg/utils" 5 | 6 | "github.com/gogf/gf/v2/frame/g" 7 | "github.com/gogf/gf/v2/os/gctx" 8 | ) 9 | 10 | func init() { 11 | if !utils.IsDocker() { 12 | return 13 | } 14 | g.Log().Info(gctx.GetInitCtx(), "init docker environment") 15 | InitDockerDatabaseConfig() 16 | g.Log().Info(gctx.GetInitCtx(), "init docker environment finished") 17 | } 18 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/excel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "github.com/shichen437/live-dog/internal/drivers" 5 | 6 | _ "github.com/gogf/gf/contrib/drivers/mysql/v2" 7 | "github.com/gogf/gf/v2/frame/g" 8 | "github.com/gogf/gf/v2/os/gctx" 9 | 10 | "github.com/shichen437/live-dog/internal/cmd" 11 | ) 12 | 13 | func main() { 14 | if err := cmd.Migrate(); err != nil { 15 | g.Log().Fatalf(gctx.GetInitCtx(), "Start Failed: %+v", err) 16 | } 17 | cmd.Main.Run(gctx.GetInitCtx()) 18 | } 19 | -------------------------------------------------------------------------------- /web/src/utils/dynamicTitle.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | import defaultSettings from '@/settings' 3 | import useSettingsStore from '@/store/modules/settings' 4 | 5 | /** 6 | * 动态修改标题 7 | */ 8 | export function useDynamicTitle() { 9 | const settingsStore = useSettingsStore(); 10 | if (settingsStore.dynamicTitle) { 11 | document.title = settingsStore.title + ' - ' + defaultSettings.title; 12 | } else { 13 | document.title = defaultSettings.title; 14 | } 15 | } -------------------------------------------------------------------------------- /internal/app/live/model/live_history.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "github.com/gogf/gf/os/gtime" 4 | 5 | type LiveHistory struct { 6 | Id int64 `json:"id"` 7 | LiveId int64 `json:"liveId" description:"直播ID"` 8 | Anchor string `json:"anchor" description:"主播名称"` 9 | StartTime *gtime.Time `json:"startTime" description:"开始时间"` 10 | EndTime *gtime.Time `json:"endTime" description:"结束时间"` 11 | Duration float64 `json:"duration" description:"时长"` 12 | } 13 | -------------------------------------------------------------------------------- /internal/drivers/mysql.go: -------------------------------------------------------------------------------- 1 | package drivers 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/shichen437/live-dog/internal/pkg/utils" 7 | 8 | "github.com/gogf/gf/v2/database/gdb" 9 | ) 10 | 11 | func InitDockerDatabaseConfig() { 12 | n := gdb.ConfigNode{} 13 | n.Link = utils.DbLink 14 | n.Debug = false 15 | n.DryRun = false 16 | n.MaxIdleConnCount = 10 17 | n.MaxOpenConnCount = 100 18 | n.MaxConnLifeTime = time.Duration(30) * time.Second 19 | gdb.AddConfigNode("default", n) 20 | } 21 | -------------------------------------------------------------------------------- /internal/pkg/events/events.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type Event struct { 4 | Type EventType 5 | Object interface{} 6 | } 7 | 8 | type EventType string 9 | 10 | func NewEvent(eventType EventType, object interface{}) *Event { 11 | return &Event{eventType, object} 12 | } 13 | 14 | type EventHandler func(event *Event) 15 | 16 | type EventListener struct { 17 | Handler EventHandler 18 | } 19 | 20 | func NewEventListener(handler EventHandler) *EventListener { 21 | return &EventListener{handler} 22 | } 23 | -------------------------------------------------------------------------------- /internal/pkg/listeners/live_status.go: -------------------------------------------------------------------------------- 1 | package listeners 2 | 3 | const ( 4 | statusToTrueEvt uint8 = 1 << iota 5 | statusToFalseEvt 6 | nameChangedEvt 7 | ) 8 | 9 | type status struct { 10 | roomName string 11 | anchor string 12 | roomStatus bool 13 | } 14 | 15 | func (s status) Diff(that status) (res uint8) { 16 | if !s.roomStatus && that.roomStatus { 17 | res |= statusToTrueEvt 18 | } 19 | if s.roomStatus && !that.roomStatus { 20 | res |= statusToFalseEvt 21 | } 22 | return res 23 | } 24 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/app/common/model/redis.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type RedisConfig struct { 4 | Address string `json:"address"` 5 | Db int `json:"db"` 6 | IdleTimeout string `json:"idleTimeout"` 7 | MaxConnLifetime string `json:"maxConnLifetime"` 8 | WaitTimeout string `json:"waitTimeout"` 9 | DialTimeout string `json:"dialTimeout"` 10 | ReadTimeout string `json:"readTimeout"` 11 | WriteTimeout string `json:"writeTimeout"` 12 | MaxActive int `json:"maxActive"` 13 | } 14 | -------------------------------------------------------------------------------- /internal/app/monitor/controller/server.go: -------------------------------------------------------------------------------- 1 | package monitor 2 | 3 | import ( 4 | "context" 5 | 6 | v1 "github.com/shichen437/live-dog/api/v1/monitor" 7 | "github.com/shichen437/live-dog/internal/app/monitor/service" 8 | ) 9 | 10 | type serverController struct { 11 | } 12 | 13 | var ServerInfo = serverController{} 14 | 15 | func (o *serverController) GetServerInfo(ctx context.Context, req *v1.GetServerInfoReq) (res *v1.GetServerInfoRes, err error) { 16 | return service.ServerInfo().GetServerInfo(ctx, req) 17 | } 18 | -------------------------------------------------------------------------------- /docker-compose.yaml.example: -------------------------------------------------------------------------------- 1 | services: 2 | live-dog: 3 | container_name: live-dog 4 | image: shichen437/live-dog:latest 5 | restart: always 6 | ports: 7 | - '9876:9876' 8 | volumes: 9 | - /your_home_folder/upload:/LiveDog/upload 10 | - /your_home_folder/output:/LiveDog/video 11 | environment: 12 | - DATABASE_DEFAULT_LINK=mysql:root:123456@tcp(127.0.0.1:3306)/db_name?charset=utf8mb4&parseTime=true&loc=Local 13 | - PROJECT_SM4KEY=abcdefghijklmnopqrstuvwxyz123456 # SM4加密密钥, 32位字符 14 | -------------------------------------------------------------------------------- /internal/app/monitor/controller/oper_log.go: -------------------------------------------------------------------------------- 1 | package monitor 2 | 3 | import ( 4 | "context" 5 | 6 | v1 "github.com/shichen437/live-dog/api/v1/monitor" 7 | "github.com/shichen437/live-dog/internal/app/monitor/service" 8 | ) 9 | 10 | type operLogController struct { 11 | } 12 | 13 | var OperLog = operLogController{} 14 | 15 | func (o *operLogController) GetOperLogList(ctx context.Context, req *v1.GetOperLogListReq) (res *v1.GetOperLogListRes, err error) { 16 | res, err = service.SysOperLog().List(ctx, req) 17 | return 18 | } 19 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/fonts.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /internal/app/monitor/logic/logic.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ========================================================================== 4 | 5 | package logic 6 | 7 | import ( 8 | _ "github.com/shichen437/live-dog/internal/app/monitor/logic/server" 9 | _ "github.com/shichen437/live-dog/internal/app/monitor/logic/sys_job" 10 | _ "github.com/shichen437/live-dog/internal/app/monitor/logic/sys_oper_log" 11 | ) 12 | -------------------------------------------------------------------------------- /internal/pkg/utils/context.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/shichen437/live-dog/internal/pkg/lives" 7 | 8 | "github.com/gogf/gf/v2/os/gctx" 9 | ) 10 | 11 | type key int 12 | 13 | const ( 14 | Key key = 102723 15 | ) 16 | 17 | func GetGlobal(context context.Context) *lives.GLiveModel { 18 | if glm, ok := context.Value(Key).(*lives.GLiveModel); ok { 19 | return glm 20 | } 21 | return nil 22 | } 23 | 24 | func GetGlobalDefault() *lives.GLiveModel { 25 | return GetGlobal(gctx.GetInitCtx()) 26 | } 27 | -------------------------------------------------------------------------------- /manifest/config/config_docker.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | address: ":3290" 3 | openapiPath: "/api.json" 4 | swaggerPath: "/swagger" 5 | dumpRouterMap: true 6 | routeOverWrite: true 7 | accessLogEnabled: true 8 | 9 | project: 10 | platform: "docker" 11 | language: "zh-CN" 12 | 13 | logger: 14 | path: "resource/log/system/" 15 | prefix: "" 16 | file: "{Y-m-d}.log" 17 | level: "all" 18 | stdout: true 19 | 20 | # Database. 21 | database: 22 | logger: 23 | level: "all" 24 | stdout: true 25 | Path: "resource/log/sql" 26 | 27 | -------------------------------------------------------------------------------- /internal/app/admin/model/entity/sys_role_menu.go: -------------------------------------------------------------------------------- 1 | // ================================================================================= 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ================================================================================= 4 | 5 | package entity 6 | 7 | // SysRoleMenu is the golang structure for table sys_role_menu. 8 | type SysRoleMenu struct { 9 | RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` 10 | MenuId int64 `json:"menuId" orm:"menu_id" description:"菜单ID"` 11 | } 12 | -------------------------------------------------------------------------------- /internal/app/admin/model/entity/sys_user_role.go: -------------------------------------------------------------------------------- 1 | // ================================================================================= 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ================================================================================= 4 | 5 | package entity 6 | 7 | // SysUserRole is the golang structure for table sys_user_role. 8 | type SysUserRole struct { 9 | UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` 10 | RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` 11 | } 12 | -------------------------------------------------------------------------------- /internal/app/common/consts/consts.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | ContextKey = "ContextKey" 5 | ProAdmin = "admin" 6 | ProAdminId int64 = 1 7 | ProAdminRoleId int64 = 1 8 | 9 | AvatarPrefix = "/avatar/" 10 | 11 | //ctx 12 | CtxAdminId = "CtxAdminId" 13 | CtxAdminName = "CtxAdminName" 14 | CacheKeyPermsUrl = "user:perms:url:" 15 | 16 | //page 17 | PageSize = 10 18 | 19 | //采用restfull 20 | ListMethod = "Get" 21 | AddMethod = "Post" 22 | UpdateMethod = "Put" 23 | DeleteMethod = "Delete" 24 | ) 25 | -------------------------------------------------------------------------------- /web/src/api/live/download.js: -------------------------------------------------------------------------------- 1 | import request from "@/utils/request"; 2 | 3 | // 查询角色列表 4 | export function listDownload(query) { 5 | return request({ 6 | url: "/media/download/list", 7 | method: "get", 8 | params: query, 9 | }); 10 | } 11 | 12 | export function listDownloadFromCache() { 13 | return request({ 14 | url: "/media/download/listCache", 15 | method: "get", 16 | }); 17 | } 18 | 19 | export function delRecord(id) { 20 | return request({ 21 | url: "/media/download/" + id, 22 | method: "delete", 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /web/src/layout/components/InnerLink/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 25 | -------------------------------------------------------------------------------- /web/src/plugins/index.js: -------------------------------------------------------------------------------- 1 | import tab from './tab' 2 | import auth from './auth' 3 | import cache from './cache' 4 | import modal from './modal' 5 | import download from './download' 6 | 7 | export default function installPlugins(app){ 8 | // 页签操作 9 | app.config.globalProperties.$tab = tab 10 | // 认证对象 11 | app.config.globalProperties.$auth = auth 12 | // 缓存对象 13 | app.config.globalProperties.$cache = cache 14 | // 模态框对象 15 | app.config.globalProperties.$modal = modal 16 | // 下载文件 17 | app.config.globalProperties.$download = download 18 | } 19 | -------------------------------------------------------------------------------- /api/v1/monitor/server.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "github.com/shichen437/live-dog/internal/app/monitor/model" 5 | 6 | "github.com/gogf/gf/v2/frame/g" 7 | ) 8 | 9 | type GetServerInfoReq struct { 10 | g.Meta `path:"/monitor/server" method:"get" tags:"服务监控" summary:"服务器详情"` 11 | } 12 | type GetServerInfoRes struct { 13 | g.Meta `mime:"application/json"` 14 | CpuInfo *model.CpuInfo `json:"cpu"` 15 | MemoryInfo *model.MemoryInfo `json:"mem"` 16 | SystemInfo *model.SystemInfo `json:"sys"` 17 | DiskInfo *[]model.DiskInfo `json:"disks"` 18 | } 19 | -------------------------------------------------------------------------------- /internal/app/common/consts/consts_i18n.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | ListF = `{#list-failed}` 5 | AddF = `{#add-failed}` 6 | UpdateF = `{#update-failed}` 7 | DeleteF = `{#delete-failed}` 8 | GetF = `{#get-failed}` 9 | 10 | IDEmpty = `{#id-empty}` 11 | DataCodeEmpty = `{#data-code-empty}` 12 | DataNotFound = `{#data-not-found}` 13 | 14 | ErrLoginFailMsg = `{#err-login-fail-msg}` 15 | ErrLoginCodeFailMsg = `{#err-login-code-fail-msg}` 16 | ErrAuthFailMsg = `{#err-auth-fail-msg}` 17 | Success = `{#success}` 18 | ) 19 | -------------------------------------------------------------------------------- /internal/pkg/media_parser/parser_test.go: -------------------------------------------------------------------------------- 1 | package media_parser_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gogf/gf/v2/os/gctx" 7 | "github.com/shichen437/live-dog/internal/pkg/media_parser" 8 | _ "github.com/shichen437/live-dog/internal/pkg/media_parser/douyin" 9 | ) 10 | 11 | func TestDownload(t *testing.T) { 12 | loader, err := media_parser.NewParser("0.28 01/02 baa:/ B@t.eO 新年新气象。2025一切顺利!# 诸事顺利 # 一切都在慢慢变好 https://v.douyin.com/i5Wk7anF/ 复制此链接,打开Dou音搜索,直接观看视频!") 13 | if err != nil { 14 | t.Error(err) 15 | } 16 | loader.ParseURL(gctx.New()) 17 | } 18 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/exit-fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/api/monitor/operlog.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 查询操作日志列表 4 | export function list(query) { 5 | return request({ 6 | url: '/monitor/operlog/list', 7 | method: 'get', 8 | params: query 9 | }) 10 | } 11 | 12 | // 删除操作日志 13 | export function delOperlog(operId) { 14 | return request({ 15 | url: '/monitor/operlog/' + operId, 16 | method: 'delete' 17 | }) 18 | } 19 | 20 | // 清空操作日志 21 | export function cleanOperlog() { 22 | return request({ 23 | url: '/monitor/operlog/clean', 24 | method: 'delete' 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/slider.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/pkg/media_parser/douyin/douyin_consts.go: -------------------------------------------------------------------------------- 1 | package douyin 2 | 3 | var ( 4 | platform = "douyin" 5 | domain = "https://www.douyin.com" 6 | 7 | randomCookieChars = "1234567890abcdef" 8 | 9 | videoDetailPath = "https://www.iesdouyin.com/share/video/" 10 | 11 | douyinHeaders = map[string]string{ 12 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", 13 | "Referer": "https://www.douyin.com", 14 | "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", 15 | } 16 | ) 17 | -------------------------------------------------------------------------------- /internal/app/common/logic/logic.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ========================================================================== 4 | 5 | package logic 6 | 7 | import ( 8 | _ "github.com/shichen437/live-dog/internal/app/common/logic/bizctx" 9 | _ "github.com/shichen437/live-dog/internal/app/common/logic/captcha" 10 | _ "github.com/shichen437/live-dog/internal/app/common/logic/middleware" 11 | _ "github.com/shichen437/live-dog/internal/app/common/logic/session" 12 | ) 13 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/vite/plugins/index.js: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | 3 | import createAutoImport from './auto-import' 4 | import createSvgIcon from './svg-icon' 5 | import createCompression from './compression' 6 | import createSetupExtend from './setup-extend' 7 | 8 | export default function createVitePlugins(viteEnv, isBuild = false) { 9 | const vitePlugins = [vue()] 10 | vitePlugins.push(createAutoImport()) 11 | vitePlugins.push(createSetupExtend()) 12 | vitePlugins.push(createSvgIcon(isBuild)) 13 | isBuild && vitePlugins.push(...createCompression(viteEnv)) 14 | return vitePlugins 15 | } 16 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /api/v1/tool/captcha.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import "github.com/gogf/gf/v2/frame/g" 4 | 5 | type CaptchaReq struct { 6 | g.Meta `path:"/captchaImage" tags:"验证码" method:"get" summary:"获取验证码"` 7 | } 8 | type CaptchaRes struct { 9 | g.Meta `mime:"application/json"` 10 | Key string `json:"key"` 11 | Img string `json:"img"` 12 | Uuid string `json:"uuid"` 13 | CaptchaEnabled bool `json:"captchaEnabled"` 14 | } 15 | type TestReq struct { 16 | g.Meta `path:"/test" tags:"验证码" method:"get" summary:"获取测试验证码"` 17 | } 18 | type TestRes struct { 19 | g.Meta `mime:"application/json"` 20 | } 21 | -------------------------------------------------------------------------------- /internal/app/admin/model/do/sys_role_menu.go: -------------------------------------------------------------------------------- 1 | // ================================================================================= 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ================================================================================= 4 | 5 | package do 6 | 7 | import ( 8 | "github.com/gogf/gf/v2/frame/g" 9 | ) 10 | 11 | // SysRoleMenu is the golang structure of table sys_role_menu for DAO operations like Where/Data. 12 | type SysRoleMenu struct { 13 | g.Meta `orm:"table:sys_role_menu, do:true"` 14 | RoleId interface{} // 角色ID 15 | MenuId interface{} // 菜单ID 16 | } 17 | -------------------------------------------------------------------------------- /internal/app/admin/model/do/sys_user_role.go: -------------------------------------------------------------------------------- 1 | // ================================================================================= 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ================================================================================= 4 | 5 | package do 6 | 7 | import ( 8 | "github.com/gogf/gf/v2/frame/g" 9 | ) 10 | 11 | // SysUserRole is the golang structure of table sys_user_role for DAO operations like Where/Data. 12 | type SysUserRole struct { 13 | g.Meta `orm:"table:sys_user_role, do:true"` 14 | UserId interface{} // 用户ID 15 | RoleId interface{} // 角色ID 16 | } 17 | -------------------------------------------------------------------------------- /internal/pkg/utils/err.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/gogf/gf/v2/frame/g" 7 | ) 8 | 9 | func WriteErrLog(ctx context.Context, err error, msg ...string) { 10 | if !g.IsNil(err) { 11 | g.Log().Error(ctx, err.Error()) 12 | if len(msg) > 0 { 13 | panic(msg[0]) 14 | } else { 15 | panic(err.Error()) 16 | } 17 | } 18 | } 19 | 20 | func WriteErrLogT(ctx context.Context, err error, msg ...string) { 21 | if !g.IsNil(err) { 22 | g.Log().Error(ctx, err.Error()) 23 | if len(msg) > 0 { 24 | panic(T(ctx, msg[0])) 25 | } else { 26 | panic(err.Error()) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /internal/app/common/consts/consts_system.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | UserSessionKey = "UserSessionKey" 5 | 6 | //sys_menu 7 | SysMenuStatusOk = "0" 8 | SysMenuStatusNo = "1" 9 | 10 | //sys_role 11 | SysRoleStatusOk = "0" 12 | SysRoleStatusNo = "1" 13 | 14 | SysRoleDataScopeAll = "1" 15 | SysRoleDataScopeCustom = "2" 16 | SysRoleDataScopeCurrent = "3" 17 | SysRoleDataScopeCurrents = "4" 18 | SysRoleDataScopeCurrentUser = "5" 19 | 20 | //sys_user 21 | SysUserStatusOk = "0" 22 | SysUserStatusNo = "1" 23 | 24 | //gen_table 25 | GenTableStatusOk = "0" 26 | GenTableStatusNo = "1" 27 | ) 28 | -------------------------------------------------------------------------------- /web/src/layout/components/IframeToggle/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 20 | -------------------------------------------------------------------------------- /internal/app/common/consts/consts_openapi.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | OpenAPITitle = `GoFrame Demos` 5 | OpenAPIDescription = `This is a simple demos HTTP server project that is using GoFrame. Enjoy 💖 ` 6 | 7 | MySwaggerUITemplate = ` 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ` 20 | ) 21 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/education.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/cmd/cmd_job.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/gogf/gf/v2/frame/g" 5 | "github.com/gogf/gf/v2/os/gctx" 6 | "github.com/shichen437/live-dog/internal/app/monitor/service" 7 | "github.com/shichen437/live-dog/internal/pkg/crons" 8 | ) 9 | 10 | func JobInit() { 11 | g.Log().Info(gctx.GetInitCtx(), "job monitor start!") 12 | 13 | jobs, err := service.SysJob().ListAll4Init(gctx.New()) 14 | if err != nil { 15 | g.Log().Error(gctx.GetInitCtx(), "job monitor start error!", err) 16 | return 17 | } 18 | for _, job := range jobs { 19 | crons.AddSystemJob(job.JobId) 20 | } 21 | 22 | g.Log().Info(gctx.GetInitCtx(), "job monitor shutdown!") 23 | } 24 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/switch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/cookie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /api/v1/monitor/oper_log.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "github.com/shichen437/live-dog/api/v1/common" 5 | "github.com/shichen437/live-dog/internal/app/monitor/model/entity" 6 | 7 | "github.com/gogf/gf/v2/frame/g" 8 | ) 9 | 10 | type GetOperLogListReq struct { 11 | g.Meta `path:"/monitor/operlog/list" method:"get" tags:"操作日志" summary:"current data list"` 12 | common.PageReq 13 | Title string `p:"title"` 14 | OperName string `p:"operName"` 15 | BusinessType int `p:"businessType"` 16 | Status int `p:"status"` 17 | } 18 | type GetOperLogListRes struct { 19 | g.Meta `mime:"application/json"` 20 | Rows []*entity.SysOperLog `json:"rows"` 21 | Total int `json:"total"` 22 | } 23 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/druid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/peoples.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/input.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/server.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/pkg/media_parser/bilibili/bilibili_models.go: -------------------------------------------------------------------------------- 1 | package bilibili 2 | 3 | type BilibiliVideoDetail struct { 4 | Aid string 5 | Author string 6 | AuthorUid string 7 | Cid string 8 | Desc string 9 | VideoCover string 10 | } 11 | 12 | type BilibiliMediaData struct { 13 | Audios []*BilibiliMediaDetail `json:"audios"` 14 | Videos []*BilibiliMediaDetail `json:"videos"` 15 | } 16 | 17 | type BilibiliMediaDetail struct { 18 | Codec string `json:"codec"` 19 | Height int `json:"height"` 20 | Mirrors []string `json:"mirrors"` 21 | Quality int `json:"quality"` 22 | QualityDesc string `json:"quality_desc"` 23 | Url string `json:"url"` 24 | Width int `json:"width"` 25 | } 26 | -------------------------------------------------------------------------------- /internal/app/live/model/do/live_history.go: -------------------------------------------------------------------------------- 1 | // ================================================================================= 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ================================================================================= 4 | 5 | package do 6 | 7 | import ( 8 | "github.com/gogf/gf/v2/frame/g" 9 | "github.com/gogf/gf/v2/os/gtime" 10 | ) 11 | 12 | // LiveHistory is the golang structure of table live_history for DAO operations like Where/Data. 13 | type LiveHistory struct { 14 | g.Meta `orm:"table:live_history, do:true"` 15 | Id interface{} // 16 | LiveId interface{} // 直播ID 17 | StartTime *gtime.Time // 直播开始时间 18 | EndTime *gtime.Time // 直播结束时间 19 | Duration interface{} // 直播时长 20 | } 21 | -------------------------------------------------------------------------------- /web/src/directive/permission/hasRole.js: -------------------------------------------------------------------------------- 1 | /** 2 | * v-hasRole 角色权限处理 3 | * Copyright (c) 2019 ruoyi 4 | */ 5 | 6 | import useUserStore from '@/store/modules/user' 7 | 8 | export default { 9 | mounted(el, binding, vnode) { 10 | const { value } = binding 11 | const super_admin = "admin"; 12 | const roles = useUserStore().roles 13 | 14 | if (value && value instanceof Array && value.length > 0) { 15 | const roleFlag = value 16 | 17 | const hasRole = roles.some(role => { 18 | return super_admin === role || roleFlag.includes(role) 19 | }) 20 | 21 | if (!hasRole) { 22 | el.parentNode && el.parentNode.removeChild(el) 23 | } 24 | } else { 25 | throw new Error(`请设置角色权限标签值`) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /web/src/api/monitor/logininfor.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 查询登录日志列表 4 | export function list(query) { 5 | return request({ 6 | url: '/monitor/logininfor/list', 7 | method: 'get', 8 | params: query 9 | }) 10 | } 11 | 12 | // 删除登录日志 13 | export function delLogininfor(infoId) { 14 | return request({ 15 | url: '/monitor/logininfor/' + infoId, 16 | method: 'delete' 17 | }) 18 | } 19 | 20 | // 解锁用户登录状态 21 | export function unlockLogininfor(userName) { 22 | return request({ 23 | url: '/monitor/logininfor/unlock/' + userName, 24 | method: 'get' 25 | }) 26 | } 27 | 28 | // 清空登录日志 29 | export function cleanLogininfor() { 30 | return request({ 31 | url: '/monitor/logininfor/clean', 32 | method: 'delete' 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/textarea.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/app/live/model/do/live_cookie.go: -------------------------------------------------------------------------------- 1 | // ================================================================================= 2 | // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 3 | // ================================================================================= 4 | 5 | package do 6 | 7 | import ( 8 | "github.com/gogf/gf/v2/frame/g" 9 | "github.com/gogf/gf/v2/os/gtime" 10 | ) 11 | 12 | // LiveCookie is the golang structure of table live_cookie for DAO operations like Where/Data. 13 | type LiveCookie struct { 14 | g.Meta `orm:"table:live_cookie, do:true"` 15 | Id interface{} // ID 16 | Platform interface{} // 平台 17 | Cookie interface{} // cookie 18 | Remark interface{} // 备注 19 | CreateTime *gtime.Time // 创建时间 20 | ActionTime *gtime.Time // 更新时间 21 | } 22 | -------------------------------------------------------------------------------- /web/src/assets/icons/svg/time.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/layout/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 41 | -------------------------------------------------------------------------------- /web/src/components/iFrame/index.vue: -------------------------------------------------------------------------------- 1 |