|
|
@@ -0,0 +1,179 @@
|
|
|
+import { DataSource, Repository } from 'typeorm';
|
|
|
+import { Group } from './group.entity';
|
|
|
+import { BelieverGroup } from './believer-group.entity';
|
|
|
+import { logger } from '@/server/utils/logger';
|
|
|
+import { Believer } from '../believers/believer.entity';
|
|
|
+
|
|
|
+export class GroupService {
|
|
|
+ private groupRepository: Repository<Group>;
|
|
|
+ private believerGroupRepository: Repository<BelieverGroup>;
|
|
|
+
|
|
|
+ constructor(dataSource: DataSource) {
|
|
|
+ this.groupRepository = dataSource.getRepository(Group);
|
|
|
+ this.believerGroupRepository = dataSource.getRepository(BelieverGroup);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建小组
|
|
|
+ */
|
|
|
+ async createGroup(data: Partial<Group>): Promise<Group> {
|
|
|
+ try {
|
|
|
+ const group = this.groupRepository.create(data);
|
|
|
+ return await this.groupRepository.save(group);
|
|
|
+ } catch (error) {
|
|
|
+ logger.error('创建小组失败:', error);
|
|
|
+ throw new Error('创建小组记录失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取小组列表(分页)
|
|
|
+ */
|
|
|
+ async getGroupsWithPagination(params: {
|
|
|
+ page: number;
|
|
|
+ pageSize: number;
|
|
|
+ keyword?: string;
|
|
|
+ }): Promise<[Group[], number]> {
|
|
|
+ const { page, pageSize, keyword } = params;
|
|
|
+ const skip = (page - 1) * pageSize;
|
|
|
+
|
|
|
+ const query = this.groupRepository.createQueryBuilder('group');
|
|
|
+
|
|
|
+ if (keyword) {
|
|
|
+ query.andWhere('group.name LIKE :keyword', { keyword: `%${keyword}%` })
|
|
|
+ .orWhere('group.description LIKE :keyword', { keyword: `%${keyword}%` });
|
|
|
+ }
|
|
|
+
|
|
|
+ return query.skip(skip)
|
|
|
+ .take(pageSize)
|
|
|
+ .orderBy('group.createdAt', 'DESC')
|
|
|
+ .getManyAndCount();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据ID获取小组详情
|
|
|
+ */
|
|
|
+ async getGroupById(id: number): Promise<Group | null> {
|
|
|
+ try {
|
|
|
+ return await this.groupRepository.findOneBy({ id });
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`获取小组ID为${id}的详情失败:`, error);
|
|
|
+ throw new Error('获取小组详情失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新小组信息
|
|
|
+ */
|
|
|
+ async updateGroup(id: number, data: Partial<Group>): Promise<Group | null> {
|
|
|
+ try {
|
|
|
+ await this.groupRepository.update(id, data);
|
|
|
+ return this.getGroupById(id);
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`更新小组ID为${id}的信息失败:`, error);
|
|
|
+ throw new Error('更新小组信息失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除小组
|
|
|
+ */
|
|
|
+ async deleteGroup(id: number): Promise<boolean> {
|
|
|
+ try {
|
|
|
+ // 先删除关联记录
|
|
|
+ await this.believerGroupRepository.delete({ groupId: id });
|
|
|
+
|
|
|
+ // 再删除小组
|
|
|
+ const result = await this.groupRepository.delete(id);
|
|
|
+ return result.affected === 1;
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`删除小组ID为${id}的记录失败:`, error);
|
|
|
+ throw new Error('删除小组记录失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加信徒到小组
|
|
|
+ */
|
|
|
+ async addBelieverToGroup(believerId: number, groupId: number): Promise<BelieverGroup> {
|
|
|
+ try {
|
|
|
+ // 检查是否已存在关联
|
|
|
+ const existing = await this.believerGroupRepository.findOneBy({
|
|
|
+ believerId,
|
|
|
+ groupId
|
|
|
+ });
|
|
|
+
|
|
|
+ if (existing) {
|
|
|
+ throw new Error('该信徒已在小组中');
|
|
|
+ }
|
|
|
+
|
|
|
+ const believerGroup = this.believerGroupRepository.create({
|
|
|
+ believerId,
|
|
|
+ groupId
|
|
|
+ });
|
|
|
+
|
|
|
+ return await this.believerGroupRepository.save(believerGroup);
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`添加信徒${believerId}到小组${groupId}失败:`, error);
|
|
|
+ throw error instanceof Error ? error : new Error('添加信徒到小组失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从小组移除信徒
|
|
|
+ */
|
|
|
+ async removeBelieverFromGroup(believerId: number, groupId: number): Promise<boolean> {
|
|
|
+ try {
|
|
|
+ const result = await this.believerGroupRepository.delete({
|
|
|
+ believerId,
|
|
|
+ groupId
|
|
|
+ });
|
|
|
+
|
|
|
+ return result.affected === 1;
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`从小组${groupId}移除信徒${believerId}失败:`, error);
|
|
|
+ throw new Error('从小组移除信徒失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取小组的所有信徒
|
|
|
+ */
|
|
|
+ async getBelieversInGroup(groupId: number): Promise<Believer[]> {
|
|
|
+ try {
|
|
|
+ const query = this.believerGroupRepository.createQueryBuilder('believerGroup')
|
|
|
+ .leftJoinAndSelect('believerGroup.believer', 'believer')
|
|
|
+ .where('believerGroup.groupId = :groupId', { groupId });
|
|
|
+
|
|
|
+ const believerGroups = await query.getMany();
|
|
|
+ return believerGroups.map(bg => bg.believer);
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`获取小组${groupId}的信徒列表失败:`, error);
|
|
|
+ throw new Error('获取小组信徒列表失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置小组组长
|
|
|
+ */
|
|
|
+ async setGroupLeader(groupId: number, leaderId: number): Promise<Group | null> {
|
|
|
+ try {
|
|
|
+ // 先确认该信徒是否在小组中
|
|
|
+ const isMember = await this.believerGroupRepository.exists({
|
|
|
+ where: {
|
|
|
+ groupId,
|
|
|
+ believerId: leaderId
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!isMember) {
|
|
|
+ throw new Error('组长必须是小组中的成员');
|
|
|
+ }
|
|
|
+
|
|
|
+ return this.updateGroup(groupId, { leaderId });
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(`设置小组${groupId}的组长${leaderId}失败:`, error);
|
|
|
+ throw error instanceof Error ? error : new Error('设置小组组长失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|