|
|
@@ -6,6 +6,7 @@ import { PetInfo } from '../entities/pet-info.entity'
|
|
|
import { GoodsInfo } from '../entities/goods-info.entity'
|
|
|
import { LinkInfo } from '../entities/link-info.entity'
|
|
|
import { UserQrCode } from '../entities/user-qr-code.entity'
|
|
|
+import { User } from '../entities/user.entity'
|
|
|
import { PaginationResponse } from '../dto/common.dto'
|
|
|
import { FileService } from './file.service'
|
|
|
|
|
|
@@ -248,44 +249,82 @@ export class QrCodeService {
|
|
|
endDate?: string,
|
|
|
page: number = 0,
|
|
|
pageSize: number = 20
|
|
|
- ): Promise<PaginationResponse<QrCode>> {
|
|
|
- const queryBuilder = this.qrCodeRepository.createQueryBuilder('qrCode')
|
|
|
+ ): Promise<PaginationResponse<any>> {
|
|
|
+ const baseQueryBuilder = this.qrCodeRepository.createQueryBuilder('qrCode')
|
|
|
|
|
|
if (qrCode) {
|
|
|
- queryBuilder.andWhere('qrCode.qrCode = :qrCode', { qrCode })
|
|
|
+ baseQueryBuilder.andWhere('qrCode.qrCode = :qrCode', { qrCode })
|
|
|
}
|
|
|
|
|
|
if (qrType) {
|
|
|
- queryBuilder.andWhere('qrCode.qrType = :qrType', { qrType })
|
|
|
+ baseQueryBuilder.andWhere('qrCode.qrType = :qrType', { qrType })
|
|
|
}
|
|
|
|
|
|
if (isActivated !== undefined) {
|
|
|
const isActivatedBool =
|
|
|
typeof isActivated === 'string' ? isActivated === 'true' || isActivated === '1' : Boolean(isActivated)
|
|
|
- queryBuilder.andWhere('qrCode.isActivated = :isActivated', { isActivated: isActivatedBool })
|
|
|
+ baseQueryBuilder.andWhere('qrCode.isActivated = :isActivated', { isActivated: isActivatedBool })
|
|
|
}
|
|
|
|
|
|
if (startDate && endDate) {
|
|
|
- queryBuilder.andWhere('DATE(qrCode.createdAt) BETWEEN :startDate AND :endDate', { startDate, endDate })
|
|
|
+ const start = `${startDate} 00:00:00`
|
|
|
+ const end = `${endDate} 23:59:59`
|
|
|
+ baseQueryBuilder.andWhere('qrCode.createdAt BETWEEN :start AND :end', { start, end })
|
|
|
} else if (startDate) {
|
|
|
- queryBuilder.andWhere('DATE(qrCode.createdAt) >= :startDate', { startDate })
|
|
|
+ const start = `${startDate} 00:00:00`
|
|
|
+ baseQueryBuilder.andWhere('qrCode.createdAt >= :start', { start })
|
|
|
} else if (endDate) {
|
|
|
- queryBuilder.andWhere('DATE(qrCode.createdAt) <= :endDate', { endDate })
|
|
|
+ const end = `${endDate} 23:59:59`
|
|
|
+ baseQueryBuilder.andWhere('qrCode.createdAt <= :end', { end })
|
|
|
}
|
|
|
|
|
|
- const [content, total] = await queryBuilder
|
|
|
- .select()
|
|
|
+ const [qrCodes, total] = await baseQueryBuilder
|
|
|
+ .clone()
|
|
|
.skip(page * pageSize)
|
|
|
.take(pageSize)
|
|
|
.orderBy('qrCode.createdAt', 'DESC')
|
|
|
.getManyAndCount()
|
|
|
|
|
|
+ const qrCodeIds = qrCodes.map(item => item.id).filter(Boolean)
|
|
|
+
|
|
|
+ const ownerByQrCodeId = new Map<number, { ownerId: number; ownerName: string }>()
|
|
|
+
|
|
|
+ if (qrCodeIds.length > 0) {
|
|
|
+ const rows = await this.userQrCodeRepository
|
|
|
+ .createQueryBuilder('uq')
|
|
|
+ .leftJoin(User, 'owner', 'owner.id = uq.userId')
|
|
|
+ .select('uq.qrCodeId', 'qrCodeId')
|
|
|
+ .addSelect('owner.id', 'ownerId')
|
|
|
+ .addSelect('owner.name', 'ownerName')
|
|
|
+ .where('uq.isDeleted = :isDeleted', { isDeleted: false })
|
|
|
+ .andWhere('uq.qrCodeId IN (:...qrCodeIds)', { qrCodeIds })
|
|
|
+ .orderBy('uq.qrCodeId', 'ASC')
|
|
|
+ .addOrderBy('uq.id', 'DESC')
|
|
|
+ .getRawMany<{ qrCodeId: number; ownerId: number; ownerName: string }>()
|
|
|
+
|
|
|
+ for (const row of rows) {
|
|
|
+ const id = Number((row as any).qrCodeId)
|
|
|
+ if (!ownerByQrCodeId.has(id) && (row as any).ownerId != null) {
|
|
|
+ ownerByQrCodeId.set(id, { ownerId: Number((row as any).ownerId), ownerName: (row as any).ownerName })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const content = qrCodes.map(entity => {
|
|
|
+ const owner = ownerByQrCodeId.get(entity.id)
|
|
|
+ return {
|
|
|
+ ...entity,
|
|
|
+ ownerId: owner?.ownerId ?? null,
|
|
|
+ ownerName: owner?.ownerName ?? null
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
return {
|
|
|
content,
|
|
|
metadata: {
|
|
|
- total: Number(total),
|
|
|
- page: Number(page),
|
|
|
- size: Number(pageSize)
|
|
|
+ total: total,
|
|
|
+ page: page,
|
|
|
+ size: pageSize
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -294,9 +333,11 @@ export class QrCodeService {
|
|
|
* 根据日期获取二维码列表(用于下载)
|
|
|
*/
|
|
|
async getQrCodesByDate(date: string): Promise<QrCode[]> {
|
|
|
+ const start = `${date} 00:00:00`
|
|
|
+ const end = `${date} 23:59:59`
|
|
|
return this.qrCodeRepository
|
|
|
.createQueryBuilder('qrCode')
|
|
|
- .where('DATE(qrCode.createdAt) = :date', { date })
|
|
|
+ .where('qrCode.createdAt BETWEEN :start AND :end', { start, end })
|
|
|
.orderBy('qrCode.createdAt', 'ASC')
|
|
|
.getMany()
|
|
|
}
|
|
|
@@ -378,6 +419,17 @@ export class QrCodeService {
|
|
|
throw new Error('Maintenance code error')
|
|
|
}
|
|
|
|
|
|
+ // 一个二维码只能绑定一个用户
|
|
|
+ const activeBind = await this.userQrCodeRepository.findOne({
|
|
|
+ where: { qrCodeId: targetQrCodeId, isDeleted: false }
|
|
|
+ })
|
|
|
+ if (activeBind) {
|
|
|
+ if (activeBind.userId !== userId) {
|
|
|
+ throw new Error('QR code already bound')
|
|
|
+ }
|
|
|
+ return activeBind
|
|
|
+ }
|
|
|
+
|
|
|
const existing = await this.userQrCodeRepository.findOne({
|
|
|
where: { userId, qrCodeId: targetQrCodeId }
|
|
|
})
|
|
|
@@ -497,7 +549,6 @@ export class QrCodeService {
|
|
|
remark: qrCode?.remark
|
|
|
}
|
|
|
|
|
|
- // 根据类型添加特定字段
|
|
|
if (qrType === QrType.LINK) {
|
|
|
result.jumpUrl = jumpUrl
|
|
|
} else if (qrType === QrType.PERSON || qrType === QrType.PET || qrType === QrType.GOODS) {
|