From 3f249e399659dcd09d3fe58071b146e50e45c17f Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期五, 14 八月 2026 21:56:15 +0800
Subject: [PATCH] 为小程序端增加接口

---
 src/modules/shop/controller/app/recycleorderitem.ts   |   11 --
 src/modules/shop/controller/app/recycleorder.ts       |    8 -
 src/modules/shop/service/recycleorder.ts              |    7 
 src/modules/user/controller/app/info.ts               |   11 ++
 src/modules/shop/controller/app/recycleappointment.ts |   33 ++++++
 src/modules/user/service/info.ts                      |   30 +++++
 src/modules/shop/controller/app/transaction.ts        |   39 +++++++
 src/modules/shop/service/transaction.ts               |  142 +++++++++++++++++++++++++++
 8 files changed, 257 insertions(+), 24 deletions(-)

diff --git a/src/modules/shop/controller/app/recycleappointment.ts b/src/modules/shop/controller/app/recycleappointment.ts
new file mode 100644
index 0000000..6343c3b
--- /dev/null
+++ b/src/modules/shop/controller/app/recycleappointment.ts
@@ -0,0 +1,33 @@
+import { Inject } from "@midwayjs/core";
+import { CoolController, BaseController } from "@cool-midway/core";
+import { RecycleAppointmentEntity } from "../../entity/recycleappointment";
+import { RecycleAppointmentService } from "../../service/recycleappointment";
+
+/**
+ * 鍥炴敹棰勭害-搴旂敤绔�
+ */
+@CoolController({
+  api: ["add", "info", "page"],
+  entity: RecycleAppointmentEntity,
+  service: RecycleAppointmentService,
+  pageQueryOp: {
+    fieldEq: ["a.status", "a.campusUserId"],
+    addOrderBy: {
+      createTime: "DESC",
+    },
+    where: async (ctx) => {
+      const { tab } = ctx.request.body;
+      if (tab === "done") {
+        return [["a.status = :st", { st: "宸插畬鎴�" }]];
+      }
+      if (tab === "booked") {
+        return [["a.status != :st", { st: "宸插畬鎴�" }]];
+      }
+      return [];
+    },
+  },
+})
+export class AppRecycleAppointmentController extends BaseController {
+  @Inject()
+  recycleAppointmentService: RecycleAppointmentService;
+}
diff --git a/src/modules/shop/controller/app/recycleorder.ts b/src/modules/shop/controller/app/recycleorder.ts
index 9761a25..ffcff7b 100644
--- a/src/modules/shop/controller/app/recycleorder.ts
+++ b/src/modules/shop/controller/app/recycleorder.ts
@@ -11,12 +11,8 @@
   entity: RecycleOrderEntity,
   service: RecycleOrderService,
   pageQueryOp: {
-    fieldEq: ["a.status"],
-    where: async (ctx) => {
-      return [
-        ["a.campusUserId = :userId", { userId: ctx.user.id }]
-      ];
-    }
+    fieldEq: ["a.status","a.campusUserId","a.orderType"],
+    addOrderBy:{createTime:'DESC'}
   }
 })
 export class AppRecycleOrderController extends BaseController {
diff --git a/src/modules/shop/controller/app/recycleorderitem.ts b/src/modules/shop/controller/app/recycleorderitem.ts
index b1a5fd9..860a6f8 100644
--- a/src/modules/shop/controller/app/recycleorderitem.ts
+++ b/src/modules/shop/controller/app/recycleorderitem.ts
@@ -2,7 +2,6 @@
 import { CoolController, BaseController } from "@cool-midway/core";
 import { RecycleOrderItemEntity } from "../../entity/recycleorderitem";
 import { RecycleOrderItemService } from "../../service/recycleorderitem";
-import { RecycleItemEntity } from "../../entity/recycleitem";
 
 /**
  * 鍥炴敹璁㈠崟鏉$洰-搴旂敤绔�
@@ -12,15 +11,7 @@
   entity: RecycleOrderItemEntity,
   service: RecycleOrderItemService,
   pageQueryOp: {
-    select: ["a.*", "b.mainPic"],
-    fieldEq: ["a.orderId"],
-    join: [
-      {
-        entity: RecycleItemEntity,
-        alias: "b",
-        condition: "a.itemId = b.id",
-      },
-    ],
+    fieldEq: ["a.orderId"]
   },
 })
 export class AppRecycleOrderitemController extends BaseController {
diff --git a/src/modules/shop/controller/app/transaction.ts b/src/modules/shop/controller/app/transaction.ts
new file mode 100644
index 0000000..896860a
--- /dev/null
+++ b/src/modules/shop/controller/app/transaction.ts
@@ -0,0 +1,39 @@
+import { Body, Inject, Post } from '@midwayjs/core';
+import { CoolController, BaseController } from '@cool-midway/core';
+import { RecycleTransactionEntity } from '../../entity/transaction';
+import { RecycleTransactionService } from '../../service/transaction';
+
+/**
+ * 纰崇Н鍒嗘祦姘�-搴旂敤绔�
+ */
+@CoolController({
+  api: ['page'],
+  entity: RecycleTransactionEntity,
+  service: RecycleTransactionService,
+  pageQueryOp: {
+    addOrderBy: {
+      createTime: 'DESC',
+    },
+  },
+})
+export class AppRecycleTransactionController extends BaseController {
+  @Inject()
+  recycleTransactionService: RecycleTransactionService;
+
+  @Post('/checkUser', { summary: '鏍¢獙杞禒鎺ユ敹浜�' })
+  async checkUser(@Body('unionid') unionid: string) {
+    return this.ok(await this.recycleTransactionService.checkUser(unionid));
+  }
+
+  @Post('/transfer', { summary: '纰崇Н鍒嗚浆璧�' })
+  async transfer(
+    @Body()
+    body: {
+      fromUnionid: string;
+      toUnionid: string;
+      amount: number;
+    }
+  ) {
+    return this.ok(await this.recycleTransactionService.transfer(body));
+  }
+}
diff --git a/src/modules/shop/service/recycleorder.ts b/src/modules/shop/service/recycleorder.ts
index 1bd5240..4357256 100644
--- a/src/modules/shop/service/recycleorder.ts
+++ b/src/modules/shop/service/recycleorder.ts
@@ -119,11 +119,10 @@
     });
 
     if (order?.campusUserId) {
-      await UserInfoEntity.update(
+      await UserInfoEntity.getRepository().increment(
         { unionid: order.campusUserId },
-        {
-          carbonBalance: () => `carbonBalance + ${totalCarbonPoint}`
-        }
+        'carbonBalance',
+        totalCarbonPoint
       );
     }
 
diff --git a/src/modules/shop/service/transaction.ts b/src/modules/shop/service/transaction.ts
index e8304cd..26639b5 100644
--- a/src/modules/shop/service/transaction.ts
+++ b/src/modules/shop/service/transaction.ts
@@ -1,8 +1,9 @@
 import { Provide } from '@midwayjs/core';
-import { BaseService } from '@cool-midway/core';
+import { BaseService, CoolCommException, CoolTransaction } from '@cool-midway/core';
 import { InjectEntityModel } from '@midwayjs/typeorm';
-import { Repository } from 'typeorm';
+import { QueryRunner, Repository } from 'typeorm';
 import { RecycleTransactionEntity } from '../entity/transaction';
+import { UserInfoEntity } from '../../user/entity/info';
 
 /**
  * 纰崇Н鍒嗘祦杞褰�
@@ -12,4 +13,139 @@
   @InjectEntityModel(RecycleTransactionEntity)
   recycleTransactionEntity: Repository<RecycleTransactionEntity>;
 
-}
\ No newline at end of file
+  @InjectEntityModel(UserInfoEntity)
+  userInfoEntity: Repository<UserInfoEntity>;
+
+  /**
+   * App 绔垎椤碉細杞禒 tab 鍙湅璧犻��/鎺ュ彈锛屾敹鏀� tab 鐪嬪叾浣欑被鍨�
+   */
+  async page(query: any) {
+    const { userId, tab, page = 1, size = 10 } = query || {};
+    const find = this.recycleTransactionEntity.createQueryBuilder('a');
+
+    if (userId) {
+      find.andWhere('a.userId = :uid', { uid: String(userId) });
+    }
+
+    if (tab === 'io') {
+      find.andWhere('(a.sourceType != :t1 AND a.sourceType != :t2)', {
+        t1: '璧犻��',
+        t2: '鎺ュ彈',
+      });
+    } else {
+      find.andWhere('(a.sourceType = :t1 OR a.sourceType = :t2)', {
+        t1: '璧犻��',
+        t2: '鎺ュ彈',
+      });
+    }
+
+    find.orderBy('a.createTime', 'DESC');
+    find.addOrderBy('a.id', 'DESC');
+
+    console.log(find)
+
+    return this.entityRenderPage(find, { ...query, page, size }, false);
+  }
+
+  async checkUser(unionid: string) {
+    if (!unionid) {
+      throw new CoolCommException('璇烽�夋嫨绯荤粺鐢ㄦ埛浣滀负鎺ュ彈杞禒瀵硅薄');
+    }
+    const user = await this.userInfoEntity.findOneBy({ unionid });
+    if (!user) {
+      throw new CoolCommException('璇烽�夋嫨绯荤粺鐢ㄦ埛浣滀负鎺ュ彈杞禒瀵硅薄');
+    }
+    return {
+      unionid: user.unionid,
+      nickName: user.nickName,
+      phone: user.phone,
+    };
+  }
+
+  @CoolTransaction()
+  async transfer(
+    param: { fromUnionid: string; toUnionid: string; amount: number },
+    queryRunner?: QueryRunner
+  ) {
+    if (!queryRunner) {
+      throw new CoolCommException('浜嬪姟鍚姩澶辫触');
+    }
+
+    const fromUnionid = String(param.fromUnionid || '').trim();
+    const toUnionid = String(param.toUnionid || '').trim();
+    const amount = Number(param.amount);
+
+    if (!fromUnionid || !toUnionid) {
+      throw new CoolCommException('杞禒鍙傛暟涓嶅畬鏁�');
+    }
+    if (fromUnionid === toUnionid) {
+      throw new CoolCommException('涓嶈兘杞禒缁欒嚜宸�');
+    }
+    if (!amount || amount <= 0) {
+      throw new CoolCommException('杞禒閲戦蹇呴』澶т簬0');
+    }
+
+    const manager = queryRunner.manager;
+    const fromUser = await manager.findOne(UserInfoEntity, {
+      where: { unionid: fromUnionid },
+    });
+    const toUser = await manager.findOne(UserInfoEntity, {
+      where: { unionid: toUnionid },
+    });
+
+    if (!toUser) {
+      throw new CoolCommException('璇烽�夋嫨绯荤粺鐢ㄦ埛浣滀负鎺ュ彈杞禒瀵硅薄');
+    }
+    if (!fromUser) {
+      throw new CoolCommException('褰撳墠鐢ㄦ埛涓嶅瓨鍦�');
+    }
+    if (Number(fromUser.carbonBalance || 0) < amount) {
+      throw new CoolCommException('纰崇Н鍒嗕笉瓒�');
+    }
+
+    const dec = await manager
+      .createQueryBuilder()
+      .update(UserInfoEntity)
+      .set({ carbonBalance: () => `carbonBalance - ${amount}` })
+      .where('unionid = :unionid AND carbonBalance >= :amount', {
+        unionid: fromUnionid,
+        amount,
+      })
+      .execute();
+
+    if (!dec.affected) {
+      throw new CoolCommException('纰崇Н鍒嗕笉瓒�');
+    }
+
+    await manager
+      .createQueryBuilder()
+      .update(UserInfoEntity)
+      .set({ carbonBalance: () => `carbonBalance + ${amount}` })
+      .where('unionid = :unionid', { unionid: toUnionid })
+      .execute();
+
+    const fromName = fromUser.nickName || fromUser.phone || fromUnionid;
+    const toName = toUser.nickName || toUser.phone || toUnionid;
+
+    await manager.save(RecycleTransactionEntity, [
+      {
+        userId: fromUnionid,
+        departmentId: fromUser.departmentId,
+        type: '鏀嚭',
+        amount,
+        sourceType: '璧犻��',
+        remark: `杞禒缁�${toName}`,
+      },
+      {
+        userId: toUnionid,
+        departmentId: toUser.departmentId,
+        type: '鏀跺叆',
+        amount,
+        sourceType: '鎺ュ彈',
+        remark: `浠�${fromName}鑾疯禒`,
+      },
+    ]);
+
+    return true;
+  }
+}
diff --git a/src/modules/user/controller/app/info.ts b/src/modules/user/controller/app/info.ts
index b1a94ab..d96e807 100644
--- a/src/modules/user/controller/app/info.ts
+++ b/src/modules/user/controller/app/info.ts
@@ -62,4 +62,15 @@
       )
     );
   }
