service.xpcool.com/internal/controller/recruitment/recruitment.go
夏犀麟 4445b8e8bf
Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 14s
CHG: house transaction service 层 + recruitment 招聘模块 + 012 菜单 SQL(补提交未推送代码)
2026-08-27 00:41:59 +08:00

160 lines
6.6 KiB
Go

package recruitment
import (
"context"
recruitmentv1 "service.xpcool.com/api/recruitment/v1"
"service.xpcool.com/internal/model/dto"
"service.xpcool.com/internal/service/recruitment"
)
// toItem 将服务层 VO 映射为 API 出参项。
func toItem(v *dto.RecruitmentInfoVO) *recruitmentv1.RecruitmentItem {
if v == nil {
return nil
}
return &recruitmentv1.RecruitmentItem{
Id: v.Id, Title: v.Title, SourceId: v.SourceId, SourceName: v.SourceName,
OrgId: v.OrgId, OrgName: v.OrgName, Category: v.Category, CategoryName: v.CategoryName,
Region: v.Region, PublishDate: v.PublishDate, Deadline: v.Deadline, ExamDate: v.ExamDate,
Url: v.Url, Content: v.Content, Attachments: v.Attachments, Status: v.Status,
StatusName: v.StatusName, GroupKey: v.GroupKey, CreatedAt: v.CreatedAt,
}
}
// InfoList 招聘公告列表(多维筛选)。
func (c *Controller) InfoList(ctx context.Context, req *recruitmentv1.RecruitmentListReq) (res *recruitmentv1.RecruitmentListRes, err error) {
list, total, err := recruitment.Recruitment().List(ctx, dto.RecruitmentFilter{
Page: req.Page, Size: req.Size, Region: req.Region, Category: req.Category,
Keyword: req.Keyword, Status: req.Status, DateFrom: req.DateFrom, DateTo: req.DateTo,
OrgName: req.OrgName, SourceId: req.SourceId, OnlyNewToday: req.OnlyNewToday,
})
if err != nil {
return nil, err
}
out := make([]*recruitmentv1.RecruitmentItem, 0, len(list))
for i := range list {
out = append(out, toItem(&list[i]))
}
return &recruitmentv1.RecruitmentListRes{List: out, Total: total}, nil
}
// InfoDetail 招聘公告详情。
func (c *Controller) InfoDetail(ctx context.Context, req *recruitmentv1.RecruitmentDetailReq) (res *recruitmentv1.RecruitmentDetailRes, err error) {
info, err := recruitment.Recruitment().Detail(ctx, req.Id)
if err != nil {
return nil, err
}
return &recruitmentv1.RecruitmentDetailRes{Info: toItem(info)}, nil
}
// Stats 招聘数据看板统计。
func (c *Controller) Stats(ctx context.Context, req *recruitmentv1.RecruitmentStatsReq) (res *recruitmentv1.RecruitmentStatsRes, err error) {
s, err := recruitment.Recruitment().Stats(ctx, req.Region)
if err != nil {
return nil, err
}
byCat := make([]recruitmentv1.CategoryAggItem, 0, len(s.ByCategory))
for _, v := range s.ByCategory {
byCat = append(byCat, recruitmentv1.CategoryAggItem{Category: v.Category, CategoryName: v.CategoryName, Count: v.Count})
}
byRegion := make([]recruitmentv1.RegionAggItem, 0, len(s.ByRegion))
for _, v := range s.ByRegion {
byRegion = append(byRegion, recruitmentv1.RegionAggItem{Region: v.Region, Count: v.Count})
}
trend := make([]recruitmentv1.TrendPointItem, 0, len(s.RecentTrend))
for _, v := range s.RecentTrend {
trend = append(trend, recruitmentv1.TrendPointItem{Date: v.Date, Count: v.Count})
}
return &recruitmentv1.RecruitmentStatsRes{
Total: s.Total, TodayNew: s.TodayNew, WeekNew: s.WeekNew,
ByCategory: byCat, ByRegion: byRegion, RecentTrend: trend,
}, nil
}
// Trend 招聘公告趋势(按日)。
func (c *Controller) Trend(ctx context.Context, req *recruitmentv1.RecruitmentTrendReq) (res *recruitmentv1.RecruitmentTrendRes, err error) {
pts, err := recruitment.Recruitment().Trend(ctx, req.Region, req.Category, req.Days)
if err != nil {
return nil, err
}
out := make([]recruitmentv1.TrendPointItem, 0, len(pts))
for _, v := range pts {
out = append(out, recruitmentv1.TrendPointItem{Date: v.Date, Count: v.Count})
}
return &recruitmentv1.RecruitmentTrendRes{Trend: out}, nil
}
// SourceList 数据源列表与运行状态。
func (c *Controller) SourceList(ctx context.Context, req *recruitmentv1.RecruitmentSourcesReq) (res *recruitmentv1.RecruitmentSourcesRes, err error) {
list, err := recruitment.Recruitment().Sources(ctx)
if err != nil {
return nil, err
}
out := make([]*recruitmentv1.SourceItem, 0, len(list))
for i := range list {
v := &list[i]
out = append(out, &recruitmentv1.SourceItem{
Id: v.Id, Name: v.Name, BaseUrl: v.BaseUrl, SourceType: v.SourceType,
Category: v.Category, Region: v.Region, Enabled: v.Enabled,
LastSuccessAt: v.LastSuccessAt, FailCount: v.FailCount, LastSummary: v.LastSummary,
})
}
return &recruitmentv1.RecruitmentSourcesRes{List: out}, nil
}
// CrawlTrigger 手动触发抓取(单源或全量)。
func (c *Controller) CrawlTrigger(ctx context.Context, req *recruitmentv1.RecruitmentTriggerReq) (res *recruitmentv1.RecruitmentTriggerRes, err error) {
n, summary, err := recruitment.Recruitment().Trigger(ctx, req.SourceId, req.Force)
if err != nil {
return nil, err
}
return &recruitmentv1.RecruitmentTriggerRes{Triggered: n, Summary: summary}, nil
}
// PushTest Bark 推送测试。
func (c *Controller) PushTest(ctx context.Context, req *recruitmentv1.RecruitmentPushTestReq) (res *recruitmentv1.RecruitmentPushTestRes, err error) {
ok, msg, err := recruitment.Recruitment().PushTest(ctx, req.SubscriptionId, req.Title, req.Body)
if err != nil {
return nil, err
}
return &recruitmentv1.RecruitmentPushTestRes{Result: ok, Message: msg}, nil
}
// SubscriptionList 推送订阅列表。
func (c *Controller) SubscriptionList(ctx context.Context, req *recruitmentv1.RecruitmentSubscriptionListReq) (res *recruitmentv1.RecruitmentSubscriptionListRes, err error) {
list, err := recruitment.Recruitment().SubscriptionList(ctx)
if err != nil {
return nil, err
}
out := make([]*recruitmentv1.SubscriptionItem, 0, len(list))
for i := range list {
v := &list[i]
out = append(out, &recruitmentv1.SubscriptionItem{
Id: v.Id, Name: v.Name, DeviceKey: v.DeviceKey, Regions: v.Regions,
Categories: v.Categories, OnlyNew: v.OnlyNew, PushTime: v.PushTime, Enabled: v.Enabled,
})
}
return &recruitmentv1.RecruitmentSubscriptionListRes{List: out}, nil
}
// SubscriptionSave 保存推送订阅(新增/更新)。
func (c *Controller) SubscriptionSave(ctx context.Context, req *recruitmentv1.RecruitmentSubscriptionSaveReq) (res *recruitmentv1.RecruitmentSubscriptionSaveRes, err error) {
id, err := recruitment.Recruitment().SubscriptionSave(ctx, dto.SubscriptionInput{
Id: req.Id, Name: req.Name, DeviceKey: req.DeviceKey, Regions: req.Regions,
Categories: req.Categories, OnlyNew: req.OnlyNew, PushTime: req.PushTime, Enabled: req.Enabled,
})
if err != nil {
return nil, err
}
return &recruitmentv1.RecruitmentSubscriptionSaveRes{Id: id}, nil
}
// SubscriptionDelete 删除推送订阅。
func (c *Controller) SubscriptionDelete(ctx context.Context, req *recruitmentv1.RecruitmentSubscriptionDeleteReq) (res *recruitmentv1.RecruitmentSubscriptionDeleteRes, err error) {
if err = recruitment.Recruitment().SubscriptionDelete(ctx, req.Id); err != nil {
return nil, err
}
return &recruitmentv1.RecruitmentSubscriptionDeleteRes{}, nil
}