9276ab9028
## 新增功能 - 冲刺版 ¥49.9/月:完整支付→激活→权益扣减链路 - 每日一题定时推送(@nestjs/schedule,早8点微信订阅消息) - miniprogram-ci 编译上传脚本(scripts/upload-mp.js) ## Bug修复 - 套餐值统一:vip→growth/sprint(interview轮次限制、analyze次数检查) - member/pay 移除开发绕过:改为订单校验后激活 - progress→report 参数名不匹配:id→interviewId - result.vue resume.create() 参数传错(对象→独立参数) - resume.vue analyze请求缺少Authorization header - bank.vue contribution请求缺少Authorization header - member.vue startPay() 缺少try/catch导致网络错误崩溃 - login.vue 调试面板 v-if="true" 生产泄漏 ## 配置 - 微信支付生产证书就位(商户号1113760598) - .env 清理冗余文件(删除.example/.production) - WX_NOTIFY_URL 更新为 zhiyinwx.yzrcloud.cn ## 文档 - PROJECT-STATUS.md v4.1→v4.2,状态全面更新 - DEPLOYMENT.md 新增小程序编译上传章节、清理检查清单
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common'
|
|
import { Cron } from '@nestjs/schedule'
|
|
import { InjectModel } from '@nestjs/mongoose'
|
|
import { Model } from 'mongoose'
|
|
import { WechatTokenService } from './wechat-token.service'
|
|
import { DailyQuestion, DailyQuestionDocument } from '../schemas/daily-question.schema'
|
|
import { User, UserDocument } from '../user/user.schema'
|
|
|
|
const DAILY_QUESTION_TEMPLATE_ID = process.env.WX_DAILY_QUESTION_TMPL || ''
|
|
|
|
@Injectable()
|
|
export class DailyQuestionPushService {
|
|
private readonly logger = new Logger(DailyQuestionPushService.name)
|
|
|
|
constructor(
|
|
@InjectModel(DailyQuestion.name) private dailyQuestionModel: Model<DailyQuestionDocument>,
|
|
@InjectModel(User.name) private userModel: Model<UserDocument>,
|
|
private wechatToken: WechatTokenService,
|
|
) {}
|
|
|
|
@Cron('0 8 * * *')
|
|
async pushDailyQuestion() {
|
|
this.logger.log('开始每日一题推送任务')
|
|
|
|
if (!DAILY_QUESTION_TEMPLATE_ID) {
|
|
this.logger.warn('未配置 WX_DAILY_QUESTION_TMPL,跳过每日推送')
|
|
return
|
|
}
|
|
|
|
const today = new Date()
|
|
today.setHours(0, 0, 0, 0)
|
|
|
|
const question = await this.dailyQuestionModel.findOne({ pushed: false }).sort({ date: -1 }).exec()
|
|
if (!question) {
|
|
this.logger.warn('没有未推送的题目')
|
|
return
|
|
}
|
|
|
|
const users = await this.userModel.find({ wxOpenid: { $ne: '', $exists: true } }).exec()
|
|
this.logger.log(`找到 ${users.length} 个用户待推送`)
|
|
|
|
let successCount = 0
|
|
for (const user of users) {
|
|
if (!user.wxOpenid) continue
|
|
const ok = await this.wechatToken.sendSubscribeMessage(
|
|
user.wxOpenid,
|
|
DAILY_QUESTION_TEMPLATE_ID,
|
|
{
|
|
thing1: { value: question.question.slice(0, 20) + (question.question.length > 20 ? '...' : '') },
|
|
thing2: { value: question.position || '通用' },
|
|
thing3: { value: question.referenceAnswer.slice(0, 20) + (question.referenceAnswer.length > 20 ? '...' : '') },
|
|
},
|
|
'pages/interview/interview',
|
|
)
|
|
if (ok) successCount++
|
|
}
|
|
|
|
question.pushed = true
|
|
await question.save()
|
|
|
|
this.logger.log(`每日一题推送完成:成功 ${successCount}/${users.length}`)
|
|
}
|
|
}
|