feat: 更新 PocketBase API 路由,增强认证安全性
- 修改登录路由为 `/pb/api/wechat/login`,新增局部 try/catch 以保留业务状态码并返回统一结构 `{ code, msg, data }`。
- 更新所有相关 API 路由前缀为 `/pb`,包括系统、平台、字典、附件和文档接口。
- 新增文档接口支持多个附件 ID,更新 OpenAPI 文档以反映这些变化。
- 在数据库模式中添加对字典名称的唯一索引,确保全局唯一性。
- 更新文档字段,设置 `document_title` 和 `document_type` 为必填项,并在验证过程中检查字段的必填属性。
This commit is contained in:
@@ -49,8 +49,8 @@ const collections = [
|
||||
{ name: 'document_id', type: 'text', required: true },
|
||||
{ name: 'document_effect_date', type: 'date' },
|
||||
{ name: 'document_expiry_date', type: 'date' },
|
||||
{ name: 'document_type', type: 'text' },
|
||||
{ name: 'document_title', type: 'text' },
|
||||
{ name: 'document_type', type: 'text', required: true },
|
||||
{ name: 'document_title', type: 'text', required: true },
|
||||
{ name: 'document_subtitle', type: 'text' },
|
||||
{ name: 'document_summary', type: 'text' },
|
||||
{ name: 'document_content', type: 'text' },
|
||||
@@ -167,6 +167,7 @@ function normalizeFieldList(fields) {
|
||||
return (fields || []).map((field) => ({
|
||||
name: field.name,
|
||||
type: field.type,
|
||||
required: !!field.required,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -210,8 +211,10 @@ async function verifyCollections(targetCollections) {
|
||||
const remoteFields = normalizeFieldList(remote.fields);
|
||||
const targetFields = normalizeFieldList(target.fields);
|
||||
const remoteFieldMap = new Map(remoteFields.map((field) => [field.name, field.type]));
|
||||
const remoteRequiredMap = new Map(remoteFields.map((field) => [field.name, field.required]));
|
||||
const missingFields = [];
|
||||
const mismatchedTypes = [];
|
||||
const mismatchedRequired = [];
|
||||
|
||||
for (const field of targetFields) {
|
||||
if (!remoteFieldMap.has(field.name)) {
|
||||
@@ -222,6 +225,10 @@ async function verifyCollections(targetCollections) {
|
||||
if (remoteFieldMap.get(field.name) !== field.type) {
|
||||
mismatchedTypes.push(`${field.name}:${remoteFieldMap.get(field.name)}!=${field.type}`);
|
||||
}
|
||||
|
||||
if (remoteRequiredMap.get(field.name) !== !!field.required) {
|
||||
mismatchedRequired.push(`${field.name}:${remoteRequiredMap.get(field.name)}!=${!!field.required}`);
|
||||
}
|
||||
}
|
||||
|
||||
const remoteIndexes = new Set(remote.indexes || []);
|
||||
@@ -231,7 +238,7 @@ async function verifyCollections(targetCollections) {
|
||||
throw new Error(`${target.name} 类型不匹配,期望 ${target.type},实际 ${remote.type}`);
|
||||
}
|
||||
|
||||
if (!missingFields.length && !mismatchedTypes.length && !missingIndexes.length) {
|
||||
if (!missingFields.length && !mismatchedTypes.length && !mismatchedRequired.length && !missingIndexes.length) {
|
||||
console.log(`✅ ${target.name} 校验通过。`);
|
||||
continue;
|
||||
}
|
||||
@@ -243,6 +250,9 @@ async function verifyCollections(targetCollections) {
|
||||
if (mismatchedTypes.length) {
|
||||
console.log(` - 字段类型不匹配: ${mismatchedTypes.join(', ')}`);
|
||||
}
|
||||
if (mismatchedRequired.length) {
|
||||
console.log(` - 字段必填属性不匹配: ${mismatchedRequired.join(', ')}`);
|
||||
}
|
||||
if (missingIndexes.length) {
|
||||
console.log(` - 缺失索引: ${missingIndexes.join(' | ')}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user