feat: ship self-hosted KOC LOOP workflows
This commit is contained in:
@@ -83,9 +83,9 @@ export async function taskList(
|
||||
(SELECT COUNT(*) FROM distributions d WHERE d.task_id = t.id AND COALESCE(d.publish_url, '') != '') AS published_count,
|
||||
(SELECT COUNT(*) FROM distributions d WHERE d.task_id = t.id AND d.exposure IS NOT NULL AND d.views IS NOT NULL) AS day7_count
|
||||
FROM tasks t ${where}
|
||||
ORDER BY t.created_at DESC LIMIT ? OFFSET ?`,
|
||||
ORDER BY t.created_at DESC LIMIT ${limit} OFFSET ${offset}`,
|
||||
)
|
||||
.bind(...bindings, limit, offset)
|
||||
.bind(...bindings)
|
||||
.all<Record<string, unknown>>(),
|
||||
db
|
||||
.prepare(`SELECT COUNT(*) AS total FROM tasks t ${where}`)
|
||||
@@ -96,14 +96,19 @@ export async function taskList(
|
||||
total: count?.total ?? 0,
|
||||
limit,
|
||||
offset,
|
||||
tasks: rows.results.map((row) => ({
|
||||
...row,
|
||||
collection_days: parseJsonArray(row.collection_days),
|
||||
claim_url:
|
||||
portalUrl && row.share_token
|
||||
? buildClaimUrl(portalUrl, String(row.share_token))
|
||||
: null,
|
||||
})),
|
||||
tasks: rows.results.map(
|
||||
(row): Record<string, unknown> & {
|
||||
collection_days: unknown[];
|
||||
claim_url: string | null;
|
||||
} => ({
|
||||
...row,
|
||||
collection_days: parseJsonArray(row.collection_days),
|
||||
claim_url:
|
||||
portalUrl && row.share_token
|
||||
? buildClaimUrl(portalUrl, String(row.share_token))
|
||||
: null,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -151,15 +156,19 @@ export async function taskGet(taskId: string, portalUrl: string) {
|
||||
.bind(taskId)
|
||||
.all<Record<string, unknown>>(),
|
||||
]);
|
||||
return {
|
||||
task: {
|
||||
const taskOutput: Record<string, unknown> & {
|
||||
collection_days: unknown[];
|
||||
claim_url: string | null;
|
||||
} = {
|
||||
...task,
|
||||
collection_days: parseJsonArray(task.collection_days),
|
||||
claim_url:
|
||||
portalUrl && task.share_token
|
||||
? buildClaimUrl(portalUrl, String(task.share_token))
|
||||
: null,
|
||||
},
|
||||
};
|
||||
return {
|
||||
task: taskOutput,
|
||||
notes: notes.results.map((row) => ({
|
||||
...row,
|
||||
image_assets: parseJsonArray(row.image_assets),
|
||||
@@ -214,9 +223,9 @@ export async function recoveryList(
|
||||
`SELECT d.*, t.name AS task_name, c.source_row, c.title,
|
||||
a.nickname AS account_nickname, a.profile_url, p.name AS cooperation_source,
|
||||
cl.claimant_name ${base}
|
||||
ORDER BY COALESCE(d.publish_time, d.claimed_at) DESC LIMIT ? OFFSET ?`,
|
||||
ORDER BY COALESCE(d.publish_time, d.claimed_at) DESC LIMIT ${limit} OFFSET ${offset}`,
|
||||
)
|
||||
.bind(...bindings, limit, offset)
|
||||
.bind(...bindings)
|
||||
.all<Record<string, unknown>>(),
|
||||
db
|
||||
.prepare(`SELECT COUNT(*) AS total ${base}`)
|
||||
@@ -359,10 +368,12 @@ function resourceWhere(input: ResourceFilters) {
|
||||
}
|
||||
if (input.cooperationSource?.trim()) {
|
||||
conditions.push(
|
||||
`EXISTS (SELECT 1 FROM distributions dx JOIN partners px ON px.id = dx.partner_id
|
||||
WHERE dx.account_id = a.id AND px.name LIKE ? ESCAPE '\\')`,
|
||||
`(a.cooperation_source LIKE ? ESCAPE '\\' OR
|
||||
EXISTS (SELECT 1 FROM distributions dx JOIN partners px ON px.id = dx.partner_id
|
||||
WHERE dx.account_id = a.id AND px.name LIKE ? ESCAPE '\\'))`,
|
||||
);
|
||||
bindings.push(like(input.cooperationSource.trim()));
|
||||
const pattern = like(input.cooperationSource.trim());
|
||||
bindings.push(pattern, pattern);
|
||||
}
|
||||
if (input.platform?.trim() && input.platform !== "all") {
|
||||
conditions.push("a.platform = ?");
|
||||
@@ -380,18 +391,27 @@ export async function resourceSearch(input: ResourceFilters) {
|
||||
(SELECT COUNT(*) FROM distributions d WHERE d.account_id = a.id) AS cooperation_count,
|
||||
(SELECT GROUP_CONCAT(DISTINCT p.name) FROM distributions d JOIN partners p ON p.id = d.partner_id WHERE d.account_id = a.id) AS cooperation_sources`;
|
||||
const [rows, count] = await Promise.all([
|
||||
db.prepare(`${select} FROM accounts a ${where} ORDER BY a.last_seen_at DESC LIMIT ? OFFSET ?`)
|
||||
.bind(...bindings, limit, offset).all<Record<string, unknown>>(),
|
||||
db.prepare(`${select} FROM accounts a ${where} ORDER BY a.last_seen_at DESC LIMIT ${limit} OFFSET ${offset}`)
|
||||
.bind(...bindings).all<Record<string, unknown>>(),
|
||||
db.prepare(`SELECT COUNT(*) AS total FROM accounts a ${where}`).bind(...bindings).first<{ total: number }>(),
|
||||
]);
|
||||
return {
|
||||
total: count?.total ?? 0,
|
||||
limit,
|
||||
offset,
|
||||
accounts: rows.results.map((row) => ({
|
||||
...row,
|
||||
cooperation_sources: String(row.cooperation_sources ?? "").split(",").filter(Boolean),
|
||||
})),
|
||||
accounts: rows.results.map(
|
||||
(row): Record<string, unknown> & { cooperation_sources: string[] } => ({
|
||||
...row,
|
||||
cooperation_sources: [
|
||||
...new Set(
|
||||
`${row.cooperation_sources ?? ""}、${row.cooperation_source ?? ""}`
|
||||
.split(/[、,,;;|]/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean),
|
||||
),
|
||||
],
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user