' + HANDLE_STATUS[item.handleStatus] +
'';
}).join('');
}
function renderFeedbackDetail(item) {
var feedback = normalizeFeedback(item);
var details;
if (!feedback) return '
反馈记录不存在或无权查看
';
details = [
feedback.contactInfo ? '
提交联系方式
' + escapeHtml(feedback.contactInfo) + '
' : '',
'
处理状态
' + HANDLE_STATUS[feedback.handleStatus] + '
',
feedback.handleResult ? '
处理结果
' + escapeHtml(feedback.handleResult) + '
' : '',
feedback.handleTime ? '
处理时间
' + escapeHtml(feedback.handleTime) + '
' : '',
feedback.remark ? '
备注
' + escapeHtml(feedback.remark) + '
' : ''
].filter(Boolean).join('');
return '
' +
escapeHtml(feedback.feedbackTypeLabel) +
'
问题说明
' + escapeHtml(feedback.feedbackContent) +
'
' + details + '
';
}
function shouldRedirectToLogin(api, error) {
var status = error && (error.status || error.code);
return !api || !api.getToken || !api.getToken() || Number(status) === 401;
}
function redirectToLogin(api) {
if (api && api.clearToken) api.clearToken();
root.NavigationUtil.open('login.html');
}
function isForbidden(error) {
return Number(error && (error.status || error.code)) === 403;
}
function getFormValues(form) {
var values = {};
Array.prototype.forEach.call(form.querySelectorAll('[name]'), function (field) {
values[field.name] = field.value;
});
return values;
}
function setApiState(target, type, message) {
if (!target) return;
if (root.ProfileUI && root.ProfileUI.setApiState && type) {
root.ProfileUI.setApiState(target, type, message);
return;
}
target.textContent = message || '';
}
function setStatus(type, message) {
var status = root.document && root.document.querySelector('[data-feedback-status]');
setApiState(status, type, message);
}
function setFeedbackList(list, items, detailPage) {
if (!list) return;
if (!items.length) {
setApiState(list, 'empty', '当前没有反馈记录。');
return;
}
list.innerHTML = renderFeedbackList(items, { detailPage: detailPage || 'ticket-detail.html' });
}
function setPendingButton(button, pending, label) {
if (!button) return;
if (!button.dataset.defaultLabel) button.dataset.defaultLabel = button.textContent;
button.disabled = pending;
button.textContent = pending ? label : button.dataset.defaultLabel;
}
async function loadFeedbackTypeOptions(api, select) {
var options = normalizeFeedbackTypeOptions(await api.businessDictionary('gen_feedback_type'));
if (!options.length) throw new Error('反馈类型选项响应无效');
if (select) {
select.innerHTML = '' + options.map(function (item) {
return '';
}).join('');
}
return options;
}
async function readMyFeedback(api) {
var data = await api.myFeedback();
var items = normalizeFeedbackList(data);
if (!Array.isArray(data) || items.length !== data.length) {
throw new Error('反馈列表响应无效');
}
return items;
}
async function initFeedbackFormPage() {
var form = root.document && root.document.querySelector('[data-feedback-form]');
var list = root.document && root.document.querySelector('[data-feedback-list]');
var refresh = root.document && root.document.querySelector('[data-feedback-refresh]');
var page = root.document && root.document.querySelector('[data-feedback-page]');
var api = root.GenealogyApi && root.GenealogyApi.defaultClient;
var pageMode = page && page.getAttribute('data-feedback-page');
var feedbackTypeSelect = form && form.querySelector('[data-feedback-type-options]');
var allowedFeedbackTypes = [];
var writePending = false;
if (!form) return;
if (shouldRedirectToLogin(api)) {
redirectToLogin(api);
return;
}
try {
allowedFeedbackTypes = (await loadFeedbackTypeOptions(api, feedbackTypeSelect)).map(function (item) {
return item.value;
});
} catch (error) {
if (feedbackTypeSelect) feedbackTypeSelect.innerHTML = '';
}
async function loadList() {
var items;
if (!list) return [];
setApiState(list, 'loading', '正在读取反馈记录…');
setStatus('loading', '正在读取反馈记录…');
try {
items = await readMyFeedback(api);
setFeedbackList(list, items, 'ticket-detail.html');
setStatus('', '');
return items;
} catch (error) {
if (shouldRedirectToLogin(api, error)) {
redirectToLogin(api);
return [];
}
setApiState(list, isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限查看反馈记录。' : '读取反馈记录失败,请稍后重试。');
setStatus(isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限查看反馈记录。' : (error.message || '读取反馈记录失败,请稍后重试。'));
return [];
}
}
if (refresh) refresh.addEventListener('click', async function () {
setPendingButton(refresh, true, '正在刷新…');
try {
await loadList();
} finally {
setPendingButton(refresh, false, '正在刷新…');
}
});
form.addEventListener('submit', async function (event) {
var body;
var validation;
var created;
var refreshed;
var button = form.querySelector('[data-feedback-submit]');
event.preventDefault();
if (writePending) return;
body = buildFeedbackBody(getFormValues(form));
validation = validateFeedbackBody(body, allowedFeedbackTypes);
if (validation) {
setStatus('error', validation);
return;
}
writePending = true;
setPendingButton(button, true, '正在提交…');
setStatus('loading', '正在提交反馈…');
try {
created = normalizeFeedback(await api.submitFeedback(body));
if (!created) throw new Error('提交响应缺少有效反馈信息');
refreshed = await readMyFeedback(api);
if (!refreshed.some(function (item) { return item.feedbackId === created.feedbackId; })) {
throw new Error('提交后无法读取同一反馈记录');
}
if (pageMode === 'ticket') {
root.NavigationUtil.open(buildFeedbackDetailUrl(created.feedbackId));
return;
}
setFeedbackList(list, refreshed, 'ticket-detail.html');
form.reset();
setStatus('', '反馈已提交');
} catch (error) {
if (shouldRedirectToLogin(api, error)) {
redirectToLogin(api);
return;
}
setStatus(isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限提交反馈。' : (error.message || '提交反馈失败,请稍后重试。'));
} finally {
writePending = false;
setPendingButton(button, false, '正在提交…');
}
});
await loadList();
}
async function initFeedbackListPage() {
var page = root.document && root.document.querySelector('[data-feedback-list-page]');
var list = root.document && root.document.querySelector('[data-feedback-list]');
var refresh = root.document && root.document.querySelector('[data-feedback-refresh]');
var api = root.GenealogyApi && root.GenealogyApi.defaultClient;
if (!page || !list) return;
if (shouldRedirectToLogin(api)) {
redirectToLogin(api);
return;
}
async function loadList() {
try {
setApiState(list, 'loading', '正在读取反馈记录…');
setStatus('loading', '正在读取反馈记录…');
setFeedbackList(list, await readMyFeedback(api), 'ticket-detail.html');
setStatus('', '');
} catch (error) {
if (shouldRedirectToLogin(api, error)) {
redirectToLogin(api);
return;
}
setApiState(list, isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限查看反馈记录。' : '读取反馈记录失败,请稍后重试。');
setStatus(isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限查看反馈记录。' : (error.message || '读取反馈记录失败,请稍后重试。'));
}
}
if (refresh) refresh.addEventListener('click', async function () {
setPendingButton(refresh, true, '正在刷新…');
try {
await loadList();
} finally {
setPendingButton(refresh, false, '正在刷新…');
}
});
await loadList();
}
async function initFeedbackDetailPage() {
var page = root.document && root.document.querySelector('[data-feedback-detail-page]');
var detail = root.document && root.document.querySelector('[data-feedback-detail]');
var api = root.GenealogyApi && root.GenealogyApi.defaultClient;
var feedbackId = getFeedbackId();
var item;
if (!page || !detail) return;
if (!feedbackId) {
setApiState(detail, 'empty', '反馈记录不存在或无权查看。');
return;
}
if (shouldRedirectToLogin(api)) {
redirectToLogin(api);
return;
}
try {
setApiState(detail, 'loading', '正在读取反馈详情…');
setStatus('loading', '正在读取反馈详情…');
item = findFeedbackById(await api.myFeedback(), feedbackId);
if (item) detail.innerHTML = renderFeedbackDetail(item);
else setApiState(detail, 'empty', '反馈记录不存在或无权查看。');
setStatus('', item ? '' : '反馈记录不存在或无权查看。');
} catch (error) {
if (shouldRedirectToLogin(api, error)) {
redirectToLogin(api);
return;
}
setApiState(detail, isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限查看该反馈详情。' : '反馈详情读取失败,请稍后重试。');
setStatus(isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '暂无权限查看该反馈详情。' : (error.message || '反馈详情读取失败,请稍后重试。'));
}
}
async function init() {
if (root.document && root.document.querySelector('[data-feedback-form]')) {
await initFeedbackFormPage();
return;
}
if (root.document && root.document.querySelector('[data-feedback-list-page]')) {
await initFeedbackListPage();
return;
}
if (root.document && root.document.querySelector('[data-feedback-detail-page]')) {
await initFeedbackDetailPage();
}
}
return {
getFeedbackId: getFeedbackId,
buildFeedbackBody: buildFeedbackBody,
validateFeedbackBody: validateFeedbackBody,
normalizeFeedbackTypeOptions: normalizeFeedbackTypeOptions,
normalizeFeedback: normalizeFeedback,
normalizeFeedbackList: normalizeFeedbackList,
findFeedbackById: findFeedbackById,
buildFeedbackDetailUrl: buildFeedbackDetailUrl,
renderFeedbackList: renderFeedbackList,
renderFeedbackDetail: renderFeedbackDetail,
isForbidden: isForbidden,
initFeedbackFormPage: initFeedbackFormPage,
initFeedbackListPage: initFeedbackListPage,
initFeedbackDetailPage: initFeedbackDetailPage,
init: init
};
});