修改功能
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
(function (root, factory) {
|
||||
if (typeof module === 'object' && module.exports) {
|
||||
module.exports = factory(root);
|
||||
return;
|
||||
}
|
||||
root.PersonDocumentPages = factory(root);
|
||||
if (root.document) root.document.addEventListener('DOMContentLoaded', root.PersonDocumentPages.init);
|
||||
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
|
||||
'use strict';
|
||||
|
||||
function confirmAction(message) {
|
||||
if (root.ProfileUI && typeof root.ProfileUI.confirmAction === 'function') {
|
||||
return root.ProfileUI.confirmAction(message);
|
||||
}
|
||||
return Promise.resolve(!root['confirm'] || root['confirm'](message));
|
||||
}
|
||||
|
||||
function promptAction(title) {
|
||||
if (root.ProfileUI && typeof root.ProfileUI.promptAction === 'function') {
|
||||
return root.ProfileUI.promptAction({ title: title, formType: 1, maxlength: 100 });
|
||||
}
|
||||
return Promise.resolve(root['prompt'] ? root['prompt'](title) : null);
|
||||
}
|
||||
|
||||
var USAGE_LABELS = { FRONT: '正面', BACK: '反面', ATTACHMENT: '附件' };
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value === undefined || value === null ? '' : value)
|
||||
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||
.replace(/"/g, '"').replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function normalizeId(value) {
|
||||
var text = String(value === undefined || value === null ? '' : value).trim();
|
||||
return /^[1-9][0-9]*$/.test(text) ? text : '';
|
||||
}
|
||||
|
||||
function normalizeDocument(item) {
|
||||
var source = item || {};
|
||||
var documentId = normalizeId(source.documentId);
|
||||
var personId = normalizeId(source.lineagePersonId);
|
||||
var title = String(source.documentTitle || '').trim();
|
||||
|
||||
if (!documentId || !personId || !title || !Array.isArray(source.resources)) return null;
|
||||
return {
|
||||
documentId: documentId,
|
||||
lineagePersonId: personId,
|
||||
lineagePersonName: String(source.lineagePersonName || '').trim(),
|
||||
documentType: String(source.documentType || '').trim(),
|
||||
documentTypeLabel: String(source.documentTypeLabel || source.documentType || '').trim(),
|
||||
documentTitle: title,
|
||||
maskedIdentifier: String(source.maskedIdentifier || '').trim(),
|
||||
description: String(source.description || '').trim(),
|
||||
contentProtected: source.contentProtected === true,
|
||||
contentUnlocked: source.contentUnlocked === true,
|
||||
canEdit: source.canEdit === true,
|
||||
canDelete: source.canDelete === true,
|
||||
resources: source.resources.map(function (resource) {
|
||||
var resourceId = normalizeId(resource && resource.resourceId);
|
||||
var usageType = String(resource && resource.usageType || '').trim();
|
||||
return resourceId && USAGE_LABELS[usageType] ? { resourceId: resourceId, usageType: usageType } : null;
|
||||
}).filter(Boolean)
|
||||
};
|
||||
}
|
||||
|
||||
function buildDocumentBody(values) {
|
||||
var source = values || {};
|
||||
return {
|
||||
lineagePersonId: normalizeId(source.lineagePersonId),
|
||||
documentType: String(source.documentType || '').trim(),
|
||||
documentTitle: String(source.documentTitle || '').trim(),
|
||||
maskedIdentifier: String(source.maskedIdentifier || '').trim(),
|
||||
description: String(source.description || '').trim(),
|
||||
status: '0'
|
||||
};
|
||||
}
|
||||
|
||||
function validateDocumentBody(body) {
|
||||
if (!body.lineagePersonId) return '请选择关联人物';
|
||||
if (!body.documentType) return '请选择证件类型';
|
||||
if (!body.documentTitle) return '请填写证件标题';
|
||||
if (body.documentTitle.length > 100) return '证件标题不能超过 100 个字符';
|
||||
if (body.maskedIdentifier.length > 100) return '脱敏标识不能超过 100 个字符';
|
||||
if (body.description.length > 1000) return '说明不能超过 1000 个字符';
|
||||
return '';
|
||||
}
|
||||
|
||||
function renderDocuments(data) {
|
||||
var items = Array.isArray(data) ? data.map(normalizeDocument).filter(Boolean) : [];
|
||||
|
||||
if (!items.length) return '<div class="api-empty">当前家谱还没有重要证件档案</div>';
|
||||
return items.map(function (item) {
|
||||
var resources = item.resources.map(function (resource) {
|
||||
return '<button class="btn outline" type="button" data-document-resource="' +
|
||||
escapeHtml(resource.resourceId) + '" data-document-id="' + escapeHtml(item.documentId) + '">' +
|
||||
escapeHtml(USAGE_LABELS[resource.usageType]) + '</button>';
|
||||
}).join('');
|
||||
return '<article class="module-card" data-document-row="' + escapeHtml(item.documentId) + '"><h3>' +
|
||||
escapeHtml(item.documentTitle) + '</h3><p>' +
|
||||
escapeHtml([item.lineagePersonName, item.documentTypeLabel, item.maskedIdentifier, item.description].filter(Boolean).join(' · ')) +
|
||||
'</p><div class="row-actions">' + resources +
|
||||
(item.contentProtected && !item.contentUnlocked ? '<button class="btn outline" type="button" data-document-unlock="' + item.documentId + '">解锁</button>' : '') +
|
||||
(item.canEdit ? '<button class="btn outline" type="button" data-document-protect="' + item.documentId + '">' + (item.contentProtected ? '取消密码' : '设置密码') + '</button>' : '') +
|
||||
(item.canDelete ? '<button class="btn danger" type="button" data-document-delete="' + item.documentId + '">删除</button>' : '') +
|
||||
'</div></article>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
async function init() {
|
||||
var page = root.document && root.document.querySelector('[data-person-document-page]');
|
||||
var api = root.GenealogyApi && root.GenealogyApi.defaultClient;
|
||||
var genealogyId = root.ProfileUI && root.ProfileUI.getGenealogyId ? root.ProfileUI.getGenealogyId() : '';
|
||||
var form = page && page.querySelector('[data-document-form]');
|
||||
var list = page && page.querySelector('[data-document-list]');
|
||||
var status = page && page.querySelector('[data-document-status]');
|
||||
var personSelect = page && page.querySelector('[data-document-person]');
|
||||
var typeSelect = page && page.querySelector('[data-document-type]');
|
||||
var ossInput = page && page.querySelector('[data-document-oss-id]');
|
||||
var usageSelect = page && page.querySelector('[data-document-usage]');
|
||||
var documents = [];
|
||||
var accessTokens = {};
|
||||
var pending = false;
|
||||
|
||||
if (!page) return;
|
||||
if (!api || !api.getToken || !api.getToken()) {
|
||||
if (root.location) root.location.href = 'login.html';
|
||||
return;
|
||||
}
|
||||
if (!genealogyId) {
|
||||
root.ProfileUI.setApiState(status, 'error', '缺少家谱上下文,请从“我的家谱”重新进入。');
|
||||
return;
|
||||
}
|
||||
|
||||
function setStatus(type, message) {
|
||||
if (type) root.ProfileUI.setApiState(status, type, message);
|
||||
else status.textContent = message || '';
|
||||
}
|
||||
|
||||
async function loadDocuments() {
|
||||
documents = (await api.personDocuments(genealogyId)).map(normalizeDocument).filter(Boolean);
|
||||
list.innerHTML = renderDocuments(documents);
|
||||
}
|
||||
|
||||
try {
|
||||
var initial = await Promise.all([
|
||||
api.lineagePersonOptions(genealogyId),
|
||||
api.businessDictionary('gen_person_document_type'),
|
||||
api.personDocuments(genealogyId)
|
||||
]);
|
||||
personSelect.innerHTML = '<option value="">请选择人物</option>' + (Array.isArray(initial[0]) ? initial[0] : []).map(function (item) {
|
||||
var id = normalizeId(item.personId || item.lineagePersonId);
|
||||
var name = String(item.displayName || item.personName || item.name || '').trim();
|
||||
return id && name ? '<option value="' + escapeHtml(id) + '">' + escapeHtml(name) + '</option>' : '';
|
||||
}).join('');
|
||||
typeSelect.innerHTML = '<option value="">请选择证件类型</option>' + (Array.isArray(initial[1]) ? initial[1] : []).filter(function (item) {
|
||||
return item && item.enabled === true && String(item.value || '').trim();
|
||||
}).map(function (item) {
|
||||
return '<option value="' + escapeHtml(item.value) + '">' + escapeHtml(item.label || item.value) + '</option>';
|
||||
}).join('');
|
||||
documents = (Array.isArray(initial[2]) ? initial[2] : []).map(normalizeDocument).filter(Boolean);
|
||||
list.innerHTML = renderDocuments(documents);
|
||||
setStatus('', '重要证件档案已加载');
|
||||
} catch (error) {
|
||||
setStatus('error', error.message || '重要证件档案读取失败');
|
||||
return;
|
||||
}
|
||||
|
||||
form.addEventListener('submit', async function (event) {
|
||||
var body;
|
||||
var validation;
|
||||
var created;
|
||||
var ossId;
|
||||
|
||||
event.preventDefault();
|
||||
if (pending) return;
|
||||
body = buildDocumentBody({
|
||||
lineagePersonId: personSelect.value,
|
||||
documentType: typeSelect.value,
|
||||
documentTitle: form.elements.documentTitle.value,
|
||||
maskedIdentifier: form.elements.maskedIdentifier.value,
|
||||
description: form.elements.description.value
|
||||
});
|
||||
validation = validateDocumentBody(body);
|
||||
if (validation) return setStatus('error', validation);
|
||||
ossId = normalizeId(ossInput.value);
|
||||
if (!ossId) return setStatus('error', '请先上传证件文件');
|
||||
pending = true; setStatus('loading', '正在保存证件档案…');
|
||||
try {
|
||||
created = normalizeDocument(await api.createPersonDocument(genealogyId, body));
|
||||
if (!created) throw new Error('创建响应缺少有效档案信息');
|
||||
await api.addPersonDocumentResource(genealogyId, created.documentId, {
|
||||
ossId: ossId, usageType: usageSelect.value
|
||||
});
|
||||
form.reset(); ossInput.value = '';
|
||||
await loadDocuments();
|
||||
setStatus('', '证件档案已保存');
|
||||
} catch (error) { setStatus('error', error.message || '证件档案保存失败'); }
|
||||
finally { pending = false; }
|
||||
});
|
||||
|
||||
list.addEventListener('click', async function (event) {
|
||||
var resourceButton = event.target.closest('[data-document-resource]');
|
||||
var unlockButton = event.target.closest('[data-document-unlock]');
|
||||
var protectButton = event.target.closest('[data-document-protect]');
|
||||
var deleteButton = event.target.closest('[data-document-delete]');
|
||||
var documentId;
|
||||
var password;
|
||||
var documentItem;
|
||||
var accessWindow;
|
||||
|
||||
if (pending) return;
|
||||
try {
|
||||
if (resourceButton) {
|
||||
accessWindow = root.open('about:blank', '_blank', 'noopener');
|
||||
documentId = resourceButton.getAttribute('data-document-id');
|
||||
var access = await api.personDocumentResourceAccess(
|
||||
genealogyId, documentId, resourceButton.getAttribute('data-document-resource'), accessTokens[documentId]
|
||||
);
|
||||
if (!access || !access.accessUrl) throw new Error('文件访问响应缺少地址');
|
||||
if (accessWindow) accessWindow.location.replace(access.accessUrl);
|
||||
else root.location.href = access.accessUrl;
|
||||
return;
|
||||
}
|
||||
if (unlockButton) {
|
||||
documentId = unlockButton.getAttribute('data-document-unlock');
|
||||
password = await promptAction('请输入档案访问密码');
|
||||
if (!password) return;
|
||||
var grant = await api.unlockPersonDocument(genealogyId, documentId, password);
|
||||
if (!grant || !grant.accessToken) throw new Error('解锁响应缺少访问令牌');
|
||||
accessTokens[documentId] = grant.accessToken;
|
||||
await loadDocuments(); setStatus('', '档案已临时解锁'); return;
|
||||
}
|
||||
if (protectButton) {
|
||||
documentId = protectButton.getAttribute('data-document-protect');
|
||||
documentItem = documents.find(function (item) { return item.documentId === documentId; });
|
||||
if (!documentItem) return;
|
||||
if (documentItem.contentProtected) {
|
||||
if (!await confirmAction('确认取消此档案的密码保护吗?')) return;
|
||||
await api.unprotectPersonDocument(genealogyId, documentId);
|
||||
} else {
|
||||
password = await promptAction('设置档案访问密码');
|
||||
if (!password) return;
|
||||
await api.protectPersonDocument(genealogyId, documentId, password);
|
||||
}
|
||||
await loadDocuments(); setStatus('', '密码保护设置已更新'); return;
|
||||
}
|
||||
if (deleteButton) {
|
||||
documentId = deleteButton.getAttribute('data-document-delete');
|
||||
if (!await confirmAction('确认删除这份证件档案吗?')) return;
|
||||
await api.deletePersonDocument(genealogyId, documentId);
|
||||
await loadDocuments(); setStatus('', '证件档案已删除');
|
||||
}
|
||||
} catch (error) {
|
||||
if (accessWindow) accessWindow.close();
|
||||
setStatus('error', error.message || '操作失败,请稍后重试');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
normalizeDocument: normalizeDocument,
|
||||
buildDocumentBody: buildDocumentBody,
|
||||
validateDocumentBody: validateDocumentBody,
|
||||
renderDocuments: renderDocuments,
|
||||
init: init
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user