first commit

This commit is contained in:
wangfuduo 2026-09-21 16:28:08 +08:00
commit c69b63abda
137 changed files with 9125 additions and 0 deletions

48
.gitignore vendored Normal file
View File

@ -0,0 +1,48 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
cmd/**/*.exe
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
/logs
/src/test
/src/test
log
data
conf/server.conf.dev
conf/server.conf.rzh
*.wfd
*.log
readme.md

27
Dockerfile Normal file
View File

@ -0,0 +1,27 @@
FROM registry.cn-shanghai.aliyuncs.com/devcon/godev:v1.0.19
ADD . /app/src
WORKDIR /app/src
RUN date +"%Y%m%d_%H%M%S"> /etc/build_time
RUN git rev-parse HEAD> /etc/git_commit_id
RUN mkdir -p /app/bin /app/log /app/base/static /app/data
RUN export GOROOT=/usr/local/go1.24.5 && \
export GOPROXY=https://goproxy.cn && \
export GOPRIVATE=git.u8t.cn && \
export PATH=$PATH:$GOROOT/bin && \
go mod tidy && \
go get git.u8t.cn/open/go-server && \
go build cmd/yintai-api/yintai-api.go && \
go build cmd/yintai-worker/yintai-worker.go && \
mv yintai-api /app/bin && \
mv yintai-worker /app/bin && \
cp -r conf /app && \
cp start.sh /app && \
chmod +x /app/start.sh
WORKDIR /app
EXPOSE 9202
CMD ["/app/start.sh"]

View File

