From 50e5cdbaceee71f000341a434620d10a87b582f5 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期六, 15 八月 2026 17:12:59 +0800
Subject: [PATCH] 修改 用户属性表中userId从number到string

---
 src/modules/order/controller/app/info.ts  |    3 
 src/modules/order/entity/info.ts          |    4 
 src/modules/base/db.json                  |    7 ++
 src/modules/market/entity/coupon/user.ts  |    2 
 src/modules/user/service/login.ts         |   14 ++--
 src/modules/market/service/coupon/info.ts |    4 
 src/modules/user/service/wx.ts            |    4 
 src/modules/order/service/pay.ts          |  113 ++++++++++++++++++++++++++++++++++---
 src/modules/market/service/coupon/user.ts |    8 +-
 src/modules/order/controller/app/pay.ts   |    7 ++
 src/modules/order/service/info.ts         |    9 ++-
 11 files changed, 144 insertions(+), 31 deletions(-)

diff --git a/src/modules/base/db.json b/src/modules/base/db.json
index f5c591c..558a743 100644
--- a/src/modules/base/db.json
+++ b/src/modules/base/db.json
@@ -15,6 +15,13 @@
           "remark": "鑷姩纭鏀惰揣鏃堕棿锛屼粠鏀粯鎴愬姛璧风畻锛屽崟浣嶏細澶�"
       },
       {
+          "keyName": "carbonratio",
+          "name": "纰崇Н鍒嗗厬鎹㈡瘮渚�",
+          "data": "100",
+          "dataType": 0,
+          "remark": "鍟嗗煄纰崇Н鍒嗘敮浠橈細鎵�闇�绉垎 = 璁㈠崟閲戦 * carbonratio锛岄粯璁� 100"
+      },
+      {
           "keyName": "userAgreement",
           "name": "鐢ㄦ埛鍗忚",
           "data": "<h3 style=\"text-align: center;\"><strong>鐢ㄦ埛鍗忚</strong></h3><p><br></p><p>xxxxxx</p>",
diff --git a/src/modules/market/entity/coupon/user.ts b/src/modules/market/entity/coupon/user.ts
index e32f162..d7992c5 100644
--- a/src/modules/market/entity/coupon/user.ts
+++ b/src/modules/market/entity/coupon/user.ts
@@ -8,7 +8,7 @@
 export class MarketCouponUserEntity extends BaseEntity {
   @Index()
   @Column({ comment: '鐢ㄦ埛ID' })
-  userId: number;
+  userId: string;
 
   @Index()
   @Column({ comment: '浼樻儬鍒窱D' })
diff --git a/src/modules/market/service/coupon/info.ts b/src/modules/market/service/coupon/info.ts
index b163a7e..5646d4a 100644
--- a/src/modules/market/service/coupon/info.ts
+++ b/src/modules/market/service/coupon/info.ts
@@ -56,7 +56,7 @@
    * @param couponId
    * @param userId
    */
-  async receive(couponId: number, userId: number) {
+  async receive(couponId: number, userId: string) {
     // 妫�鏌ヤ紭鎯犲埜
     await this.check(couponId);
     // 妫�鏌ョ敤鎴锋槸鍚﹀凡棰嗗彇
@@ -79,7 +79,7 @@
    * @param userId
    * @param order
    */
-  async checkAndUse(couponId: number, userId: number, order: OrderInfoEntity) {
+  async checkAndUse(couponId: number, userId: string, order: OrderInfoEntity) {
     // 鍒ゆ柇浼樻儬鍒�
     const couponInfo = await this.check(couponId);
     // 鍒ゆ柇鐢ㄦ埛
diff --git a/src/modules/market/service/coupon/user.ts b/src/modules/market/service/coupon/user.ts
index 566a4da..f8aad00 100644
--- a/src/modules/market/service/coupon/user.ts
+++ b/src/modules/market/service/coupon/user.ts
@@ -23,7 +23,7 @@
    * @param idcouponId
    * @param userId
    */
-  async save(couponId: number, userId: number) {
+  async save(couponId: number, userId: string) {
     const couponUser = new MarketCouponUserEntity();
     couponUser.userId = userId;
     couponUser.couponId = couponId;
@@ -35,7 +35,7 @@
    * @param couponId
    * @param userId
    */
-  async check(couponId: number, userId: number) {
+  async check(couponId: number, userId: string) {
     const info = await this.marketCouponUserEntity.findOneBy({
       couponId: Equal(couponId),
       userId: Equal(userId),
@@ -52,7 +52,7 @@
    * @param couponId
    * @param userId
    */
-  async checkExist(couponId: number, userId: number) {
+  async checkExist(couponId: number, userId: string) {
     const info = await this.marketCouponUserEntity.findOneBy({
       couponId: Equal(couponId),
       userId: Equal(userId),
@@ -65,7 +65,7 @@
    * @param couponId
    * @param userId
    */
-  async use(couponId: number, userId: number) {
+  async use(couponId: number, userId: string) {
     await this.marketCouponUserEntity.update(
       { couponId: Equal(couponId), userId: Equal(userId) },
       { status: 1, useTime: new Date() }
diff --git a/src/modules/order/controller/app/info.ts b/src/modules/order/controller/app/info.ts
index 0018a8b..200d5f0 100644
--- a/src/modules/order/controller/app/info.ts
+++ b/src/modules/order/controller/app/info.ts
@@ -12,7 +12,7 @@
   entity: OrderInfoEntity,
   service: OrderInfoService,
   pageQueryOp: {
-    fieldEq: ['status'],
+    fieldEq: ['status','userId'],
     where: ctx => {
       return [
         // 杩囨护鐢ㄦ埛ID
@@ -37,6 +37,7 @@
       remark: string;
       title: string;
       couponId: number;
+      payType?: number;
     }
   ) {
     return this.ok(
diff --git a/src/modules/order/controller/app/pay.ts b/src/modules/order/controller/app/pay.ts
index ffa1b39..34d2408 100644
--- a/src/modules/order/controller/app/pay.ts
+++ b/src/modules/order/controller/app/pay.ts
@@ -61,4 +61,11 @@
       await this.orderPayService.wxAppPay(orderId, this.ctx.user.id)
     );
   }
+
+  @Post('/carbonPay', { summary: '纰崇Н鍒嗘敮浠�' })
+  async carbonPay(@Body('orderId') orderId) {
+    return this.ok(
+      await this.orderPayService.carbonPay(orderId, this.ctx.user.id)
+    );
+  }
 }
diff --git a/src/modules/order/entity/info.ts b/src/modules/order/entity/info.ts
index ee48bb0..968dce4 100644
--- a/src/modules/order/entity/info.ts
+++ b/src/modules/order/entity/info.ts
@@ -10,12 +10,12 @@
 export class OrderInfoEntity extends BaseEntity {
   @Index()
   @Column({ comment: '鐢ㄦ埛ID' })
-  userId: number;
+  userId: string;
 
   @Column({ comment: '鏍囬', nullable: true })
   title: string;
 
-  @Column({ comment: '鏀粯鏂瑰紡 0-寰呮敮浠� 1-寰俊 2-鏀粯瀹�', default: 0 })
+  @Column({ comment: '鏀粯鏂瑰紡 0-寰呮敮浠� 1-寰俊 2-鏀粯瀹� 3-纰崇Н鍒�', default: 0 })
   payType: number;
 
   @Column({ comment: '鏀粯鏃堕棿', type: 'datetime', nullable: true })
diff --git a/src/modules/order/service/info.ts b/src/modules/order/service/info.ts
index ed47d6b..48786ee 100644
--- a/src/modules/order/service/info.ts
+++ b/src/modules/order/service/info.ts
@@ -178,20 +178,23 @@
    * @param data
    */
   async create(data: {
-    userId: number;
+    userId: string;
     goodsList: OrderGoodsEntity[];
     addressId: number;
     remark: string;
     title: string;
     couponId?: number;
+    payType?: number;
   }) {
     const address = await this.userAddressService.info(data.addressId);
+    const payType = Number(data.payType) || 0;
     const order = {
       userId: data.userId,
       address,
       remark: data.remark,
       title: data.title,
       goodsList: data.goodsList,
+      payType,
     } as OrderInfoEntity;
     // 妫�鏌ュ簱瀛�
     await this.checkStock(data.goodsList);
@@ -211,9 +214,9 @@
     // 鐢熸垚璁㈠崟鍙�
     const orderNum = await this.generateOrderNum(order.id);
 
-    // 鏇存柊璁㈠崟
     await this.orderInfoEntity.update(order.id, {
       orderNum,
+      payType,
     });
 
     // 淇濆瓨璁㈠崟鍟嗗搧
@@ -375,7 +378,7 @@
    * 鐗╂祦淇℃伅
    * @param orderId
    */
-  async logistics(orderId: number, userId?: number) {
+  async logistics(orderId: number, userId?: string) {
     const order: OrderInfoEntity = await this.info(orderId);
     if (userId && order.userId != userId) {
       throw new CoolCommException('闈炴硶鎿嶄綔');
diff --git a/src/modules/order/service/pay.ts b/src/modules/order/service/pay.ts
index 9f5d9f4..3fc8a61 100644
--- a/src/modules/order/service/pay.ts
+++ b/src/modules/order/service/pay.ts
@@ -1,14 +1,16 @@
 import { Init, Inject, Provide } from '@midwayjs/core';
-import { BaseService, CoolCommException } from '@cool-midway/core';
+import { BaseService, CoolCommException, CoolTransaction } from '@cool-midway/core';
 import { PluginService } from '../../plugin/service/info';
 import { OrderInfoService } from './info';
 import { UserWxService } from '../../user/service/wx';
 import BigNumber from 'bignumber.js';
 import { OrderInfoEntity } from '../entity/info';
 import { InjectEntityModel } from '@midwayjs/typeorm';
-import { Repository } from 'typeorm';
+import { QueryRunner, Repository } from 'typeorm';
 import { Action, OrderQueue } from '../queue/order';
 import { BaseSysParamService } from '../../base/service/sys/param';
+import { UserInfoEntity } from '../../user/entity/info';
+import { RecycleTransactionEntity } from '../../shop/entity/transaction';
 
 /**
  * 鏀粯
@@ -17,6 +19,12 @@
 export class OrderPayService extends BaseService {
   @InjectEntityModel(OrderInfoEntity)
   orderInfoEntity: Repository<OrderInfoEntity>;
+
+  @InjectEntityModel(UserInfoEntity)
+  userInfoEntity: Repository<UserInfoEntity>;
+
+  @InjectEntityModel(RecycleTransactionEntity)
+  recycleTransactionEntity: Repository<RecycleTransactionEntity>;
 
   @Inject()
   pluginService: PluginService;
@@ -41,7 +49,7 @@
   /**
    * 鏀粯鎴愬姛
    * @param orderNum 璁㈠崟鍙�
-   * @param payType 鏀粯鏂瑰紡 0-寰呮敮浠� 1-寰俊 2-鏀粯瀹�
+   * @param payType 鏀粯鏂瑰紡 0-寰呮敮浠� 1-寰俊 2-鏀粯瀹� 3-纰崇Н鍒�
    */
   async paySuccess(orderNum: string, payType: number) {
     const order = await this.orderInfoService.getByOrderNum(orderNum);
@@ -49,7 +57,7 @@
       await this.orderInfoEntity.update(order.id, {
         payType,
         status: 1,
-        payTime: order.payTime,
+        payTime: new Date(),
       });
       // 鍙戦�佽嚜鍔ㄧ‘璁ゆ敹璐ч槦鍒�
       const orderConfirm = await this.baseSysParamService.dataByKey(
@@ -71,7 +79,7 @@
    * @param userId
    * @param orderId
    */
-  async wxMiniPay(orderId: number, userId: number) {
+  async wxMiniPay(orderId: number, userId: string) {
     await this.orderInfoEntity.update(orderId, { wxType: 0 });
     return await this.wxJSAPI(orderId, userId, 0);
   }
@@ -81,7 +89,7 @@
    * @param userId
    * @param orderId
    */
-  async wxMpPay(orderId: number, userId: number) {
+  async wxMpPay(orderId: number, userId: string) {
     await this.orderInfoEntity.update(orderId, { wxType: 1 });
     return await this.wxJSAPI(orderId, userId, 1);
   }
@@ -134,7 +142,7 @@
    * @param userId
    * @returns
    */
-  async wxAppPay(orderId: number, userId: number) {
+  async wxAppPay(orderId: number, userId: string) {
     const appid = await this.getAppidByType(2);
 
     const { config, instance } = await this.wxPayInstance(appid);
@@ -162,7 +170,7 @@
    * @param userId
    * @returns
    */
-  async getOrder(orderId: number, userId: number) {
+  async getOrder(orderId: number, userId: string) {
     const order: OrderInfoEntity = await this.orderInfoService.info(orderId);
     if (!order || order.status != 0 || order.userId != userId) {
       throw new CoolCommException('璁㈠崟涓嶅瓨鍦ㄦ垨涓嶆槸鍙互鏀粯鐨勭姸鎬�');
@@ -177,7 +185,7 @@
    * @param type 0-灏忕▼搴� 1-鍏紬鍙� 2-App
    * @returns
    */
-  async wxJSAPI(orderId: number, userId: number, type = 0) {
+  async wxJSAPI(orderId: number, userId: string, type = 0) {
     const order = await this.getOrder(orderId, userId);
     const openid = await this.userWxService.getOpenid(userId, type);
 
@@ -235,4 +243,91 @@
     }
     throw new CoolCommException(result.message);
   }
+
+  /**
+   * 璇诲彇纰崇Н鍒嗗厬鎹㈡瘮渚嬶紝榛樿 100
+   */
+  async getCarbonRatio() {
+    try {
+      const value = await this.baseSysParamService.dataByKey('carbonratio');
+      const ratio = Number(value);
+      if (ratio > 0) {
+        return ratio;
+      }
+    } catch (e) {}
+    return 100;
+  }
+
+  /**
+   * 纰崇Н鍒嗘敮浠橈細涓嶈皟鐢ㄥ閮ㄦ笭閬�
+   * 鎵e噺绉垎 = 璁㈠崟瀹炰粯閲戦 * carbonratio
+   */
+  @CoolTransaction()
+  async carbonPay(orderId: number, userId: string, queryRunner?: QueryRunner) {
+    if (!queryRunner) {
+      throw new CoolCommException('浜嬪姟鍚姩澶辫触');
+    }
+
+    const manager = queryRunner.manager;
+    const order = await manager.findOne(OrderInfoEntity, {
+      where: { id: orderId },
+    });
+    if (!order || order.status != 0 || order.userId != userId) {
+      throw new CoolCommException('璁㈠崟涓嶅瓨鍦ㄦ垨涓嶆槸鍙互鏀粯鐨勭姸鎬�');
+    }
+
+    const user = await manager.findOne(UserInfoEntity, {
+      where: { unionid: userId },
+    });
+    if (!user) {
+      throw new CoolCommException('鐢ㄦ埛涓嶅瓨鍦�');
+    }
+
+    const ratio = await this.getCarbonRatio();
+    const payAmount = new BigNumber(order.price).minus(order.discountPrice || 0);
+    const carbonCost = payAmount.multipliedBy(ratio).toNumber();
+
+    if (Number(user.carbonBalance || 0) < carbonCost) {
+      throw new CoolCommException('纰崇Н鍒嗕笉瓒�');
+    }
+
+    const dec = await manager
+      .createQueryBuilder()
+      .update(UserInfoEntity)
+      .set({ carbonBalance: () => `carbonBalance - ${carbonCost}` })
+      .where('id = :id AND carbonBalance >= :cost', {
+        id: userId,
+        cost: carbonCost,
+      })
+      .execute();
+    if (!dec.affected) {
+      throw new CoolCommException('纰崇Н鍒嗕笉瓒�');
+    }
+
+    await manager.update(OrderInfoEntity, order.id, {
+      payType: 3,
+      status: 1,
+      payTime: new Date(),
+    });
+
+    await manager.save(RecycleTransactionEntity, {
+      userId: user.unionid || String(userId),
+      departmentId: user.departmentId,
+      type: '鏀嚭',
+      amount: carbonCost,
+      sourceType: '鍟嗗煄',
+      remark: `鍟嗗煄璁㈠崟 ${order.orderNum} 纰崇Н鍒嗘敮浠榒,
+      orderId: order.orderNum,
+    });
+
+    const orderConfirm = await this.baseSysParamService.dataByKey('orderConfirm');
+    this.orderQueue.add(
+      { orderId: order.id, action: Action.CONFIRM },
+      {
+        delay: orderConfirm * 60 * 60 * 1000,
+      }
+    );
+
+    return true;
+  }
 }
diff --git a/src/modules/user/service/login.ts b/src/modules/user/service/login.ts
index 0b8d2f2..18d5cb3 100644
--- a/src/modules/user/service/login.ts
+++ b/src/modules/user/service/login.ts
@@ -120,7 +120,7 @@
       };
       await this.userInfoEntity.insert(user);
     }
-    return this.token({ id: user.id });
+    return this.token({ id: user.unionid });
   }
 
   /**
@@ -187,7 +187,7 @@
     const find: any = { openid: wxUserInfo.openid };
     let wxInfo: any = await this.userWxEntity.findOneBy(find);
     if (wxInfo) {
-      wxUserInfo.id = wxInfo.id;
+      wxUserInfo.id = wxInfo.unionid;
     }
     return this.userWxEntity.save({
       ...wxUserInfo,
@@ -237,7 +237,7 @@
       };
       await this.userInfoEntity.insert(userInfo);
     }
-    return this.token({ id: userInfo.id });
+    return this.token({ id: userInfo.unionid });
   }
 
   /**
@@ -253,7 +253,7 @@
       const userInfo = await this.userInfoEntity.findOneBy({
         id: info['id'],
       });
-      return this.token({ id: userInfo.id });
+      return this.token({ id: userInfo?.unionid });
     } catch (e) {
       throw new CoolCommException(
         '鍒锋柊token澶辫触锛岃妫�鏌efreshToken鏄惁姝g‘鎴栬繃鏈�'
@@ -271,7 +271,7 @@
 
     if (user && user.password == md5(password)) {
       return this.token({
-        id: user.id,
+        id: user.unionid,
       });
     } else {
       throw new CoolCommException('璐﹀彿鎴栧瘑鐮侀敊璇�');
@@ -328,7 +328,7 @@
    */
   async generateToken(info, isRefresh = false) {
     const { expire, refreshExpire, secret } = this.jwtConfig;
-    const user = await this.userInfoEntity.findOneBy({ id: Equal(info.id) });
+    const user = await this.userInfoEntity.findOneBy({ unionid: Equal(info.unionid) });
     const tokenInfo = {
       isRefresh,
       ...info,
@@ -346,7 +346,7 @@
    */
   async generateSorterToken(info, isRefresh = false) {
     const { expire, refreshExpire, secret } = this.jwtConfig;
-    const user = await this.basicdataSorterEntity.findOneBy({ businessId: Equal(info.id) });
+    const user = await this.basicdataSorterEntity.findOneBy({ businessId: Equal(info.unionid) });
     const tokenInfo = {
       isRefresh,
       ...info,
diff --git a/src/modules/user/service/wx.ts b/src/modules/user/service/wx.ts
index 76ed2d0..9c1c97a 100644
--- a/src/modules/user/service/wx.ts
+++ b/src/modules/user/service/wx.ts
@@ -74,9 +74,9 @@
    * @param userId
    * @param type 0-灏忕▼搴� 1-鍏紬鍙� 2-App
    */
-  async getOpenid(userId: number, type = 0) {
+  async getOpenid(userId: string, type = 0) {
     const user = await this.userInfoEntity.findOneBy({
-      id: Equal(userId),
+      unionid: Equal(userId),
       status: 1,
     });
     if (!user) {

--
Gitblit v1.9.1