✨ 今日校园任务的编辑

This commit is contained in:
sugarBecomer
2025-10-29 15:21:42 +08:00
parent 70ff7ca806
commit c8beca447e
9 changed files with 223 additions and 29 deletions
+23 -13
View File
@@ -1,6 +1,11 @@
package v1
import "github.com/gogf/gf/v2/frame/g"
import (
"likedream-goframe/internal/application/cpdaily/task/formtype"
"likedream-goframe/internal/ent/cptask"
"github.com/gogf/gf/v2/frame/g"
)
type GetRecentTasksReq struct {
g.Meta `path:"/task/recent" method:"get" tags:"CpTask" summary:"获取最近任务"`
@@ -23,26 +28,31 @@ type CpTaskListReq struct {
}
type GetCpTaskFormReq struct {
g.Meta `path:"/task" method:"get" tags:"CpTask" summary:"获取任务表单"`
g.Meta `path:"/task/form/{id}" method:"get" tags:"CpTask" summary:"获取任务表单"`
Id int64 `json:"id"`
}
type UpdateCpTaskFormReq struct {
g.Meta `path:"/task" method:"put" tags:"CpTask" summary:"更新任务表单"`
type PutCpTaskFormReq struct {
g.Meta `path:"/task/form/{id}" method:"put" tags:"CpTask" summary:"更新任务表单"`
Id int64 `json:"id"`
Forms []*formtype.CpTaskFormItem `json:"forms" v:"required$表单信息不能为空"`
}
type GetCpTaskExecuteReq struct {
g.Meta `path:"/task/execute/{id}" method:"get" tags:"CpTask" summary:"执行任务参数"`
Id int64 `json:"id"`
}
type GetCoTaskExecuteReq struct {
g.Meta `path:"/task/execute" method:"get" tags:"CpTask" summary:"执行任务参数"`
Id int64 `json:"id"`
}
type UpdateCpTaskExecuteReq struct {
g.Meta `path:"/task/execute" method:"put" tags:"CpTask" summary:"更新执行任务参数"`
Id int64 `json:"id"`
type PostCpTaskExecuteReq struct {
g.Meta `path:"/task/execute/{id}" method:"post" tags:"CpTask" summary:"更新执行任务参数"`
Id int64 `json:"id"`
Frequency int `json:"frequency"`
NotificationTypeNone cptask.NotificationType `json:"notificationType"`
ExecuteHour int `json:"executeHour"`
ExecuteMinute int `json:"executeMinute"`
}
type DeleteTaskReq struct {
g.Meta `path:"/task" method:"delete" tags:"CpTask" summary:"删除任务"`
g.Meta `path:"/task/{id}" method:"delete" tags:"CpTask" summary:"删除任务"`
Id int64 `json:"id"`
}
+5 -1
View File
@@ -44,7 +44,11 @@ func NewCas(ctx context.Context) CpdailyLogin {
func (c *CpdailyCasLogin) GetCookieJar() http.CookieJar {
return c.client.CookieJar()
}
func (c *CpdailyCasLogin) GetCookieString() string {
cookieJar := c.GetCookieJar()
serializableJar := cookieJar.(*cookiejar.PersistCookieJar)
return serializableJar.Serialize()
}
func (c *CpdailyCasLogin) GetClient() *resty.Client {
return c.client.SetRedirectPolicy(resty.NoRedirectPolicy())
}
@@ -3,6 +3,8 @@ package login
import (
"context"
"fmt"
"likedream-goframe/internal/application/cookiejar"
"likedream-goframe/internal/application/httpclient"
"likedream-goframe/internal/common/errors"
"likedream-goframe/internal/utils"
"strings"
@@ -79,6 +81,35 @@ func ActivateSession(ctx context.Context, host string, client *resty.Client) {
client = client.SetRedirectPolicy(resty.NoRedirectPolicy())
}
func CookieEnabled(ctx context.Context, host string, client *resty.Client) bool {
client = client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(20))
defer func() {
client = client.SetRedirectPolicy(resty.NoRedirectPolicy())
}()
host = strings.TrimSuffix(host, "/")
sessionResponse, err := client.R().
WithContext(ctx).
SetBody(map[string]any{}).
Post(fmt.Sprintf("%s/wec-counselor-attendance-apps/student/attendance/getStuSignInfosByWeekMonth", host))
utils.OkOrPanic(err)
defer sessionResponse.Body.Close()
if !sessionResponse.IsSuccess() {
return sessionResponse.StatusCode() == 405
}
responseContentType := sessionResponse.Header().Get("Content-Type")
return strings.Contains(responseContentType, "json")
}
func GetClient(ctx context.Context, cookie string) *resty.Client {
cookieJar := cookiejar.NewPersistCookieJar()
cookieJar.Deserialize(cookie)
client := httpclient.Cpdaily.Clone(ctx)
client.SetCookieJar(cookieJar)
return client
}
func SendDynamicCodeByPhone(ctx context.Context, username string, host string, client *resty.Client) {
host = strings.TrimSuffix(host, "/")
response, err := client.R().
+8 -3
View File
@@ -3,8 +3,6 @@ package login
import (
"context"
"fmt"
"github.com/samber/oops"
"github.com/tidwall/gjson"
"io"
"likedream-goframe/internal/application/cookiejar"
"likedream-goframe/internal/application/cpdaily/school"
@@ -13,6 +11,9 @@ import (
"likedream-goframe/internal/utils"
"net/http"
"net/url"
"github.com/samber/oops"
"github.com/tidwall/gjson"
"resty.dev/v3"
)
@@ -151,7 +152,11 @@ func (c *CpdailyIapLogin) Login(ctx context.Context, schoolDetail *school.School
func (c *CpdailyIapLogin) GetCookieJar() http.CookieJar {
return c.client.CookieJar()
}
func (c *CpdailyIapLogin) GetCookieString() string {
cookieJar := c.GetCookieJar()
serializableJar := cookieJar.(*cookiejar.PersistCookieJar)
return serializableJar.Serialize()
}
func getIapValidLoginUrl(schoolDetail *school.SchoolDetailInfo) string {
loginUrl := utils.GetFirstNotEmptyString(schoolDetail.WecloudUrl, schoolDetail.AmpUrl, schoolDetail.AmpUrl2, schoolDetail.AmpUrl3)
@@ -4,11 +4,13 @@ import (
"context"
"likedream-goframe/internal/application/cpdaily/school"
"net/http"
"resty.dev/v3"
)
type CpdailyLogin interface {
Login(ctx context.Context, schoolDetail *school.SchoolDetailInfo, username, password string)
GetCookieJar() http.CookieJar
GetCookieString() string
GetClient() *resty.Client
}
@@ -26,6 +26,29 @@ func (c CpTaskServiceV1) AddTask(ctx context.Context, req *v1.AddTaskReq) (res *
return service.Global.CpTask.AddTask(ctx, req), nil
}
func (c CpTaskServiceV1) TaskFormData(ctx context.Context, req *v1.GetCpTaskFormReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.CpTask.TaskFormData(ctx, req), nil
}
func (c CpTaskServiceV1) PutFormData(ctx context.Context, req *v1.PutCpTaskFormReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.CpTask.PutTaskFormData(ctx, req), nil
}
func (c CpTaskServiceV1) TaskExecute(ctx context.Context, req *v1.GetCpTaskExecuteReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.CpTask.TaskExecute(ctx, req), nil
}
func (c CpTaskServiceV1) PostExecute(ctx context.Context, req *v1.PostCpTaskExecuteReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.CpTask.PostExecute(ctx, req), nil
}
func (c CpTaskServiceV1) Delete(ctx context.Context, req *v1.DeleteTaskReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.CpTask.Delete(ctx, req), nil
}
func NewCpTaskCtrlV1() ICpTaskCtrlV1 {
return &CpTaskServiceV1{}
}
+5 -1
View File
@@ -11,5 +11,9 @@ type ICpTaskCtrlV1 interface {
GetRecentTasks(ctx context.Context, req *v1.GetRecentTasksReq) (*utils.Response[[]string], error)
AddTask(ctx context.Context, req *v1.AddTaskReq) (res *utils.Response[any], err error)
List(ctx context.Context, req *v1.CpTaskListReq) (res *utils.Response[[]*ent.CpTask], err error)
TaskFormData(ctx context.Context, req *v1.TaskFormDataReq) (res *utils.Response[any], err error)
TaskFormData(ctx context.Context, req *v1.GetCpTaskFormReq) (res *utils.Response[any], err error)
PutFormData(ctx context.Context, req *v1.PutCpTaskFormReq) (res *utils.Response[any], err error)
TaskExecute(ctx context.Context, req *v1.GetCpTaskExecuteReq) (res *utils.Response[any], err error)
PostExecute(ctx context.Context, req *v1.PostCpTaskExecuteReq) (res *utils.Response[any], err error)
Delete(ctx context.Context, req *v1.DeleteTaskReq) (res *utils.Response[any], err error)
}
+124 -4
View File
@@ -2,8 +2,12 @@ package cpdaily
import (
"context"
"encoding/json"
v1 "likedream-goframe/internal/api/v1"
"likedream-goframe/internal/application/cpdaily/login"
"likedream-goframe/internal/application/cpdaily/school"
"likedream-goframe/internal/application/cpdaily/task"
"likedream-goframe/internal/application/cpdaily/task/formtype"
errors2 "likedream-goframe/internal/common/errors"
"likedream-goframe/internal/db"
"likedream-goframe/internal/ent"
@@ -19,10 +23,19 @@ type CpTaskServiceV1 struct {
func (v CpTaskServiceV1) GetRecentTasks(ctx context.Context, req *v1.GetRecentTasksReq) *utils.Response[[]string] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpuser
cpUser := db.Global.CpUser.Query().Where(cpuser.ID(req.UserId)).WithSysuser().OnlyX(ctx)
if cpUser.Edges.Sysuser == nil || cpUser.Edges.Sysuser.ID != user.ID {
cpUser := db.Global.CpUser.Query().Where(cpuser.ID(req.UserId), cpuser.HasSysuserWith(sysuser.ID(user.ID))).WithSysuser().WithSchool().OnlyX(ctx)
if cpUser.Edges.Sysuser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
schoolDetail := school.GetSchoolDetail(ctx, cpUser.SchoolID)
client := login.GetClient(ctx, cpUser.Cookie)
if !login.CookieEnabled(ctx, schoolDetail.WecloudUrl, client) {
loginExecutor := login.GetCpdailyLoginBySchoolInfo(ctx, &schoolDetail)
loginExecutor.Login(ctx, &schoolDetail, cpUser.Username, cpUser.Password)
cookie := loginExecutor.GetCookieString()
db.Global.CpUser.UpdateOne(cpUser).SetCookie(cookie).ExecX(ctx)
client = login.GetClient(ctx, cookie)
}
taskService := task.GetCpdailyTaskService(ctx, req.Type, cpUser.Cookie, cpUser.SchoolID)
titleList := taskService.GetRecentTaskTitle(ctx)
return utils.SuccessWithData[[]string](titleList)
@@ -31,8 +44,8 @@ func (v CpTaskServiceV1) GetRecentTasks(ctx context.Context, req *v1.GetRecentTa
func (v CpTaskServiceV1) AddTask(ctx context.Context, req *v1.AddTaskReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpuser
cpUser := db.Global.CpUser.Query().Where(cpuser.ID(req.UserId)).WithSysuser().OnlyX(ctx)
if cpUser.Edges.Sysuser == nil || cpUser.Edges.Sysuser.ID != user.ID {
cpUser := db.Global.CpUser.Query().Where(cpuser.ID(req.UserId), cpuser.HasSysuserWith(sysuser.ID(user.ID))).WithSysuser().OnlyX(ctx)
if cpUser.Edges.Sysuser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
db.Global.CpTask.Create().
@@ -69,6 +82,113 @@ func (v CpTaskServiceV1) List(ctx context.Context, req *v1.CpTaskListReq) *utils
return utils.SuccessWithTotal[[]*ent.CpTask](data, total)
}
func (v CpTaskServiceV1) TaskFormData(ctx context.Context, req *v1.GetCpTaskFormReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpTask
cpTask := db.Global.CpTask.Query().Where(cptask.ID(req.Id),
cptask.HasSysUserWith(sysuser.ID(user.ID))).
WithCpUser().WithSysUser().OnlyX(ctx)
cpUser := cpTask.Edges.CpUser
if cpUser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
if cpTask.FormData != "" {
var formData []*formtype.CpTaskFormItem
err := json.Unmarshal([]byte(cpTask.FormData), &formData)
utils.OkOrPanic(err)
return utils.SuccessWithData[any](formData)
}
schoolDetail := school.GetSchoolDetail(ctx, cpTask.Edges.CpUser.SchoolID)
client := login.GetClient(ctx, cpUser.Cookie)
if !login.CookieEnabled(ctx, schoolDetail.WecloudUrl, client) {
loginExecutor := login.GetCpdailyLoginBySchoolInfo(ctx, &schoolDetail)
loginExecutor.Login(ctx, &schoolDetail, cpUser.Username, cpUser.Password)
cookie := loginExecutor.GetCookieString()
db.Global.CpUser.UpdateOne(cpUser).SetCookie(cookie).ExecX(ctx)
client = login.GetClient(ctx, cookie)
}
taskService := task.GetCpdailyTaskService(ctx, string(cpTask.TaskType), cpUser.Cookie, cpUser.SchoolID)
formMap := taskService.QueryFormByTitle(ctx, cpTask.Title)
formDetail := taskService.ParseFormJson(ctx, formMap)
return utils.SuccessWithData[any](formDetail)
}
func (v CpTaskServiceV1) PutTaskFormData(ctx context.Context, req *v1.PutCpTaskFormReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpTask
cpTask := db.Global.CpTask.Query().Where(cptask.ID(req.Id),
cptask.HasSysUserWith(sysuser.ID(user.ID))).
WithCpUser().WithSysUser().OnlyX(ctx)
cpUser := cpTask.Edges.CpUser
if cpUser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
update := db.Global.CpTask.UpdateOne(cpTask)
marshal, _ := json.Marshal(req.Forms)
update.SetFormData(string(marshal))
if cpTask.Step == cptask.StepForm {
update.SetStep(cptask.StepExecute)
}
update.SaveX(ctx)
return utils.SuccessWithMsg("保存成功")
}
func (v CpTaskServiceV1) TaskExecute(ctx context.Context, req *v1.GetCpTaskExecuteReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpTask
cpTask := db.Global.CpTask.Query().Where(cptask.ID(req.Id),
cptask.HasSysUserWith(sysuser.ID(user.ID))).
WithCpUser().WithSysUser().OnlyX(ctx)
cpUser := cpTask.Edges.CpUser
if cpUser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
return utils.SuccessWithData[any](cpTask)
}
func (v CpTaskServiceV1) PostExecute(ctx context.Context, req *v1.PostCpTaskExecuteReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpTask
cpTask := db.Global.CpTask.Query().Where(cptask.ID(req.Id),
cptask.HasSysUserWith(sysuser.ID(user.ID))).
WithCpUser().WithSysUser().OnlyX(ctx)
cpUser := cpTask.Edges.CpUser
if cpUser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
if cpTask.Step < cptask.StepExecute {
utils.OkOrPanic(errors2.NewBusinessError(400, "请先完成前置参数设置"))
}
pointConsume := req.Frequency - cpTask.Frequency
if pointConsume < 0 {
utils.OkOrPanic(errors2.NewBusinessError(400, "执行次数应不低于原有次数"))
}
//todo 扣积分
db.Global.CpTask.UpdateOne(cpTask).
SetStep(cptask.StepComplete).
SetFrequency(req.Frequency).
SetTaskStatus(cptask.TaskStatusNotStart).
SetNotificationType(req.NotificationTypeNone).
SetExecuteHour(req.ExecuteHour).
SetExecuteMinute(req.ExecuteMinute).
Exec(ctx)
return utils.SuccessWithMsg("更新成功")
}
func (v CpTaskServiceV1) Delete(ctx context.Context, req *v1.DeleteTaskReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 检测是否属于自己的cpTask
cpTask := db.Global.CpTask.Query().Where(cptask.ID(req.Id),
cptask.HasSysUserWith(sysuser.ID(user.ID))).
WithCpUser().WithSysUser().OnlyX(ctx)
cpUser := cpTask.Edges.CpUser
if cpUser == nil {
utils.OkOrPanic(errors2.NewBusinessError(400, "非法的今日校园账号"))
}
db.Global.CpTask.DeleteOne(cpTask).ExecX(ctx)
return utils.SuccessWithMsg("删除成功")
}
func NewCpTaskServiceV1() *CpTaskServiceV1 {
return &CpTaskServiceV1{}
}
+2 -7
View File
@@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
v1 "likedream-goframe/internal/api/v1"
"likedream-goframe/internal/application/cookiejar"
"likedream-goframe/internal/application/cpdaily/login"
"likedream-goframe/internal/application/cpdaily/school"
"likedream-goframe/internal/db"
@@ -29,13 +28,11 @@ func (v CpUserServiceV1) Add(ctx context.Context, req *v1.CpUserAddReq) *utils.R
schoolDetail := school.GetSchoolDetail(ctx, req.SchoolId)
loginExecutor := login.GetCpdailyLoginBySchoolInfo(ctx, &schoolDetail)
loginExecutor.Login(ctx, &schoolDetail, req.Username, req.Password)
cookieJar := loginExecutor.GetCookieJar()
serializableJar := cookieJar.(*cookiejar.PersistCookieJar)
db.Global.CpUser.Create().
SetUsername(req.Username).
SetPassword(req.Password).
SetEmail(req.Email).
SetCookie(serializableJar.Serialize()).
SetCookie(loginExecutor.GetCookieString()).
SetMobileCode(utils.UUID()).
SetMobileType(cpuser.MobileTypeRandom).
SetSchoolID(req.SchoolId).
@@ -56,13 +53,11 @@ func (v CpUserServiceV1) ConfirmAdd(ctx context.Context, req *v1.CpUserConfirmAd
json.Unmarshal([]byte(schoolInfo), &sc)
loginExecutor := login.GetCpdailyLoginBySchoolInfo(ctx, &sc)
loginExecutor.(*login.CpdailyCasLogin).ConfirmAdd(ctx, &sc, req.Username, req.Password, req.Key, req.DynamicCode)
cookieJar := loginExecutor.GetCookieJar()
serializableJar := cookieJar.(*cookiejar.PersistCookieJar)
db.Global.CpUser.Create().
SetUsername(req.Username).
SetPassword(req.Password).
SetEmail(req.Email).
SetCookie(serializableJar.Serialize()).
SetCookie(loginExecutor.GetCookieString()).
SetMobileCode(utils.UUID()).
SetMobileType(cpuser.MobileTypeRandom).
SetSchoolID(sc.Id).