+
+   @Post('/dashboard', { summary: '鑾峰彇鐢ㄦ埛纰崇Н鍒嗕俊鎭�' })
+  async dashboard(@Body() body) {
+    console.log(body)
+    const {unionid} = body;
+    return this.ok(
+      await this.userInfoService.dashboard(
+        unionid
+      )
+    );
+  }
 }
diff --git a/src/modules/user/service/info.ts b/src/modules/user/service/info.ts
index 1331c45..c918e6f 100644
--- a/src/modules/user/service/info.ts
+++ b/src/modules/user/service/info.ts
@@ -8,6 +8,8 @@
 import { UserInfoEntity } from '../entity/info';
 import { UserSmsService } from './sms';
 import { UserWxService } from './wx';
+import { RecycleOrderEntity } from '../../shop/entity/recycleorder';
+
 
 /**
  * 鐢ㄦ埛淇℃伅
@@ -16,6 +18,9 @@
 export class UserInfoService extends BaseService {
   @InjectEntityModel(UserInfoEntity)
   userInfoEntity: Repository<UserInfoEntity>;
+
+  @InjectEntityModel(RecycleOrderEntity)
+  recycleOrderEntity: Repository<RecycleOrderEntity>;
 
   @Inject()
   pluginService: PluginService;
@@ -85,7 +90,7 @@
           uuid() + '.png'
         );
       }
-    } catch (err) {}
+    } catch (err) { }
     try {
       return await this.userInfoEntity.update({ id }, param);
     } catch (err) {
@@ -129,4 +134,27 @@
     }
     await this.userInfoEntity.update({ id: userId }, { phone });
   }
+
+  /**
+     * 鑾峰彇鐢ㄦ埛鐨勭⒊绉垎淇℃伅
+     * @param unionid
+     */
+  async dashboard(unionid) {
+    const info = await this.userInfoEntity.findOneBy({ unionid: unionid });
+    if (!info) {
+      throw new CoolCommException('鏌ヨ鏃犵粨鏋�');
+    }
+
+    const count_ = await this.recycleOrderEntity.countBy({
+      campusUserId: unionid
+    });
+
+
+    return { carbonPoints: info.carbonBalance, recycleCount:count_, overPercent: 90 }
+
+  }
+
+
+
+
 }

--
Gitblit v1.9.1