/**
* search.js — 语义检索页
*/
const SearchPage = {
state: { query: '', mode: 'semantic', category: '', province: '', city: '', results: [], total: 0, page: 1, pageSize: 20, loading: false, error: null },
render() {
const isKeyword = this.state.mode === 'keyword';
return `
法规检索
${isKeyword ? '按法规名+条号精确匹配,如"郑州市劳动用工条例 第三十二条"' : '自然语言语义搜索,如"加班工资计算基数"'}
${this.state.query.length}/1000
${UI.emptyState('输入查询开始检索', isKeyword ? '按法规名+条号精确匹配' : '支持自然语言查询,如"个人信息跨境传输的规定"')}
`;
},
setMode(mode) {
this.state.mode = mode;
this.state.results = [];
this.state.total = 0;
const content = document.getElementById('content');
content.innerHTML = this.render();
this.init();
},
init() {
// 加载省份列表(从统计或固定列表)
this.loadProvinces();
// 恢复筛选状态
if (this.state.category) document.getElementById('filter-category').value = this.state.category;
if (this.state.province) document.getElementById('filter-province').value = this.state.province;
},
provinces: ['北京市','天津市','河北省','山西省','内蒙古自治区','辽宁省','吉林省','黑龙江省','上海市','江苏省','浙江省','安徽省','福建省','江西省','山东省','河南省','湖北省','湖南省','广东省','广西壮族自治区','海南省','重庆市','四川省','贵州省','云南省','西藏自治区','陕西省','甘肃省','青海省','宁夏回族自治区','新疆维吾尔自治区'],
loadProvinces() {
const sel = document.getElementById('filter-province');
if (!sel) return;
this.provinces.forEach(p => {
const opt = document.createElement('option');
opt.value = p; opt.textContent = p;
sel.appendChild(opt);
});
},
onFilterChange() {
this.state.category = document.getElementById('filter-category').value;
this.state.province = document.getElementById('filter-province').value;
if (this.state.query) this.doSearch();
},
async doSearch(page) {
const input = document.getElementById('search-input');
if (input) this.state.query = input.value.trim();
if (!this.state.query) return;
// 自动判定模式:包含"第X条"且看起来像法规名+条号时,自动用精确查找
const hasClauseNo = /第[一二三四五六七八九十百千零\d]+条/.test(this.state.query);
const autoMode = hasClauseNo ? 'keyword' : this.state.mode;
this.state.page = page || 1;
this.state.loading = true;
this.state.error = null;
this.renderResults();
try {
const params = {
query: this.state.query,
mode: autoMode,
top_k: 20,
page: this.state.page,
page_size: this.state.pageSize,
};
if (this.state.category) params.category = this.state.category;
if (this.state.province) params.province = this.state.province;
const resp = await API.search(params);
this.state.results = resp.data.results || [];
this.state.total = resp.data.total || 0;
this.state.loading = false;
this.renderResults();
} catch (e) {
this.state.loading = false;
this.state.error = e.message;
this.renderResults();
}
},
renderResults() {
const el = document.getElementById('search-results');
if (!el) return;
if (this.state.loading) {
el.innerHTML = `${UI.spinner(20)}检索中...
`;
return;
}
if (this.state.error) {
el.innerHTML = UI.errorState(this.state.error, 'SearchPage.doSearch()');
return;
}
if (!this.state.results.length && this.state.query) {
el.innerHTML = UI.emptyState('无检索结果', '试试调整查询词或筛选条件');
return;
}
if (!this.state.results.length) {
el.innerHTML = UI.emptyState('输入查询开始检索', '支持自然语言查询');
return;
}
const cards = this.state.results.map(r => UI.clauseCard(r)).join('');
const pager = UI.pagination(this.state.page, this.state.pageSize, this.state.total, 'SearchPage.doSearch');
// 显示当前检索模式
const hasClauseNo = /第[一二三四五六七八九十百千零\d]+条/.test(this.state.query);
const autoMode = hasClauseNo ? 'keyword' : this.state.mode;
const modeLabel = autoMode === 'keyword' ? '精确查找' : '语义检索';
const autoHint = hasClauseNo && this.state.mode === 'semantic' ? ' (检测到条号,自动切换精确查找)' : '';
el.innerHTML = `找到 ${this.state.total} 条结果 [${modeLabel}]${autoHint}
${cards}${pager}`;
},
};