feat(M3.5): 结果展示组件(静态) (v0.2.5)
This commit is contained in:
parent
fde62ba8fb
commit
70a76ac438
@ -7,7 +7,7 @@
|
||||
## 版本速查
|
||||
|
||||
### 当前版本
|
||||
`0.2.4` → 下一目标 `0.2.5` ([M3.5](./M3.md))
|
||||
`0.2.5` → 下一目标 `0.2.6` ([M3.6](./M3.md))
|
||||
|
||||
### 模块版本范围
|
||||
|
||||
|
||||
@ -65,9 +65,9 @@ M11.10完成 → 1.0.0 (正式发布)
|
||||
|
||||
## 当前状态
|
||||
|
||||
**当前版本**: `0.2.4`
|
||||
**当前进度**: 18/97 (19%)
|
||||
**下一任务**: [M3.5 结果展示组件(静态)](./M3.md#m35-结果展示组件静态--目标版本-025)
|
||||
**当前版本**: `0.2.5`
|
||||
**当前进度**: 19/97 (20%)
|
||||
**下一任务**: [M3.6 点击图标查词(Mock数据)](./M3.md#m36-点击图标查词mock数据--目标版本-026)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
| M3.2 | 0.2.2 | 词典管理器 | ✅ | 2026-02-11 |
|
||||
| M3.3 | 0.2.3 | 必应词典(Mock) | ✅ | 2026-02-11 |
|
||||
| M3.4 | 0.2.4 | 后台查询接口 | ✅ | 2026-02-11 |
|
||||
| M3.5 | 0.2.5 | 结果展示组件 | ⬜ | - |
|
||||
| M3.5 | 0.2.5 | 结果展示组件 | ✅ | 2026-02-11 |
|
||||
| M3.6 | 0.2.6 | 点击图标查词(Mock) | ⬜ | - |
|
||||
| M3.7 | 0.2.7 | 必应词典真实API | ⬜ | - |
|
||||
| M3.8 | 0.2.8 | 加载状态显示 | ⬜ | - |
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "沙拉查词",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.5",
|
||||
"description": "聚合词典划词翻译",
|
||||
"permissions": [
|
||||
"storage",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "salad-dict",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.5",
|
||||
"description": "聚合词典划词翻译",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@ -71,6 +71,9 @@ export class DictPanel {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
@ -78,6 +81,67 @@ export class DictPanel {
|
||||
text-align: center;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.word-title {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.phonetic {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 16px;
|
||||
font-family: 'Times New Roman', serif;
|
||||
}
|
||||
|
||||
.meanings-section {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #4CAF50;
|
||||
margin-bottom: 8px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.meaning-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.part-of-speech {
|
||||
color: #2196F3;
|
||||
font-weight: 500;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.definition {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.examples-section {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.example-item {
|
||||
margin-bottom: 12px;
|
||||
padding: 8px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.example-sentence {
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.example-translation {
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
<div class="panel">
|
||||
<div class="header">词典结果</div>
|
||||
@ -232,6 +296,101 @@ export class DictPanel {
|
||||
this.element.parentNode.removeChild(this.element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染词典查询结果
|
||||
* @param {Object} result - 查询结果
|
||||
* @param {string} result.word - 单词
|
||||
* @param {string} [result.phonetic] - 音标
|
||||
* @param {Array} [result.meanings] - 释义列表
|
||||
* @param {Array} [result.examples] - 例句列表
|
||||
*/
|
||||
renderResult(result) {
|
||||
const content = this.element.shadowRoot.querySelector('.content');
|
||||
|
||||
if (!result) {
|
||||
content.innerHTML = '<div class="placeholder">暂无查询结果</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
const html = `
|
||||
<div class="word-title">${this._escapeHtml(result.word)}</div>
|
||||
${result.phonetic ? `<div class="phonetic">${this._escapeHtml(result.phonetic)}</div>` : ''}
|
||||
|
||||
${this._renderMeanings(result.meanings)}
|
||||
${this._renderExamples(result.examples)}
|
||||
`;
|
||||
|
||||
content.innerHTML = html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染释义列表
|
||||
* @private
|
||||
* @param {Array} meanings - 释义列表
|
||||
* @returns {string} HTML 字符串
|
||||
*/
|
||||
_renderMeanings(meanings) {
|
||||
if (!meanings || meanings.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const meaningsHtml = meanings.map(m => `
|
||||
<div class="meaning-item">
|
||||
<span class="part-of-speech">${this._escapeHtml(m.partOfSpeech || '')}</span>
|
||||
<span class="definition">${this._escapeHtml(m.definitions?.join(';') || '')}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
return `
|
||||
<div class="meanings-section">
|
||||
<div class="section-title">释义</div>
|
||||
${meaningsHtml}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染例句列表
|
||||
* @private
|
||||
* @param {Array} examples - 例句列表
|
||||
* @returns {string} HTML 字符串
|
||||
*/
|
||||
_renderExamples(examples) {
|
||||
if (!examples || examples.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// 最多显示2个例句
|
||||
const displayExamples = examples.slice(0, 2);
|
||||
|
||||
const examplesHtml = displayExamples.map(e => `
|
||||
<div class="example-item">
|
||||
<div class="example-sentence">${this._escapeHtml(e.sentence || '')}</div>
|
||||
${e.translation ? `<div class="example-translation">${this._escapeHtml(e.translation)}</div>` : ''}
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
return `
|
||||
<div class="examples-section">
|
||||
<div class="section-title">例句</div>
|
||||
${examplesHtml}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML 转义,防止 XSS
|
||||
* @private
|
||||
* @param {string} text - 原始文本
|
||||
* @returns {string} 转义后的文本
|
||||
*/
|
||||
_escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user