150 lines
4.6 KiB
JavaScript
150 lines
4.6 KiB
JavaScript
|
|
import { createRequire } from 'module';
|
|||
|
|
import fs from 'fs';
|
|||
|
|
import path from 'path';
|
|||
|
|
import { fileURLToPath } from 'url';
|
|||
|
|
import PocketBase from 'pocketbase';
|
|||
|
|
|
|||
|
|
const require = createRequire(import.meta.url);
|
|||
|
|
const __filename = fileURLToPath(import.meta.url);
|
|||
|
|
const __dirname = path.dirname(__filename);
|
|||
|
|
|
|||
|
|
let runtimeConfig = {};
|
|||
|
|
try {
|
|||
|
|
runtimeConfig = require('../pocket-base/bai_api_pb_hooks/bai_api_shared/config/runtime.js');
|
|||
|
|
} catch (_error) {
|
|||
|
|
runtimeConfig = {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function readEnvFile(filePath) {
|
|||
|
|
if (!fs.existsSync(filePath)) return {};
|
|||
|
|
|
|||
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|||
|
|
const result = {};
|
|||
|
|
|
|||
|
|
for (const rawLine of content.split(/\r?\n/)) {
|
|||
|
|
const line = rawLine.trim();
|
|||
|
|
if (!line || line.startsWith('#')) continue;
|
|||
|
|
|
|||
|
|
const index = line.indexOf('=');
|
|||
|
|
if (index === -1) continue;
|
|||
|
|
|
|||
|
|
const key = line.slice(0, index).trim();
|
|||
|
|
const value = line.slice(index + 1).trim();
|
|||
|
|
result[key] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const backendEnv = readEnvFile(path.resolve(__dirname, '..', 'back-end', '.env'));
|
|||
|
|
const pbUrl = String(
|
|||
|
|
process.env.PB_URL
|
|||
|
|
|| backendEnv.POCKETBASE_API_URL
|
|||
|
|
|| runtimeConfig.POCKETBASE_API_URL
|
|||
|
|
|| 'http://127.0.0.1:8090'
|
|||
|
|
).replace(/\/+$/, '');
|
|||
|
|
const authToken = process.env.POCKETBASE_AUTH_TOKEN || runtimeConfig.POCKETBASE_AUTH_TOKEN || '';
|
|||
|
|
|
|||
|
|
if (!authToken) {
|
|||
|
|
console.error('❌ 缺少 POCKETBASE_AUTH_TOKEN,无法执行字段迁移。');
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function normalizeFieldPayload(field, targetSpec) {
|
|||
|
|
const payload = {
|
|||
|
|
name: targetSpec && targetSpec.name ? targetSpec.name : field.name,
|
|||
|
|
type: targetSpec && targetSpec.type ? targetSpec.type : field.type,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (field && field.id) {
|
|||
|
|
payload.id = field.id;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof field.required !== 'undefined') {
|
|||
|
|
payload.required = !!field.required;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (payload.type === 'autodate') {
|
|||
|
|
payload.onCreate = typeof field.onCreate === 'boolean' ? field.onCreate : true;
|
|||
|
|
payload.onUpdate = typeof field.onUpdate === 'boolean' ? field.onUpdate : false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return payload;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function run() {
|
|||
|
|
const pb = new PocketBase(pbUrl);
|
|||
|
|
pb.authStore.save(authToken, null);
|
|||
|
|
|
|||
|
|
console.log(`🔄 开始处理字段迁移,PocketBase: ${pbUrl}`);
|
|||
|
|
|
|||
|
|
const collections = await pb.collections.getFullList({ sort: '-created' });
|
|||
|
|
const collection = collections.find((item) => item.name === 'tbl_product_list');
|
|||
|
|
|
|||
|
|
if (!collection) {
|
|||
|
|
throw new Error('未找到集合 tbl_product_list');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const targetFieldName = 'prod_list_function';
|
|||
|
|
const targetFieldType = 'json';
|
|||
|
|
const existingField = (collection.fields || []).find((field) => field.name === targetFieldName);
|
|||
|
|
|
|||
|
|
if (existingField && existingField.type === targetFieldType) {
|
|||
|
|
console.log('✅ 字段已存在且类型正确,无需变更。');
|
|||
|
|
console.log('✅ 校验完成: tbl_product_list.prod_list_function (json)');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const nextFields = [];
|
|||
|
|
let patched = false;
|
|||
|
|
|
|||
|
|
for (let i = 0; i < (collection.fields || []).length; i += 1) {
|
|||
|
|
const field = collection.fields[i];
|
|||
|
|
if (field.name === targetFieldName) {
|
|||
|
|
nextFields.push(normalizeFieldPayload(field, { name: targetFieldName, type: targetFieldType }));
|
|||
|
|
patched = true;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
nextFields.push(normalizeFieldPayload(field));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!patched) {
|
|||
|
|
nextFields.push({
|
|||
|
|
name: targetFieldName,
|
|||
|
|
type: targetFieldType,
|
|||
|
|
required: false,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await pb.collections.update(collection.id, {
|
|||
|
|
name: collection.name,
|
|||
|
|
type: collection.type,
|
|||
|
|
listRule: collection.listRule,
|
|||
|
|
viewRule: collection.viewRule,
|
|||
|
|
createRule: collection.createRule,
|
|||
|
|
updateRule: collection.updateRule,
|
|||
|
|
deleteRule: collection.deleteRule,
|
|||
|
|
fields: nextFields,
|
|||
|
|
indexes: collection.indexes || [],
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const updated = await pb.collections.getOne(collection.id);
|
|||
|
|
const verifiedField = (updated.fields || []).find((field) => field.name === targetFieldName);
|
|||
|
|
|
|||
|
|
if (!verifiedField || verifiedField.type !== targetFieldType) {
|
|||
|
|
throw new Error('字段写入后校验失败:prod_list_function 未成功写入 json 类型');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('✅ 字段迁移成功: tbl_product_list.prod_list_function (json)');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
run().catch((error) => {
|
|||
|
|
console.error('❌ 迁移失败:', {
|
|||
|
|
status: error && error.status,
|
|||
|
|
message: error && error.message,
|
|||
|
|
response: error && error.response,
|
|||
|
|
});
|
|||
|
|
process.exit(1);
|
|||
|
|
});
|