31cc1e02ce
- 新增 AffiliateProgram / AffiliateLink / AffiliateClick 规范化 Prisma 模型 取代原手写裸表 affiliate_stats / affiliate_clicks - 新增迁移 prisma/migrations/20260711000000_add_affiliate_models - 重构 affiliate.service.ts 改用 Prisma ORM,消除 $queryRawUnsafe SQL 注入 - 重构 affiliate.controller.ts 接口:programs / links(?skillId,?toolId) / stats / click - 前端 affiliate 页接入真实接口,移除硬编码 demo 数据 - 技能详情页新增「学此技能推荐使用的工具」联盟链接区块 - 新增 affiliate.service.spec.ts(4 用例通过)与幂等种子 seed-affiliate.ts - 更新 docs/progress/current.md,明确无 ICP 经营许可证下以联盟返佣为合规变现主路径 - 含此前工作区未提交改动(工具 slug 路由、支付/订单、SEO 等) Co-Authored-By: opencode <opencode@anthropic.com>
71 lines
2.8 KiB
TypeScript
71 lines
2.8 KiB
TypeScript
import 'dotenv/config';
|
||
import { PrismaClient, ContentStatus } from '@prisma/client';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
interface LinkInfo {
|
||
url: string;
|
||
title: string;
|
||
description?: string;
|
||
}
|
||
|
||
const links: LinkInfo[] = [
|
||
{ url: 'https://www.aliyun.com/minisite/goods?userCode=kap6n5tc', title: '云小站_专享特惠_云产品推荐-阿里云' },
|
||
{ url: 'https://www.aliyun.com/benefit/client/cross?userCode=kap6n5tc', title: '云聚 AI 长效权益' },
|
||
{ url: 'https://www.aliyun.com/activity/hub/ai-innovation?userCode=kap6n5tc', title: 'AI 加速季,智惠生产力' },
|
||
{ url: 'https://opc.aliyun.com/products?utm_content=g_1000413977&userCode=kap6n5tc', title: 'OPC(One Person Company一人公司)创业装备库' },
|
||
{ url: 'https://www.aliyun.com/activity/ecs/clawdbot?userCode=kap6n5tc', title: '稳定不贵,不写代码,分钟级部署Hermes/OpenClaw' },
|
||
{ url: 'https://dashi.aliyun.com/activity/aigc?userCode=kap6n5tc', title: '一键轻松打造你的专属AI应用' },
|
||
{ url: 'https://dashi.aliyun.com/activity/aiagent?userCode=kap6n5tc', title: '一站式轻松搭建企业级 AI Agent' },
|
||
{ url: 'https://www.aliyun.com/daily-act/ecs/activity_selection?userCode=kap6n5tc', title: '开年焕新,限时特惠' },
|
||
{ url: 'https://wanwang.aliyun.com/website/index?userCode=kap6n5tc', title: '阿里云建站_AI建站_设计师定制建站_系统定制开发-阿里云' },
|
||
{ url: 'https://www.aliyun.com/daily-act/ecs/ecs25srdeepseek?userCode=kap6n5tc', title: 'DeepSeek 个人站点-快速部署方案' },
|
||
{ url: 'https://www.aliyun.com/activity?userCode=kap6n5tc', title: '活动中心' },
|
||
{ url: 'https://dashi.aliyun.com/activity/oss?userCode=kap6n5tc', title: '阿里云存储产品云大使征集令' },
|
||
];
|
||
|
||
function slugFromUrl(urlStr: string): string {
|
||
try {
|
||
const url = new URL(urlStr);
|
||
let path = url.pathname.replace(/^\/|\/$/g, '').replace(/\//g, '-');
|
||
if (!path) path = 'home';
|
||
return `aliyun-${path}`;
|
||
} catch {
|
||
return `aliyun-${Math.random().toString(36).substring(2, 8)}`;
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
for (const link of links) {
|
||
let baseSlug = slugFromUrl(link.url);
|
||
let slug = baseSlug;
|
||
let counter = 1;
|
||
while (true) {
|
||
const existing = await prisma.tool.findUnique({ where: { slug } });
|
||
if (!existing) break;
|
||
slug = `${baseSlug}-${counter++}`;
|
||
}
|
||
await prisma.tool.create({
|
||
data: {
|
||
name: link.title,
|
||
slug,
|
||
url: link.url,
|
||
description: '',
|
||
status: ContentStatus.PUBLISHED,
|
||
tags: '阿里云,云大使',
|
||
isFeatured: true,
|
||
},
|
||
});
|
||
console.log(`✅ Created tool: ${slug} -> ${link.title}`);
|
||
}
|
||
}
|
||
|
||
main()
|
||
.catch((e) => {
|
||
console.error('❌ Seed failed:', e);
|
||
process.exit(1);
|
||
})
|
||
.finally(async () => {
|
||
await prisma.$disconnect();
|
||
});
|