delivery-address.service.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { GenericCrudService } from '@d8d/shared-crud';
  2. import { DataSource } from 'typeorm';
  3. import { DeliveryAddress } from '../entities';
  4. import { AreaService } from '@d8d/geo-areas';
  5. import { AreaLevel } from '@d8d/geo-areas';
  6. export class DeliveryAddressService extends GenericCrudService<DeliveryAddress> {
  7. private areaService: AreaService;
  8. constructor(dataSource: DataSource, areaService: AreaService) {
  9. super(dataSource, DeliveryAddress);
  10. this.areaService = areaService;
  11. }
  12. /**
  13. * 获取用户的收货地址列表
  14. * @param userId 用户ID
  15. * @returns 收货地址列表
  16. */
  17. async findByUser(userId: number): Promise<DeliveryAddress[]> {
  18. return this.repository.find({
  19. where: { userId, state: 1 },
  20. relations: ['user', 'province', 'city', 'district', 'town'],
  21. order: { isDefault: 'DESC', createdAt: 'DESC' }
  22. });
  23. }
  24. /**
  25. * 设置默认地址
  26. * @param id 地址ID
  27. * @param userId 用户ID
  28. * @returns 是否设置成功
  29. */
  30. async setDefault(id: number, userId: number): Promise<boolean> {
  31. await this.repository.manager.transaction(async (transactionalEntityManager) => {
  32. // 先将该用户的所有地址设为非默认
  33. await transactionalEntityManager.update(DeliveryAddress,
  34. { userId },
  35. { isDefault: 0 }
  36. );
  37. // 将指定地址设为默认
  38. await transactionalEntityManager.update(DeliveryAddress,
  39. { id, userId },
  40. { isDefault: 1 }
  41. );
  42. });
  43. return true;
  44. }
  45. /**
  46. * 获取用户的默认地址
  47. * @param userId 用户ID
  48. * @returns 默认地址或null
  49. */
  50. async findDefaultByUser(userId: number): Promise<DeliveryAddress | null> {
  51. return this.repository.findOne({
  52. where: { userId, isDefault: 1, state: 1 },
  53. relations: ['user', 'province', 'city', 'district', 'town']
  54. });
  55. }
  56. /**
  57. * 验证地区数据
  58. * @param provinceId 省份ID
  59. * @param cityId 城市ID
  60. * @param districtId 区县ID
  61. * @param townId 街道ID
  62. * @returns 验证结果
  63. */
  64. async validateAreaData(
  65. provinceId: number,
  66. cityId: number,
  67. districtId: number,
  68. townId: number
  69. ): Promise<boolean> {
  70. try {
  71. // 验证省份
  72. if (provinceId > 0) {
  73. const province = await this.areaService.getAreaTreeByLevel(AreaLevel.PROVINCE);
  74. const validProvince = province.some(area => area.id === provinceId);
  75. if (!validProvince) return false;
  76. }
  77. // 验证城市
  78. if (cityId > 0) {
  79. const city = await this.areaService.getAreaTreeByLevel(AreaLevel.CITY);
  80. const validCity = city.some(area => area.id === cityId);
  81. if (!validCity) return false;
  82. // 验证城市是否属于指定的省份
  83. if (provinceId > 0) {
  84. const cityEntity = await this.areaService.getSubTree(cityId);
  85. if (!cityEntity || cityEntity.parentId !== provinceId) {
  86. return false;
  87. }
  88. }
  89. }
  90. // 验证区县
  91. if (districtId > 0) {
  92. const district = await this.areaService.getAreaTreeByLevel(AreaLevel.DISTRICT);
  93. const validDistrict = district.some(area => area.id === districtId);
  94. if (!validDistrict) return false;
  95. // 验证区县是否属于指定的城市
  96. if (cityId > 0) {
  97. const districtEntity = await this.areaService.getSubTree(districtId);
  98. if (!districtEntity || districtEntity.parentId !== cityId) {
  99. return false;
  100. }
  101. }
  102. }
  103. // 验证街道(如果支持)
  104. if (townId > 0) {
  105. // 街道级别的验证可以根据需要扩展
  106. // 目前假设街道ID是有效的
  107. return true;
  108. }
  109. return true;
  110. } catch (error) {
  111. console.error('地区数据验证失败:', error);
  112. return false;
  113. }
  114. }
  115. /**
  116. * 创建配送地址(包含地区验证)
  117. * @param data 创建数据
  118. * @returns 创建的地址
  119. */
  120. async createWithValidation(data: Partial<DeliveryAddress>): Promise<DeliveryAddress> {
  121. // 验证地区数据
  122. const isValid = await this.validateAreaData(
  123. data.receiverProvince || 0,
  124. data.receiverCity || 0,
  125. data.receiverDistrict || 0,
  126. data.receiverTown || 0
  127. );
  128. if (!isValid) {
  129. throw new Error('地区数据验证失败,请检查省市区信息是否正确');
  130. }
  131. return this.create(data);
  132. }
  133. /**
  134. * 更新配送地址(包含地区验证)
  135. * @param id 地址ID
  136. * @param data 更新数据
  137. * @returns 更新的地址
  138. */
  139. async updateWithValidation(id: number, data: Partial<DeliveryAddress>): Promise<DeliveryAddress | null> {
  140. // 验证地区数据
  141. const isValid = await this.validateAreaData(
  142. data.receiverProvince || 0,
  143. data.receiverCity || 0,
  144. data.receiverDistrict || 0,
  145. data.receiverTown || 0
  146. );
  147. if (!isValid) {
  148. throw new Error('地区数据验证失败,请检查省市区信息是否正确');
  149. }
  150. return this.update(id, data);
  151. }
  152. }