add new features

This commit is contained in:
mubai
2024-10-29 22:30:01 +08:00
parent 7ceb125746
commit d1433e4b5b
23 changed files with 525 additions and 129 deletions

View File

@@ -23,8 +23,8 @@ const (
// -------------------------redis key-----------------------------------
const (
// CategoryTreeKey 分类树 key
CategoryTreeKey = "CategoryTree"
CategoryTreeExpired = time.Hour * 24 * 90
CategoryTreeKey = "CategoryTree"
FilmExpired = time.Hour * 24 * 365 * 10
// MovieListInfoKey movies分类列表 key
MovieListInfoKey = "MovieList:Cid%d"
@@ -62,6 +62,8 @@ const (
ManageConfigExpired = time.Hour * 24 * 365 * 10
// SiteConfigBasic 网站参数配置
SiteConfigBasic = "SystemConfig:SiteConfig:Basic"
// BannersKey 轮播组件key 你
BannersKey = "SystemConfig:Banners"
// FilmCrontabKey 定时任务列表信息
FilmCrontabKey = "Cron:Task:Film"

View File

@@ -9,6 +9,7 @@ import (
"server/plugin/SystemInit"
"server/plugin/common/util"
"server/plugin/spider"
"strconv"
)
func ManageIndex(c *gin.Context) {
@@ -235,6 +236,99 @@ func ResetSiteBasic(c *gin.Context) {
system.SuccessOnlyMsg("配置信息重置成功", c)
}
// ------------------------------------------------------ 轮播数据配置 ------------------------------------------------------
// BannerList 获取轮播图数据
func BannerList(c *gin.Context) {
bl := logic.ML.GetBanners()
system.Success(bl, "配置信息重置成功", c)
}
// BannerFind 返回ID对应的横幅信息
func BannerFind(c *gin.Context) {
idStr := c.Query("id")
if idStr == "" {
system.Failed("Banner信息获取失败, ID信息异常", c)
return
}
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
system.Failed("删除失败,参数类型异常", c)
return
}
bl := logic.ML.GetBanners()
for _, b := range bl {
if b.Id == id {
system.Success(b, "Banner信息获取成功", c)
return
}
}
system.Failed("Banner信息获取失败", c)
}
// BannerAdd 添加海报数据
func BannerAdd(c *gin.Context) {
var b system.Banner
if err := c.ShouldBindJSON(&b); err != nil {
system.Failed("Banner参数提交异常", c)
return
}
bl := logic.ML.GetBanners()
bl = append(bl, b)
if err := logic.ML.SaveBanners(bl); err != nil {
system.Failed(fmt.Sprintln("Banners信息添加失败,", err), c)
return
}
system.SuccessOnlyMsg("海报信息添加成功", c)
}
// BannerUpdate 更新海报数据
func BannerUpdate(c *gin.Context) {
var banner system.Banner
if err := c.ShouldBindJSON(&banner); err != nil {
system.Failed("Banner参数提交异常", c)
return
}
bl := logic.ML.GetBanners()
for i, b := range bl {
if b.Id == banner.Id {
bl[i] = banner
if err := logic.ML.SaveBanners(bl); err != nil {
system.Failed("海报信息更新失败", c)
} else {
system.SuccessOnlyMsg("海报信息更新成功", c)
return
}
}
}
system.Failed("海报信息更新失败, 未匹配对应Banner信息", c)
}
// BannerDel 删除海报数据
func BannerDel(c *gin.Context) {
idStr := c.Query("id")
if idStr == "" {
system.Failed("Banner信息获取失败, ID信息异常", c)
return
}
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
system.Failed("删除失败,参数类型异常", c)
return
}
bl := logic.ML.GetBanners()
for i, b := range bl {
if b.Id == id {
bl = append(bl[:i], bl[i+1:]...)
_ = logic.ML.SaveBanners(bl)
system.SuccessOnlyMsg("海报信息删除成功", c)
return
}
}
system.Failed("海报信息删除失败", c)
}
// ------------------------------------------------------ 参数校验 ------------------------------------------------------
func validFilmSource(fs system.FilmSource) error {
// 资源名称不能为空 且长度不能超过20

View File

@@ -3,6 +3,7 @@ package controller
import (
"fmt"
"github.com/gin-gonic/gin"
"server/config"
"server/logic"
"server/model/system"
"strconv"
@@ -64,13 +65,27 @@ func StarSpider(c *gin.Context) {
system.SuccessOnlyMsg("采集任务已成功开启!!!", c)
}
// ClearAllFilm 删除所有film信息
func ClearAllFilm(c *gin.Context) {
// 清空采集数据进行重新采集前校验输入的密码是否正确
pwd := c.DefaultQuery("password", "")
// 如密码错误则不执行后续操作
if !verifyPassword(c, pwd) {
system.Failed("重置失败, 密钥校验失败!!!", c)
return
}
// 删除已采集的所有影片信息
logic.SL.ClearFilms()
system.SuccessOnlyMsg("影视数据已删除!!!", c)
}
// SpiderReset 重置影视数据, 清空库存, 从零开始
func SpiderReset(c *gin.Context) {
// 清空采集数据进行重新采集前校验输入的密码是否正确
key := c.DefaultQuery("accessKey", "")
pwd := c.DefaultQuery("password", "")
// 如密码错误则不执行后续操作
if len(key) <= 0 || key != "Re0" {
system.Failed("重置失败, 密校验失败!!!", c)
if !verifyPassword(c, pwd) {
system.Failed("重置失败, 密校验失败!!!", c)
return
}
// 前置校验通过则清空采集数据并对已启用站点进行 全量采集
@@ -87,3 +102,17 @@ func CoverFilmClass(c *gin.Context) {
}
system.SuccessOnlyMsg("影视分类信息重置成功, 请稍等片刻后刷新页面", c)
}
// 校验密码有效性
func verifyPassword(c *gin.Context, password string) bool {
// 获取已登录的用户信息
v, ok := c.Get(config.AuthUserClaims)
if !ok {
system.Failed("操作失败,登录信息异常!!!", c)
return false
}
// 从context中获取用户的登录信息
uc := v.(*system.UserClaims)
// 校验密码
return logic.UL.VerifyUserPassword(uc.UserID, password)
}

View File

@@ -16,18 +16,22 @@ func (ml *ManageLogic) GetFilmSourceList() []system.FilmSource {
return system.GetCollectSourceList()
}
// GetFilmSource 获取ID对应的采集源信息
func (ml *ManageLogic) GetFilmSource(id string) *system.FilmSource {
return system.FindCollectSourceById(id)
}
// UpdateFilmSource 更新采集源信息
func (ml *ManageLogic) UpdateFilmSource(s system.FilmSource) error {
return system.UpdateCollectSource(s)
}
// SaveFilmSource 保存采集源信息
func (ml *ManageLogic) SaveFilmSource(s system.FilmSource) error {
return system.AddCollectSource(s)
}
// DelFilmSource 删除采集源信息
func (ml *ManageLogic) DelFilmSource(id string) error {
// 先查找是否存在对应ID的站点信息
s := system.FindCollectSourceById(id)
@@ -51,3 +55,13 @@ func (ml *ManageLogic) GetSiteBasicConfig() system.BasicConfig {
func (ml *ManageLogic) UpdateSiteBasic(c system.BasicConfig) error {
return system.SaveSiteBasic(c)
}
// GetBanners 获取轮播组件信息
func (ml *ManageLogic) GetBanners() system.Banners {
return system.GetBanners()
}
// SaveBanners 保存轮播信息
func (ml *ManageLogic) SaveBanners(bl system.Banners) error {
return system.SaveBanners(bl)
}

View File

@@ -38,6 +38,11 @@ func (sl *SpiderLogic) AutoCollect(time int) {
go spider.AutoCollect(time)
}
// ClearFilms 删除采集的数据信息
func (sl *SpiderLogic) ClearFilms() {
go spider.ClearSpider()
}
// ZeroCollect 数据清除从零开始采集
func (sl *SpiderLogic) ZeroCollect(time int) {
go spider.StarZero(time)

View File

@@ -57,6 +57,7 @@ func (ul *UserLogic) ChangePassword(account, password, newPassword string) error
return nil
}
// GetUserInfo 获取用户基本信息
func (ul *UserLogic) GetUserInfo(id uint) system.UserInfoVo {
// 通过用户ID查询对应的用户信息
u := system.GetUserById(id)
@@ -64,3 +65,11 @@ func (ul *UserLogic) GetUserInfo(id uint) system.UserInfoVo {
var vo = system.UserInfoVo{Id: u.ID, UserName: u.UserName, Email: u.Email, Gender: u.Gender, NickName: u.NickName, Avatar: u.Avatar, Status: u.Status}
return vo
}
// VerifyUserPassword 校验密码
func (ul *UserLogic) VerifyUserPassword(id uint, password string) bool {
// 获取当前登录的用户全部信息
u := system.GetUserById(id)
// 校验密码是否正确
return util.PasswordEncrypt(password, u.Salt) == u.Password
}

View File

@@ -32,6 +32,7 @@ func start() {
// 启动前先执行数据库内容的初始化工作
DefaultDataInit()
SystemInit.BannersInit()
// 开启路由监听
r := router.SetupRouter()
_ = r.Run(fmt.Sprintf(":%s", config.ListenerPort))

View File

@@ -26,7 +26,7 @@ type CategoryTree struct {
// SaveCategoryTree 保存影片分类信息
func SaveCategoryTree(tree *CategoryTree) error {
data, _ := json.Marshal(tree)
return db.Rdb.Set(db.Cxt, config.CategoryTreeKey, data, config.CategoryTreeExpired).Err()
return db.Rdb.Set(db.Cxt, config.CategoryTreeKey, data, config.FilmExpired).Err()
}
// GetCategoryTree 获取影片分类信息

View File

@@ -5,8 +5,10 @@ import (
"log"
"server/config"
"server/plugin/db"
"sort"
)
// BasicConfig 网站基本信息
type BasicConfig struct {
SiteName string `json:"siteName"` // 网站名称
Domain string `json:"domain"` // 网站域名
@@ -17,6 +19,30 @@ type BasicConfig struct {
Hint string `json:"hint"` // 网站关闭提示
}
// Banner 首页横幅信息
type Banner struct {
Id int64 `json:"id"` // 绑定所属影片Id
Name string `json:"name"` // 影片名称
Year int64 `json:"year"` // 上映年份
CName string `json:"cName"` // 分类名称
Poster string `json:"poster"` // 海报图片链接
Picture string `json:"picture"` // 横幅大图链接
Remark string `json:"remark"` // 更新状态描述信息
Sort int64 `json:"sort"` // 排序分值
}
type Banners []Banner
func (bl Banners) Len() int {
return len(bl)
}
func (bl Banners) Less(i, j int) bool {
return bl[i].Sort < bl[j].Sort
}
func (bl Banners) Swap(i, j int) {
bl[i], bl[j] = bl[j], bl[i]
}
// ------------------------------------------------------ Redis ------------------------------------------------------
// SaveSiteBasic 保存网站基本配置信息
@@ -34,3 +60,21 @@ func GetSiteBasic() BasicConfig {
}
return c
}
// GetBanners 获取轮播配置信息
func GetBanners() Banners {
var bl Banners
data := db.Rdb.Get(db.Cxt, config.BannersKey).Val()
if err := json.Unmarshal([]byte(data), &bl); err != nil {
log.Println("Get Banners Error", err)
}
// 通过 sort 对banners进行排序
sort.Sort(bl)
return bl
}
// SaveBanners 保存轮播配置信息
func SaveBanners(bl Banners) error {
data, _ := json.Marshal(bl)
return db.Rdb.Set(db.Cxt, config.BannersKey, data, config.ManageConfigExpired).Err()
}

View File

@@ -99,7 +99,7 @@ func SaveDetails(list []MovieDetail) (err error) {
data, _ := json.Marshal(detail)
// 1. 原使用Zset存储, 但是不便于单个检索 db.Rdb.ZAdd(db.Cxt, fmt.Sprintf("%s:Cid%d", config.MovieDetailKey, detail.Cid), redis.Z{Score: float64(detail.Id), Member: member}).Err()
// 改为普通 k v 存储, k-> id关键字, v json序列化的结果
err = db.Rdb.Set(db.Cxt, fmt.Sprintf(config.MovieDetailKey, detail.Cid, detail.Id), data, config.CategoryTreeExpired).Err()
err = db.Rdb.Set(db.Cxt, fmt.Sprintf(config.MovieDetailKey, detail.Cid, detail.Id), data, config.FilmExpired).Err()
// 2. 同步保存简略信息到redis中
SaveMovieBasicInfo(detail)
// 3. 保存 Search tag redis中
@@ -121,7 +121,7 @@ func SaveDetail(detail MovieDetail) (err error) {
// 序列化影片详情信息
data, _ := json.Marshal(detail)
// 保存影片信息到Redis
err = db.Rdb.Set(db.Cxt, fmt.Sprintf(config.MovieDetailKey, detail.Cid, detail.Id), data, config.CategoryTreeExpired).Err()
err = db.Rdb.Set(db.Cxt, fmt.Sprintf(config.MovieDetailKey, detail.Cid, detail.Id), data, config.FilmExpired).Err()
if err != nil {
return err
}
@@ -156,7 +156,7 @@ func SaveMovieBasicInfo(detail MovieDetail) {
Year: detail.Year,
}
data, _ := json.Marshal(basicInfo)
_ = db.Rdb.Set(db.Cxt, fmt.Sprintf(config.MovieBasicInfoKey, detail.Cid, detail.Id), data, config.CategoryTreeExpired).Err()
_ = db.Rdb.Set(db.Cxt, fmt.Sprintf(config.MovieBasicInfoKey, detail.Cid, detail.Id), data, config.FilmExpired).Err()
}
// SaveSitePlayList 仅保存播放url列表信息到当前站点

View File

@@ -20,3 +20,13 @@ func BasicConfigInit() {
}
_ = system.SaveSiteBasic(bc)
}
func BannersInit() {
var bl = system.Banners{
system.Banner{Name: "樱花庄的宠物女孩", Year: 2020, CName: "日韩动漫", Poster: "https://s2.loli.net/2024/02/21/Wt1QDhabdEI7HcL.jpg", Picture: "https://img.bfzypic.com/upload/vod/20230424-43/06e79232a4650aea00f7476356a49847.jpg", Remark: "已完结"},
system.Banner{Name: "从零开始的异世界生活", Year: 2020, CName: "日韩动漫", Poster: "https://s2.loli.net/2024/02/21/Wt1QDhabdEI7HcL.jpg", Picture: "https://img.bfzypic.com/upload/vod/20230424-43/06e79232a4650aea00f7476356a49847.jpg", Remark: "已完结"},
system.Banner{Name: "五等分的花嫁", Year: 2020, CName: "日韩动漫", Poster: "https://s2.loli.net/2024/02/21/Wt1QDhabdEI7HcL.jpg", Picture: "https://img.bfzypic.com/upload/vod/20230424-43/06e79232a4650aea00f7476356a49847.jpg", Remark: "已完结"},
system.Banner{Name: "我的青春恋爱物语果然有问题", Year: 2020, CName: "日韩动漫", Poster: "https://s2.loli.net/2024/02/21/Wt1QDhabdEI7HcL.jpg", Picture: "https://img.bfzypic.com/upload/vod/20230424-43/06e79232a4650aea00f7476356a49847.jpg", Remark: "已完结"},
}
_ = system.SaveBanners(bl)
}

View File

@@ -229,6 +229,11 @@ func AutoCollect(h int) {
}
}
// ClearSpider 删除已采集的影片信息
func ClearSpider() {
system.FilmZero()
}
// StarZero 情况站点内所有影片信息
func StarZero(h int) {
// 首先清除影视信息

View File

@@ -34,14 +34,26 @@ func SetupRouter() *gin.Engine {
manageRoute.Use(middleware.AuthToken())
{
manageRoute.GET(`/index`, controller.ManageIndex)
// 系统相关
sysConfig := manageRoute.Group(`/config`)
{
sysConfig.GET("/basic", controller.SiteBasicConfig)
sysConfig.POST("/basic/update", controller.UpdateSiteBasic)
sysConfig.GET("/basic/reset", controller.ResetSiteBasic)
sysConfig.GET(`/basic`, controller.SiteBasicConfig)
sysConfig.POST(`/basic/update`, controller.UpdateSiteBasic)
sysConfig.GET(`/basic/reset`, controller.ResetSiteBasic)
}
// 轮播相关
banner := manageRoute.Group(`banner`)
{
banner.GET(`/list`, controller.BannerList)
banner.GET(`/find`, controller.BannerFind)
banner.POST(`/add`, controller.BannerAdd)
banner.GET(`/update`, controller.BannerUpdate)
banner.GET(`/del`, controller.BannerDel)
}
// 用户相关
userRoute := manageRoute.Group(`/user`)
{
userRoute.GET(`/info`, controller.UserInfo)
@@ -77,6 +89,7 @@ func SetupRouter() *gin.Engine {
{
spiderRoute.POST(`/start`, controller.StarSpider)
spiderRoute.GET(`/zero`, controller.SpiderReset)
spiderRoute.GET(`/clear`, controller.ClearAllFilm)
spiderRoute.GET(`/class/cover`, controller.CoverFilmClass)
}
// filmManage 影视管理