@ -0,0 +1,50 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Category struct{}
func (r *Category) Create(ctx *gin.Context) {
var req request.CategoryCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Category).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Category) Update(ctx *gin.Context) {
var req request.CategoryUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Category).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Category) Delete(ctx *gin.Context) {
var req request.CategoryDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Category).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Category) List(ctx *gin.Context) {
var req request.CategoryList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Category).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,50 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Config struct{}
func (r *Config) Create(ctx *gin.Context) {
var req request.ConfigCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Config).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Config) Update(ctx *gin.Context) {
var req request.ConfigUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Config).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Config) Delete(ctx *gin.Context) {
var req request.ConfigDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Config).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Config) List(ctx *gin.Context) {
var req request.ConfigList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Config).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,57 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Document struct{}
func (r *Document) Create(ctx *gin.Context) {
var req request.DocumentCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Document).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Document) Update(ctx *gin.Context) {
var req request.DocumentUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Document).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Document) Delete(ctx *gin.Context) {
var req request.DocumentDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Document).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Document) List(ctx *gin.Context) {
var req request.DocumentList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Document).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *Document) Get(ctx *gin.Context) {
var req request.DocumentDelete
req.ID = ctx.Param("id")
res := new(service.Document).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,31 @@
package controller
import (
"net/http"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Files struct{}
func (f *Files) Upload(ctx *gin.Context) {
file, err := ctx.FormFile("file")
if err != nil {
err2.ParamErr(err)
}
if file == nil {
err2.ParamErr()
}
res := new(service.Files).Upload(file, ctx)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}
func (f *Files) UploadToken(ctx *gin.Context) {
token := new(service.Files).UploadToken()
ctx.JSON(http.StatusOK, response.NewRsp(map[string]any{"token": token}))
}

View File

@ -0,0 +1,57 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Job struct{}
func (r *Job) Create(ctx *gin.Context) {
var req request.JobCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Job).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Job) Update(ctx *gin.Context) {
var req request.JobUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Job).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Job) Delete(ctx *gin.Context) {
var req request.JobDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Job).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Job) List(ctx *gin.Context) {
var req request.JobList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Job).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *Job) Get(ctx *gin.Context) {
var req request.JobDelete
req.ID = ctx.Param("id")
res := new(service.Job).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,57 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type News struct{}
func (r *News) Create(ctx *gin.Context) {
var req request.NewsCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.News).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *News) Update(ctx *gin.Context) {
var req request.NewsUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.News).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *News) Delete(ctx *gin.Context) {
var req request.NewsDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.News).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *News) List(ctx *gin.Context) {
var req request.NewsList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.News).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *News) Get(ctx *gin.Context) {
var req request.NewsDelete
req.ID = ctx.Param("id")
res := new(service.News).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,50 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Page struct{}
func (r *Page) Create(ctx *gin.Context) {
var req request.PageCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Page).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Page) Update(ctx *gin.Context) {
var req request.PageUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Page).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Page) Delete(ctx *gin.Context) {
var req request.PageDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Page).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Page) List(ctx *gin.Context) {
var req request.PageList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Page).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,57 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Process struct{}
func (r *Process) Create(ctx *gin.Context) {
var req request.ProcessCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Process).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Process) Update(ctx *gin.Context) {
var req request.ProcessUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Process).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Process) Delete(ctx *gin.Context) {
var req request.ProcessDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Process).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Process) List(ctx *gin.Context) {
var req request.ProcessList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Process).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *Process) Get(ctx *gin.Context) {
var req request.ProcessDelete
req.ID = ctx.Param("id")
res := new(service.Process).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,50 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Resource struct{}
func (r *Resource) Create(ctx *gin.Context) {
var req request.ResourceCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Resource).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Resource) Update(ctx *gin.Context) {
var req request.ResourceUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Resource).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Resource) Delete(ctx *gin.Context) {
var req request.ResourceDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Resource).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Resource) List(ctx *gin.Context) {
var req request.ResourceList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Resource).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,64 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Role struct{}
func (r *Role) Create(ctx *gin.Context) {
var req request.RoleCreate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
id := new(service.Role).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(id))
}
func (r *Role) Update(ctx *gin.Context) {
var req request.RoleUpdate
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Role).Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Role) Delete(ctx *gin.Context) {
var req request.RoleDelete
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
new(service.Role).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (r *Role) List(ctx *gin.Context) {
var req request.RoleList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Role).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *Role) Get(ctx *gin.Context) {
var req request.RoleGet
req.ID = ctx.Param("id")
res := new(service.Role).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}
func (r *Role) Accounts(ctx *gin.Context) {
var req request.RoleGet
req.ID = ctx.Param("id")
res := new(service.Role).Accounts(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,22 @@
package controller
import (
"net/http"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"yintai-api/app/common/service"
"github.com/gin-gonic/gin"
)
type Translate struct{}
func (Translate) Translate2En(ctx *gin.Context) {
text := ctx.Query("text")
en, err := service.NewBaiduTranslate().ZH2EN(text)
if err != nil {
err2.TranslateErr()
}
ctx.JSON(http.StatusOK, response.NewRsp(en))
}

View File

@ -0,0 +1,90 @@
package controller
import (
"net/http"
"yintai-api/app/admin/request"
"yintai-api/app/admin/service"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"yintai-api/base/config"
"github.com/gin-gonic/gin"
"github.com/spf13/cast"
)
type User struct{}
func (a *User) Create(ctx *gin.Context) {
var req request.UserCreate
if err := ctx.ShouldBind(&req); err != nil {
err2.ParamErr("<user create>", err)
}
id := new(service.User).Create(req)
ctx.JSON(http.StatusOK, response.NewRsp(map[string]any{"id": id}))
}
func (a *User) Update(ctx *gin.Context) {
var req request.UserUpdate
var err error
if err = ctx.ShouldBind(&req); err != nil {
err2.ParamErr("<user update>", err)
}
// 获取当前登录用户的账号
userinfo := service.NewToken().UserInfo(ctx.GetHeader("token"))
if userId := cast.ToInt64(req.UserId); userId != 0 {
userinfo, err = dao.NewUser().GetUserId(userId)
if userinfo == nil {
panic(config.ErrNotExists.New().Append())
}
}
userService := service.NewUser(userinfo)
userService.Update(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (a *User) Delete(ctx *gin.Context) {
var req request.UserDelete
if err := ctx.ShouldBind(&req); err != nil {
err2.ParamErr("<user delete>", err)
}
userinfo := service.NewToken().UserInfo(ctx.GetHeader("token"))
if userinfo.ID == cast.ToInt64(req.ID) {
err2.PriErr("you can't delete yourself")
}
new(service.User).Delete(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}
func (a *User) List(ctx *gin.Context) {
var req request.UserList
if err := ctx.ShouldBind(&req); err != nil {
err2.ParamErr("<user list>", err)
}
res, count := new(service.User).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (a *User) Login(ctx *gin.Context) {
var req request.UserLogin
if err := ctx.ShouldBind(&req); err != nil {
err2.ParamErr("<user login>", err)
}
res := new(service.User).Login(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
return
}
func (a *User) Logout(ctx *gin.Context) {
var req request.UserLogout
if err := ctx.ShouldBindHeader(&req); err != nil {
err2.ParamErr("<user logout>", err)
}
new(service.User).Logout(req)
ctx.JSON(http.StatusOK, response.NewRspOk())
}

View File

@ -0,0 +1,89 @@
package middleware
import (
"encoding/json"
"strings"
"yintai-api/app/common/cache"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/app/common/utils"
"yintai-api/base/global"
"github.com/gin-gonic/gin"
)
func Login(c *gin.Context) {
token := c.Request.Header.Get("token")
token = strings.TrimSpace(token)
if token == "" {
err2.TokenErr("<login middleware> token not exists")
c.Abort()
return
}
key := cache.NewKeys().User() + token
if res := global.GetRedis().Get(key); res.Val() == "" {
err2.TokenErr("<login middleware> token not exists", res.Err())
c.Abort()
return
}
c.Next()
}
// Permission user router permission check
func Permission() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.Request.Header.Get("token")
token = strings.TrimSpace(token)
if token == "" {
err2.TokenErr("<permission middleware> token not exists")
c.Abort()
return
}
key := cache.NewKeys().User() + token
val := global.GetRedis().Get(key).Val()
if val == "" {
err2.TokenErr("<permission middleware> token not exists")
c.Abort()
return
}
var user *model.UserWithRole
err := json.Unmarshal([]byte(val), &user)
if err != nil {
err2.TokenErr("<permission middleware> token not exists")
}
key = cache.NewKeys().Api(user.RoleID)
member := utils.SourceFormat(c.Request.Method, c.FullPath())
// skip no auth
if noAuth(member) {
c.Next()
}
if val := global.GetRedis().SIsMember(key, member); !val.Val() {
err2.PriErr("<permission middleware> no permission", val.Err())
c.Abort()
return
}
c.Next()
}
}
// 不需要鉴权的接口
func noAuth(source string) bool {
type no struct {
Method string
Url string
}
x := make([]no, 0)
x = append(x, no{"POST", "/yt/user/login"})
for _, v := range x {
if source == utils.SourceFormat(v.Method, v.Url) {
return true
}
}
return false
}

View File

@ -0,0 +1,27 @@
package request
import "yintai-api/app/common/request"
type CategoryCreate struct {
Name string `json:"name"`
NameEn string `json:"name_en"`
Pid string `json:"pid"`
Type string `json:"type"`
}
type CategoryUpdate struct {
ID string `json:"id"`
CategoryCreate
}
type CategoryDelete struct {
ID string `form:"id"`
}
type CategoryList struct {
request.Paginate
Pid string `form:"pid"`
Name string `form:"name"`
NameEn string `form:"name_en"`
Type string `form:"type"`
}

View File

@ -0,0 +1,19 @@
package request
import "yintai-api/app/common/request"
type ConfigCreate struct {
}
type ConfigUpdate struct {
ID string `json:"id"`
ConfigCreate
}
type ConfigDelete struct {
ID string `form:"id"`
}
type ConfigList struct {
request.Paginate
}

View File

@ -0,0 +1,38 @@
package request
import "yintai-api/app/common/request"
type DocTrans struct {
Path string `json:"path"`
FileName string `json:"file_name"`
Title string `json:"title"`
SubTitle string `json:"sub_title"`
Cover string `json:"cover"`
Desc string `json:"desc"`
Extra string `json:"extra"`
}
type DocumentCreate struct {
Trans map[string]DocTrans `json:"translations"`
CategoryID string `json:"category_id"`
Weight string `json:"weight"`
}
type DocumentUpdate struct {
ID string `json:"id"`
DocumentCreate
}
type DocumentDelete struct {
ID string `form:"id"`
}
type DocumentList struct {
request.Paginate
Lang string `form:"lang"`
Category string `form:"category_id"`
FileName string `form:"file_name"`
Title string `form:"title"`
SubTitle string `form:"sub_title"`
Desc string `form:"desc"`
}

40
app/admin/request/job.go Normal file
View File

@ -0,0 +1,40 @@
package request
import "yintai-api/app/common/request"
type JobTrans struct {
Name string `json:"name"`
Desc string `json:"description"`
Requirement string `json:"requirement"`
ContractInfo string `json:"contract_info"`
}
type JobCreate struct {
JobType string `json:"job_type"`
JobArea string `json:"job_area"`
JobUnit string `json:"job_unit"`
RecruitCount string `json:"recruit_count"`
City string `json:"city"`
Translations map[string]JobTrans `json:"translations"`
}
type JobUpdate struct {
ID string `json:"id"`
JobCreate
}
type JobDelete struct {
ID string `form:"id"`
}
type JobList struct {
request.Paginate
Lang string `form:"lang" binding:"required"`
City string `form:"city"`
Title string `form:"title"`
JobType string `form:"job_type"`
JobArea string `form:"job_area"`
JobUnit string `form:"job_unit"`
Desc string `form:"desc"`
Reqs string `form:"reqs"`
}

37
app/admin/request/news.go Normal file
View File

@ -0,0 +1,37 @@
package request
import "yintai-api/app/common/request"
type NewsTranslation struct {
Title string `json:"title"`
Content string `json:"content"`
PublishTime string `json:"publish_time"`
}
type NewsCreate struct {
CategoryID string `json:"category_id"`
CoverShow string `json:"cover_show"`
Weight string `json:"weight"`
Pinned string `json:"pinned"`
CoverResource map[string][]string `json:"cover_resource"`
Trans map[string]NewsTranslation `json:"translations"`
}
type NewsUpdate struct {
ID string `json:"id"`
NewsCreate
}
type NewsDelete struct {
ID string `form:"id"`
}
type NewsList struct {
request.Paginate
Lang string `form:"lang" binding:"required"`
Title string `form:"title"`
Content string `form:"content"`
PublishTime string `form:"publish_time"`
CategoryID string `form:"category_id"`
}

28
app/admin/request/page.go Normal file
View File

@ -0,0 +1,28 @@
package request
import (
"yintai-api/app/common/request"
)
type PageCreate struct {
Pid string `json:"pid"`
Name string `json:"name"`
Page string `json:"page"`
Extra string `json:"content"`
Weight string `json:"weight"`
Tags string `json:"tags"`
}
type PageUpdate struct {
ID string `json:"id"`
PageCreate
}
type PageDelete struct {
ID string `form:"id"`
}
type PageList struct {
request.Paginate
Name string `form:"name"`
}

View File

@ -0,0 +1,33 @@
package request
import "yintai-api/app/common/request"
type ProcessTranslation struct {
Title string `json:"title"`
Images []string `json:"images"`
Content string `json:"content"`
ProcessTime string `json:"process_time"`
}
type ProcessCreate struct {
CategoryID string `json:"category_id"`
Translations map[string]ProcessTranslation `json:"translations"`
}
type ProcessUpdate struct {
ID string `json:"id"`
ProcessCreate
}
type ProcessDelete struct {
ID string `form:"id"`
}
type ProcessList struct {
request.Paginate
Lang string `form:"lang" binding:"required"`
Title string `form:"title"`
Content string `form:"content"`
ProcessTime string `form:"process_time"`
CategoryID string `form:"category_id"`
}

View File

@ -0,0 +1,31 @@
package request
import "yintai-api/app/common/request"
type ResourceCreate struct {
Name string `json:"name"`
Type string `json:"type"`
Code string `json:"code"`
Path string `json:"path"`
Method string `json:"method"`
Pid string `json:"pid"`
}
type ResourceUpdate struct {
ID string `json:"id"`
ResourceCreate
}
type ResourceDelete struct {
ID string `form:"id"`
}
type ResourceList struct {
request.Paginate
Name string `form:"name"`
Type string `form:"type"`
Code string `form:"code"`
Path string `form:"path"`
Method string `form:"method"`
Pid string `form:"pid"`
}

29
app/admin/request/role.go Normal file
View File

@ -0,0 +1,29 @@
package request
import "yintai-api/app/common/request"
type RoleCreate struct {
Name string `json:"name"`
Desc string `json:"desc"`
Resource []string `json:"resource"`
}
type RoleUpdate struct {
ID string `json:"id"`
RoleCreate
}
type RoleDelete struct {
ID string `form:"id"`
DelAccount string `form:"del_account"`
}
type RoleList struct {
request.Paginate
Name string `form:"name"`
Desc string `form:"desc"`
}
type RoleGet struct {
ID string `form:"id"`
}

38
app/admin/request/user.go Normal file
View File

@ -0,0 +1,38 @@
package request
import "yintai-api/app/common/request"
type UserCreate struct {
Username string `json:"username"`
Account string `json:"account"`
Password string `json:"password"`
Role string `json:"role"`
}
type UserUpdate struct {
UserId string `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Role string `json:"role"`
Status string `json:"status"`
}
type UserDelete struct {
ID string `form:"id"`
}
type UserList struct {
request.Paginate
Username string `form:"username"`
Account string `form:"account"`
Role string `from:"role"`
}
type UserLogin struct {
Account string `json:"account"`
Password string `json:"password"`
}
type UserLogout struct {
Token string `header:"token"`
}

75
app/admin/service/base.go Normal file
View File

@ -0,0 +1,75 @@
package service
import (
"fmt"
"time"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/app/common/service"
"gorm.io/gorm"
)
func Images(s []string) []string {
imgs := make([]string, 0)
for _, img := range s {
temp := service.NewQiniu().ObjectKey(img)
if temp != "" {
imgs = append(imgs, temp)
}
}
return imgs
}
func BizCateCreate(tx *gorm.DB, BizID, cateID int64, cateType string) error {
cate, err := dao.NewCategory(tx).GetWithType(cateID, cateType)
if err != nil {
return err
}
if cate == nil {
err2.NotEsxErr(fmt.Sprintf("category not exist: type [%s] id [%d]", cateType, cateID))
}
m := &model.CategoryRelation{
CategoryId: cateID,
Type: cateType,
BizId: BizID,
CreateTime: time.Now().Unix(),
}
if err = dao.NewCategoryRelation(tx).Create(m); err != nil {
return err
}
return nil
}
func BizCateUpdate(tx *gorm.DB, BizID int64, cateID int64, cateType string) error {
cate, err := dao.NewCategory(tx).GetWithType(cateID, cateType)
if err != nil {
return err
}
if cate == nil {
err2.NotEsxErr(fmt.Sprintf("category not exist: type [%s] id [%d]", cateType, cateID))
}
if err = dao.NewCategoryRelation(tx).DeleteByCondition(BizID, cateType); err != nil {
return err
}
m := &model.CategoryRelation{
CategoryId: cateID,
Type: cateType,
BizId: BizID,
CreateTime: time.Now().Unix(),
}
if err = dao.NewCategoryRelation(tx).Create(m); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,199 @@
package service
import (
"fmt"
"slices"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Category struct{}
func (r *Category) Create(req request.CategoryCreate) int64 {
if cast.ToInt64(req.Pid) != 0 {
ok, err := dao.NewCategory().Exists(cast.ToInt64(req.Pid))
if err != nil {
err2.DbErr(err)
}
if !ok {
err2.NotEsxErr()
}
}
if !slices.Contains(model.CategoryTypes, req.Type) {
err2.ParamErr()
}
m := new(model.Category)
m.Pid = cast.ToInt64(req.Pid)
m.Name = req.Name
m.NameEn = req.NameEn
m.Type = req.Type
m.CreateTime = time.Now().Unix()
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewCategory(tx).Create(m); err != nil {
return fmt.Errorf("<category create>: create category error: " + err.Error())
}
path := fmt.Sprintf("%d/", m.ID)
if m.Pid != 0 {
parent, err := dao.NewCategory(tx).Get(m.Pid)
if err != nil {
return fmt.Errorf("<category create>: create category error: " + err.Error())
}
path = fmt.Sprintf("%s%d/", parent.Path, m.ID)
}
m.Path = path
if err := dao.NewCategory(tx).Update(m); err != nil {
return fmt.Errorf("<category create>: update category path error: " + err.Error())
}
return nil
})
if err != nil {
err2.DbErr(err.Error())
}
return m.ID
}
func (r *Category) Update(req request.CategoryUpdate) {
m, err := dao.NewCategory().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if req.Name != "" {
m.Name = req.Name
}
if req.NameEn != "" {
m.NameEn = req.NameEn
}
if req.Type != "" {
if !slices.Contains(model.CategoryTypes, req.Type) {
err2.ParamErr()
}
m.Type = req.Type
}
oldPath := m.Path
oldPid := m.Pid
m.Pid = cast.ToInt64(req.Pid)
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
path := fmt.Sprintf("%d/", m.ID)
if m.Pid != 0 {
if parentCate, err := dao.NewCategory(tx).Get(m.Pid); err != nil {
return fmt.Errorf("<category update>: get category error: " + err.Error())
} else {
path = fmt.Sprintf("%s%d/", parentCate.Path, m.ID)
}
}
m.Path = path
m.UpdateTime = time.Now().Unix()
if err = dao.NewCategory(tx).Update(m); err != nil {
return fmt.Errorf("<category update>: update category path error: " + err.Error())
}
if oldPid == m.Pid {
return nil
}
// 更新子级别
subCate, err := dao.NewCategory(tx).GetByPath(oldPath)
if err != nil {
return fmt.Errorf("<category update>: get sub category data error: " + err.Error())
}
for _, category := range subCate {
parentCate, _ := dao.NewCategory(tx).Get(category.Pid)
category.Path = fmt.Sprintf("%s%d/", parentCate.Path, category.ID)
category.UpdateTime = time.Now().Unix()
if err = dao.NewCategory(tx).Update(category); err != nil {
return fmt.Errorf("<category update>: update sub category path error: " + err.Error())
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Category) Delete(req request.CategoryDelete) {
m, err := dao.NewCategory().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
// 查询这个分类下的所有数据
ms, err := dao.NewCategory().GetByPath(m.Path)
if err != nil {
err2.DbErr(err)
}
if ms == nil {
err2.NotEsxErr()
}
ids := make([]int64, 0)
for _, category := range ms {
ids = append(ids, cast.ToInt64(category.ID))
}
relation, err := dao.NewCategoryRelation().GetByIds(ids...)
if err != nil {
err2.DbErr(err)
}
if relation != nil && len(relation) > 0 {
err2.InUseErr()
}
if err = dao.NewCategory().Delete(m.Path); err != nil {
err2.DbErr(err)
}
return
}
func (r *Category) List(req request.CategoryList) (any, int64) {
if !slices.Contains(model.CategoryTypes, req.Type) {
err2.ParamErr()
}
req.Pagination()
lists, count, err := dao.NewCategory().List(cast.ToInt64(req.Pid), req.Name, req.NameEn, req.Type, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

View File

@ -0,0 +1,74 @@
package service
import (
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"github.com/spf13/cast"
)
type Config struct{}
func (r *Config) Create(req request.ConfigCreate) int64 {
m := new(model.Config)
m.CreateTime = time.Now().Unix()
if err := dao.NewConfig().Create(m); err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *Config) Update(req request.ConfigUpdate) {
m, err := dao.NewConfig().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
m.UpdateTime = time.Now().Unix()
if err = dao.NewConfig().Update(m); err != nil {
err2.DbErr(err)
}
return
}
func (r *Config) Delete(req request.ConfigDelete) {
m, err := dao.NewConfig().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if err = dao.NewConfig().Delete(m.ID); err != nil {
err2.DbErr(err)
}
return
}
func (r *Config) List(req request.ConfigList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewConfig().List(req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

View File

@ -0,0 +1,207 @@
package service
import (
"slices"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/app/common/service"
"yintai-api/base/global"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Document struct{}
func (r *Document) Create(req request.DocumentCreate) int64 {
m := new(model.Document)
m.Weight = cast.ToInt64(req.Weight)
m.CreateTime = time.Now().Unix()
trans := make([]*model.DocumentTranslations, 0)
for lang, tran := range req.Trans {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
trans = append(trans, &model.DocumentTranslations{
DocumentID: 0,
Lang: lang,
Name: tran.FileName,
Title: tran.Title,
SubTitle: tran.SubTitle,
ImageTitle: "",
Description: tran.Desc,
StorageType: "qiniu",
StoragePath: service.NewQiniu().ObjectKey(tran.Path),
Cover: service.NewQiniu().ObjectKey(tran.Cover),
Extra: tran.Extra,
})
}
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewDocument(tx).Create(m); err != nil {
return err
}
for _, tran := range trans {
tran.DocumentID = m.ID
if err := dao.NewDocumentTranslations(tx).Create(tran); err != nil {
return err
}
}
if err := BizCateCreate(tx, m.ID, cast.ToInt64(req.CategoryID), model.CateTypeFile); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *Document) Update(req request.DocumentUpdate) {
m, err := dao.NewDocument().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if weight := cast.ToInt64(req.Weight); weight != m.Weight {
m.Weight = weight
}
m.UpdateTime = time.Now().Unix()
trans := make([]*model.DocumentTranslations, 0)
for lang, tran := range req.Trans {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
t, err := dao.NewDocumentTranslations().GetByMaster(m.ID, lang)
if err != nil {
err2.DbErr(err)
}
if t == nil {
t = new(model.DocumentTranslations)
}
if tran.Path != "" {
t.StoragePath = service.NewQiniu().ObjectKey(tran.Path)
}
if tran.FileName != "" {
t.Name = tran.FileName
}
if tran.SubTitle != "" {
t.SubTitle = tran.SubTitle
}
if tran.Cover != "" {
t.Cover = service.NewQiniu().ObjectKey(tran.Cover)
}
if tran.Desc != "" {
t.Description = tran.Desc
}
if tran.Extra != "" {
t.Extra = tran.Extra
}
trans = append(trans, t)
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewDocument(tx).Update(m); err != nil {
return err
}
for _, t := range trans {
t.DocumentID = m.ID
if err = dao.NewDocumentTranslations(tx).Update(t); err != nil {
return err
}
}
if v := cast.ToInt64(req.CategoryID); v != 0 {
if err = BizCateUpdate(tx, m.ID, v, model.CateTypeFile); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
}
func (r *Document) Delete(req request.DocumentDelete) {
m, err := dao.NewDocument().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewDocument(tx).Delete(m.ID); err != nil {
return err
}
if err = dao.NewDocumentTranslations(tx).Delete(m.ID); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
}
func (r *Document) List(req request.DocumentList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewDocument().List(req.Lang, cast.ToInt64(req.Category), req.FileName, req.Title, req.SubTitle, req.Desc, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}
func (r *Document) Get(req request.DocumentDelete) any {
res := make(map[string]any)
for _, lang := range consts.LangSupport {
x, err := dao.NewDocument().GetLang(lang, cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
res[lang] = x.Format()
}
return res
}

102
app/admin/service/files.go Normal file
View File

@ -0,0 +1,102 @@
package service
import (
"fmt"
"mime/multipart"
"os"
"path"
"runtime"
"slices"
"strings"
"time"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/service"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil"
)
type Files struct{}
// 直接上传到七牛云上。返回保存的地址,访问的url每次都用新的
func (f Files) UploadToken() string {
return service.NewQiniu().UploadToken()
}
func (f Files) Upload(file *multipart.FileHeader, ctx *gin.Context) any {
start := time.Now()
defer log.Debug(" [all] time cost:", time.Since(start))
if file == nil {
err2.ParamErr("file is nil")
return nil
}
// support check
if err := f.Support(path.Ext(file.Filename), file.Size); err != nil {
err2.ParamErr(err)
}
// 保存本地临时文件
dst := f.Dst(file.Filename)
if runtime.GOOS == "windows" {
dst = dst[1:]
}
err := ctx.SaveUploadedFile(file, dst)
if err != nil {
err2.InnerErr(err)
}
objectKey := service.NewQiniu().Save(dst, f.ObjectKey(file.Filename))
defer func() {
_ = os.Remove(dst)
}()
return service.NewQiniu().ForeverUrl(objectKey)
}
func (f Files) ObjectKey(ext string) string {
return fmt.Sprintf("yintai/%s", f.Name(ext))
}
func (f Files) Dst(ext string) string {
return "/tmp/" + f.Name(ext)
}
func (f Files) Name(ext string) string {
now := time.Now().Format("20060102150405")
return fmt.Sprintf("%s_%s%s", now, goutil.RandomStr(4), ext)
}
func (f Files) Support(ext string, size int64) error {
video := []string{"mp4", "m3u8"}
audio := []string{"mp3"}
img := []string{"png", "jpg", "jpeg", "jpg", "svg", "gif", "webp"}
doc := []string{"ppt", "xls", "xlsx", "pptx", "pdf"}
type T struct {
support []string
size int64
}
x := make([]T, 0)
x = append(x, T{support: video, size: 30 << 20})
x = append(x, T{support: audio, size: 30 << 20})
x = append(x, T{support: img, size: 10 << 20})
x = append(x, T{support: doc, size: 120 << 20})
for _, t := range x {
ext = strings.TrimLeft(ext, ".")
if slices.Contains(t.support, ext) {
if size > t.size {
return fmt.Errorf("file too large")
}
}
}
return nil
}

287
app/admin/service/job.go Normal file
View File

@ -0,0 +1,287 @@
package service
import (
"slices"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Job struct{}
func (r *Job) Create(req request.JobCreate) int64 {
m := new(model.Job)
m.RecruitCount = cast.ToInt64(req.RecruitCount)
m.City = req.City
m.JobType = cast.ToInt64(req.JobType)
m.JobArea = cast.ToInt64(req.JobArea)
m.JobUnit = cast.ToInt64(req.JobUnit)
m.CreateTime = time.Now().Unix()
ms := make([]*model.JobTranslations, 0)
for lang, trans := range req.Translations {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
temp := &model.JobTranslations{
Lang: lang,
Name: trans.Name,
Description: trans.Desc,
Requirement: trans.Requirement,
ContractInfo: trans.ContractInfo,
}
ms = append(ms, temp)
}
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewJob(tx).Create(m); err != nil {
return err
}
for _, trans := range ms {
trans.JobID = m.ID
if err := dao.NewJobTranslations(tx).Create(trans); err != nil {
return err
}
}
if err := BizCateCreate(tx, m.ID, cast.ToInt64(req.JobType), model.CateTypeJobType); err != nil {
return err
}
if err := BizCateCreate(tx, m.ID, cast.ToInt64(req.JobArea), model.CateTypeJobArea); err != nil {
return err
}
if err := BizCateCreate(tx, m.ID, cast.ToInt64(req.JobUnit), model.CateTypeJobUnit); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *Job) Update(req request.JobUpdate) {
m, err := dao.NewJob().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if cast.ToInt64(req.RecruitCount) != 0 {
m.RecruitCount = cast.ToInt64(req.RecruitCount)
}
if req.City != "" {
m.City = req.City
}
m.UpdateTime = time.Now().Unix()
ms := make([]*model.JobTranslations, 0)
for lang, trans := range req.Translations {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
t := new(model.JobTranslations)
if t, err = dao.NewJobTranslations().GetByMaster(m.ID, lang); err != nil {
err2.DbErr(err)
}
if trans.Name != "" {
t.Name = trans.Name
}
if trans.Desc != "" {
t.Description = trans.Desc
}
if trans.Requirement != "" {
t.Requirement = trans.Requirement
}
if trans.ContractInfo != "" {
t.ContractInfo = trans.ContractInfo
}
ms = append(ms, t)
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
for _, trans := range ms {
if err = dao.NewJobTranslations(tx).Update(trans); err != nil {
return err
}
}
if v := cast.ToInt64(req.JobType); v > 0 {
m.JobType = v
if err = BizCateUpdate(tx, m.ID, v, model.CateTypeJobType); err != nil {
return err
}
}
if v := cast.ToInt64(req.JobArea); v > 0 {
m.JobArea = v
if err = BizCateUpdate(tx, m.ID, v, model.CateTypeJobArea); err != nil {
return err
}
}
if v := cast.ToInt64(req.JobUnit); v > 0 {
m.JobUnit = v
if err = BizCateUpdate(tx, m.ID, v, model.CateTypeJobUnit); err != nil {
return err
}
}
if err = dao.NewJob(tx).Update(m); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Job) Delete(req request.JobDelete) {
m, err := dao.NewJob().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewJob().Delete(m.ID); err != nil {
return err
}
if err = dao.NewJobTranslations(tx).Delete(m.ID); err != nil {
return err
}
if err = dao.NewCategoryRelation(tx).DeleteByCondition(m.ID, model.CateTypeJob); err != nil {
return err
}
for _, t := range model.CateJobTypes {
if err = dao.NewCategoryRelation(tx).DeleteByCondition(m.ID, t); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Job) List(req request.JobList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewJob().List(req.Lang, req.City, req.Title, req.Desc, req.Reqs, req.JobType, req.JobArea, req.JobUnit, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
temp := list.Format()
temp["category"] = r.GetCate(list)[list.Lang]
res = append(res, temp)
}
return res, count
}
func (r *Job) Get(req request.JobDelete) any {
res := make(map[string]any)
for _, lang := range consts.LangSupport {
x, err := dao.NewJob().GetLang(cast.ToInt64(req.ID), lang)
if err != nil {
err2.DbErr(err)
}
if x == nil {
res[lang] = make(map[string]any)
continue
}
format := x.Format()
format["category"] = r.GetCate(x)[x.Lang]
res[lang] = format
}
return res
}
func (r *Job) GetCate(params *model.JobPage) map[string]map[string]any {
// type:id
s := map[string]int64{
model.CateTypeJobType: params.JobType,
model.CateTypeJobArea: params.JobArea,
model.CateTypeJobUnit: params.JobUnit,
}
res := make(map[string]map[string]any)
for t, id := range s {
x, err := dao.NewCategory().GetWithType(id, t)
if err != nil {
err2.DbErr(err)
}
if x == nil {
x = new(model.Category)
}
for _, lang := range consts.LangSupport {
name := ""
switch lang {
case consts.LangZH:
name = x.Name
case consts.LangEN:
name = x.NameEn
}
if _, ok := res[lang]; !ok {
res[lang] = make(map[string]any)
}
res[lang][t] = x.ID
res[lang][t+"_name"] = name
}
}
return res
}

229
app/admin/service/news.go Normal file
View File

@ -0,0 +1,229 @@
package service
import (
"encoding/json"
"slices"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type News struct{}
func (r *News) Create(req request.NewsCreate) int64 {
images := make(map[string][]string)
for sourceType, imgs := range req.CoverResource {
images[sourceType] = Images(imgs)
}
m := new(model.News)
m.CoverImages = goutil.EncodeJSON(images)
m.CoverShow = req.CoverShow
m.Count = 0
m.CreateTime = time.Now().Unix()
m.Weight = cast.ToInt64(req.Weight)
m.Pinned = cast.ToInt64(req.Pinned) % 2
ms := make([]*model.NewsTranslations, 0)
for lang, trans := range req.Trans {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
ms = append(ms, &model.NewsTranslations{
Lang: lang,
Title: trans.Title,
PublishTime: trans.PublishTime,
Content: trans.Content,
})
}
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewNews(tx).Create(m); err != nil {
return err
}
for _, trans := range ms {
trans.NewsID = m.ID
if err := dao.NewNewsTranslations(tx).Create(trans); err != nil {
return err
}
}
if err := BizCateCreate(tx, m.ID, cast.ToInt64(req.CategoryID), model.CateTypeNews); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *News) Update(req request.NewsUpdate) {
m, err := dao.NewNews().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
images := make(map[string][]string)
_ = json.Unmarshal([]byte(m.CoverImages), &images)
if req.CoverResource != nil {
for sourceType, imgs := range req.CoverResource {
images[sourceType] = Images(imgs)
}
m.CoverImages = goutil.EncodeJSON(images)
}
if m.CoverShow != "" {
m.CoverShow = req.CoverShow
}
if weight := cast.ToInt64(req.Weight); weight != m.Weight {
m.Weight = weight
}
if pinned := cast.ToInt64(req.Pinned); pinned != m.Pinned {
m.Pinned = pinned
}
m.UpdateTime = time.Now().Unix()
ms := make([]*model.NewsTranslations, 0)
for lang, trans := range req.Trans {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
t, err := dao.NewNewsTranslations().GetByMaster(m.ID, lang)
if err != nil {
err2.DbErr(err)
}
if t == nil {
t = new(model.NewsTranslations)
}
if trans.Title != "" {
t.Title = trans.Title
}
if trans.PublishTime != "" {
t.PublishTime = trans.PublishTime
}
if trans.Content != "" {
t.Content = trans.Content
}
ms = append(ms, t)
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewNews(tx).Update(m); err != nil {
return err
}
for _, trans := range ms {
trans.NewsID = m.ID
if err = dao.NewNewsTranslations(tx).Update(trans); err != nil {
return err
}
}
if cast.ToInt64(req.CategoryID) > 0 {
if err = BizCateUpdate(tx, m.ID, cast.ToInt64(req.CategoryID), model.CateTypeNews); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *News) Delete(req request.NewsDelete) {
m, err := dao.NewNews().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewNews(tx).Delete(m.ID); err != nil {
return err
}
if err = dao.NewNewsTranslations(tx).Delete(m.ID); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *News) List(req request.NewsList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewNews().List(req.Lang, req.Title, req.Content, req.PublishTime, cast.ToInt64(req.CategoryID), -1, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}
func (r *News) Get(req request.NewsDelete) any {
res := make(map[string]any)
for _, lang := range consts.LangSupport {
x, err := dao.NewNews().GetLang(cast.ToInt64(req.ID), lang)
if err != nil {
err2.DbErr(err)
}
if x == nil {
res[lang] = make(map[string]any)
continue
}
res[lang] = x.Format()
}
return res
}

196
app/admin/service/page.go Normal file
View File

@ -0,0 +1,196 @@
package service
import (
"fmt"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Page struct{}
func (r *Page) Create(req request.PageCreate) int64 {
r.Pid(req.Pid)
m := new(model.Page)
m.Name = req.Name
m.Pid = cast.ToInt64(req.Pid)
m.Page = req.Page
m.Content = req.Extra
m.Weight = cast.ToInt64(req.Weight)
m.Tags = req.Tags
m.CreateTime = time.Now().Unix()
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewPage(tx).Create(m); err != nil {
return err
}
m.Path = r.Path(m.ID, m.Pid)
if err := dao.NewPage(tx).Update(m); err != nil {
return err
}
// no category
return nil
})
if err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *Page) Path(id, pid int64) string {
p := ""
m, err := dao.NewPage().Get(cast.ToInt64(pid))
if err != nil {
err2.DbErr(err)
}
if m == nil {
p = fmt.Sprintf("/%d", id)
} else {
p = fmt.Sprintf("%s/%d", m.Path, id)
}
return p
}
// Pid :pid check
func (r *Page) Pid(id string) {
idx := cast.ToInt64(id)
if idx == 0 {
return
}
e, err := dao.NewPage().Exists(idx)
if err != nil {
err2.DbErr(err)
}
if !e {
err2.NotEsxErr()
}
}
func (r *Page) Update(req request.PageUpdate) {
r.Pid(req.Pid)
m, err := dao.NewPage().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
oldPid := m.Pid
oldPath := m.Path
if req.Name != "" {
m.Name = req.Name
}
if req.Page != "" {
m.Page = req.Page
}
if req.Extra != "" {
m.Content = req.Extra
}
if weight := cast.ToInt64(req.Weight); weight != 0 {
m.Weight = weight
}
if req.Tags != "" {
m.Tags = req.Tags
}
if pid := cast.ToInt64(req.Pid); pid != m.Pid {
if pid == m.ID {
pid = 0
}
m.Path = fmt.Sprintf("/%d", m.ID)
if pid != 0 {
m.Path = r.Path(m.ID, m.Pid)
}
m.Pid = pid
}
m.UpdateTime = time.Now().Unix()
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewPage(tx).Update(m); err != nil {
return err
}
if oldPid == m.Pid {
return nil
}
// pid was updated
subs, err := dao.NewPage(tx).GetByPath(oldPath)
if err != nil {
return err
}
for _, sub := range subs {
parent, _ := dao.NewPage(tx).Get(sub.Pid)
sub.Path = fmt.Sprintf("%s/%d", parent.Path, sub.ID)
if err = dao.NewPage(tx).Update(sub); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Page) Delete(req request.PageDelete) {
m, err := dao.NewPage().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if err = dao.NewPage().Delete(m.ID); err != nil {
err2.DbErr(err)
}
return
}
func (r *Page) List(req request.PageList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewPage().List(req.Name, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

View File

@ -0,0 +1,192 @@
package service
import (
"slices"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Process struct{}
func (r *Process) Create(req request.ProcessCreate) int64 {
m := &model.Process{CreateTime: time.Now().Unix()}
mt := make([]*model.ProcessTranslations, 0)
for lang, trans := range req.Translations {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
t := new(model.ProcessTranslations)
// 图片处理,只提取object_key
t.Images = goutil.EncodeJSON(Images(trans.Images))
t.Lang = lang
t.Content = trans.Content
t.ProcessTime = trans.ProcessTime
t.Title = trans.Title
mt = append(mt, t)
}
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewProcess(tx).Create(m); err != nil {
return err
}
for _, trans := range mt {
trans.ProcessID = m.ID
if err := dao.NewProcessTranslations(tx).Create(trans); err != nil {
return err
}
}
if err := BizCateCreate(tx, m.ID, cast.ToInt64(req.CategoryID), model.CateTypeProcess); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *Process) Update(req request.ProcessUpdate) {
m, err := dao.NewProcess().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
mt := make([]*model.ProcessTranslations, 0)
for lang, trans := range req.Translations {
lang = strings.ToUpper(lang)
if !slices.Contains(consts.LangSupport, lang) {
continue
}
t, err := dao.NewProcessTranslations().GetByMaster(m.ID, lang)
if err != nil {
err2.DbErr(err)
}
if t == nil {
t = new(model.ProcessTranslations)
}
if trans.Title != "" {
t.Title = trans.Title
}
if len(trans.Images) > 0 {
t.Images = goutil.EncodeJSON(Images(trans.Images))
}
if trans.Content != "" {
t.Content = trans.Content
}
if trans.ProcessTime != "" {
t.ProcessTime = trans.ProcessTime
}
mt = append(mt, t)
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
m.UpdateTime = time.Now().Unix()
_ = dao.NewProcess(tx).Update(m)
for _, trans := range mt {
trans.ProcessID = m.ID
if err = dao.NewProcessTranslations(tx).Update(trans); err != nil {
return err
}
}
if cast.ToInt64(req.CategoryID) != 0 {
if err = BizCateUpdate(tx, m.ID, cast.ToInt64(req.CategoryID), model.CateTypeProcess); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Process) Delete(req request.ProcessDelete) {
m, err := dao.NewProcess().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewProcess().Delete(m.ID); err != nil {
err2.DbErr(err)
}
if err = dao.NewProcessTranslations().Delete(m.ID); err != nil {
err2.DbErr(err)
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Process) List(req request.ProcessList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewProcess().List(req.Lang, req.Title, req.Content, req.ProcessTime, cast.ToInt64(req.CategoryID), req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}
func (r *Process) Get(req request.ProcessDelete) any {
res := make(map[string]any)
for _, lang := range consts.LangSupport {
x, err := dao.NewProcess().GetLang(lang, cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
res[lang] = x.Format()
}
return res
}

View File

@ -0,0 +1,203 @@
package service
import (
"fmt"
"net/http"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm"
)
var methods = map[string]struct{}{
http.MethodGet: {},
http.MethodPut: {},
http.MethodPost: {},
http.MethodPatch: {},
http.MethodDelete: {},
}
var types = map[string]struct{}{
model.ResourceTypeApi: {},
model.ResourceTypePage: {},
}
type Resource struct{}
func (r *Resource) Create(req request.ResourceCreate) int64 {
if _, ok := types[req.Type]; !ok {
err2.ParamErr("type", req.Type)
}
if req.Method != "" {
if _, ok := methods[strings.ToUpper(req.Method)]; !ok {
err2.ParamErr("method", req.Method)
}
}
// pid check
r.PidCheck(cast.ToInt64(req.Pid))
m := new(model.Resource)
m.Name = req.Name
m.Type = req.Type
m.Path = req.Path
m.Code = goutil.Md5(req.Path)
m.Method = req.Method
m.CreateTime = time.Now().Unix()
m.Pid = cast.ToInt64(req.Pid)
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewResource().Create(m); err != nil {
return err
}
resource, _ := dao.NewResource().Get(m.Pid)
if resource == nil {
m.Maps = fmt.Sprintf("/%d", m.ID)
} else {
m.Maps = fmt.Sprintf("%s/%d", resource.Maps, m.ID)
}
if err := dao.NewResource().Update(m); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return m.ID
}
func (r *Resource) PidCheck(pid int64) {
if pid == 0 {
return
}
resource, err := dao.NewResource().Get(pid)
if err != nil {
err2.DbErr(err)
}
if resource == nil {
err2.NotEsxErr()
}
}
func (r *Resource) Update(req request.ResourceUpdate) {
m, err := dao.NewResource().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if req.Name != "" {
m.Name = req.Name
}
if _, ok := types[req.Type]; !ok {
err2.ParamErr("type", req.Type)
}
if req.Method != "" {
if _, ok := methods[strings.ToUpper(req.Method)]; !ok {
err2.ParamErr("method", req.Method)
}
}
if cast.ToInt64(req.Pid) != m.Pid {
r.PidCheck(m.Pid)
}
if req.Path != "" {
m.Path = req.Path
}
pid := cast.ToInt64(req.Pid)
if pid == m.ID {
err2.ParamErr("pid not error")
}
m.UpdateTime = time.Now().Unix()
oldMaps := m.Maps
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
// 查询上级的maps更新m的maps
if pid != 0 {
// 先更新本级
m.Pid = pid
c, _ := dao.NewResource().Get(pid)
m.Maps = fmt.Sprintf("%s/%d", c.Maps, m.ID)
if err = dao.NewResource().Update(m); err != nil {
return err
}
// 再更新下级
slavers, _ := dao.NewResource().GetMaps(oldMaps)
for _, slaver := range slavers {
master, _ := dao.NewResource().Get(slaver.Pid)
if master != nil {
slaver.Maps = fmt.Sprintf("%s/%d", master.Maps, slaver.ID)
if err = dao.NewResource().Update(slaver); err != nil {
return err
}
}
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
return
}
func (r *Resource) Delete(req request.ResourceDelete) {
m, err := dao.NewResource().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if err = dao.NewResource().Delete(m.ID); err != nil {
err2.DbErr(err)
}
return
}
func (r *Resource) List(req request.ResourceList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewResource().List(req.Name, req.Type, req.Code, req.Method, req.Path, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

250
app/admin/service/role.go Normal file
View File

@ -0,0 +1,250 @@
package service
import (
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/cache"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/app/common/utils"
"yintai-api/base/global"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Role struct{}
func (r *Role) Create(req request.RoleCreate) int64 {
if req.Name == "" {
err2.ParamErr("name is empty.")
}
m := new(model.Role)
m.Name = req.Name
m.Desc = req.Desc
m.CreateTime = time.Now().Unix()
err := global.GetDB().Transaction(func(tx *gorm.DB) error {
if err := dao.NewRole(tx).Create(m); err != nil {
return err
}
if len(req.Resource) == 0 {
return nil
}
resource := make([]int64, 0, len(req.Resource))
for _, s := range req.Resource {
if v := cast.ToInt64(s); v > 0 {
resource = append(resource, v)
}
}
mr, err := dao.NewResource(tx).GetByIds(resource)
if err != nil {
return err
}
rs := make([]*model.RoleResource, 0, len(resource))
for _, v := range mr {
rs = append(rs, &model.RoleResource{
RoleID: m.ID,
ResourceID: v.ID,
})
}
if err = dao.NewRoleResource(tx).Create(rs); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
try := 3
for try > 0 {
if err = utils.LazyLoadPermission(m.ID); err == nil {
break
}
try--
}
return m.ID
}
func (r *Role) Update(req request.RoleUpdate) {
m, err := dao.NewRole().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
if req.Name != "" {
m.Name = req.Name
}
if req.Desc != "" {
m.Desc = req.Desc
}
m.UpdateTime = time.Now().Unix()
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewRole(tx).Update(m); err != nil {
return err
}
if len(req.Resource) == 0 {
return nil
}
resource := make([]int64, 0, len(req.Resource))
for _, s := range req.Resource {
if v := cast.ToInt64(s); v > 0 {
resource = append(resource, v)
}
}
mr, err := dao.NewResource(tx).GetByIds(resource)
if err != nil {
return err
}
rs := make([]*model.RoleResource, 0, len(resource))
for _, v := range mr {
rs = append(rs, &model.RoleResource{
RoleID: m.ID,
ResourceID: v.ID,
})
}
if err = dao.NewRoleResource(tx).Delete(m.ID); err != nil {
return err
}
if err = dao.NewRoleResource(tx).Create(rs); err != nil {
return err
}
return nil
})
if err != nil {
err2.DbErr(err)
}
try := 3
for try > 0 {
if err = utils.LazyLoadPermission(m.ID); err == nil {
break
}
try--
}
return
}
func (r *Role) Delete(req request.RoleDelete) {
m, err := dao.NewRole().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
if m == nil {
err2.NotEsxErr()
return
}
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewRole(tx).Delete(m.ID); err != nil {
return err
}
if err = dao.NewRoleResource(tx).Delete(m.ID); err != nil {
return err
}
if cast.ToBool(req.DelAccount) == true {
users, err := dao.NewUserRole(tx).GetAccount(m.ID)
if err != nil {
return err
}
if users == nil {
return nil
}
userIds := make([]int64, 0, len(users))
for _, user := range users {
userIds = append(userIds, user.ID)
}
if err = dao.NewUser().BatchDelete(userIds); err != nil {
return err
}
if err = dao.NewUserRole(tx).RoleDelete(m.ID); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr(err)
}
cache.GetRedis().Expire(cache.NewKeys().Api(m.ID), 1)
return
}
func (r *Role) List(req request.RoleList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewRole().List(req.Name, req.Desc, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}
func (r *Role) Get(req request.RoleGet) any {
resources, err := dao.NewResource().RoleGet(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0, len(resources))
for _, resource := range resources {
res = append(res, resource.Format())
}
return res
}
func (r *Role) Accounts(req request.RoleGet) any {
users, err := dao.NewUserRole().GetAccount(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0, len(users))
for _, user := range users {
res = append(res, user.Format())
}
return res
}

View File

@ -0,0 +1,29 @@
package service
import (
"encoding/json"
"yintai-api/app/common/cache"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
)
type Token struct{}
func NewToken() *Token {
return &Token{}
}
func (t *Token) UserInfo(token string) *model.UserWithRole {
key := cache.NewKeys().User() + token
tx := cache.GetRedis().Get(key)
if tx.Val() == "" {
err2.TokenErr()
}
user := new(model.UserWithRole)
if err := json.Unmarshal([]byte(tx.Val()), user); err != nil {
err2.TokenErr("parse user info error", err)
}
return user
}

263
app/admin/service/user.go Normal file
View File

@ -0,0 +1,263 @@
package service
import (
"fmt"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/cache"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type User struct {
user *model.UserWithRole
}
func NewUser(u *model.UserWithRole) *User {
return &User{user: u}
}
func (a *User) Create(req request.UserCreate) int64 {
// 通过 account 判断用户是否存在
exist, err := dao.NewUser().AccountExists(req.Account)
if err != nil {
err2.DbErr("<admin service create>", err)
}
if exist {
err2.EsxErr()
}
req.Password = strings.TrimSpace(req.Password)
if len(req.Password) < 1 {
err2.ParamErr("<admin service create>: password too short")
}
if cast.ToInt64(req.Role) != 0 {
// 检查 role 是否存在
exist, err = dao.NewRole().Exists(cast.ToInt64(req.Role))
if err != nil {
err2.DbErr("<admin service create>", err)
}
if !exist {
err2.NotEsxErr("<admin service create> check role")
}
}
// 通过事务来创建账号以及分配用户角色
m := new(model.User)
m.Username = req.Username
m.Account = req.Account
m.Password = goutil.Md5(req.Password + model.Salt)
m.CreateTime = time.Now().Unix()
m.Status = model.UserStatusNormal
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewUser(tx).Create(m); err != nil {
return err
}
if cast.ToInt64(req.Role) != 0 {
var role *model.Role
// 获取这个角色的页面和路由的所有权限
role, err = dao.NewRole(tx).Get(cast.ToInt64(req.Role))
if err != nil {
return err
}
m := new(model.UserRole)
m.UserID = cast.ToInt64(role.ID)
m.RoleID = cast.ToInt64(role.ID)
if err = dao.NewUserRole(tx).Create(m); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr("<admin service create>", err)
}
return m.ID
}
func (a *User) Update(req request.UserUpdate) {
var user *model.User
var err error
user, err = dao.NewUser().AccountGet(a.user.Account)
if err != nil {
err2.DbErr("<user service update>", err)
}
if user == nil {
err2.NotEsxErr("<user service update>")
return
}
if req.Username != "" {
user.Username = req.Username
}
if cast.ToInt64(req.Status) != 0 {
user.Status = cast.ToInt64(req.Status)
}
if cast.ToInt64(req.Role) != 0 {
role, err := dao.NewRole().Exists(cast.ToInt64(req.Role))
if err != nil {
err2.DbErr("<user service update>", err)
}
if !role {
err2.NotEsxErr()
}
}
// 不能修改密码
//req.Password = strings.TrimSpace(req.Password)
//if len(req.Password) < 1 {
// err2.ParamErr("<user service update>: password too short")
//}
//
//user.Password = goutil.Md5(req.Password + Salt)
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewUser(tx).Update(user); err != nil {
return err
}
if cast.ToInt64(req.Role) != 0 {
if err = dao.NewUserRole(tx).Delete(user.ID); err != nil {
return err
}
if err = dao.NewUserRole(tx).Create(&model.UserRole{UserID: user.ID, RoleID: cast.ToInt64(req.Role)}); err != nil {
return err
}
}
// 禁用即下线
if user.Status == model.UserStatusBaned {
a.expireByAccount(user.Account)
}
return nil
})
if err != nil {
err2.DbErr("<user service update>", err)
}
}
func (a *User) Delete(req request.UserDelete) {
var user *model.User
var err error
user, err = dao.NewUser().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr("<user service update>", err)
}
if user == nil {
err2.NotEsxErr("<user service update>")
return
}
if err = dao.NewUser().Delete(user.ID); err != nil {
err2.DbErr("<user service update>", err)
}
a.expireByAccount(user.Account)
return
}
func (a *User) List(req request.UserList) (any, int64) {
req.Pagination()
users, count, err := dao.NewUser().List(req.Username, req.Account, cast.ToInt64(req.Role), req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr("<users service list>", err)
}
res := make([]map[string]any, 0)
for _, m := range users {
res = append(res, m.Format())
}
return res, count
}
func (a *User) Login(req request.UserLogin) any {
user, err := dao.NewUser().GetWithRole(req.Account)
if err != nil {
err2.DbErr("<user service login>", err)
}
if user == nil {
err2.NotEsxErr("<user service login>")
return ""
}
if user.Password != goutil.Md5(req.Password+model.Salt) {
err2.PriErr("<user service login>: wrong password")
}
token := fmt.Sprintf("%s", goutil.RandomStr(64))
expire := time.Hour * 24 * 30
redix := cache.GetRedis()
key := cache.NewKeys().User() + token
if err = redix.Set(key, goutil.EncodeJSON(user), expire).Err(); err != nil {
err2.DbErr("<user service login>", err)
}
// 保存用户的user_id 到token
// 通过用户的account来创建一个 k-v account是key,其他的是value
if oldToken := redix.Get(cache.NewKeys().User2Token() + user.Account).Val(); oldToken != "" {
a.expire(oldToken)
}
redix.Set(cache.NewKeys().User2Token()+user.Account, token, expire)
resource, err := dao.NewResource().RoleGet(user.RoleID)
if err != nil {
err2.DbErr("<user service login>", err)
}
userResource := make([]map[string]any, 0)
for _, v := range resource {
if v.Type != "page" {
continue
}
userResource = append(userResource, v.Format())
}
res := make(map[string]any)
res["resource"] = userResource
res["token"] = token
return res
}
func (a *User) Logout(req request.UserLogout) {
a.expire(req.Token)
return
}
func (a *User) expireByAccount(account string) {
key := cache.NewKeys().User2Token() + account
token := cache.GetRedis().Get(key).Val()
if token == "" {
return
}
a.expire(token)
}
func (a *User) expire(token string) {
redix := cache.GetRedis()
key := cache.NewKeys().User() + token
redix.Del(key)
return
}

View File

@ -0,0 +1,22 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Category struct{}
func (r *Category) List(ctx *gin.Context) {
var req request.CategoryList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Category).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,22 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Config struct{}
func (r *Config) List(ctx *gin.Context) {
var req request.ConfigList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Config).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,29 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Document struct{}
func (r *Document) List(ctx *gin.Context) {
var req request.DocumentList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Document).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *Document) Get(ctx *gin.Context) {
var req request.DocumentDelete
req.ID = ctx.Param("id")
res := new(service.Document).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

29
app/api/controller/job.go Normal file
View File

@ -0,0 +1,29 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Job struct{}
func (r *Job) List(ctx *gin.Context) {
var req request.JobList2
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Job).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *Job) Get(ctx *gin.Context) {
var req request.JobDelete
req.ID = ctx.Param("id")
res := new(service.Job).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,38 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type News struct{}
func (r *News) List(ctx *gin.Context) {
var req request.NewsList2
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.News).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}
func (r *News) Get(ctx *gin.Context) {
var req request.NewsDelete
req.ID = ctx.Param("id")
res := new(service.News).Get(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}
func (r *News) PreNext(ctx *gin.Context) {
var req request.PreNext
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res := new(service.News).PreNext(req)
ctx.JSON(http.StatusOK, response.NewRsp(res))
}

View File

@ -0,0 +1,22 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Page struct{}
func (r *Page) List(ctx *gin.Context) {
var req request.PageList
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Page).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,22 @@
package controller
import (
"net/http"
"yintai-api/app/api/request"
"yintai-api/app/api/service"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
)
type Process struct{}
func (r *Process) List(ctx *gin.Context) {
var req request.ProcessList2
if err := ctx.Bind(&req); err != nil {
err2.ParamErr(err)
}
res, count := new(service.Process).List(req)
ctx.JSON(http.StatusOK, response.NewListRsp(count, res))
}

View File

@ -0,0 +1,27 @@
package request
import "yintai-api/app/common/request"
type CategoryCreate struct {
Name string `json:"name"`
NameEn string `json:"name_en"`
Pid string `json:"pid"`
Type string `json:"type"`
}
type CategoryUpdate struct {
ID string `json:"id"`
CategoryCreate
}
type CategoryDelete struct {
ID string `form:"id"`
}
type CategoryList struct {
request.Paginate
Pid string `form:"pid"`
Name string `form:"name"`
NameEn string `form:"name_en"`
Type string `form:"type"`
}

19
app/api/request/config.go Normal file
View File

@ -0,0 +1,19 @@
package request
import "yintai-api/app/common/request"
type ConfigCreate struct {
}
type ConfigUpdate struct {
ID string `json:"id"`
ConfigCreate
}
type ConfigDelete struct {
ID string `form:"id"`
}
type ConfigList struct {
request.Paginate
}

View File

@ -0,0 +1,36 @@
package request
import "yintai-api/app/common/request"
type DocTrans struct {
Path string `json:"path"`
FileName string `json:"file_name"`
Title string `json:"title"`
SubTitle string `json:"sub_title"`
Desc string `json:"desc"`
Extra string `json:"extra"`
}
type DocumentCreate struct {
Trans map[string]DocTrans `json:"translations"`
CategoryID string `json:"category_id"`
}
type DocumentUpdate struct {
ID string `json:"id"`
DocumentCreate
}
type DocumentDelete struct {
ID string `form:"id"`
}
type DocumentList struct {
request.Paginate
Lang string `form:"lang"`
Category string `form:"category_id"`
FileName string `form:"file_name"`
Title string `form:"title"`
SubTitle string `form:"sub_title"`
Desc string `form:"desc"`
}

52
app/api/request/job.go Normal file
View File

@ -0,0 +1,52 @@
package request
import "yintai-api/app/common/request"
type JobTrans struct {
Name string `json:"name"`
Desc string `json:"description"`
Requirement string `json:"requirement"`
ContractInfo string `json:"contract_info"`
}
type JobCreate struct {
JobType string `json:"job_type"`
JobArea string `json:"job_area"`
JobUnit string `json:"job_unit"`
RecruitCount string `json:"recruit_count"`
City string `json:"city"`
Translations map[string]JobTrans `json:"translations"`
}
type JobUpdate struct {
ID string `json:"id"`
JobCreate
}
type JobDelete struct {
ID string `form:"id"`
}
type JobList struct {
request.Paginate
Lang string `form:"lang" binding:"required"`
City string `form:"city"`
Title string `form:"title"`
JobType string `form:"job_type"`
JobArea string `form:"job_area"`
JobUnit string `form:"job_unit"`
Desc string `form:"desc"`
Reqs string `form:"reqs"`
}
type JobList2 struct {
request.Paginate
Lang string `form:"lang"`
City string `form:"city"`
Title string `form:"title"`
JobType string `form:"job_type"`
JobArea string `form:"job_area"`
JobUnit string `form:"job_unit"`
Desc string `form:"desc"`
Reqs string `form:"reqs"`
}

51
app/api/request/news.go Normal file
View File

@ -0,0 +1,51 @@
package request
import "yintai-api/app/common/request"
type NewsTranslation struct {
Title string `json:"title"`
Content string `json:"content"`
PublishTime string `json:"publish_time"`
}
type NewsCreate struct {
CategoryID string `json:"category_id"`
CoverResource map[string][]string `json:"cover_resource"`
CoverShow string `json:"cover_show"`
Trans map[string]NewsTranslation `json:"translations"`
}
type NewsUpdate struct {
ID string `json:"id"`
NewsCreate
}
type NewsDelete struct {
ID string `form:"id"`
}
type NewsList struct {
request.Paginate
Lang string `form:"lang" binding:"required"`
Title string `form:"title"`
Content string `form:"content"`
PublishTime string `form:"publish_time"`
CategoryID string `form:"category_id"`
}
type NewsList2 struct {
request.Paginate
Lang string `form:"lang"`
Title string `form:"title"`
Content string `form:"content"`
PublishTime string `form:"publish_time"`
CategoryID string `form:"category_id"`
Pinned string `form:"pinned"`
}
type PreNext struct {
ID string `form:"id"`
CategoryID string `form:"category_id"`
Sort string `form:"sort"`
Lang string `form:"lang"`
}

28
app/api/request/page.go Normal file
View File

@ -0,0 +1,28 @@
package request
import (
"yintai-api/app/common/request"
)
type PageCreate struct {
Pid string `json:"pid"`
Name string `json:"name"`
Page string `json:"page"`
Extra string `json:"content"`
Weight string `json:"weight"`
Tags string `json:"tags"`
}
type PageUpdate struct {
ID string `json:"id"`
PageCreate
}
type PageDelete struct {
ID string `form:"id"`
}
type PageList struct {
request.Paginate
Name string `form:"name"`
}

View File

@ -0,0 +1,42 @@
package request
import "yintai-api/app/common/request"
type ProcessTranslation struct {
Title string `json:"title"`
Images []string `json:"images"`
Content string `json:"content"`
ProcessTime string `json:"process_time"`
}
type ProcessCreate struct {
CategoryID string `json:"category_id"`
Translations map[string]ProcessTranslation `json:"translations"`
}
type ProcessUpdate struct {
ID string `json:"id"`
ProcessCreate
}
type ProcessDelete struct {
ID string `form:"id"`
}
type ProcessList struct {
request.Paginate
Lang string `form:"lang" binding:"required"`
Title string `form:"title"`
Content string `form:"content"`
ProcessTime string `form:"process_time"`
CategoryID string `form:"category_id"`
}
type ProcessList2 struct {
request.Paginate
Lang string `form:"lang"`
Title string `form:"title"`
Content string `form:"content"`
ProcessTime string `form:"process_time"`
CategoryID string `form:"category_id"`
}

View File

@ -0,0 +1,32 @@
package service
import (
"slices"
"yintai-api/app/api/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"github.com/spf13/cast"
)
type Category struct{}
func (r *Category) List(req request.CategoryList) (any, int64) {
if !slices.Contains(model.CategoryTypes, req.Type) {
err2.ParamErr()
}
req.Pagination()
lists, count, err := dao.NewCategory().List(cast.ToInt64(req.Pid), req.Name, req.NameEn, req.Type, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

24
app/api/service/config.go Normal file
View File

@ -0,0 +1,24 @@
package service
import (
"yintai-api/app/api/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
)
type Config struct{}
func (r *Config) List(req request.ConfigList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewConfig().List(req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

View File

@ -0,0 +1,87 @@
package service
import (
"fmt"
"slices"
"sync"
"yintai-api/app/api/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
log "github.com/sirupsen/logrus"
"github.com/spf13/cast"
)
type Document struct{}
func (r *Document) List(req request.DocumentList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewDocument().List(req.Lang, cast.ToInt64(req.Category), req.FileName, req.Title, req.SubTitle, req.Desc, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
listLang := make([]string, 0)
for _, list := range lists {
listLang = append(listLang, fmt.Sprintf("%d_%s", list.ID, list.Lang))
}
res := make([]any, 0)
var store sync.Map
var wg sync.WaitGroup
for _, list := range lists {
wg.Add(1)
go func(list *model.DocumentPage) {
defer wg.Done()
store.Store(fmt.Sprintf("%d_%s", list.ID, list.Lang), list.Format())
for _, lang := range consts.LangSupport {
lang = fmt.Sprintf("%d_%s", list.ID, list.Lang)
if !slices.Contains(listLang, lang) {
log.Debugf("%s is writen", list.Lang)
store.Store(lang, r.One(lang, list.ID))
}
}
}(list)
}
wg.Wait()
written := make(map[string]bool)
for _, list := range lists {
for _, lang := range consts.LangSupport {
lang = fmt.Sprintf("%d_%s", list.ID, list.Lang)
if _, ok := written[lang]; ok {
continue
}
v, ok := store.Load(lang)
if !ok {
continue
}
res = append(res, v)
written[lang] = true
}
}
return res, count
}
func (r *Document) One(lang string, id int64) map[string]any {
x, err := dao.NewDocument().GetLang(lang, id)
if err != nil {
err2.DbErr(err)
}
return x.Format()
}
func (r *Document) Get(req request.DocumentDelete) any {
res := make([]map[string]any, 0)
for _, lang := range consts.LangSupport {
res = append(res, r.One(lang, cast.ToInt64(req.ID)))
}
return res
}

114
app/api/service/job.go Normal file
View File

@ -0,0 +1,114 @@
package service
import (
"fmt"
"slices"
"yintai-api/app/api/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"github.com/spf13/cast"
)
type Job struct{}
func (r *Job) List(req request.JobList2) (any, int64) {
req.Pagination()
lists, count, err := dao.NewJob().List(req.Lang, req.City, req.Title, req.Desc, req.Reqs, req.JobType, req.JobArea, req.JobUnit, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
listLang := make([]string, 0)
for _, list := range lists {
listLang = append(listLang, fmt.Sprintf("%d_%s", list.ID, list.Lang))
}
res := make([]map[string]any, 0)
for _, list := range lists {
temp := list.Format()
temp["category"] = r.GetCate(list)[list.Lang]
res = append(res, temp)
for _, lang := range consts.LangSupport {
lang = fmt.Sprintf("%d_%s", list.ID, list.Lang)
if slices.Contains(listLang, lang) {
continue
}
temp = r.One(lang, list.ID)
temp["category"] = r.GetCate(list)[list.Lang]
res = append(res, temp)
}
}
return res, count
}
func (r *Job) One(lang string, id int64) map[string]any {
x, err := dao.NewJob().GetLang(id, lang)
if err != nil {
err2.DbErr(err)
}
return x.Format()
}
func (r *Job) Get(req request.JobDelete) any {
res := make([]map[string]any, 0)
for _, lang := range consts.LangSupport {
x, err := dao.NewJob().GetLang(cast.ToInt64(req.ID), lang)
if err != nil {
err2.DbErr(err)
}
if x == nil {
continue
}
format := x.Format()
format["category"] = r.GetCate(x)[x.Lang]
res = append(res, format)
}
return res
}
func (r *Job) GetCate(params *model.JobPage) map[string]map[string]any {
// type:id
s := map[string]int64{
model.CateTypeJobType: params.JobType,
model.CateTypeJobArea: params.JobArea,
model.CateTypeJobUnit: params.JobUnit,
}
res := make(map[string]map[string]any)
for t, id := range s {
x, err := dao.NewCategory().GetWithType(id, t)
if err != nil {
err2.DbErr(err)
}
if x == nil {
x = new(model.Category)
}
for _, lang := range consts.LangSupport {
name := ""
switch lang {
case consts.LangZH:
name = x.Name
case consts.LangEN:
name = x.NameEn
}
if _, ok := res[lang]; !ok {
res[lang] = make(map[string]any)
}
res[lang][t] = x.ID
res[lang][t+"_name"] = name
}
}
return res
}

124
app/api/service/news.go Normal file
View File

@ -0,0 +1,124 @@
package service
import (
"fmt"
"math"
"slices"
"yintai-api/app/api/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"github.com/spf13/cast"
)
type News struct{}
func (r *News) List(req request.NewsList2) (any, int64) {
req.Pagination()
lists, count, err := dao.NewNews().List(req.Lang, req.Title, req.Content, req.PublishTime, cast.ToInt64(req.CategoryID), cast.ToInt64(req.Pinned), req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := r.ListFormat(lists)
return res, count
}
func (r *News) One(lang string, id int64) map[string]any {
x, err := dao.NewNews().GetLang(id, lang)
if err != nil {
err2.DbErr(err)
}
if x == nil {
return nil
}
return x.Format()
}
func (r *News) Get(req request.NewsDelete) any {
res := make([]map[string]any, 0)
for _, lang := range consts.LangSupport {
data := r.One(lang, cast.ToInt64(req.ID))
if data == nil {
continue
}
res = append(res, data)
}
_ = dao.NewNews().Incr(cast.ToInt64(req.ID))
return res
}
func (r *News) PreNext(req request.PreNext) any {
news := make([]*model.NewsPage, 0)
var err error
if news, err = dao.NewNews().GetN(cast.ToInt64(req.CategoryID), req.Lang, 1, math.MaxInt32, req.Sort); err != nil {
err2.DbErr(err)
}
res := make([]any, 0)
for i, v := range news {
if v.News.ID == cast.ToInt64(req.ID) {
if i > 0 {
v := news[i-1]
res = append(res, r.preFormat(v))
}
if i+1 < len(news) {
v := news[i+1]
res = append(res, r.preFormat(v))
}
break
}
}
return res
}
func (r *News) preFormat(v *model.NewsPage) any {
res := make(map[string]any)
res["id"] = v.ID
res["title"] = v.Title
res["weight"] = v.Weight
res["lang"] = v.Lang
return res
}
func (r *News) ListFormat(lists []*model.NewsPage) any {
listLang := make([]string, 0)
for _, list := range lists {
if list == nil {
continue
}
listLang = append(listLang, fmt.Sprintf("%d_%s", list.ID, list.Lang))
}
res := make([]map[string]any, 0)
for _, list := range lists {
if list == nil {
continue
}
res = append(res, list.Format())
for _, lang := range consts.LangSupport {
langFormat := fmt.Sprintf("%d_%s", list.ID, lang)
if slices.Contains(listLang, langFormat) {
continue
}
data := r.One(lang, list.ID)
if data == nil {
continue
}
res = append(res, data)
}
}
return res
}

24
app/api/service/page.go Normal file
View File

@ -0,0 +1,24 @@
package service
import (
"yintai-api/app/api/request"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
)
type Page struct{}
func (r *Page) List(req request.PageList) (any, int64) {
req.Pagination()
lists, count, err := dao.NewPage().List(req.Name, req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
}
return res, count
}

View File

@ -0,0 +1,49 @@
package service
import (
"fmt"
"slices"
"yintai-api/app/api/request"
"yintai-api/app/common/consts"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"github.com/spf13/cast"
)
type Process struct{}
func (r *Process) List(req request.ProcessList2) (any, int64) {
req.Pagination()
lists, count, err := dao.NewProcess().List(req.Lang, req.Title, req.Content, req.ProcessTime, cast.ToInt64(req.CategoryID), req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr(err)
}
listLang := make([]string, 0)
for _, list := range lists {
listLang = append(listLang, fmt.Sprintf("%d_%s", list.ID, list.Lang))
}
res := make([]map[string]any, 0)
for _, list := range lists {
res = append(res, list.Format())
for _, lang := range consts.LangSupport {
lang = fmt.Sprintf("%d_%s", list.ID, list.Lang)
if slices.Contains(listLang, lang) {
continue
}
res = append(res, r.Get(lang, list.ID))
}
}
return res, count
}
func (r *Process) Get(lang string, id int64) map[string]any {
x, err := dao.NewProcess().GetLang(lang, id)
if err != nil {
err2.DbErr(err)
}
return x.Format()
}

33
app/common/cache/keys.go vendored Normal file
View File

@ -0,0 +1,33 @@
package cache
import (
"fmt"
"yintai-api/app/common/model"
"github.com/smbrave/goutil"
)
type Keys struct{}
func NewKeys() *Keys {
return &Keys{}
}
func (k Keys) User() string {
key := "home:user:info:"
return key
}
func (k Keys) User2Token() string {
key := "home:user:u2token:"
return key
}
func (k Keys) UserToken(account string) string {
key := fmt.Sprintf("%s_%s_%s", account, model.Salt, account)
return goutil.Md5(key)
}
func (k Keys) Api(roleID int64) string {
return fmt.Sprintf("%s%d", "home:user:api:", roleID)
}

11
app/common/cache/redis.go vendored Normal file
View File

@ -0,0 +1,11 @@
package cache
import (
"yintai-api/base/global"
"github.com/go-redis/redis"
)
func GetRedis() *redis.Client {
return global.GetRedis()
}

View File

@ -0,0 +1,8 @@
package consts
const (
LangZH = "ZH"
LangEN = "EN"
)
var LangSupport = []string{LangEN, LangZH}

15
app/common/dao/base.go Normal file
View File

@ -0,0 +1,15 @@
package dao
import (
"yintai-api/base/global"
"gorm.io/gorm"
)
func getDB(db ...*gorm.DB) *gorm.DB {
if len(db) > 0 {
return db[0]
}
return global.GetDB()
}

148
app/common/dao/category.go Normal file
View File

@ -0,0 +1,148 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type Category struct {
db *gorm.DB
}
func NewCategory(db ...*gorm.DB) *Category {
return &Category{db: getDB(db...)}
}
func (r *Category) TableName() string {
return "yt_category"
}
func (r *Category) Create(m *model.Category) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Category) Update(m *model.Category) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Category) Delete(path string) error {
return r.db.Table(r.TableName()).Where("path LIKE ?", fmt.Sprintf("%s%%", path)).Delete(&model.Category{}).Error
}
func (r *Category) Get(id int64) (*model.Category, error) {
var res model.Category
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Category) GetWithType(id int64, t string) (*model.Category, error) {
var res model.Category
if err := r.db.Table(r.TableName()).Where("id = ? AND type = ?", id, t).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Category) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Category) GetByPath(path string) ([]*model.Category, error) {
var res []*model.Category
if err := r.db.Table(r.TableName()).Where("path LIKE ?", fmt.Sprintf("%s%%", path)).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *Category) List(pid int64, name, nameEn, types string, page, size int, sort string) ([]*model.Category, int64, error) {
var req []*model.Category
var count int64
tx := r.db.Table(r.TableName()).Where("type = ?", types)
if pid != 0 {
tx = tx.Where("pid = ?", pid)
}
if name != "" {
tx = tx.Where("name LIKE ?", fmt.Sprintf("%%%s%%", name))
}
if nameEn != "" {
tx = tx.Where("name_en LIKE ?", fmt.Sprintf("%%%s%%", nameEn))
}
if sort != "" {
tx = tx.Order(sort)
} else {
tx = tx.Order("create_time desc")
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if err := tx.Offset((page - 1) * size).Limit(size).Find(&req).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, 0, nil
}
return nil, 0, err
}
return req, count, nil
}
func (c *Category) GetByBiz(BizID int64, BizType string) (*model.Category, error) {
var res model.Category
tx := c.db.Table(c.TableName() + " c ").Joins(fmt.Sprintf(" LEFT JON %s r ON c.id = r.cateory_id", NewCategoryRelation().TableName()))
tx = tx.Where("r.biz_id = ? AND c.type = ?", BizID, BizType)
if err := tx.First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (c *Category) GetByIds(ids ...int64) (map[int64]*model.Category, error) {
resMap := make(map[int64]*model.Category)
var res []*model.Category
if len(ids) > 0 {
tx := c.db.Table(c.TableName()).Where("id IN (?)", ids).Find(&res)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return resMap, nil
}
return resMap, tx.Error
}
}
for _, re := range res {
resMap[re.ID] = re
}
return resMap, nil
}

View File

@ -0,0 +1,73 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type CategoryRelation struct {
db *gorm.DB
}
func NewCategoryRelation(db ...*gorm.DB) *CategoryRelation {
return &CategoryRelation{db: getDB(db...)}
}
func (r *CategoryRelation) TableName() string {
return "yt_category_relation"
}
func (r *CategoryRelation) Create(m *model.CategoryRelation) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *CategoryRelation) Update(m *model.CategoryRelation) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *CategoryRelation) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&CategoryRelation{}).Error
}
func (r *CategoryRelation) DeleteByCondition(bizID int64, bizType string) error {
return r.db.Table(r.TableName()).Where("biz_id = ? AND type = ?", bizID, bizType).Delete(&CategoryRelation{}).Error
}
func (r *CategoryRelation) Get(id int64) (*model.CategoryRelation, error) {
var res model.CategoryRelation
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *CategoryRelation) GetByIds(ids ...int64) ([]*model.CategoryRelation, error) {
var res []*model.CategoryRelation
if len(ids) == 0 {
return res, nil
}
if err := r.db.Table(r.TableName()).Where("id in (?)", ids).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *CategoryRelation) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *CategoryRelation) List(...any) ([]*model.CategoryRelation, int64, error) {
panic("implement me")
}

55
app/common/dao/config.go Normal file
View File

@ -0,0 +1,55 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type Config struct {
db *gorm.DB
}
func NewConfig(db ...*gorm.DB) *Config {
return &Config{db: getDB(db...)}
}
func (r *Config) TableName() string {
return "yt_config"
}
func (r *Config) Create(m *model.Config) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Config) Update(m *model.Config) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Config) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Config{}).Error
}
func (r *Config) Get(id int64) (*model.Config, error) {
var res model.Config
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Config) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Config) List(...any) ([]*model.Config, int64, error) {
panic("implement me")
}

View File

@ -0,0 +1,55 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type ConfigTranslations struct {
db *gorm.DB
}
func NewConfigTranslations(db ...*gorm.DB) *ConfigTranslations {
return &ConfigTranslations{db: getDB(db...)}
}
func (r *ConfigTranslations) TableName() string {
return "yt_config_translations"
}
func (r *ConfigTranslations) Create(m *model.ConfigTranslations) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *ConfigTranslations) Update(m *model.ConfigTranslations) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *ConfigTranslations) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&ConfigTranslations{}).Error
}
func (r *ConfigTranslations) Get(id int64) (*model.ConfigTranslations, error) {
var res model.ConfigTranslations
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *ConfigTranslations) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *ConfigTranslations) List(...any) ([]*model.ConfigTranslations, int64, error) {
panic("implement me")
}

121
app/common/dao/document.go Normal file
View File

@ -0,0 +1,121 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Document struct {
db *gorm.DB
}
func NewDocument(db ...*gorm.DB) *Document {
return &Document{db: getDB(db...)}
}
func (r *Document) TableName() string {
return "yt_document"
}
func (r *Document) Create(m *model.Document) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Document) Update(m *model.Document) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Document) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Document{}).Error
}
func (r *Document) Get(id int64) (*model.Document, error) {
var res model.Document
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Document) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Document) List(lang string, categoryID int64, fileName, title, subTitle, desc string, page, size int, sort string) ([]*model.DocumentPage, int64, error) {
var list []*model.DocumentPage
var count int64
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS t ON p.id = t.document_id ", NewDocumentTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeFile)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
if lang != "" {
tx = tx.Where("t.lang = ?", lang)
}
if fileName != "" {
tx = tx.Where("t.name LIKE ?", "%"+fileName+"%")
}
if title != "" {
tx = tx.Where("t.title LIKE ?", "%"+title+"%")
}
if subTitle != "" {
tx = tx.Where("t.sub_title LIKE ?", "%"+subTitle+"%")
}
if desc != "" {
tx = tx.Where("t.description LIKE ?", "%"+desc+"%")
}
if cast.ToInt64(categoryID) != 0 {
tx = tx.Where("c.id = ?", cast.ToInt64(categoryID))
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort == "" {
tx = tx.Order("p.weight DESC")
} else {
tx = tx.Order(sort)
}
if err := tx.Offset((page - 1) * size).Limit(size).Select("p.*,t.*,c.name as category_name,c.name_en as category_en,c.id as category_id").Find(&list).Error; err != nil {
return nil, 0, err
}
return list, count, nil
}
func (r *Document) GetLang(lang string, id int64) (*model.DocumentPage, error) {
var res *model.DocumentPage
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS t ON p.id = t.document_id ", NewDocumentTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeFile)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
tx = tx.Where("t.lang = ?", lang)
tx = tx.Where("p.id = ?", id)
field := "p.*,t.*,c.name as category_name,c.name_en as category_en,c.id as category_id"
if err := tx.Select(field).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}

View File

@ -0,0 +1,67 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type DocumentTranslations struct {
db *gorm.DB
}
func NewDocumentTranslations(db ...*gorm.DB) *DocumentTranslations {
return &DocumentTranslations{db: getDB(db...)}
}
func (r *DocumentTranslations) TableName() string {
return "yt_document_translations"
}
func (r *DocumentTranslations) Create(m *model.DocumentTranslations) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *DocumentTranslations) Update(m *model.DocumentTranslations) error {
return r.db.Table(r.TableName()).Where("document_id = ? AND lang = ?", m.DocumentID, m.Lang).Save(m).Error
}
func (r *DocumentTranslations) Delete(masterID int64) error {
return r.db.Table(r.TableName()).Where("document_id = ?", masterID).Delete(&DocumentTranslations{}).Error
}
func (r *DocumentTranslations) Get(id int64) (*model.DocumentTranslations, error) {
var res model.DocumentTranslations
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *DocumentTranslations) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *DocumentTranslations) List(...any) ([]*model.DocumentTranslations, int64, error) {
panic("implement me")
}
func (r *DocumentTranslations) GetByMaster(masterID int64, lang string) (*model.DocumentTranslations, error) {
var res model.DocumentTranslations
tx := r.db.Table(r.TableName()).Where("document_id = ? AND lang = ?", masterID, lang).First(&res)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return &res, nil
}

124
app/common/dao/job.go Normal file
View File

@ -0,0 +1,124 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Job struct {
db *gorm.DB
}
func NewJob(db ...*gorm.DB) *Job {
return &Job{db: getDB(db...)}
}
func (r *Job) TableName() string {
return "yt_job"
}
func (r *Job) Create(m *model.Job) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Job) Update(m *model.Job) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Job) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Job{}).Error
}
func (r *Job) Get(id int64) (*model.Job, error) {
var res model.Job
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Job) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Job) List(lang, city, title, desc, reqs, jobType, jobArea, jobUnit string, page, size int, sort string) ([]*model.JobPage, int64, error) {
var list []*model.JobPage
var count int64
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s t ON p.id = t.job_id ", NewJobTranslations().TableName()))
if lang != "" {
tx = tx.Where("t.lang = ?", lang)
}
if city != "" {
tx = tx.Where("p.city = ?", city)
}
if title != "" {
tx = tx.Where("t.name LIKE ?", "%"+title+"%")
}
if desc != "" {
tx = tx.Where("t.description LIKE ?", "%"+desc+"%")
}
if reqs != "" {
tx = tx.Where("t.requirement LIKE ?", "%"+reqs+"%")
}
if v := cast.ToInt64(jobType); v != 0 {
tx = tx.Where("p.job_type = ?", v)
}
if v := cast.ToInt64(jobArea); v != 0 {
tx = tx.Where("p.job_area = ?", v)
}
if v := cast.ToInt64(jobUnit); v != 0 {
tx = tx.Where("p.job_unit = ?", v)
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort == "" {
tx = tx.Order(sort)
} else {
tx = tx.Order(sort)
}
if err := tx.Offset((page - 1) * size).Limit(size).Select("p.*,t.*").Find(&list).Error; err != nil {
return nil, 0, err
}
return list, count, nil
}
func (r *Job) GetLang(id int64, lang string) (*model.JobPage, error) {
var res *model.JobPage
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s t ON p.id = t.job_id ", NewJobTranslations().TableName()))
tx = tx.Where("t.lang = ?", lang)
tx = tx.Where("p.id = ?", id)
if err := tx.Select("p.*,t.*").First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}

View File

@ -0,0 +1,67 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type JobTranslations struct {
db *gorm.DB
}
func NewJobTranslations(db ...*gorm.DB) *JobTranslations {
return &JobTranslations{db: getDB(db...)}
}
func (r *JobTranslations) TableName() string {
return "yt_job_translations"
}
func (r *JobTranslations) Create(m *model.JobTranslations) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *JobTranslations) Update(m *model.JobTranslations) error {
return r.db.Table(r.TableName()).Where("job_id = ? AND lang = ?", m.JobID, m.Lang).Save(m).Error
}
func (r *JobTranslations) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("job_id = ?", id).Delete(&JobTranslations{}).Error
}
func (r *JobTranslations) Get(id int64) (*model.JobTranslations, error) {
var res model.JobTranslations
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *JobTranslations) GetByMaster(masterID int64, lang string) (*model.JobTranslations, error) {
var res model.JobTranslations
tx := r.db.Table(r.TableName()).Where("job_id = ? AND lang = ?", masterID, lang).First(&res)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return &res, nil
}
func (r *JobTranslations) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *JobTranslations) List(...any) ([]*model.JobTranslations, int64, error) {
panic("implement me")
}

174
app/common/dao/news.go Normal file
View File

@ -0,0 +1,174 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type News struct {
db *gorm.DB
}
func NewNews(db ...*gorm.DB) *News {
return &News{db: getDB(db...)}
}
func (r *News) TableName() string {
return "yt_news"
}
func (r *News) Create(m *model.News) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *News) Update(m *model.News) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *News) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&News{}).Error
}
func (r *News) Get(id int64) (*model.News, error) {
var res model.News
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *News) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *News) List(lang, title, content, publishTime string, categoryID, pinned int64, page, size int, sort string) ([]*model.NewsPage, int64, error) {
var list []*model.NewsPage
var count int64
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf("LEFT JOIN %s AS t ON p.id = t.news_id ", NewNewsTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeNews)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
if lang != "" {
tx = tx.Where("t.lang = ?", lang)
}
if title != "" {
tx = tx.Where("t.title LIKE ?", "%"+title+"%")
}
if content != "" {
tx = tx.Where("t.content LIKE ?", "%"+content+"%")
}
if publishTime != "" {
tx = tx.Where("t.publish_time = ?", publishTime)
}
if cast.ToInt64(categoryID) != 0 {
tx = tx.Where("c.id = ?", cast.ToInt64(categoryID))
}
if pinned > 0 {
tx = tx.Where("p.pinned = ?", pinned)
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort != "" {
tx = tx.Order(sort)
} else {
tx = tx.Order("pinned desc,weight desc,create_time desc")
}
if err := tx.Offset((page - 1) * size).Limit(size).Select("p.*,t.*,c.name as category_name,c.name_en as category_en,c.id as category_id").Find(&list).Error; err != nil {
return nil, 0, err
}
return list, count, nil
}
func (r *News) GetLang(id int64, lang string) (*model.NewsPage, error) {
var res *model.NewsPage
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS t ON p.id = t.news_id ", NewNewsTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeNews)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
tx = tx.Where("p.id = ?", id)
tx = tx.Where("t.lang = ?", lang)
if err := tx.Select("p.*,t.*,c.name as category_name,c.name_en as category_en,c.id as category_id").First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *News) GetN(categoryID int64, lang string, page, size int, sort string) ([]*model.NewsPage, error) {
var res []*model.NewsPage
tx := r.db.Table(r.TableName() + " AS p ")
tx = tx.Joins(fmt.Sprintf("LEFT JOIN %s AS t ON p.id = t.news_id ", NewNewsTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeNews)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
tx = tx.Where("c.id = ?", cast.ToInt64(categoryID))
tx = tx.Where("t.lang = ?", lang)
if sort != "" {
tx = tx.Order(sort)
} else {
tx = tx.Order("pinned desc,weight desc,create_time desc")
}
tx = tx.Offset((page - 1) * size).Limit(size)
if err := tx.Select("p.*,t.title").Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *News) PureAll() ([]*model.News, error) {
var res []*model.News
tx := r.db.Table(r.TableName()).Find(&res)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return res, nil
}
func (r *News) Incr(id int64, counts ...int) error {
count := 1
if len(counts) > 0 {
count = counts[0]
}
tx := r.db.Table(r.TableName()).Where("id = ?", id).Updates(map[string]any{"count": gorm.Expr("count + ?", count)})
if tx.Error != nil {
return tx.Error
}
if tx.RowsAffected == 0 {
return gorm.ErrRecordNotFound
}
return nil
}

View File

@ -0,0 +1,67 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type NewsTranslations struct {
db *gorm.DB
}
func NewNewsTranslations(db ...*gorm.DB) *NewsTranslations {
return &NewsTranslations{db: getDB(db...)}
}
func (r *NewsTranslations) TableName() string {
return "yt_news_translations"
}
func (r *NewsTranslations) Create(m *model.NewsTranslations) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *NewsTranslations) Update(m *model.NewsTranslations) error {
return r.db.Table(r.TableName()).Where("news_id = ? AND lang = ?", m.NewsID, m.Lang).Save(m).Error
}
func (r *NewsTranslations) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("news_id = ?", id).Delete(&NewsTranslations{}).Error
}
func (r *NewsTranslations) Get(id int64) (*model.NewsTranslations, error) {
var res model.NewsTranslations
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *NewsTranslations) GetByMaster(masterID int64, lang string) (*model.NewsTranslations, error) {
var res model.NewsTranslations
tx := r.db.Table(r.TableName()).Where("news_id = ? AND lang = ?", masterID, lang).First(&res)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return &res, nil
}
func (r *NewsTranslations) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *NewsTranslations) List(...any) ([]*model.NewsTranslations, int64, error) {
panic("implement me")
}

87
app/common/dao/page.go Normal file
View File

@ -0,0 +1,87 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type Page struct {
db *gorm.DB
}
func NewPage(db ...*gorm.DB) *Page {
return &Page{db: getDB(db...)}
}
func (r *Page) TableName() string {
return "yt_page"
}
func (r *Page) Create(m *model.Page) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Page) Update(m *model.Page) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Page) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Page{}).Error
}
func (r *Page) Get(id int64) (*model.Page, error) {
var res model.Page
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Page) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Page) List(name string, page, size int, sort string) ([]*model.Page, int64, error) {
var list []*model.Page
var count int64
tx := r.db.Table(r.TableName()).Where("name LIKE ?", fmt.Sprintf("%%%s%%", name))
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort != "" {
tx = tx.Order(sort)
} else {
tx = tx.Order("id,pid,weight desc")
}
if err := tx.Offset((page - 1) * size).Limit(size).Find(&list).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, 0, err
}
return nil, 0, err
}
return list, count, nil
}
func (r *Page) GetByPath(path string) ([]*model.Page, error) {
var list []*model.Page
tx := r.db.Table(r.TableName()).Where("path LIKE ?", fmt.Sprintf("%s%%", path)).Find(&list)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return list, nil
}

114
app/common/dao/process.go Normal file
View File

@ -0,0 +1,114 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type Process struct {
db *gorm.DB
}
func NewProcess(db ...*gorm.DB) *Process {
return &Process{db: getDB(db...)}
}
func (r *Process) TableName() string {
return "yt_process"
}
func (r *Process) Create(m *model.Process) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Process) Update(m *model.Process) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Process) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Process{}).Error
}
func (r *Process) Get(id int64) (*model.Process, error) {
var res model.Process
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Process) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Process) List(lang, title, content, processTime string, categoryID int64, page, size int, sort string) ([]*model.ProcessPage, int64, error) {
var list []*model.ProcessPage
var count int64
tx := r.db.Table(r.TableName() + " AS p ").Joins(fmt.Sprintf("LEFT JOIN %s AS t ON p.id = t.process_id ", NewProcessTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeProcess)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
if lang != "" {
tx = tx.Where("t.lang = ?", lang)
}
if title != "" {
tx = tx.Where("t.title LIKE ?", "%"+title+"%")
}
if content != "" {
tx = tx.Where("t.content LIKE ?", "%"+content+"%")
}
if processTime != "" {
tx = tx.Where("t.process_time = ?", processTime)
}
if cast.ToInt64(categoryID) != 0 {
tx = tx.Where("c.id = ?", cast.ToInt64(categoryID))
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort == "" {
tx = tx.Order(sort)
} else {
tx = tx.Order(sort)
}
if err := tx.Offset((page - 1) * size).Limit(size).Select("p.*,t.*,c.name as category_name,c.name_en as category_en,c.id as category_id").Find(&list).Error; err != nil {
return nil, 0, err
}
return list, count, nil
}
func (r *Process) GetLang(lang string, id int64) (*model.ProcessPage, error) {
var res *model.ProcessPage
tx := r.db.Table(r.TableName() + " AS p ").Joins(fmt.Sprintf("LEFT JOIN %s AS t ON p.id = t.process_id ", NewProcessTranslations().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s l ON l.biz_id = p.id AND l.type = ?", NewCategoryRelation().TableName()), model.CateTypeProcess)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s c ON c.id = l.category_id", NewCategory().TableName()))
tx = tx.Where("t.lang = ?", lang)
tx = tx.Where("p.id = ?", id)
field := "p.*,t.*,c.name as category_name,c.name_en as category_en,c.id as category_id"
if err := tx.Select(field).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}

View File

@ -0,0 +1,67 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type ProcessTranslations struct {
db *gorm.DB
}
func NewProcessTranslations(db ...*gorm.DB) *ProcessTranslations {
return &ProcessTranslations{db: getDB(db...)}
}
func (r *ProcessTranslations) TableName() string {
return "yt_process_translations"
}
func (r *ProcessTranslations) Create(m *model.ProcessTranslations) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *ProcessTranslations) Update(m *model.ProcessTranslations) error {
return r.db.Table(r.TableName()).Where("process_id = ? AND lang = ?", m.ProcessID, m.Lang).Save(m).Error
}
func (r *ProcessTranslations) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("process_id = ?", id).Delete(&ProcessTranslations{}).Error
}
func (r *ProcessTranslations) Get(id int64) (*model.ProcessTranslations, error) {
var res model.ProcessTranslations
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *ProcessTranslations) GetByMaster(masterID int64, lang string) (*model.ProcessTranslations, error) {
var res model.ProcessTranslations
tx := r.db.Table(r.TableName()).Where("process_id = ? AND lang = ?", masterID, lang).First(&res)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return &res, nil
}
func (r *ProcessTranslations) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *ProcessTranslations) List(...any) ([]*model.ProcessTranslations, int64, error) {
panic("implement me")
}

126
app/common/dao/resource.go Normal file
View File

@ -0,0 +1,126 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type Resource struct {
db *gorm.DB
}
func NewResource(db ...*gorm.DB) *Resource {
return &Resource{db: getDB(db...)}
}
func (r *Resource) TableName() string {
return "yt_resource"
}
func (r *Resource) Create(m *model.Resource) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Resource) Update(m *model.Resource) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Resource) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Resource{}).Error
}
func (r *Resource) Get(id int64) (*model.Resource, error) {
var res model.Resource
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Resource) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Resource) List(name, types, code, method, path string, page, size int, sort string) ([]*model.Resource, int64, error) {
var res []*model.Resource
var count int64
tx := r.db.Table(r.TableName())
if name != "" {
tx = tx.Where("name LIKE ?", fmt.Sprintf("%%%s%%", name))
}
if types != "" {
tx = tx.Where("type = ?", types)
}
if path != "" {
tx = tx.Where("path LIKE ?", fmt.Sprintf("%%%s%%", path))
}
if method != "" {
tx = tx.Where("method = ?", method)
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort != "" {
tx = tx.Order(sort)
} else {
tx = tx.Order("id desc")
}
if err := tx.Offset((page - 1) * size).Limit(size).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, 0, nil
}
return nil, 0, err
}
return res, count, nil
}
func (r *Resource) GetByIds(ids []int64) ([]*model.Resource, error) {
var res []*model.Resource
if err := r.db.Table(r.TableName()).Where("id in (?)", ids).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *Resource) RoleGet(roleId int64) ([]*model.Resource, error) {
var res []*model.Resource
tx := r.db.Table(NewRoleResource().TableName()+" as rr").Where("rr.role_id = ?", roleId)
tx = tx.Joins(fmt.Sprintf(" JOIN %s r ON r.id = rr.resource_id", r.TableName()))
if err := tx.Select("r.*").Order("id desc").Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *Resource) GetMaps(maps string) ([]*model.Resource, error) {
var res []*model.Resource
if err := r.db.Table(r.TableName()).Where("maps LIKE ?", fmt.Sprintf("%s/%%", maps)).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}

83
app/common/dao/role.go Normal file
View File

@ -0,0 +1,83 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type Role struct {
db *gorm.DB
}
func NewRole(db ...*gorm.DB) *Role {
return &Role{db: getDB(db...)}
}
func (r *Role) TableName() string {
return "yt_role"
}
func (r *Role) Create(m *model.Role) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *Role) Update(m *model.Role) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *Role) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&Role{}).Error
}
func (r *Role) Get(id int64) (*model.Role, error) {
var res model.Role
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *Role) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *Role) List(name, desc string, page, size int, sort string) ([]*model.Role, int64, error) {
var res []*model.Role
var count int64
tx := r.db.Table(r.TableName())
if name != "" {
tx = tx.Where("name LIKE ?", fmt.Sprintf("%%%s%%", name))
}
if desc != "" {
tx = tx.Where("desc LIKE ?", fmt.Sprintf("%%%s%%", desc))
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
if sort != "" {
tx = tx.Order(sort)
} else {
tx = tx.Order("id desc")
}
if err := tx.Offset((page - 1) * size).Limit(size).Find(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, 0, nil
}
return nil, 0, err
}
return res, count, nil
}

View File

@ -0,0 +1,55 @@
package dao
import (
"errors"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type RoleResource struct {
db *gorm.DB
}
func NewRoleResource(db ...*gorm.DB) *RoleResource {
return &RoleResource{db: getDB(db...)}
}
func (r *RoleResource) TableName() string {
return "yt_role_resource"
}
func (r *RoleResource) Create(m []*model.RoleResource) error {
return r.db.Table(r.TableName()).CreateInBatches(m, 100).Error
}
func (r *RoleResource) Update(m *model.RoleResource) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *RoleResource) Delete(roleID int64) error {
return r.db.Table(r.TableName()).Where("role_id = ?", roleID).Delete(&RoleResource{}).Error
}
func (r *RoleResource) Get(id int64) (*model.RoleResource, error) {
var res model.RoleResource
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *RoleResource) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *RoleResource) List(...any) ([]*model.RoleResource, int64, error) {
panic("implement me")
}

139
app/common/dao/user.go Normal file
View File

@ -0,0 +1,139 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type User struct {
db *gorm.DB
}
func NewUser(db ...*gorm.DB) *User {
return &User{db: getDB(db...)}
}
func (r *User) TableName() string {
return "yt_user"
}
func (r *User) Create(m *model.User) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *User) Update(m *model.User) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *User) Delete(id int64) error {
return r.db.Table(r.TableName()).Where("id = ?", id).Delete(&User{}).Error
}
func (r *User) BatchDelete(ids []int64) error {
return r.db.Table(r.TableName()).Where("id in (?)", ids).Delete(&User{}).Error
}
func (r *User) Get(id int64) (*model.User, error) {
var res model.User
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *User) AccountGet(account string) (*model.User, error) {
var res model.User
if err := r.db.Table(r.TableName()).Where("account = ?", account).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *User) GetWithRole(account string) (*model.UserWithRole, error) {
var res *model.UserWithRole
tx := r.db.Table(r.TableName()+" as u ").Where("u.account = ?", account).Where("u.status = ?", model.UserStatusNormal)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS ur ON ur.user_id = u.id", NewUserRole().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS r ON r.id = ur.role_id", NewRole().TableName()))
if err := tx.Select("u.*,r.id as role_id,r.name as role_name").First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *User) GetUserId(userId int64) (*model.UserWithRole, error) {
var res *model.UserWithRole
tx := r.db.Table(r.TableName()+" as u ").Where("u.id = ?", userId).Where("u.status = ?", model.UserStatusNormal)
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS ur ON ur.user_id = u.id", NewUserRole().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS r ON r.id = ur.role_id", NewRole().TableName()))
if err := tx.Select("u.*,r.id as role_id,r.name as role_name").First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return res, nil
}
func (r *User) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *User) AccountExists(account string) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("account = ?", account).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *User) List(username, account string, role int64, page, size int, sort string) ([]*model.UserWithRole, int64, error) {
var res []*model.UserWithRole
var count int64
tx := r.db.Table(r.TableName() + " as u")
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS ur ON ur.user_id = u.id", NewUserRole().TableName()))
tx = tx.Joins(fmt.Sprintf(" LEFT JOIN %s AS r ON r.id = ur.role_id", NewRole().TableName()))
if username != "" {
tx = tx.Where("u.username LIKE ?", fmt.Sprintf("%%%s%%", username))
}
if account != "" {
tx = tx.Where("u.account LIKE ?", fmt.Sprintf("%%%s%%", account))
}
if role != 0 {
tx = tx.Where("r.role = ?", role)
}
if err := tx.Count(&count).Error; err != nil {
return nil, 0, err
}
tx = tx.Order("id DESC")
if sort != "" {
tx = tx.Order(sort)
}
if err := tx.Limit(size).Offset((page - 1) * size).Select("u.*,r.id as role_id,r.name as role_name").Find(&res).Error; err != nil {
return nil, 0, err
}
return res, count, nil
}

View File

@ -0,0 +1,70 @@
package dao
import (
"errors"
"fmt"
"yintai-api/app/common/model"
"gorm.io/gorm"
)
type UserRole struct {
db *gorm.DB
}
func NewUserRole(db ...*gorm.DB) *UserRole {
return &UserRole{db: getDB(db...)}
}
func (r *UserRole) TableName() string {
return "yt_user_role"
}
func (r *UserRole) Create(m *model.UserRole) error {
return r.db.Table(r.TableName()).Create(m).Error
}
func (r *UserRole) Update(m *model.UserRole) error {
return r.db.Table(r.TableName()).Save(m).Error
}
func (r *UserRole) Delete(userID int64) error {
return r.db.Table(r.TableName()).Where("user_id = ? ", userID).Delete(&UserRole{}).Error
}
func (r *UserRole) RoleDelete(roleID int64) error {
return r.db.Table(r.TableName()).Where("role_id = ? ", roleID).Delete(&UserRole{}).Error
}
func (r *UserRole) Get(id int64) (*model.UserRole, error) {
var res model.UserRole
if err := r.db.Table(r.TableName()).Where("id = ?", id).First(&res).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &res, nil
}
func (r *UserRole) Exists(id int64) (bool, error) {
var count int64
if err := r.db.Table(r.TableName()).Where("id = ?", id).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}
func (r *UserRole) List(...any) ([]*model.UserRole, int64, error) {
panic("implement me")
}
func (r *UserRole) GetAccount(roleID int64) ([]*model.User, error) {
var res []*model.User
tx := r.db.Table(r.TableName()+" as ur ").Where("ur.role_id = ? ", roleID)
tx = tx.Joins(fmt.Sprintf(" JOIN %s u ON u.id = ur.user_id", NewUser().TableName()))
if err := tx.Order("id desc").Select("u.*").Find(&res).Error; err != nil {
return nil, err
}
return res, nil
}

51
app/common/err/err.go Normal file
View File

@ -0,0 +1,51 @@
package err
import (
"yintai-api/base/config"
"github.com/gogap/errors"
)
func errCatch(template errors.ErrCodeTemplate, err ...interface{}) {
panic(template.New().Append(err...))
}
func ParamErr(err ...interface{}) {
errCatch(config.ErrParam, err)
}
func DbErr(err ...interface{}) {
errCatch(config.ErrDb, err)
}
func PriErr(err ...interface{}) {
errCatch(config.ErrPriv, err)
}
func EsxErr(err ...interface{}) {
errCatch(config.ErrExist, err)
}
func NotEsxErr(err ...interface{}) {
errCatch(config.ErrNotExists, err)
}
func InnerErr(err ...interface{}) {
errCatch(config.ErrInternal, err)
}
func TokenErr(err ...interface{}) {
errCatch(config.ErrNeedLogin, err)
}
func ExtNotSupportErr(err ...interface{}) {
errCatch(config.ErrExt, err)
}
func TranslateErr(err ...interface{}) {
errCatch(config.TranslateErr, err)
}
func InUseErr(err ...interface{}) {
errCatch(config.InUseErr, err)
}

View File

@ -0,0 +1,36 @@
package middleware
import (
"fmt"
"net/http"
"runtime"
"yintai-api/app/common/response"
"github.com/gin-gonic/gin"
"github.com/gogap/errors"
log "github.com/sirupsen/logrus"
)
func Recovery(ctx *gin.Context) {
defer func() {
if err := recover(); err != nil {
var rsp response.BaseResponse
if e, ok := err.(errors.ErrCode); ok {
rsp.Code = int(e.Code())
rsp.Message = e.Error()
ctx.JSON(http.StatusOK, rsp)
log.Errorf("[%s][%s][%s] %v", ctx.Request.Method, ctx.Request.URL.Path, ctx.Request.URL.RawQuery, e)
} else {
var buf [2 << 10]byte
stack := string(buf[:runtime.Stack(buf[:], true)])
log.Errorf("[%s][%s][%s] Internal ERROR:::%v stack:%s", ctx.Request.Method, ctx.Request.URL.Path, ctx.Request.URL.RawQuery, err, stack)
rsp.Code = -1
rsp.Message = fmt.Sprintf("%v", err)
ctx.JSON(http.StatusOK, rsp)
}
ctx.Abort()
}
}()
ctx.Next()
}

10
app/common/model/base.go Normal file
View File

@ -0,0 +1,10 @@
package model
const (
UserStatusNormal = 1
UserStatusBaned = 2
)
const (
Salt string = "yintai_api"
)

View File

@ -0,0 +1,61 @@
package model
type Category struct {
ID int64
Pid int64
Name string
NameEn string
Path string
Type string
CreateTime int64
UpdateTime int64
}
func (r *Category) Format() map[string]any {
res := make(map[string]any)
res["id"] = r.ID
res["pid"] = r.Pid
res["name"] = r.Name
res["name_en"] = r.NameEn
return res
}
func (r *Category) FormatEn() map[string]any {
res := make(map[string]any)
res["id"] = r.ID
res["pid"] = r.Pid
res["name"] = r.NameEn
return res
}
const (
CateTypeProcess = "process" // 历程
CateTypeNews = "news" // 新闻
CateTypeLogic = "logic" //
CateTypeFile = "file" // 文件
CateTypeJob = "job" // 工作
CateTypeJobType = "job_type" // 职业类别
CateTypeJobArea = "job_area" // 业务领域
CateTypeJobUnit = "job_unit" //所属板块
)
var CategoryTypes = []string{
CateTypeProcess,
CateTypeNews,
CateTypeJob,
CateTypeLogic,
CateTypeFile,
CateTypeJobType,
CateTypeJobArea,
CateTypeJobUnit,
}
var CateJobTypes = []string{
CateTypeJobType,
CateTypeJob,
CateTypeJobArea,
}

View File

@ -0,0 +1,15 @@
package model
type CategoryRelation struct {
ID int64
CategoryId int64
Type string
BizId int64
CreateTime int64
}
func (r *CategoryRelation) Format() map[string]any {
res := make(map[string]any)
return res
}

View File

@ -0,0 +1,14 @@
package model
type Config struct {
ID int64
Name string
CreateTime int64
UpdateTime int64
}
func (r *Config) Format() map[string]any {
res := make(map[string]any)
return res
}

View File

@ -0,0 +1,13 @@
package model
type ConfigTranslations struct {
ConfigID int64
Lang string
Config string
}
func (r *ConfigTranslations) Format() map[string]any {
res := make(map[string]any)
return res
}

View File

@ -0,0 +1,51 @@
package model
import (
"time"
"yintai-api/app/common/service"
)
type Document struct {
ID int64
Code string
Weight int64
CreateTime int64
UpdateTime int64
}
type DocumentPage struct {
Document
DocumentTranslations
CategoryID int64
CategoryName string
CategoryEn string
}
func (d *DocumentPage) Format() map[string]any {
res := make(map[string]any)
res["id"] = d.ID
res["code"] = d.Code
res["create_time"] = time.Now().Format("2006-01-02 15:04:05")
res["lang"] = d.Lang
res["name"] = d.Name
res["title"] = d.Title
res["sub_title"] = d.SubTitle
res["image_title"] = d.ImageTitle
res["desc"] = d.Description
res["path"] = service.NewQiniu().QuarterUrl(d.StoragePath)
res["cover"] = service.NewQiniu().QuarterUrl(d.Cover)
res["extra"] = d.Extra
res["category_id"] = d.CategoryID
res["category_name"] = d.CategoryName
res["categroy_name_en"] = d.CategoryEn
res["weight"] = d.Weight
return res
}
func (r *Document) Format() map[string]any {
res := make(map[string]any)
return res
}

View File

@ -0,0 +1,22 @@
package model
type DocumentTranslations struct {
DocumentID int64
Lang string
Name string
Title string
SubTitle string
ImageTitle string
Description string
StorageType string
StoragePath string
Size int64
Cover string
Extra string
}
func (r *DocumentTranslations) Format() map[string]any {
res := make(map[string]any)
return res
}

42
app/common/model/job.go Normal file
View File

@ -0,0 +1,42 @@
package model
import (
"time"
)
type Job struct {
ID int64
RecruitCount int64
City string
JobType int64
JobArea int64
JobUnit int64
CreateTime int64
UpdateTime int64
}
func (r *Job) Format() map[string]any {
res := make(map[string]any)
return res
}
type JobPage struct {
Job
JobTranslations
}
func (r *JobPage) Format() map[string]any {
res := make(map[string]any)
res["id"] = r.ID
res["city"] = r.City
res["recruit_count"] = r.RecruitCount
res["create_time"] = time.Unix(r.CreateTime, 0).Format("2006-01-02 15:04:05")
res["lang"] = r.Lang
res["title"] = r.Name
res["description"] = r.Description
res["requirement"] = r.Requirement
res["contract_info"] = r.ContractInfo
return res
}

View File

@ -0,0 +1,16 @@
package model
type JobTranslations struct {
JobID int64
Lang string
Name string
Description string
Requirement string
ContractInfo string
}
func (r *JobTranslations) Format() map[string]any {
res := make(map[string]any)
return res
}

61
app/common/model/news.go Normal file
View File

@ -0,0 +1,61 @@
package model
import (
"encoding/json"
"time"
"yintai-api/app/common/service"
)
type News struct {
ID int64
CoverImages string
CoverShow string
Count int64
CreateTime int64
UpdateTime int64
Weight int64
Pinned int64
}
func (r *News) Format() map[string]any {
res := make(map[string]any)
return res
}
type NewsPage struct {
News
NewsTranslations
CategoryID int64
CategoryName string
CategoryEn string
}
func (r *NewsPage) Format() map[string]any {
res := make(map[string]any)
images := make(map[string][]string, 0)
_ = json.Unmarshal([]byte(r.CoverImages), &images)
for k, imgs := range images {
for idx, img := range imgs {
img = service.NewQiniu().QuarterUrl(img)
images[k][idx] = img
}
}
res["id"] = r.ID
res["covers"] = images
res["covers_show"] = r.CoverShow
res["count"] = r.Count
res["create_time"] = time.Unix(r.CreateTime, 0).Format("2006-01-02 15:04:05")
res["lang"] = r.Lang
res["title"] = r.Title
res["content"] = r.Content
res["publish_time"] = r.PublishTime
res["category_id"] = r.CategoryID
res["category_name"] = r.CategoryName
res["category_name_en"] = r.CategoryEn
res["weight"] = r.Weight
res["pinned"] = r.Pinned
return res
}

View File

@ -0,0 +1,15 @@
package model
type NewsTranslations struct {
NewsID int64
Lang string
Title string
PublishTime string
Content string
}
func (r *NewsTranslations) Format() map[string]any {
res := make(map[string]any)
return res
}

30
app/common/model/page.go Normal file
View File

@ -0,0 +1,30 @@
package model
import "time"
type Page struct {
ID int64
Name string
Page string
Pid int64
Path string
Weight int64
Content string
Tags string
CreateTime int64
UpdateTime int64
}
func (r *Page) Format() map[string]any {
res := make(map[string]any)
res["id"] = r.ID
res["name"] = r.Name
res["page"] = r.Page
res["pid"] = r.Pid
res["path"] = r.Path
res["weight"] = r.Weight
res["content"] = r.Content
res["tags"] = r.Tags
res["create_time"] = time.Unix(r.CreateTime, 0).Format("2006-01-02 15:04:05")
return res
}

View File

@ -0,0 +1,43 @@
package model
import (
"encoding/json"
"time"
"yintai-api/app/common/service"
)
type Process struct {
ID int64
CreateTime int64
UpdateTime int64
}
type ProcessPage struct {
Process
ProcessTranslations
CategoryID int64
CategoryName string
CategoryEn string
}
func (r *ProcessPage) Format() map[string]any {
res := make(map[string]any)
images := make([]string, 0)
_ = json.Unmarshal([]byte(r.Images), &images)
for _, img := range images {
img = service.NewQiniu().QuarterUrl(img)
images = append(images, img)
}
res["images"] = images
res["id"] = r.ID
res["create_time"] = time.Unix(r.CreateTime, 0).Format("2006-01-02 15:04:05")
res["lang"] = r.Lang
res["title"] = r.Title
res["content"] = r.Content
res["process_time"] = r.ProcessTime
res["category_id"] = r.CategoryID
res["category_name"] = r.CategoryName
res["category_name_en"] = r.CategoryEn
return res
}

View File

@ -0,0 +1,33 @@
package model
import (
"encoding/json"
"yintai-api/app/common/service"
)
type ProcessTranslations struct {
ProcessID int64
Lang string
Title string
Images string
Content string
ProcessTime string
}
func (r *ProcessTranslations) Format() map[string]any {
res := make(map[string]any)
images := make([]string, 0)
_ = json.Unmarshal([]byte(r.Images), &images)
for _, img := range images {
img = service.NewQiniu().QuarterUrl(img)
images = append(images, img)
}
res["process_id"] = r.ProcessID
res["images"] = images
res["lang"] = r.Lang
res["title"] = r.Title
res["content"] = r.Content
res["process_time"] = r.ProcessTime
return res
}

View File

@ -0,0 +1,35 @@
package model
import "time"
type Resource struct {
ID int64
Name string
Type string
Code string
Path string
Method string
Pid int64
Maps string
CreateTime int64
UpdateTime int64
}
const (
ResourceTypeApi = "api"
ResourceTypePage = "page"
)
func (r *Resource) Format() map[string]any {
res := make(map[string]any)
res["id"] = r.ID
res["name"] = r.Name
res["type"] = r.Type
res["path"] = r.Path
//res["code"] = r.Code
res["pid"] = r.Pid
res["method"] = r.Method
res["create_time"] = time.Unix(r.CreateTime, 0).Format("2006-01-02 15:04:05")
return res
}

21
app/common/model/role.go Normal file
View File

@ -0,0 +1,21 @@
package model
import "time"
type Role struct {
ID int64
Name string
Desc string
CreateTime int64
UpdateTime int64
}
func (r *Role) Format() map[string]any {
res := make(map[string]any)
res["id"] = r.ID
res["name"] = r.Name
res["desc"] = r.Desc
res["create_time"] = time.Unix(r.CreateTime, 0).Format("2006-01-02 15:04:05")
return res
}

View File

@ -0,0 +1,13 @@
package model
type RoleResource struct {
ID int64
RoleID int64
ResourceID int64
}
func (r *RoleResource) Format() map[string]any {
res := make(map[string]any)
return res
}

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