26 lines
2.4 KiB
TypeScript
26 lines
2.4 KiB
TypeScript
import {randomUUID} from 'node:crypto';
|
||
import type {PoolClient} from 'pg';
|
||
import type {Parameters} from './layout-parameters';
|
||
|
||
export type DesignRow={id:string;layout_id:string;name:string;parameters:Parameters;revision:number;post_id:string|null;archived?:boolean;created_at:Date;updated_at:Date};
|
||
export const studioPageUrl=(design:Pick<DesignRow,'id'|'layout_id'>)=>`/studio/layouts/${design.layout_id}?id=${design.id}`;
|
||
function postDescription(design:DesignRow){return `已保存的 ${design.layout_id} 排版页面,可直接打开并继续编辑。`}
|
||
/** Caller holds the design row lock. All writes share the design's transaction. */
|
||
export async function ensureDesignPost(client:PoolClient,design:DesignRow):Promise<DesignRow>{
|
||
if(design.post_id){
|
||
// A manually edited Wiki note keeps its own title, body, tags and cover.
|
||
await client.query('UPDATE posts SET title=$2,description=$3,updated_at=now() WHERE id=$1 AND edited_at IS NULL',[design.post_id,design.name,postDescription(design)]);
|
||
return design;
|
||
}
|
||
const postId=randomUUID(),textId=randomUUID(),imageIds=[...new Set(Object.values(design.parameters.images||{}).flatMap(image=>image.assetId?[image.assetId]:[]))];
|
||
const images=imageIds.length?(await client.query("SELECT id FROM assets WHERE id=ANY($1::uuid[]) AND kind='image'",[imageIds])).rows.map(row=>row.id as string):[];
|
||
const body=`[打开页面并继续编辑](${studioPageUrl(design)})\n\n排版:${design.layout_id}\n\n页面 ID:\`${design.id}\`\n\n此笔记关联独立保存的页面;页面内容以链接中的保存记录为准。`;
|
||
await client.query("INSERT INTO posts(id,slug,kind,title,description,cover_asset_id) VALUES($1,$2,'article',$3,$4,$5)",[postId,'studio-design-'+design.id,design.name,postDescription(design),images[0]||null]);
|
||
await client.query("INSERT INTO assets(id,kind,body) VALUES($1,'text',$2)",[textId,body]);
|
||
await client.query("INSERT INTO post_assets(post_id,asset_id,position,role) VALUES($1,$2,0,'caption')",[postId,textId]);
|
||
for(const [index,imageId] of images.entries())await client.query("INSERT INTO post_assets(post_id,asset_id,position,role) VALUES($1,$2,$3,'content')",[postId,imageId,index+1]);
|
||
await client.query("INSERT INTO post_tags(post_id,tag_id) SELECT $1,id FROM tags WHERE name='高级感排版' AND kind='normal' ON CONFLICT DO NOTHING",[postId]);
|
||
await client.query('UPDATE studio_designs SET post_id=$2 WHERE id=$1',[design.id,postId]);
|
||
return {...design,post_id:postId};
|
||
}
|