| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- package opsdev
- import (
- "context"
- "dashoo.cn/opms_libary/myerrors"
- opsdevdao "dashoo.cn/opms_parent/app/dao/opsdev"
- opsdevmodel "dashoo.cn/opms_parent/app/model/opsdev"
- "dashoo.cn/opms_parent/app/service"
- "github.com/gogf/gf/database/gdb"
- "github.com/gogf/gf/frame/g"
- "github.com/gogf/gf/os/gtime"
- "github.com/gogf/gf/util/gconv"
- )
- // PlatMeetingService 会议业务逻辑实现类
- type PlatMeetingService struct {
- *service.ContextService
- MeetingDao *opsdevdao.PlatMeetingDao
- AttendeeDao *opsdevdao.PlatMeetingAttendeeDao
- WorkHourDao *opsdevdao.PlatMeetingWorkHourDao
- }
- // NewPlatMeetingService 初始化service
- func NewPlatMeetingService(ctx context.Context) (svc *PlatMeetingService, err error) {
- svc = new(PlatMeetingService)
- if svc.ContextService, err = svc.Init(ctx); err != nil {
- return nil, err
- }
- svc.MeetingDao = opsdevdao.NewPlatMeetingDao(svc.Tenant)
- svc.AttendeeDao = opsdevdao.NewPlatMeetingAttendeeDao(svc.Tenant)
- svc.WorkHourDao = opsdevdao.NewPlatMeetingWorkHourDao(svc.Tenant)
- return svc, nil
- }
- // GetList 分页查询会议列表
- func (s *PlatMeetingService) GetList(req *opsdevmodel.PlatMeetingSearchReq) (total int, list []*opsdevmodel.PlatMeetingRsp, err error) {
- db := s.MeetingDao.FieldsEx(s.MeetingDao.Columns.DeletedTime)
- if req.MeetingTitle != "" {
- db = db.Where(s.MeetingDao.Columns.MeetingTitle+" like ?", "%"+req.MeetingTitle+"%")
- }
- if req.OrganizerName != "" {
- db = db.Where(s.MeetingDao.Columns.OrganizerName+" like ?", "%"+req.OrganizerName+"%")
- }
- if req.DeptId > 0 {
- db = db.Where(s.MeetingDao.Columns.DeptId, req.DeptId)
- }
- if req.MeetingDateStart != "" {
- db = db.Where(s.MeetingDao.Columns.MeetingDate+" >= ?", req.MeetingDateStart)
- }
- if req.MeetingDateEnd != "" {
- db = db.Where(s.MeetingDao.Columns.MeetingDate+" <= ?", req.MeetingDateEnd)
- }
- total, err = db.Count()
- if err != nil {
- return 0, nil, myerrors.DbError("获取会议总数失败")
- }
- pageNum, pageSize := req.GetPage()
- db = db.Order(s.MeetingDao.Columns.CreatedTime + " desc")
- var entities []*opsdevmodel.PlatMeeting
- err = db.Page(pageNum, pageSize).Scan(&entities)
- if err != nil {
- return 0, nil, myerrors.DbError("查询会议列表失败")
- }
- if err = gconv.Structs(entities, &list); err != nil {
- return 0, nil, myerrors.DbError("数据转换失败")
- }
- // 查询每个会议的参会人员
- for _, item := range list {
- attendees, _ := s.getAttendeesByMeetingId(int(item.Id))
- item.Attendees = attendees
- }
- return
- }
- // GetById 根据ID获取会议详情
- func (s *PlatMeetingService) GetById(id int) (*opsdevmodel.PlatMeetingRsp, error) {
- var entity opsdevmodel.PlatMeeting
- err := s.MeetingDao.FieldsEx(s.MeetingDao.Columns.DeletedTime).
- WherePri(s.MeetingDao.Columns.Id, id).Scan(&entity)
- if err != nil {
- return nil, myerrors.DbError("查询会议失败")
- }
- if entity.Id <= 0 {
- return nil, myerrors.TipsError("会议不存在")
- }
- var rsp opsdevmodel.PlatMeetingRsp
- if err := gconv.Struct(entity, &rsp); err != nil {
- return nil, myerrors.DbError("数据转换失败")
- }
- attendees, err := s.getAttendeesByMeetingId(id)
- if err != nil {
- return nil, err
- }
- rsp.Attendees = attendees
- return &rsp, nil
- }
- // Create 新增会议(含参会人员 + 工时生成)
- func (s *PlatMeetingService) Create(req *opsdevmodel.PlatMeetingAddReq) error {
- data := g.Map{
- s.MeetingDao.Columns.MeetingTitle: req.MeetingTitle,
- s.MeetingDao.Columns.MeetingContent: req.MeetingContent,
- s.MeetingDao.Columns.OrganizerId: req.OrganizerId,
- s.MeetingDao.Columns.OrganizerName: req.OrganizerName,
- s.MeetingDao.Columns.DeptId: req.DeptId,
- s.MeetingDao.Columns.Duration: req.Duration,
- s.MeetingDao.Columns.Remark: req.Remark,
- }
- if req.MeetingDate != "" {
- data[s.MeetingDao.Columns.MeetingDate] = req.MeetingDate
- }
- service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- return s.MeetingDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- result, err := s.MeetingDao.TX(tx).Data(data).Insert()
- if err != nil {
- return myerrors.DbError("新增会议失败")
- }
- meetingId, err := result.LastInsertId()
- if err != nil {
- return myerrors.DbError("获取会议ID失败")
- }
- if err := s.batchInsertAttendees(tx, int(meetingId), req.UserIds, req.UserNames); err != nil {
- return err
- }
- // 生成发起人工时
- workDate := gtime.Now()
- if req.MeetingDate != "" {
- workDate = gtime.NewFromStr(req.MeetingDate)
- }
- orgWhData := g.Map{
- s.WorkHourDao.Columns.MeetingId: int(meetingId),
- s.WorkHourDao.Columns.AttendeeId: 0,
- s.WorkHourDao.Columns.UserId: req.OrganizerId,
- s.WorkHourDao.Columns.UserName: req.OrganizerName,
- s.WorkHourDao.Columns.WorkDate: workDate,
- s.WorkHourDao.Columns.WorkHour: req.Duration,
- s.WorkHourDao.Columns.Remark: req.MeetingTitle,
- }
- service.SetCreatedInfo(orgWhData, s.GetCxtUserId(), s.GetCxtUserName())
- if _, err := s.WorkHourDao.TX(tx).Data(orgWhData).Insert(); err != nil {
- return myerrors.DbError("生成发起人工时失败")
- }
- // 生成参会人员工时
- attendees, err := s.AttendeeDao.TX(tx).FieldsEx(s.AttendeeDao.Columns.DeletedTime).
- Where(s.AttendeeDao.Columns.MeetingId, int(meetingId)).All()
- if err != nil {
- return myerrors.DbError("查询参会人员失败")
- }
- for _, row := range attendees {
- whData := g.Map{
- s.WorkHourDao.Columns.MeetingId: int(meetingId),
- s.WorkHourDao.Columns.AttendeeId: row.Id,
- s.WorkHourDao.Columns.UserId: row.UserId,
- s.WorkHourDao.Columns.UserName: row.UserName,
- s.WorkHourDao.Columns.WorkDate: workDate,
- s.WorkHourDao.Columns.WorkHour: req.Duration,
- s.WorkHourDao.Columns.Remark: req.MeetingTitle,
- }
- service.SetCreatedInfo(whData, s.GetCxtUserId(), s.GetCxtUserName())
- if _, err := s.WorkHourDao.TX(tx).Data(whData).Insert(); err != nil {
- return myerrors.DbError("生成参会人工时失败")
- }
- }
- // 标记参会人工时已生成
- if _, err := s.AttendeeDao.TX(tx).
- Data(g.Map{s.AttendeeDao.Columns.WorkHourGenerated: 1}).
- Where(s.AttendeeDao.Columns.MeetingId, int(meetingId)).Update(); err != nil {
- return myerrors.DbError("更新参会人标记失败")
- }
- return nil
- })
- }
- // UpdateById 更新会议
- func (s *PlatMeetingService) UpdateById(req *opsdevmodel.PlatMeetingUpdateReq) error {
- var entity opsdevmodel.PlatMeeting
- err := s.MeetingDao.FieldsEx(s.MeetingDao.Columns.DeletedTime).
- WherePri(s.MeetingDao.Columns.Id, req.Id).Scan(&entity)
- if err != nil {
- return myerrors.DbError("查询会议失败")
- }
- if entity.Id <= 0 {
- return myerrors.TipsError("会议不存在")
- }
- data := g.Map{}
- if req.MeetingTitle != "" {
- data[s.MeetingDao.Columns.MeetingTitle] = req.MeetingTitle
- }
- if req.MeetingContent != "" {
- data[s.MeetingDao.Columns.MeetingContent] = req.MeetingContent
- }
- if req.MeetingDate != "" {
- data[s.MeetingDao.Columns.MeetingDate] = req.MeetingDate
- }
- if req.Duration > 0 {
- data[s.MeetingDao.Columns.Duration] = req.Duration
- }
- if req.OrganizerId > 0 {
- data[s.MeetingDao.Columns.OrganizerId] = req.OrganizerId
- }
- if req.OrganizerName != "" {
- data[s.MeetingDao.Columns.OrganizerName] = req.OrganizerName
- }
- if req.DeptId > 0 {
- data[s.MeetingDao.Columns.DeptId] = req.DeptId
- }
- if req.Remark != "" {
- data[s.MeetingDao.Columns.Remark] = req.Remark
- }
- if len(data) == 0 && len(req.UserIds) == 0 {
- return nil
- }
- service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- return s.MeetingDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- if len(data) > 0 {
- _, err = s.MeetingDao.TX(tx).FieldsEx(service.UpdateFieldEx...).
- Data(data).WherePri(s.MeetingDao.Columns.Id, req.Id).Update()
- if err != nil {
- return myerrors.DbError("更新会议失败")
- }
- }
- // 全量替换参会人员
- if len(req.UserIds) > 0 {
- if _, err := s.AttendeeDao.TX(tx).
- Where(s.AttendeeDao.Columns.MeetingId, req.Id).Delete(); err != nil {
- return myerrors.DbError("清除旧参会人员失败")
- }
- if err := s.batchInsertAttendees(tx, req.Id, req.UserIds, req.UserNames); err != nil {
- return err
- }
- }
- return nil
- })
- }
- // DeleteByIds 删除会议(软删除会议及参会人员)
- func (s *PlatMeetingService) DeleteByIds(ids []int64) error {
- if len(ids) == 0 {
- return myerrors.TipsError("请选择需要删除的记录")
- }
- return s.MeetingDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- // 软删除参会人员
- for _, id := range ids {
- if _, err := s.AttendeeDao.TX(tx).
- Where(s.AttendeeDao.Columns.MeetingId, id).Delete(); err != nil {
- return myerrors.DbError("删除参会人员失败")
- }
- }
- // 软删除会议
- if _, err := s.MeetingDao.TX(tx).WhereIn(s.MeetingDao.Columns.Id, ids).Delete(); err != nil {
- return myerrors.DbError("删除会议失败")
- }
- return nil
- })
- }
- // AddAttendees 追加参会人员
- func (s *PlatMeetingService) AddAttendees(req *opsdevmodel.PlatMeetingAddAttendeeReq) error {
- // 校验会议存在
- var entity opsdevmodel.PlatMeeting
- err := s.MeetingDao.FieldsEx(s.MeetingDao.Columns.DeletedTime).
- WherePri(s.MeetingDao.Columns.Id, req.MeetingId).Scan(&entity)
- if err != nil {
- return myerrors.DbError("查询会议失败")
- }
- if entity.Id <= 0 {
- return myerrors.TipsError("会议不存在")
- }
- return s.MeetingDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- // 查询已存在参会人,避免重复插入
- existing, err := s.AttendeeDao.TX(tx).
- Where(s.AttendeeDao.Columns.MeetingId, req.MeetingId).
- WhereIn(s.AttendeeDao.Columns.UserId, req.UserIds).
- Fields(s.AttendeeDao.Columns.UserId).All()
- if err != nil {
- return myerrors.DbError("查询已有参会人员失败")
- }
- existingIds := make(map[int]bool)
- for _, row := range existing {
- existingIds[row["user_id"].Int()] = true
- }
- for i, userId := range req.UserIds {
- if existingIds[userId] {
- continue
- }
- userName := ""
- if i < len(req.UserNames) {
- userName = req.UserNames[i]
- }
- attendeeData := g.Map{
- s.AttendeeDao.Columns.MeetingId: req.MeetingId,
- s.AttendeeDao.Columns.UserId: userId,
- s.AttendeeDao.Columns.UserName: userName,
- }
- service.SetCreatedInfo(attendeeData, s.GetCxtUserId(), s.GetCxtUserName())
- if _, err := s.AttendeeDao.TX(tx).Data(attendeeData).Insert(); err != nil {
- return myerrors.DbError("新增参会人员失败")
- }
- }
- return nil
- })
- }
- // Complete 结束会议——为发起人和参会人员补生成工时
- func (s *PlatMeetingService) Complete(req *opsdevmodel.PlatMeetingCompleteReq) error {
- var entity opsdevmodel.PlatMeeting
- err := s.MeetingDao.FieldsEx(s.MeetingDao.Columns.DeletedTime).
- WherePri(s.MeetingDao.Columns.Id, req.Id).Scan(&entity)
- if err != nil {
- return myerrors.DbError("查询会议失败")
- }
- if entity.Id <= 0 {
- return myerrors.TipsError("会议不存在")
- }
- if entity.Duration <= 0 {
- return myerrors.TipsError("会议时长未设置,无法生成工时")
- }
- return s.MeetingDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- workDate := gtime.Now()
- if entity.MeetingDate != nil {
- workDate = entity.MeetingDate
- }
- // 检查发起人工时是否已存在
- orgCount, err := s.WorkHourDao.TX(tx).FieldsEx(s.WorkHourDao.Columns.DeletedTime).
- Where(s.WorkHourDao.Columns.MeetingId, req.Id).
- Where(s.WorkHourDao.Columns.UserId, entity.OrganizerId).
- Where(s.WorkHourDao.Columns.AttendeeId, 0).Count()
- if err != nil {
- return myerrors.DbError("查询发起人工时失败")
- }
- if orgCount == 0 {
- orgWhData := g.Map{
- s.WorkHourDao.Columns.MeetingId: req.Id,
- s.WorkHourDao.Columns.AttendeeId: 0,
- s.WorkHourDao.Columns.UserId: entity.OrganizerId,
- s.WorkHourDao.Columns.UserName: entity.OrganizerName,
- s.WorkHourDao.Columns.WorkDate: workDate,
- s.WorkHourDao.Columns.WorkHour: entity.Duration,
- s.WorkHourDao.Columns.Remark: entity.MeetingTitle,
- }
- service.SetCreatedInfo(orgWhData, s.GetCxtUserId(), s.GetCxtUserName())
- if _, err := s.WorkHourDao.TX(tx).Data(orgWhData).Insert(); err != nil {
- return myerrors.DbError("生成发起人工时失败")
- }
- }
- // 查询未生成工时的参会人员
- attendees, err := s.AttendeeDao.TX(tx).FieldsEx(s.AttendeeDao.Columns.DeletedTime).
- Where(s.AttendeeDao.Columns.MeetingId, req.Id).
- Where(s.AttendeeDao.Columns.WorkHourGenerated, 0).All()
- if err != nil {
- return myerrors.DbError("查询参会人员失败")
- }
- for _, row := range attendees {
- whData := g.Map{
- s.WorkHourDao.Columns.MeetingId: req.Id,
- s.WorkHourDao.Columns.AttendeeId: row.Id,
- s.WorkHourDao.Columns.UserId: row.UserId,
- s.WorkHourDao.Columns.UserName: row.UserName,
- s.WorkHourDao.Columns.WorkDate: workDate,
- s.WorkHourDao.Columns.WorkHour: entity.Duration,
- s.WorkHourDao.Columns.Remark: entity.MeetingTitle,
- }
- service.SetCreatedInfo(whData, s.GetCxtUserId(), s.GetCxtUserName())
- if _, err := s.WorkHourDao.TX(tx).Data(whData).Insert(); err != nil {
- return myerrors.DbError("生成参会人工时失败")
- }
- }
- // 标记参会人工时已生成
- if _, err := s.AttendeeDao.TX(tx).
- Data(g.Map{s.AttendeeDao.Columns.WorkHourGenerated: 1}).
- Where(s.AttendeeDao.Columns.MeetingId, req.Id).Update(); err != nil {
- return myerrors.DbError("更新参会人标记失败")
- }
- return nil
- })
- }
- // GetWorkHourList 获取会议工时记录列表
- func (s *PlatMeetingService) GetWorkHourList(meetingId int) ([]*opsdevmodel.PlatMeetingWorkHourRsp, error) {
- var entities []*opsdevmodel.PlatMeetingWorkHour
- err := s.WorkHourDao.FieldsEx(s.WorkHourDao.Columns.DeletedTime).
- Where(s.WorkHourDao.Columns.MeetingId, meetingId).
- Order(s.WorkHourDao.Columns.Id + " asc").Scan(&entities)
- if err != nil {
- return nil, myerrors.DbError("查询工时记录失败")
- }
- var list []*opsdevmodel.PlatMeetingWorkHourRsp
- if err := gconv.Structs(entities, &list); err != nil {
- return nil, myerrors.DbError("数据转换失败")
- }
- return list, nil
- }
- // getAttendeesByMeetingId 根据会议ID查询参会人员
- func (s *PlatMeetingService) getAttendeesByMeetingId(meetingId int) ([]*opsdevmodel.PlatMeetingAttendeeRsp, error) {
- var entities []*opsdevmodel.PlatMeetingAttendee
- err := s.AttendeeDao.FieldsEx(s.AttendeeDao.Columns.DeletedTime).
- Where(s.AttendeeDao.Columns.MeetingId, meetingId).
- Order(s.AttendeeDao.Columns.Id + " asc").Scan(&entities)
- if err != nil {
- return nil, myerrors.DbError("查询参会人员失败")
- }
- var list []*opsdevmodel.PlatMeetingAttendeeRsp
- if err := gconv.Structs(entities, &list); err != nil {
- return nil, myerrors.DbError("数据转换失败")
- }
- return list, nil
- }
- // batchInsertAttendees 批量新增参会人员(需在事务内调用)
- func (s *PlatMeetingService) batchInsertAttendees(
- tx *gdb.TX, meetingId int, userIds []int, userNames []string,
- ) error {
- for i, userId := range userIds {
- userName := ""
- if i < len(userNames) {
- userName = userNames[i]
- }
- data := g.Map{
- s.AttendeeDao.Columns.MeetingId: meetingId,
- s.AttendeeDao.Columns.UserId: userId,
- s.AttendeeDao.Columns.UserName: userName,
- }
- service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- if _, err := s.AttendeeDao.TX(tx).Data(data).Insert(); err != nil {
- return myerrors.DbError("新增参会人员失败")
- }
- }
- return nil
- }
|