@qxs-bns/components-wc 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"single.mjs","sources":["../../../../packages/components-wc/src/subject/single.ts"],"sourcesContent":["import type { AnswerType } from './types'\nimport { css, html, LitElement } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { safeCustomElement } from '../base/define'\nimport { uid } from '../base/uid'\nimport { renderSortingCard, sortingCardStyles } from './sorting-card'\nimport { SubjectTypeLabel } from './types'\n\nexport interface SubjectErrorOptions {\n message: string\n code?: string\n field?: string\n row?: any\n}\n\nexport class SubjectError extends Error {\n constructor(\n message: string,\n public code: string = 'VALIDATION_ERROR',\n public field?: string,\n public row?: any,\n ) {\n super(message)\n this.name = 'SubjectError'\n }\n\n static from(options: SubjectErrorOptions): SubjectError {\n return new SubjectError(options.message, options.code, options.field, options.row)\n }\n}\n\ninterface Answer {\n title: string\n isCorrect: boolean\n customAnswerId?: string\n answerId?: string\n resultItem?: string\n orderIndex?: number\n answerRelations?: any[]\n relationType?: number | null\n}\n\ninterface SubjectSnapshot {\n title: string\n answers: Answer[]\n analysis: string\n leastAnswerCount: number | null\n selectedTagList: TagItem[]\n examExpand: string\n showRichText: boolean\n richText: string\n orderList: string[]\n}\n\nconst iconPlus = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconRemove = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconArrow = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"/></svg>`\n\nfunction normalizeTitle(text: string) {\n return text\n .replace(/^\\d+\\.\\s*/, '')\n .replace(/[\\s,,。.!!??;;::、'\"“”‘’()()[\\]【】\\-_/\\\\]+/g, '')\n .toLowerCase()\n}\n\nexport function trimText(value: unknown) {\n return String(value ?? '').trim()\n}\n\nexport function trimCommaSeparatedText(value: unknown) {\n return String(value ?? '')\n .split(',')\n .map(item => item.trim())\n .filter(Boolean)\n .join(',')\n}\n\nfunction showToast(msg: string) {\n const el = document.createElement('div')\n el.textContent = msg\n Object.assign(el.style, {\n position: 'fixed', top: '20px', left: '50%', transform: 'translateX(-50%)',\n padding: '10px 20px', borderRadius: '4px', fontSize: '13px', color: '#fff',\n background: '#f56c6c', zIndex: '99999', boxShadow: '0 4px 12px rgba(0,0,0,.15)',\n transition: 'opacity .3s', opacity: '1',\n })\n document.body.appendChild(el)\n setTimeout(() => { el.style.opacity = '0'; setTimeout(() => el.remove(), 300) }, 2500)\n}\n\n/**\n * 标签项 - 用于关联题目的标签信息\n * @typedef {object} TagItem\n * @property {string|number} tagId - 标签ID\n * @property {string} tagName - 标签名称\n * @property {KnowledgePointInfo[]} [knowledgePointInfos] - 关联的知识点的列表\n */\nexport interface TagItem {\n tagId: string | number\n tagName: string\n knowledgePointInfos?: KnowledgePointInfo[]\n}\n\n/**\n * 知识点信息\n * @typedef {object} KnowledgePointInfo\n * @property {string|number} knowledgePointId - 知识点ID\n * @property {string} knowledgePointName - 知识点名称\n */\nexport interface KnowledgePointInfo {\n knowledgePointId: string | number\n knowledgePointName: string\n}\n\n/**\n * 分类选项\n * @typedef {object} Category\n * @property {string|number} categoryId - 分类ID\n * @property {string} title - 分类标题\n */\nexport interface Category {\n categoryId: string | number\n title: string\n}\n\n/**\n * 题库搜索结果项\n * @typedef {object} SearchResult\n * @property {string|number} id - 题目ID\n * @property {string} title - 题目标题\n * @property {string} value - 用于搜索框显示的值\n * @property {any} [key: string] - 其他扩展字段\n */\nexport interface SearchResult {\n id: string | number\n title: string\n value: string\n [key: string]: any\n}\n\n/**\n * 题目资源(图片或视频)\n * @typedef {object} Resource\n * @property {1|2} resourceType - 资源类型:1-图片, 2-视频\n * @property {object} resource - 资源详情\n * @property {string} [resource.url] - 资源URL\n * @property {string} [resource.middle] - 中等尺寸图片URL\n * @property {string} [resource.videoId] - 视频ID\n */\nexport interface Resource {\n resourceType: 1 | 2\n resource: {\n url?: string\n middle?: string\n videoId?: string\n [key: string]: any\n }\n}\n\n@safeCustomElement('qxs-subject-single')\nexport class QxsSubjectSingle extends LitElement {\n static styles = [sortingCardStyles, css`\n :host { display: block; font-family: system-ui, -apple-system, \"PingFang SC\", \"Microsoft YaHei\", sans-serif; font-size: 12px; color: #5a5a5a; }\n *, ::before, ::after { box-sizing: border-box; }\n\n .preview { padding: 12px 0; }\n .preview .title { font-size: 14px; color: #303133; }\n .preview .title .key-badge {\n display: inline-block;\n margin-left: 8px;\n padding: 1px 6px;\n font-size: 11px;\n color: #fff;\n background: #f56c6c;\n border-radius: 3px;\n vertical-align: middle;\n }\n .preview .rich-text { margin-top: 8px; }\n .preview .rich-text img { max-width: 100%; }\n .preview .rich-text img[data-align=\"left\"] { display: block !important; margin: 0 auto 0 0 !important; }\n .preview .rich-text img[data-align=\"center\"] { display: block !important; margin: 0 auto !important; }\n .preview .rich-text img[data-align=\"right\"] { display: block !important; margin: 0 0 0 auto !important; }\n .preview-answer { display: flex; flex-direction: column; margin-top: 12px; }\n .preview-answer .radio { margin-top: 8px; padding-left: 8px; display: flex; align-items: center; gap: 6px; }\n .preview-answer .order { color: #909399; }\n .preview-answer .correct { color: #67c23a; }\n .preview-answer .result-info { color: #909399; }\n\n .flex { display: flex; }\n .flex-items-center { display: flex; align-items: center; }\n .flex-items-start { display: flex; align-items: flex-start; }\n .flex-justify-end { display: flex; justify-content: flex-end; }\n .label { min-width: 60px; font-size: 13px; color: #606266; }\n\n textarea {\n border: 1px solid #dcdfe6; border-radius: 3px; padding: 5px 11px;\n font-size: 13px; font-family: inherit; width: 100%; resize: none; transition: border-color .2s;\n line-height: 1.5; display: block; box-sizing: border-box;\n }\n textarea:focus { border-color: #3D61E3; outline: none; }\n textarea:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .el-input { position: relative; display: block; }\n .el-input textarea { padding-bottom: 24px; }\n .el-input .char-counter {\n position: absolute; right: 12px; bottom: 8px;\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-list { margin-top: 12px; }\n .answer-item { display: flex; align-items: center; margin-top: 6px; border-radius: 4px; }\n .answer-item .label { min-width: 60px; font-size: 13px; color: #909399; }\n .answer-item .input { flex: 1; max-width: 360px; position: relative; display: block; }\n .answer-item .input input {\n height: 32px; padding: 0 50px 0 8px;\n font-size: 13px; line-height: 32px;\n border: 1px solid #dcdfe6; border-radius: 3px; width: 100%;\n transition: border-color .2s; box-sizing: border-box;\n }\n .answer-item .input input:focus { border-color: #3D61E3; outline: none; }\n .answer-item .input input:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .answer-item .input .char-counter {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-item .correct { margin: 0 10px; color: #909399; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }\n .answer-item .correct:hover { color: #3D61E3; }\n .answer-item .correct.is-correct { color: #67c23a; }\n .answer-item .correct input { width: 14px; height: 14px; cursor: pointer; accent-color: #3D61E3; }\n\n .answer-item .icon {\n margin-left: 6px; cursor: pointer; display: inline-flex;\n align-items: center; justify-content: center;\n width: 24px; height: 24px; border-radius: 4px;\n border: 1px solid #dcdfe6; background: #fff; color: #909399;\n transition: all 0.2s;\n }\n .answer-item .icon:hover { color: #3D61E3; border-color: #3D61E3; background: #ecf5ff; }\n .answer-item .icon.disabled { color: #e4e7ed; border-color: #e4e7ed; cursor: not-allowed; }\n\n .answer-item .link { margin-left: 8px; color: #3D61E3; cursor: pointer; font-size: 12px; white-space: nowrap; }\n .answer-item .link:hover { color: #2D4CB8; }\n\n .el-select {\n width: 150px; height: 32px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 8px; font-size: 13px; background: #fff; appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23c0c4cc' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 8px center;\n }\n .el-select:focus { border-color: #3D61E3; outline: none; }\n .el-select:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n\n .sort-badge { font-weight: bold; color: #3D61E3; margin-left: 10px; }\n\n .el-link { color: #3D61E3; cursor: pointer; font-size: 12px; background: none; border: none; padding: 0; margin: 0; font-family: inherit; }\n .el-link:hover { color: #2D4CB8; }\n .el-link.danger { color: #f56c6c; }\n\n .section-row { margin-top: 12px; }\n .value-text { font-size: 13px; color: #606266; white-space: pre-wrap; }\n .muted-text { font-size: 12px; color: #909399; }\n\n .search-wrap { position: relative; }\n .search-dropdown {\n position: absolute; z-index: 120; left: 0; right: 0; top: calc(100% + 4px);\n background: #fff; border: 1px solid #e4e7ed; border-radius: 6px;\n box-shadow: 0 8px 20px rgba(0,0,0,.12); overflow: hidden;\n }\n .search-item {\n padding: 10px 12px; cursor: pointer; transition: background .2s;\n font-size: 13px; color: #606266; line-height: 1.4;\n }\n .search-item:hover { background: #f5f7fa; color: #3D61E3; }\n .search-empty { padding: 10px 12px; font-size: 12px; color: #909399; }\n\n .tag-list { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-height: 32px; }\n .tag-item {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 4px 8px; font-size: 12px; line-height: 1;\n color: #3D61E3; background: #ecf5ff; border: 1px solid #d9ecff; border-radius: 4px;\n }\n .tag-item .close { cursor: pointer; color: #909399; }\n .tag-item .close:hover { color: #f56c6c; }\n .tag-hint { font-size: 12px; color: #909399; }\n\n .resource-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }\n .resource-summary { font-size: 12px; color: #606266; }\n .resource-thumbs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }\n .resource-thumb {\n width: 72px; height: 72px; object-fit: cover; border-radius: 6px;\n border: 1px solid #e4e7ed; cursor: pointer; background: #f5f7fa;\n }\n .resource-video {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 88px; height: 30px; padding: 0 10px; border: 1px solid #dcdfe6; border-radius: 4px;\n color: #606266; background: #fff; cursor: pointer; font-size: 12px; transition: all .2s;\n }\n .resource-video:hover { color: #3D61E3; border-color: #3D61E3; background: #ecf5ff; }\n .media-stage { display: flex; align-items: center; justify-content: center; min-height: 240px; }\n .media-stage img, .media-stage video { max-width: 100%; max-height: 60vh; border-radius: 6px; }\n .media-footer { display: flex; justify-content: space-between; align-items: center; gap: 8px; width: 100%; }\n .media-footer .group { display: flex; gap: 8px; }\n\n /* Multi-select with tags (Element Plus style) */\n .multi-select-wrapper { position: relative; }\n .multi-select {\n width: 240px; height: 28px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 30px 0 8px; font-size: 13px; background: #fff; cursor: pointer;\n display: flex; flex-wrap: nowrap; align-items: center; gap: 4px;\n transition: border-color .2s; position: relative; overflow: hidden;\n }\n .multi-select:hover { border-color: #c0c4cc; }\n .multi-select.focused { border-color: #3D61E3; }\n .multi-select.disabled { background: #f5f7fa; cursor: not-allowed; }\n .multi-select .placeholder { color: #c0c4cc; font-size: 13px; padding: 4px 0; }\n .multi-select .arrow {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n color: #c0c4cc; display: inline-flex; transition: transform .2s;\n }\n .multi-select.focused .arrow { transform: translateY(-50%) rotate(180deg); color: #3D61E3; }\n .multi-select .tag {\n display: inline-flex; align-items: center; gap: 2px;\n background: #f0f2f5; border-radius: 3px; padding: 0 6px; height: 20px;\n font-size: 12px; color: #606266; line-height: 20px;\n }\n .multi-select .tag .tag-close {\n display: inline-flex; cursor: pointer; color: #909399; margin-left: 2px; line-height: 1;\n }\n .multi-select .tag .tag-close:hover { color: #3D61E3; }\n .multi-select-dropdown {\n position: absolute; z-index: 100; background: #fff; left: 0; top: 100%; margin-top: 4px;\n border: 1px solid #e4e7ed; border-radius: 3px;\n box-shadow: 0 4px 12px rgba(0,0,0,.12); min-width: 240px; max-height: 140px; overflow-y: auto;\n }\n .multi-select-option {\n padding: 4px 12px; font-size: 13px; color: #606266; cursor: pointer;\n transition: background .2s;\n }\n .multi-select-option:hover { background: #f5f7fa; }\n .multi-select-option.selected { color: #3D61E3; font-weight: 500; }\n\n .modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 9000; display: flex; align-items: center; justify-content: center; }\n .modal { background: #fff; border-radius: 6px; width: 520px; max-width: 90vw; box-shadow: 0 12px 32px rgba(0,0,0,.12); display: flex; flex-direction: column; }\n .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px 12px; border-bottom: 1px solid #e4e7ed; }\n .modal-title { font-size: 14px; font-weight: 600; color: #303133; }\n .modal-close { background: none; border: none; font-size: 18px; cursor: pointer; color: #909399; padding: 0; line-height: 1; }\n .modal-close:hover { color: #3D61E3; }\n .modal-body { padding: 20px; }\n .modal-body textarea { min-height: 120px; }\n .modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid #e4e7ed; }\n .modal-footer button { padding: 6px 16px; font-size: 12px; border-radius: 3px; cursor: pointer; border: 1px solid #dcdfe6; background: #fff; color: #606266; }\n .modal-footer button:hover { color: #3D61E3; border-color: #a0cfff; }\n .modal-footer button.primary { background: #3D61E3; border-color: #3D61E3; color: #fff; }\n .modal-footer button.primary:hover { background: #2D4CB8; border-color: #2D4CB8; }\n .correct-hint-dialog { width: 520px; max-width: min(90vw, 520px); }\n .correct-hint-dialog .modal-header { padding: 18px 20px 14px; }\n .correct-hint-dialog .modal-title { font-size: 16px; font-weight: 700; color: #303133; }\n .correct-hint-dialog .modal-close { display: none; }\n .correct-hint-dialog .modal-body {\n padding: 32px 28px 20px;\n font-size: 14px;\n line-height: 1.8;\n color: #303133;\n text-align: center;\n }\n .correct-hint-copy { max-width: 420px; margin: 0 auto; }\n .correct-hint-highlight { color: #4c6fff; }\n .correct-hint-dialog .modal-footer {\n justify-content: center;\n gap: 12px;\n padding: 0 28px 28px;\n border-top: none;\n }\n .correct-hint-dialog .modal-footer button {\n min-width: 120px;\n height: 36px;\n padding: 0 18px;\n font-size: 14px;\n border-radius: 4px;\n }\n `]\n\n @property({ type: Number, attribute: 'order-index' }) 'order-index' = 0\n @property({ type: Boolean, attribute: 'is-edit' }) 'is-edit' = false\n @property({ type: Boolean, attribute: 'is-save' }) 'is-save' = false\n @property({ type: Boolean, attribute: 'is-set' }) 'is-set' = false\n @property({ type: Boolean, attribute: 'is-set-correct-answer' }) 'is-set-correct-answer' = false\n @property({ type: Boolean, attribute: 'lock-answer-key' }) lockAnswerKey = false\n @property({ type: Boolean, attribute: 'is-key' }) 'is-key' = false\n @property({ type: Boolean, attribute: 'show-action' }) 'show-action' = true\n @property({ type: Boolean, attribute: 'show-add' }) 'show-add' = true\n @property({ type: Boolean, reflect: true }) sorting = false\n @property({ type: Boolean, attribute: 'show-answer-setting' }) 'show-answer-setting' = false\n @property({ type: Boolean, attribute: 'show-key' }) 'show-key' = false\n @property({ type: Boolean, attribute: 'show-analysis' }) 'show-analysis' = true\n @property({ attribute: 'question-type', reflect: true }) type: AnswerType = 'single'\n @property({ type: Number, attribute: 'answer-check-type' }) 'answer-check-type' = 1\n @property({ type: Number, attribute: 'exam-answer-relation-type' }) 'exam-answer-relation-type' = 0\n @property({ type: String, attribute: 'rich-text-content' }) 'rich-text-content' = ''\n @property({ type: String }) analysis = ''\n @property({ type: Number, attribute: 'least-answer-count' }) 'least-answer-count': number | null = null\n @property({ type: String, attribute: 'exam-expand' }) 'exam-expand' = ''\n @property({ type: String, attribute: 'custom-id' }) 'custom-id' = ''\n @property({ type: Number, attribute: 'exam-id' }) 'exam-id' = 0\n @property({ type: String, attribute: 'category-id' }) 'category-id' = ''\n @property({ type: Object, attribute: 'upload-image' }) 'upload-image': (file: File) => Promise<string> = async (file: File) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = e => resolve(e.target?.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n @property({ type: Array, attribute: 'answer-list' })\n get 'answer-list'() { return this._answers }\n\n set 'answer-list'(v: any) {\n // 编辑模式下不接受外部更新,避免覆盖用户正在编辑的内容\n if (this['is-edit']) {\n return\n }\n const arr = Array.isArray(v) ? v : []\n this._answers = arr.length\n ? arr.map((a: any) => this._normalizeAnswerItem(a))\n : [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n this.requestUpdate('answer-list')\n }\n\n // ============ 业务接口 Props ============\n /**\n * 标签列表 - 用于关联题目的标签信息\n * @type {TagItem[]}\n * @description 业务系统传入已选择的标签列表\n */\n @property({ type: Array, attribute: 'tag-list' }) 'tag-list': TagItem[] = []\n /**\n * 分类列表 - 可用于题目的分类选项\n * @type {Category[]}\n * @description 业务系统传入可选的分类列表\n */\n @property({ type: Array, attribute: 'category-list' }) 'category-list': Category[] = []\n /**\n * AI 推荐答案 - AI 根据题目内容推荐的答案\n * @type {string}\n * @description AI 返回的推荐答案,格式如 \"1. 选项A\\n2. 选项B\"\n */\n @property({ type: String, attribute: 'ai-answer' }) 'ai-answer' = ''\n /**\n * 图片/视频资源列表 - 题目附带的媒体资源\n * @type {Resource[]}\n * @description 题目附带图片或视频资源\n */\n @property({ type: Array, attribute: 'resource-list' }) 'resource-list': Resource[] = []\n /**\n * 是否显示标签功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示标签选择 UI\n */\n @property({ type: Boolean, attribute: 'show-tag' }) 'show-tag' = false\n /**\n * 是否显示分类功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示分类选择 UI\n */\n @property({ type: Boolean, attribute: 'show-category' }) 'show-category' = false\n /**\n * 是否显示 AI 推荐功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示 AI 推荐答案 UI\n */\n @property({ type: Boolean, attribute: 'show-ai' }) 'show-ai' = false\n /**\n * 是否显示资源功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示图片/视频资源 UI\n */\n @property({ type: Boolean, attribute: 'show-resource' }) 'show-resource' = false\n /**\n * 是否显示跳题功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示跳题逻辑设置入口\n */\n @property({ type: Boolean, attribute: 'show-jump' }) 'show-jump' = false\n /**\n * 跳题状态 - 是否已设置跳题逻辑\n * @type {boolean}\n * @default false\n * @description 标记当前题目是否已设置跳题逻辑\n */\n @property({ type: Boolean, attribute: 'has-jump' }) 'has-jump' = false\n /**\n * 题库搜索接口地址\n * @type {string}\n * @description 题库模糊搜索接口地址,用于题库搜索功能\n */\n @property({ type: String, attribute: 'search-api' }) 'search-api' = ''\n /**\n * 题库搜索回调函数\n * @type {Function}\n * @param {string} query - 搜索关键词\n * @param {number} answerType - 题目类型:0-单选, 1-多选\n * @returns {Promise<SearchResult[]>} 搜索结果列表\n * @description 题库搜索的回调函数,由业务系统实现搜索逻辑\n */\n @property({ type: Object, attribute: 'search-handler' }) 'search-handler'?: (query: string, answerType: number) => Promise<SearchResult[]>\n\n // 双向绑定支持\n @property({ type: String, attribute: 'model-value' }) 'model-value' = ''\n @property({ type: Boolean, attribute: 'use-model' }) 'use-model' = false\n\n @state() private _answers: Answer[] = [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n\n @property({ type: String }) title = ''\n\n @state() private _title = ''\n @state() private _analysis = ''\n @state() private _richText = ''\n @state() private _showRichText = false\n @state() private _leastAnswerCount: number | null = null\n @state() private _answerCheckType = 1\n @state() private _isKey = false\n @state() private _orderList: string[] = []\n @state() private _selectedTagList: TagItem[] = []\n @state() private _categoryId = ''\n @state() private _searchResults: SearchResult[] = []\n @state() private _searchOpen = false\n @state() private _searchLoading = false\n @state() private _sortDropdownOpen = false\n @state() private _imageViewerOpen = false\n @state() private _imageViewerIndex = 0\n @state() private _videoViewerOpen = false\n @state() private _correctHintDialogOpen = false\n @state() private _hasShownCorrectHint = false\n @state() private _changeTypeDialogOpen = false\n\n private _searchTimer: number | null = null\n private _searchToken = 0\n\n private readonly TITLE_MAX = 200\n private readonly ANSWER_MAX = 100\n\n connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._handleDocumentClick)\n this._syncExternalProps()\n }\n\n firstUpdated() {\n this._syncExternalProps()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._handleDocumentClick)\n if (this._searchTimer) {\n window.clearTimeout(this._searchTimer)\n this._searchTimer = null\n }\n }\n\n private _handleDocumentClick = (e: MouseEvent) => {\n const path = e.composedPath()\n const wrapper = this.shadowRoot?.querySelector('.multi-select-wrapper')\n const searchWrap = this.shadowRoot?.querySelector('.search-wrap')\n if (wrapper && !path.includes(wrapper)) {\n this._sortDropdownOpen = false\n }\n if (searchWrap && !path.includes(searchWrap)) {\n this._searchOpen = false\n }\n this.requestUpdate()\n }\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('is-edit') && this['is-edit']) { this._syncProps() }\n if (!this['is-edit'] && (changed.has('title') || changed.has('answer-list') || changed.has('analysis') || changed.has('least-answer-count') || changed.has('answer-check-type') || changed.has('tag-list') || changed.has('category-id') || changed.has('rich-text-content'))) {\n this._syncExternalProps()\n }\n if (changed.has('is-key')) {\n this._isKey = this['is-key']\n }\n if (changed.has('tag-list')) {\n this._selectedTagList = Array.isArray(this['tag-list']) ? this['tag-list'].map(item => ({ ...item })) : []\n }\n if (changed.has('category-id')) {\n this._categoryId = this['category-id'] ? String(this['category-id']) : ''\n }\n if (changed.has('exam-expand') || changed.has('answer-list')) { this._syncExamExpand() }\n if (changed.has('model-value') && this['use-model']) {\n this._title = this['model-value']\n }\n }\n\n private _supportsLeastAnswerCount(answerType: AnswerType = this.type) {\n return answerType === 'multiple' || answerType === 'sort'\n }\n\n private _normalizeLeastAnswerCount(value: unknown, answerType: AnswerType = this.type): number | null {\n if (!this._supportsLeastAnswerCount(answerType) || value === '' || value === null || value === undefined) {\n return null\n }\n const count = Number(value)\n return Number.isFinite(count) && count > 0 ? count : null\n }\n\n private _leastAnswerCountSuffix(value: number | null, answerType: AnswerType = this.type) {\n if (!this._supportsLeastAnswerCount(answerType) || value === null) {\n return ''\n }\n return `,至少选${value}项${answerType === 'sort' ? '并排序' : ''}`\n }\n\n private _normalizeAnswerItem(answer: any): Answer {\n const next: Answer = {\n ...answer,\n title: trimText(answer?.title ?? answer?.answer ?? ''),\n isCorrect: !!answer?.isCorrect,\n }\n const answerId = answer?.answerId ?? answer?.examAnswerId\n if (answerId !== undefined) {\n next.answerId = answerId\n }\n return next\n }\n\n private _syncExternalProps() {\n this._title = this.title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this._normalizeLeastAnswerCount(this['least-answer-count'])\n this._answerCheckType = this['answer-check-type'] || 1\n this._isKey = this['is-key']\n this._selectedTagList = Array.isArray(this['tag-list']) ? this['tag-list'].map(item => ({ ...item })) : []\n this._categoryId = this['category-id'] ? String(this['category-id']) : ''\n this._richText = this['rich-text-content'] || ''\n this._showRichText = !!this['rich-text-content']\n if (this['answer-list']?.length) {\n this._answers = this['answer-list'].map((a: any) => this._normalizeAnswerItem(a))\n }\n }\n\n private _syncProps() {\n this._title = (this as any).title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this._normalizeLeastAnswerCount(this['least-answer-count'])\n this._answerCheckType = this['answer-check-type'] || 1\n this._isKey = this['is-key']\n this._selectedTagList = Array.isArray(this['tag-list']) ? this['tag-list'].map(item => ({ ...item })) : []\n this._categoryId = this['category-id'] ? String(this['category-id']) : ''\n this._richText = this['rich-text-content'] || ''\n this._showRichText = !!this['rich-text-content']\n if (this['answer-list']?.length) {\n this._answers = this['answer-list'].map((a: any) => this._normalizeAnswerItem(a))\n }\n this._syncExamExpand()\n }\n\n private _syncExamExpand() {\n if (!this['exam-expand'] || !this['answer-list']?.length) { return }\n const ids = this['exam-expand'].split(',')\n const answers = this['answer-list'] as any[]\n this._orderList = ids.map((id) => {\n const index = answers.findIndex((answer, answerIndex) =>\n String(answer.answerId ?? answer.orderIndex ?? (answerIndex + 1)) === String(id),\n )\n return index >= 0 ? this._label(index) : ''\n }).filter(Boolean)\n }\n\n private _emit(name: string, detail?: unknown) {\n this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail: detail ?? null }))\n }\n\n private _searchAnswerType() {\n if (this.type === 'single') { return 0 }\n if (this.type === 'multiple') { return 1 }\n return 5\n }\n\n private _queueSearch(query: string) {\n if (this._searchTimer) {\n window.clearTimeout(this._searchTimer)\n this._searchTimer = null\n }\n const keyword = query.trim()\n if (!keyword || (!this['search-api'] && typeof this['search-handler'] !== 'function')) {\n this._searchResults = []\n this._searchOpen = false\n this._searchLoading = false\n return\n }\n this._searchTimer = window.setTimeout(() => {\n void this._runSearch(keyword)\n }, 300)\n }\n\n private async _runSearch(query: string) {\n const currentToken = ++this._searchToken\n this._searchLoading = true\n this._searchOpen = true\n this.requestUpdate()\n try {\n let result: SearchResult[] = []\n if (typeof this['search-handler'] === 'function') {\n result = await this['search-handler'](query, this._searchAnswerType())\n }\n else if (this['search-api']) {\n const params = new URLSearchParams({\n searchKey: query,\n answerType: String(this._searchAnswerType()),\n })\n const response = await fetch(`${this['search-api']}${this['search-api'].includes('?') ? '&' : '?'}${params.toString()}`)\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`)\n }\n const payload = await response.json()\n const list = Array.isArray(payload) ? payload : Array.isArray(payload?.data) ? payload.data : []\n result = list.map((item: any) => ({\n ...item,\n value: item?.value || item?.title || '',\n }))\n }\n if (currentToken !== this._searchToken) { return }\n this._searchResults = Array.isArray(result) ? result : []\n }\n catch (error: any) {\n if (currentToken !== this._searchToken) { return }\n this._searchResults = []\n showToast(error?.message || '题库搜索失败')\n }\n finally {\n if (currentToken === this._searchToken) {\n this._searchLoading = false\n this.requestUpdate()\n }\n }\n }\n\n private _selectSearchResult(item: SearchResult) {\n const selectedTitle = item.value || item.title || ''\n this._title = selectedTitle\n this._searchResults = []\n this._searchOpen = false\n if (this['use-model']) {\n this.dispatchEvent(new CustomEvent('update:modelValue', {\n bubbles: true,\n composed: true,\n detail: this._title,\n }))\n }\n this._emit('title-select', {\n ...item,\n id: item.id ?? item.examId ?? item.questionId,\n title: item.title || selectedTitle,\n value: selectedTitle,\n customId: this['custom-id'] || '',\n })\n }\n\n private _applyAiAnswer() {\n if (!this['ai-answer']?.trim()) {\n showToast('暂无 AI 推荐答案')\n return\n }\n const aiTitles = this['ai-answer']\n .split(/\\r?\\n/)\n .map(line => normalizeTitle(line))\n .filter(Boolean)\n let matched = 0\n if (this.type === 'single') {\n let selected = false\n this._answers = this._answers.map((answer) => {\n const shouldSelect = !selected && aiTitles.includes(normalizeTitle(answer.title || ''))\n if (shouldSelect) {\n selected = true\n matched++\n }\n return { ...answer, isCorrect: shouldSelect }\n })\n }\n else {\n this._answers = this._answers.map((answer) => {\n const shouldSelect = aiTitles.includes(normalizeTitle(answer.title || ''))\n if (shouldSelect) { matched++ }\n return { ...answer, isCorrect: shouldSelect }\n })\n }\n if (!matched) {\n showToast('未找到匹配的选项,请检查选项内容是否一致')\n return\n }\n this.requestUpdate()\n }\n\n private _onCategoryChange(value: string) {\n this._categoryId = value\n this._emit('category-change', {\n value,\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n })\n }\n\n private _setRelation(item: Answer, answerIndex: number) {\n const answer = item.customAnswerId\n ? { ...item }\n : { ...item, customAnswerId: item.answerId || uid() }\n this._answers = this._answers.map((current, index) => index === answerIndex ? answer : current)\n this.requestUpdate()\n this._emit('set-relation', {\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n answerIndex,\n answer,\n })\n }\n\n private _relationLength(relations: any[] = []) {\n return relations.reduce((count, item) => count + (Array.isArray(item?.relationAnswers) ? item.relationAnswers.length : 0), 0)\n }\n\n private _emitEditResultItem(item: Answer, answerIndex: number) {\n this._emit('edit-result-item', {\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n answerIndex,\n answer: { ...item },\n resultItem: item.resultItem || '',\n })\n }\n\n private _resultSlotName(index: number) {\n return `business-result-item-${index}`\n }\n\n private _imageResources() {\n return (this['resource-list'] || [])\n .filter(item => item.resourceType === 1)\n .map(item => item.resource.middle || item.resource.url)\n .filter(Boolean) as string[]\n }\n\n private _videoResource() {\n return (this['resource-list'] || []).find(item => item.resourceType === 2)?.resource || null\n }\n\n private _openImageViewer(index = 0) {\n if (!this._imageResources().length) { return }\n this._imageViewerIndex = index\n this._imageViewerOpen = true\n }\n\n private _closeImageViewer() {\n this._imageViewerOpen = false\n }\n\n private _moveImage(step: number) {\n const images = this._imageResources()\n if (!images.length) { return }\n this._imageViewerIndex = (this._imageViewerIndex + step + images.length) % images.length\n }\n\n private _openVideoViewer() {\n if (!this._videoResource()?.url) { return }\n this._videoViewerOpen = true\n }\n\n private _closeVideoViewer() {\n this._videoViewerOpen = false\n }\n\n private _label(i: number) { return String.fromCharCode(65 + i) }\n\n private get _titlePlaceholder() {\n return this.type === 'single' ? '单选题' : this.type === 'multiple' ? '多选题' : '排序题'\n }\n\n private _setCorrect(item: Answer, val: boolean) {\n if (this.lockAnswerKey) { return }\n item.isCorrect = val\n this.requestUpdate()\n }\n\n private _onTitleInput(e: Event) {\n const el = e.target as HTMLTextAreaElement\n if (el.value.length > this.TITLE_MAX) { el.value = el.value.slice(0, this.TITLE_MAX) }\n this._title = el.value\n this._queueSearch(this._title)\n // 双向绑定:通知外部更新\n if (this['use-model']) {\n this.dispatchEvent(new CustomEvent('update:modelValue', {\n bubbles: true,\n composed: true,\n detail: this._title,\n }))\n }\n }\n\n private _onAnswerInput(e: Event, idx: number) {\n const el = e.target as HTMLInputElement\n if (el.value.length > this.ANSWER_MAX) { el.value = el.value.slice(0, this.ANSWER_MAX) }\n this._answers[idx].title = el.value\n this.requestUpdate()\n }\n\n private _addAnswer(index: number) {\n const arr = [...this._answers]\n arr.splice(index + 1, 0, { title: '', isCorrect: false, customAnswerId: uid() })\n this._answers = arr\n }\n\n private _deleteAnswer(index: number) {\n if (this._answers.length < 3) { return }\n this._answers = this._answers.filter((_, i) => i !== index)\n }\n\n private _toggleSortItem(letter: string) {\n const idx = this._orderList.indexOf(letter)\n if (idx >= 0) {\n this._orderList = this._orderList.filter(l => l !== letter)\n }\n else {\n this._orderList = [...this._orderList, letter]\n }\n this.requestUpdate()\n }\n\n private _removeSortItem(letter: string) {\n this._orderList = this._orderList.filter(l => l !== letter)\n this.requestUpdate()\n }\n\n private _getSortOrder(index: number): number | null {\n const pos = this._orderList.indexOf(this._label(index))\n return pos >= 0 ? pos + 1 : null\n }\n\n private _sortAnswerValue(letter: string) {\n const index = letter.charCodeAt(0) - 65\n const answer = this._answers[index] as any\n return answer?.answerId ?? index + 1\n }\n\n private _rowMeta() {\n return {\n customId: this['custom-id'] || undefined,\n answerType: this.type,\n orderIndex: this['order-index'],\n }\n }\n\n private _collectSnapshot(): SubjectSnapshot {\n const answers = (this['is-edit'] ? this._answers : this['answer-list'] || []).map((answer: any) => ({\n ...answer,\n title: trimText(answer?.title ?? answer?.answer ?? ''),\n isCorrect: !!answer?.isCorrect,\n resultItem: trimText(answer?.resultItem ?? ''),\n }))\n const orderList = this['is-edit']\n ? [...this._orderList]\n : (() => {\n const expand = this['exam-expand']\n if (!expand) { return [] }\n return expand.split(',').map((id: string) => {\n const index = (this['answer-list'] as any[])?.findIndex((answer, answerIndex) =>\n String(answer.answerId ?? answer.orderIndex ?? (answerIndex + 1)) === String(id),\n )\n return index >= 0 ? this._label(index) : ''\n }).filter(Boolean)\n })()\n return {\n title: trimText(this['is-edit'] ? this._title : (this as any).title || ''),\n answers,\n analysis: trimText(this['is-edit'] ? this._analysis : this.analysis || ''),\n leastAnswerCount: this['is-edit']\n ? this._leastAnswerCount\n : this._normalizeLeastAnswerCount(this['least-answer-count']),\n selectedTagList: Array.isArray(this._selectedTagList) ? [...this._selectedTagList] : [],\n examExpand: this['is-edit']\n ? orderList.map((letter: string) => this._sortAnswerValue(letter)).join(',')\n : (this['exam-expand'] || ''),\n showRichText: this['is-edit'] ? this._showRichText : !!this['rich-text-content'],\n richText: this['is-edit'] ? this._richText : this['rich-text-content'] || '',\n orderList,\n }\n }\n\n private _validateSnapshot(snapshot: SubjectSnapshot, answerType: AnswerType = this.type) {\n const row = this._rowMeta()\n const errors: SubjectError[] = []\n\n if (!snapshot.title) {\n errors.push(new SubjectError('题目标题不能为空!', 'EMPTY_TITLE', 'title', row))\n }\n let isSetCorrectAnswer = false\n let correctAnswerCount = 0\n\n snapshot.answers.forEach((answer, index) => {\n if (!answer.title?.trim()) {\n errors.push(new SubjectError(`选项${String.fromCharCode(65 + index)}未填写`, 'ANSWER_EMPTY', 'answers', row))\n }\n if (answerType !== 'sort' && answer.isCorrect) {\n isSetCorrectAnswer = true\n correctAnswerCount++\n }\n })\n\n const titleSet = new Set(snapshot.answers.map(answer => answer.title))\n if (titleSet.size !== snapshot.answers.length && snapshot.answers.length > 0) {\n errors.push(new SubjectError('选项不能重复', 'DUPLICATE_ANSWERS', 'answers', row))\n }\n\n if (answerType === 'single' && correctAnswerCount > 1) {\n errors.push(new SubjectError(\n '此题为单选题,设置了多个推荐/正确选项,请保存时确认是否切换为多选题',\n 'SINGLE_MULTI_CORRECT',\n 'answers',\n row,\n ))\n }\n\n if (answerType === 'multiple') {\n if (correctAnswerCount === 1) {\n errors.push(new SubjectError('请设置至少两个推荐/正确选项', 'CORRECT_COUNT_INVALID', 'answers', row))\n }\n if (correctAnswerCount > 0) {\n isSetCorrectAnswer = true\n }\n if (isSetCorrectAnswer && snapshot.leastAnswerCount !== null && correctAnswerCount < snapshot.leastAnswerCount) {\n errors.push(new SubjectError('至少选几项与推荐/正确选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'answers', row))\n }\n }\n\n if (answerType === 'sort') {\n isSetCorrectAnswer = snapshot.orderList.length > 0\n if (snapshot.leastAnswerCount !== null && snapshot.orderList.length < snapshot.leastAnswerCount) {\n errors.push(new SubjectError('至少选几项与推荐/正确选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'orderList', row))\n }\n }\n\n return {\n errors,\n isSetCorrectAnswer,\n correctAnswerCount,\n }\n }\n\n private _serialize(answerType: AnswerType = this.type) {\n const snapshot = this._collectSnapshot()\n const { errors, isSetCorrectAnswer } = this._validateSnapshot(snapshot, answerType)\n if (errors.length) {\n throw errors[0]\n }\n const result: any = {\n answerType: String(answerType),\n examTypeEnum: String(answerType),\n title: snapshot.title,\n answers: snapshot.answers.map((answer, index) => {\n const relationType = answer.resultItem\n ? 1\n : (Array.isArray(answer.answerRelations) && answer.answerRelations.length ? 2 : null)\n const next: any = { ...answer, orderIndex: index + 1, answer: answer.title, relationType }\n if (answer.answerId !== undefined) {\n next.examAnswerId = answer.answerId\n }\n if (relationType === null) {\n delete next.relationType\n }\n return next\n }),\n examExpand: snapshot.examExpand,\n analysis: snapshot.analysis,\n isSetCorrectAnswer,\n examRichTextContent: snapshot.showRichText ? snapshot.richText : '',\n }\n if (this['exam-answer-relation-type']) {\n result.examAnswerRelationType = this['exam-answer-relation-type']\n }\n if (this._supportsLeastAnswerCount(answerType)) {\n result.leastAnswerCount = snapshot.leastAnswerCount\n }\n if (this['custom-id']) { result.customId = this['custom-id'] }\n return result\n }\n\n private _shouldShowCorrectHint() {\n if (this.type === 'sort') {\n return !this._orderList.length\n }\n return !this._answers.some(answer => !!answer.isCorrect)\n }\n\n private async _finalizeSave() {\n try {\n const data = await this.toJSON()\n this._emit('save', data)\n }\n catch (err: any) {\n showToast(err.message)\n }\n }\n\n async toJSON(): Promise<any> {\n return Promise.resolve(this._serialize())\n }\n\n validate(): SubjectError[] {\n return this._validateSnapshot(this._collectSnapshot()).errors\n }\n\n setResultItem(answerIndex: number, resultItem: string) {\n if (answerIndex < 0 || answerIndex >= this._answers.length) {\n return\n }\n this._answers = this._answers.map((answer, index) => index === answerIndex\n ? { ...answer, resultItem: resultItem || '' }\n : answer)\n this.requestUpdate()\n }\n\n setAnswerRelation(customAnswerId: string, answerRelations: any) {\n if (!customAnswerId) {\n return\n }\n this._answers = this._answers.map((answer) => {\n const currentId = String(answer.customAnswerId ?? answer.answerId ?? '')\n return currentId === String(customAnswerId)\n ? { ...answer, answerRelations }\n : answer\n })\n this.requestUpdate()\n }\n\n private _renderCorrectHintDialog() {\n if (!this._correctHintDialogOpen) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => { this._correctHintDialogOpen = false }}>\n <div class=\"modal correct-hint-dialog\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">温馨提示</span>\n </div>\n <div class=\"modal-body\">\n <div class=\"correct-hint-copy\">\n 为了收集更全面、有价值的数据,建议您为问卷每题设定<span class=\"correct-hint-highlight\">推荐/正确选项</span>。这将助力深入分析,让调研结果更精准、有意义。\n </div>\n </div>\n <div class=\"modal-footer\">\n <button @click=${async () => {\n this._hasShownCorrectHint = true\n this._correctHintDialogOpen = false\n await this._finalizeSave()\n }}>完成编辑</button>\n <button class=\"primary\" @click=${() => { this._correctHintDialogOpen = false }}>去设置</button>\n </div>\n </div>\n </div>\n `\n }\n\n private _renderChangeTypeDialog() {\n if (!this._changeTypeDialogOpen) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => { this._changeTypeDialogOpen = false }}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">提示</span>\n <button class=\"modal-close\" @click=${() => { this._changeTypeDialogOpen = false }}>&#x2715;</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"value-text\">此题为单选题,设置了多个推荐/正确选项,是否切换成多选题?</div>\n </div>\n <div class=\"modal-footer\">\n <button @click=${() => { this._changeTypeDialogOpen = false }}>取消</button>\n <button class=\"primary\" @click=${() => {\n try {\n const data = this._serialize('multiple')\n this._changeTypeDialogOpen = false\n this._emit('save', data)\n }\n catch (error: any) {\n showToast(error?.message || '保存失败')\n }\n }}>切换</button>\n </div>\n </div>\n </div>\n `\n }\n\n private _renderSearchDropdown() {\n if (!this['is-edit'] || (!this._searchOpen && !this._searchLoading)) { return '' }\n return html`\n <div class=\"search-dropdown\">\n ${this._searchLoading\n ? html`<div class=\"search-empty\">搜索中...</div>`\n : this._searchResults.length\n ? this._searchResults.map(item => html`\n <div class=\"search-item\" @click=${() => this._selectSearchResult(item)}>${item.value || item.title}</div>\n `)\n : html`<div class=\"search-empty\">暂无匹配题目</div>`}\n </div>\n `\n }\n\n private _renderCategorySection() {\n if (!this['show-category']) { return '' }\n return html`\n <div class=\"flex-items-start section-row\">\n <div class=\"label\"><span>分类:</span></div>\n <div style=\"flex:1\">\n ${this['is-edit']\n ? html`\n <select class=\"el-select\" .value=${String(this._categoryId)}\n @change=${(e: Event) => this._onCategoryChange((e.target as HTMLSelectElement).value)}>\n <option value=\"\">选择分类</option>\n ${this['category-list'].map(item => html`\n <option value=${String(item.categoryId)} ?selected=${String(item.categoryId) === String(this._categoryId)}>${item.title}</option>\n `)}\n </select>\n `\n : html`<span class=\"value-text\">${this['category-list'].find(item => String(item.categoryId) === String(this._categoryId))?.title || '未选择分类'}</span>`}\n </div>\n </div>\n `\n }\n\n private _renderAiSection() {\n if (!this['show-ai'] || !['single', 'multiple'].includes(this.type)) { return '' }\n return html`\n <div class=\"flex-items-start section-row\">\n <div class=\"label\"><span>AI推荐:</span></div>\n <div style=\"flex:1\">\n <span class=\"value-text\">${this['ai-answer'] || '暂无'}</span>\n ${this['is-edit']\n ? html`<div style=\"margin-top:8px\"><span class=\"el-link\" @click=${() => this._applyAiAnswer()}>一键勾选</span></div>`\n : ''}\n </div>\n </div>\n `\n }\n\n private _renderResourceSection() {\n if (!this['show-resource']) { return '' }\n const images = this._imageResources()\n const video = this._videoResource()\n return html`\n <div class=\"flex-items-start section-row\">\n <div class=\"label\"><span>资源:</span></div>\n <div style=\"flex:1\">\n <div class=\"resource-summary\">\n 图片 ${images.length} 张${video ? ',含视频资源' : ''}\n </div>\n <div class=\"resource-actions\">\n ${images.length ? html`<span class=\"el-link\" @click=${() => this._openImageViewer(0)}>查看图片</span>` : ''}\n ${video?.url ? html`<span class=\"el-link\" @click=${() => this._openVideoViewer()}>查看视频</span>` : ''}\n ${!images.length && !video?.url ? html`<span class=\"muted-text\">暂无资源</span>` : ''}\n </div>\n ${images.length\n ? html`\n <div class=\"resource-thumbs\">\n ${images.slice(0, 4).map((src, index) => html`\n <img class=\"resource-thumb\" src=${src} alt=\"resource\" @click=${() => this._openImageViewer(index)} />\n `)}\n </div>\n `\n : ''}\n </div>\n </div>\n `\n }\n\n private _renderImageViewer() {\n if (!this._imageViewerOpen) { return '' }\n const images = this._imageResources()\n const current = images[this._imageViewerIndex]\n if (!current) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => this._closeImageViewer()}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">图片预览</span>\n <button class=\"modal-close\" @click=${() => this._closeImageViewer()}>&#x2715;</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"media-stage\"><img src=${current} alt=\"resource-preview\" /></div>\n </div>\n <div class=\"modal-footer\">\n <div class=\"media-footer\">\n <span class=\"muted-text\">${this._imageViewerIndex + 1} / ${images.length}</span>\n <div class=\"group\">\n ${images.length > 1 ? html`<button @click=${() => this._moveImage(-1)}>上一张</button>` : ''}\n ${images.length > 1 ? html`<button @click=${() => this._moveImage(1)}>下一张</button>` : ''}\n <button class=\"primary\" @click=${() => this._closeImageViewer()}>关闭</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n private _renderVideoViewer() {\n const video = this._videoResource()\n if (!this._videoViewerOpen || !video?.url) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => this._closeVideoViewer()}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">视频预览</span>\n <button class=\"modal-close\" @click=${() => this._closeVideoViewer()}>&#x2715;</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"media-stage\">\n <video src=${video.url} controls playsinline></video>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"primary\" @click=${() => this._closeVideoViewer()}>关闭</button>\n </div>\n </div>\n </div>\n `\n }\n\n private async _save(e?: Event) {\n e?.stopImmediatePropagation()\n const errors = this.validate()\n const convertWarning = errors.find(error => error.code === 'SINGLE_MULTI_CORRECT')\n const blockingErrors = errors.filter(error => error.code !== 'SINGLE_MULTI_CORRECT')\n if (blockingErrors.length) {\n showToast(blockingErrors[0].message)\n return\n }\n if (convertWarning) {\n this._changeTypeDialogOpen = true\n return\n }\n if (!this._hasShownCorrectHint && this._shouldShowCorrectHint()) {\n this._correctHintDialogOpen = true\n return\n }\n await this._finalizeSave()\n }\n\n private _renderPreview() {\n const typeSuffix = this.type === 'single'\n ? '(单选题)'\n : `(${this._titlePlaceholder}${this._leastAnswerCountSuffix(this._normalizeLeastAnswerCount(this['least-answer-count']))})`\n const answers = this['answer-list'] as Answer[]\n return html`\n <div class=\"preview\">\n <div><span class=\"title\">${this['order-index'] + 1}.${(this as any).title || ''}${typeSuffix}</span></div>\n ${this['rich-text-content'] ? html`<div class=\"rich-text\" .innerHTML=${this['rich-text-content']}></div>` : ''}\n <div class=\"preview-answer\">\n ${answers.map((a, i) => html`\n <label class=\"radio\">\n <input type=\"${this.type === 'sort' ? 'checkbox' : 'radio'}\" .checked=${!!a.isCorrect} disabled />\n <span class=\"order\">${this._label(i)}.</span> ${a.title}\n ${this.type !== 'sort' && a.isCorrect ? html`<span class=\"correct\">(推荐/正确选项)</span>` : ''}\n ${this['exam-answer-relation-type'] === 1 && this.type !== 'sort'\n ? html`<span class=\"correct\">(${a.resultItem ? '已设置结果项' : '未设置结果项'})</span>`\n : ''}\n ${this['exam-answer-relation-type'] === 2 && this.type !== 'sort'\n ? html`<span class=\"correct\">(${Array.isArray(a.answerRelations) && a.answerRelations.length ? `关联了${this._relationLength(a.answerRelations)}项` : '未设置关联'})</span>`\n : ''}\n </label>\n `)}\n </div>\n ${this['show-category'] && this._categoryId\n ? html`<div class=\"section-row\"><span class=\"value-text\">分类:${this['category-list'].find(item => String(item.categoryId) === String(this._categoryId))?.title || this._categoryId}</span></div>`\n : ''}\n ${this['show-resource'] ? this._renderResourceSection() : ''}\n </div>\n `\n }\n\n private _renderSorting() {\n const title = trimText(this['is-edit'] ? this._title : (this as any).title || '') || '未命名题目'\n const orderText = `${this['order-index'] + 1}. ${title}`\n return renderSortingCard(orderText, SubjectTypeLabel[this.type] || this.type)\n }\n\n private _renderEdit() {\n return html`\n <div class=\"flex-items-start\">\n <div class=\"label\"><span>题目:</span></div>\n <div style=\"flex:1\">\n <div class=\"el-input search-wrap\">\n <textarea rows=\"2\" .value=${this._title}\n maxlength=${this.TITLE_MAX}\n @input=${(e: Event) => this._onTitleInput(e)}\n placeholder=\"【${this._titlePlaceholder}】请输入问题\"></textarea>\n <span class=\"char-counter\">${this._title.length}/${this.TITLE_MAX}</span>\n ${this._renderSearchDropdown()}\n </div>\n </div>\n </div>\n\n ${['multiple', 'sort'].includes(this.type)\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>设置:</span></div>\n <select class=\"el-select\" .value=${this._leastAnswerCount === null ? '' : String(this._leastAnswerCount)} ?disabled=${this.lockAnswerKey}\n @change=${(e: Event) => {\n const value = (e.target as HTMLSelectElement).value\n this._leastAnswerCount = this._normalizeLeastAnswerCount(value)\n }}>\n <option value=\"\">至少选择几项</option>\n ${Array.from({ length: Math.max(0, this._answers.length - 1) }, (_, i) => i + 2).map(n => html`\n <option value=${n} ?selected=${this._leastAnswerCount === n}>至少选择${n}项</option>\n `)}\n </select>\n </div>\n `\n : ''}\n\n <div class=\"answer-list\">\n ${this._answers.map((a, i) => html`\n <div class=\"answer-item\">\n <span class=\"label\">${this._label(i)}.</span>\n <div class=\"input\">\n <input type=\"text\" .value=${a.title}\n maxlength=${this.ANSWER_MAX}\n @input=${(e: Event) => this._onAnswerInput(e, i)}\n placeholder=\"选项${this._label(i)}\" />\n <span class=\"char-counter\">${a.title.length}/${this.ANSWER_MAX}</span>\n </div>\n\n ${this.type === 'sort' && this._getSortOrder(i) !== null\n ? html`<span class=\"sort-badge\">第${this._getSortOrder(i)}位</span>`\n : ''}\n\n ${['single', 'multiple'].includes(this.type)\n ? html`\n <label class=\"correct ${a.isCorrect ? 'is-correct' : ''}\">\n <input type=\"checkbox\" .checked=${a.isCorrect} ?disabled=${this.lockAnswerKey}\n @change=${(e: Event) => this._setCorrect(a, (e.target as HTMLInputElement).checked)} />\n 推荐/正确选项\n </label>\n `\n : ''}\n\n <span class=\"icon\"\n @click=${() => this._addAnswer(i)}>\n ${iconPlus}\n </span>\n <span class=\"icon ${this._answers.length < 3 ? 'disabled' : ''}\"\n @click=${() => this._deleteAnswer(i)}>\n ${iconRemove}\n </span>\n\n ${this['exam-answer-relation-type'] === 1 && this.type !== 'sort'\n ? html`\n <slot name=${this._resultSlotName(i)}>\n <button class=\"el-link\" @click=${() => this._emitEditResultItem(a, i)}>\n ${a.resultItem ? '编辑结果' : '添加结果'}\n </button>\n </slot>\n `\n : ''}\n\n ${this['exam-answer-relation-type'] === 2 && this.type !== 'sort'\n ? html`\n <button class=\"el-link\" @click=${() => this._setRelation(a, i)}>\n ${Array.isArray(a.answerRelations) && a.answerRelations.length ? `关联了${this._relationLength(a.answerRelations)}项` : '关联检查'}\n </button>\n `\n : ''}\n\n </div>\n `)}\n </div>\n\n ${this.type === 'sort'\n ? html`\n <div class=\"flex-items-center\" style=\"margin-top:12px\">\n <div class=\"label\"><span>排序答案:</span></div>\n <div style=\"flex:1\">\n <div class=\"multi-select-wrapper\">\n <div class=\"multi-select ${this._sortDropdownOpen ? 'focused' : ''} ${this.lockAnswerKey ? 'disabled' : ''}\"\n @click=${() => { if (!this.lockAnswerKey) { this._sortDropdownOpen = !this._sortDropdownOpen; this.requestUpdate() } }}>\n ${this._orderList.length > 0\n ? this._orderList.map(l => html`\n <span class=\"tag\">\n ${l}\n <span class=\"tag-close\" @click=${(e: Event) => {\n if (this.lockAnswerKey) { return }\n e.stopPropagation()\n this._removeSortItem(l)\n }}>&#x2715;</span>\n </span>\n `)\n : html`<span class=\"placeholder\">请按顺序选择排序答案</span>`\n }\n <span class=\"arrow\">${iconArrow}</span>\n </div>\n ${this._sortDropdownOpen\n ? html`\n <div class=\"multi-select-dropdown\">\n ${this._answers.map((_, i) => html`\n <div class=\"multi-select-option ${this._orderList.includes(this._label(i)) ? 'selected' : ''}\"\n @click=${() => {\n if (this.lockAnswerKey) { return }\n this._toggleSortItem(this._label(i))\n this.requestUpdate()\n }}>\n ${this._label(i)}\n </div>\n `)}\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `\n : ''}\n\n <slot name=\"business-tag\"></slot>\n\n ${this._renderCategorySection()}\n\n ${this._renderAiSection()}\n\n ${this._renderResourceSection()}\n\n ${this._showRichText\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>副文本:</span></div>\n <div style=\"flex:1\">\n <slot name=\"sub-text\">\n <qxs-blocksuite-editor\n .content=${this._richText}\n .upload-image=${this['upload-image']}\n ?is-edit=${true}\n @input=${(e: CustomEvent) => { this._richText = (e.target as any).getContent() }}\n ></qxs-blocksuite-editor>\n </slot>\n ${!this['show-action']\n ? html`<div class=\"flex-justify-end\" style=\"margin-top:8px\"><span class=\"el-link danger\" @click=${() => { this._showRichText = false; this._richText = '' }}>删除富文本</span></div>`\n : ''}\n </div>\n </div>\n `\n : ''}\n\n ${this['show-analysis']\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>解析:</span></div>\n <div style=\"flex:1\">\n <textarea rows=\"2\" .value=${this._analysis}\n @input=${(e: Event) => { this._analysis = (e.target as HTMLTextAreaElement).value }}\n placeholder=\"请输入题目解析\"></textarea>\n </div>\n </div>\n `\n : ''}\n `\n }\n\n render() {\n if (this.sorting) {\n return this._renderSorting()\n }\n\n const content = this['is-edit']\n ? html`<div slot=\"edit\">${this._renderEdit()}</div>`\n : html`<div slot=\"preview\">${this._renderPreview()}</div>`\n\n return html`\n <qxs-subject-layout .show-edit=${this['is-edit']}>\n ${content}\n ${this['show-action']\n ? html`\n <qxs-subject-action\n .is-edit=${this['is-edit']}\n .is-set=${this['is-set']}\n .show-add=${this['show-add']}\n .show-rich-text=${this._showRichText}\n .show-jump=${this['show-jump']}\n @delete=${() => this._emit('delete')}\n @save=${this._save}\n @edit=${() => this._emit('edit')}\n @move=${(e: CustomEvent) => this._emit('move', e.detail)}\n @jump=${() => this._emit('jump', {\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n answerType: this.type,\n })}\n @add=${(e: CustomEvent) => this._emit('add', e.detail)}\n @on-show-rich-text=${() => {\n this._showRichText = !this._showRichText\n if (!this._showRichText) {\n this._richText = ''\n }\n }}\n ></qxs-subject-action>\n `\n : ''}\n </qxs-subject-layout>\n ${this._renderCorrectHintDialog()}\n ${this._renderChangeTypeDialog()}\n ${this._renderImageViewer()}\n ${this._renderVideoViewer()}\n `\n }\n}\n\nexport function register() {}\n"],"names":["SubjectError","Error","constructor","message","code","arguments","length","undefined","field","row","super","this","name","from","options","iconPlus","html","iconRemove","iconArrow","normalizeTitle","text","replace","toLowerCase","trimText","value","String","trim","trimCommaSeparatedText","split","map","item","filter","Boolean","join","showToast","msg","el","document","createElement","textContent","Object","assign","style","position","top","left","transform","padding","borderRadius","fontSize","color","background","zIndex","boxShadow","transition","opacity","body","appendChild","setTimeout","remove","QxsSubjectSingle","LitElement","lockAnswerKey","sorting","type","analysis","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","_answers","title","isCorrect","_title","_analysis","_richText","_showRichText","_leastAnswerCount","_answerCheckType","_isKey","_orderList","_selectedTagList","_categoryId","_searchResults","_searchOpen","_searchLoading","_sortDropdownOpen","_imageViewerOpen","_imageViewerIndex","_videoViewerOpen","_correctHintDialogOpen","_hasShownCorrectHint","_changeTypeDialogOpen","_searchTimer","_searchToken","TITLE_MAX","ANSWER_MAX","_handleDocumentClick","path","composedPath","wrapper","shadowRoot","querySelector","searchWrap","includes","requestUpdate","v","arr","Array","isArray","a","_normalizeAnswerItem","connectedCallback","addEventListener","_syncExternalProps","firstUpdated","disconnectedCallback","removeEventListener","window","clearTimeout","willUpdate","changed","has","_syncProps","_syncExamExpand","_supportsLeastAnswerCount","answerType","_normalizeLeastAnswerCount","count","Number","isFinite","_leastAnswerCountSuffix","answer","next","answerId","examAnswerId","ids","answers","id","index","findIndex","answerIndex","orderIndex","_label","_emit","detail","dispatchEvent","CustomEvent","bubbles","composed","_searchAnswerType","_queueSearch","query","keyword","_runSearch","currentToken","params","URLSearchParams","searchKey","response","fetch","toString","ok","status","payload","json","data","error","_selectSearchResult","selectedTitle","examId","questionId","customId","_applyAiAnswer","aiTitles","line","matched","selected","shouldSelect","_onCategoryChange","_setRelation","customAnswerId","uid","current","_relationLength","reduce","relationAnswers","_emitEditResultItem","resultItem","_resultSlotName","_imageResources","resourceType","resource","middle","url","_videoResource","find","_openImageViewer","_closeImageViewer","_moveImage","step","images","_openVideoViewer","_closeVideoViewer","i","fromCharCode","_titlePlaceholder","_setCorrect","val","_onTitleInput","slice","_onAnswerInput","idx","_addAnswer","splice","_deleteAnswer","_","_toggleSortItem","letter","indexOf","l","_removeSortItem","_getSortOrder","pos","_sortAnswerValue","charCodeAt","_rowMeta","_collectSnapshot","orderList","expand","leastAnswerCount","selectedTagList","examExpand","showRichText","richText","_validateSnapshot","snapshot","errors","push","isSetCorrectAnswer","correctAnswerCount","forEach","Set","size","_serialize","examTypeEnum","relationType","answerRelations","examRichTextContent","examAnswerRelationType","_shouldShowCorrectHint","some","_finalizeSave","toJSON","err","validate","setResultItem","setAnswerRelation","_renderCorrectHintDialog","stopPropagation","_renderChangeTypeDialog","_renderSearchDropdown","_renderCategorySection","categoryId","_renderAiSection","_renderResourceSection","video","src","_renderImageViewer","_renderVideoViewer","_save","stopImmediatePropagation","convertWarning","blockingErrors","_renderPreview","typeSuffix","_renderSorting","orderText","renderSortingCard","SubjectTypeLabel","_renderEdit","Math","max","n","checked","getContent","render","content","styles","sortingCardStyles","css","__decorateClass","property","attribute","prototype","reflect","state","safeCustomElement"],"mappings":"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"}
1
+ {"version":3,"file":"single.mjs","sources":["../../../../packages/components-wc/src/subject/single.ts"],"sourcesContent":["import type { AnswerType } from './types'\nimport { css, html, LitElement } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { safeCustomElement } from '../base/define'\nimport { uid } from '../base/uid'\nimport { renderSortingCard, sortingCardStyles } from './sorting-card'\nimport { joinSubjectTitle, resolveSubjectPrefix } from './title-prefix'\nimport { SubjectTypeLabel } from './types'\n\nexport interface SubjectErrorOptions {\n message: string\n code?: string\n field?: string\n row?: any\n}\n\nexport class SubjectError extends Error {\n constructor(\n message: string,\n public code: string = 'VALIDATION_ERROR',\n public field?: string,\n public row?: any,\n ) {\n super(message)\n this.name = 'SubjectError'\n }\n\n static from(options: SubjectErrorOptions): SubjectError {\n return new SubjectError(options.message, options.code, options.field, options.row)\n }\n}\n\ninterface Answer {\n title: string\n isCorrect: boolean\n customAnswerId?: string\n answerId?: string\n resultItem?: string\n orderIndex?: number\n answerRelations?: any[]\n relationType?: number | null\n}\n\ninterface SubjectSnapshot {\n title: string\n answers: Answer[]\n analysis: string\n leastAnswerCount: number | null\n selectedTagList: TagItem[]\n examExpand: string\n showRichText: boolean\n richText: string\n orderList: string[]\n}\n\nconst iconPlus = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconRemove = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`\nconst iconArrow = html`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"/></svg>`\n\nfunction normalizeTitle(text: string) {\n return text\n .replace(/^\\d+\\.\\s*/, '')\n .replace(/[\\s,,。.!!??;;::、'\"“”‘’()()[\\]【】\\-_/\\\\]+/g, '')\n .toLowerCase()\n}\n\nexport function trimText(value: unknown) {\n return String(value ?? '').trim()\n}\n\nexport function trimCommaSeparatedText(value: unknown) {\n return String(value ?? '')\n .split(',')\n .map(item => item.trim())\n .filter(Boolean)\n .join(',')\n}\n\nfunction showToast(msg: string) {\n const el = document.createElement('div')\n el.textContent = msg\n Object.assign(el.style, {\n position: 'fixed', top: '20px', left: '50%', transform: 'translateX(-50%)',\n padding: '10px 20px', borderRadius: '4px', fontSize: '13px', color: '#fff',\n background: '#f56c6c', zIndex: '99999', boxShadow: '0 4px 12px rgba(0,0,0,.15)',\n transition: 'opacity .3s', opacity: '1',\n })\n document.body.appendChild(el)\n setTimeout(() => { el.style.opacity = '0'; setTimeout(() => el.remove(), 300) }, 2500)\n}\n\n/**\n * 标签项 - 用于关联题目的标签信息\n * @typedef {object} TagItem\n * @property {string|number} tagId - 标签ID\n * @property {string} tagName - 标签名称\n * @property {KnowledgePointInfo[]} [knowledgePointInfos] - 关联的知识点的列表\n */\nexport interface TagItem {\n tagId: string | number\n tagName: string\n knowledgePointInfos?: KnowledgePointInfo[]\n}\n\n/**\n * 知识点信息\n * @typedef {object} KnowledgePointInfo\n * @property {string|number} knowledgePointId - 知识点ID\n * @property {string} knowledgePointName - 知识点名称\n */\nexport interface KnowledgePointInfo {\n knowledgePointId: string | number\n knowledgePointName: string\n}\n\n/**\n * 分类选项\n * @typedef {object} Category\n * @property {string|number} categoryId - 分类ID\n * @property {string} title - 分类标题\n */\nexport interface Category {\n categoryId: string | number\n title: string\n}\n\n/**\n * 题库搜索结果项\n * @typedef {object} SearchResult\n * @property {string|number} id - 题目ID\n * @property {string} title - 题目标题\n * @property {string} value - 用于搜索框显示的值\n * @property {any} [key: string] - 其他扩展字段\n */\nexport interface SearchResult {\n id: string | number\n title: string\n value: string\n [key: string]: any\n}\n\n/**\n * 题目资源(图片或视频)\n * @typedef {object} Resource\n * @property {1|2} resourceType - 资源类型:1-图片, 2-视频\n * @property {object} resource - 资源详情\n * @property {string} [resource.url] - 资源URL\n * @property {string} [resource.middle] - 中等尺寸图片URL\n * @property {string} [resource.videoId] - 视频ID\n */\nexport interface Resource {\n resourceType: 1 | 2\n resource: {\n url?: string\n middle?: string\n videoId?: string\n [key: string]: any\n }\n}\n\n@safeCustomElement('qxs-subject-single')\nexport class QxsSubjectSingle extends LitElement {\n static styles = [sortingCardStyles, css`\n :host { display: block; font-family: system-ui, -apple-system, \"PingFang SC\", \"Microsoft YaHei\", sans-serif; font-size: 12px; color: #5a5a5a; }\n *, ::before, ::after { box-sizing: border-box; }\n\n .preview { padding: 12px 0; }\n .preview .title { font-size: 14px; color: #303133; }\n .preview .title .key-badge {\n display: inline-block;\n margin-left: 8px;\n padding: 1px 6px;\n font-size: 11px;\n color: #fff;\n background: #f56c6c;\n border-radius: 3px;\n vertical-align: middle;\n }\n .preview .rich-text { margin-top: 8px; }\n .preview .rich-text img { max-width: 100%; }\n .preview .rich-text img[data-align=\"left\"] { display: block !important; margin: 0 auto 0 0 !important; }\n .preview .rich-text img[data-align=\"center\"] { display: block !important; margin: 0 auto !important; }\n .preview .rich-text img[data-align=\"right\"] { display: block !important; margin: 0 0 0 auto !important; }\n .preview-answer { display: flex; flex-direction: column; margin-top: 12px; }\n .preview-answer .radio { margin-top: 8px; padding-left: 8px; display: flex; align-items: center; gap: 6px; }\n .preview-answer .order { color: #909399; }\n .preview-answer .correct { color: #67c23a; }\n .preview-answer .result-info { color: #909399; }\n\n .flex { display: flex; }\n .flex-items-center { display: flex; align-items: center; }\n .flex-items-start { display: flex; align-items: flex-start; }\n .flex-justify-end { display: flex; justify-content: flex-end; }\n .label { min-width: 60px; font-size: 13px; color: #606266; }\n\n textarea {\n border: 1px solid #dcdfe6; border-radius: 3px; padding: 5px 11px;\n font-size: 13px; font-family: inherit; width: 100%; resize: none; transition: border-color .2s;\n line-height: 1.5; display: block; box-sizing: border-box;\n }\n textarea:focus { border-color: #3D61E3; outline: none; }\n textarea:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .el-input { position: relative; display: block; }\n .el-input textarea { padding-bottom: 24px; }\n .el-input .char-counter {\n position: absolute; right: 12px; bottom: 8px;\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-list { margin-top: 12px; }\n .answer-item { display: flex; align-items: center; margin-top: 6px; border-radius: 4px; }\n .answer-item .label { min-width: 60px; font-size: 13px; color: #909399; }\n .answer-item .input { flex: 1; max-width: 360px; position: relative; display: block; }\n .answer-item .input input {\n height: 32px; padding: 0 50px 0 8px;\n font-size: 13px; line-height: 32px;\n border: 1px solid #dcdfe6; border-radius: 3px; width: 100%;\n transition: border-color .2s; box-sizing: border-box;\n }\n .answer-item .input input:focus { border-color: #3D61E3; outline: none; }\n .answer-item .input input:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n .answer-item .input .char-counter {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n font-size: 12px; color: #909399; line-height: 1; pointer-events: none;\n }\n\n .answer-item .correct { margin: 0 10px; color: #909399; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }\n .answer-item .correct:hover { color: #3D61E3; }\n .answer-item .correct.is-correct { color: #67c23a; }\n .answer-item .correct input { width: 14px; height: 14px; cursor: pointer; accent-color: #3D61E3; }\n\n .answer-item .icon {\n margin-left: 6px; cursor: pointer; display: inline-flex;\n align-items: center; justify-content: center;\n width: 24px; height: 24px; border-radius: 4px;\n border: 1px solid #dcdfe6; background: #fff; color: #909399;\n transition: all 0.2s;\n }\n .answer-item .icon:hover { color: #3D61E3; border-color: #3D61E3; background: #ecf5ff; }\n .answer-item .icon.disabled { color: #e4e7ed; border-color: #e4e7ed; cursor: not-allowed; }\n\n .answer-item .link { margin-left: 8px; color: #3D61E3; cursor: pointer; font-size: 12px; white-space: nowrap; }\n .answer-item .link:hover { color: #2D4CB8; }\n\n .el-select {\n width: 150px; height: 32px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 8px; font-size: 13px; background: #fff; appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23c0c4cc' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 8px center;\n }\n .el-select:focus { border-color: #3D61E3; outline: none; }\n .el-select:disabled { background: #f5f7fa; color: #c0c4cc; cursor: not-allowed; }\n\n .sort-badge { font-weight: bold; color: #3D61E3; margin-left: 10px; }\n\n .el-link { color: #3D61E3; cursor: pointer; font-size: 12px; background: none; border: none; padding: 0; margin: 0; font-family: inherit; }\n .el-link:hover { color: #2D4CB8; }\n .el-link.danger { color: #f56c6c; }\n\n .section-row { margin-top: 12px; }\n .value-text { font-size: 13px; color: #606266; white-space: pre-wrap; }\n .muted-text { font-size: 12px; color: #909399; }\n\n .search-wrap { position: relative; }\n .search-dropdown {\n position: absolute; z-index: 120; left: 0; right: 0; top: calc(100% + 4px);\n background: #fff; border: 1px solid #e4e7ed; border-radius: 6px;\n box-shadow: 0 8px 20px rgba(0,0,0,.12); overflow: hidden;\n }\n .search-item {\n padding: 10px 12px; cursor: pointer; transition: background .2s;\n font-size: 13px; color: #606266; line-height: 1.4;\n }\n .search-item:hover { background: #f5f7fa; color: #3D61E3; }\n .search-empty { padding: 10px 12px; font-size: 12px; color: #909399; }\n\n .tag-list { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-height: 32px; }\n .tag-item {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 4px 8px; font-size: 12px; line-height: 1;\n color: #3D61E3; background: #ecf5ff; border: 1px solid #d9ecff; border-radius: 4px;\n }\n .tag-item .close { cursor: pointer; color: #909399; }\n .tag-item .close:hover { color: #f56c6c; }\n .tag-hint { font-size: 12px; color: #909399; }\n\n .resource-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }\n .resource-summary { font-size: 12px; color: #606266; }\n .resource-thumbs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }\n .resource-thumb {\n width: 72px; height: 72px; object-fit: cover; border-radius: 6px;\n border: 1px solid #e4e7ed; cursor: pointer; background: #f5f7fa;\n }\n .resource-video {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 88px; height: 30px; padding: 0 10px; border: 1px solid #dcdfe6; border-radius: 4px;\n color: #606266; background: #fff; cursor: pointer; font-size: 12px; transition: all .2s;\n }\n .resource-video:hover { color: #3D61E3; border-color: #3D61E3; background: #ecf5ff; }\n .media-stage { display: flex; align-items: center; justify-content: center; min-height: 240px; }\n .media-stage img, .media-stage video { max-width: 100%; max-height: 60vh; border-radius: 6px; }\n .media-footer { display: flex; justify-content: space-between; align-items: center; gap: 8px; width: 100%; }\n .media-footer .group { display: flex; gap: 8px; }\n\n /* Multi-select with tags (Element Plus style) */\n .multi-select-wrapper { position: relative; }\n .multi-select {\n width: 240px; height: 28px; border: 1px solid #dcdfe6; border-radius: 3px;\n padding: 0 30px 0 8px; font-size: 13px; background: #fff; cursor: pointer;\n display: flex; flex-wrap: nowrap; align-items: center; gap: 4px;\n transition: border-color .2s; position: relative; overflow: hidden;\n }\n .multi-select:hover { border-color: #c0c4cc; }\n .multi-select.focused { border-color: #3D61E3; }\n .multi-select.disabled { background: #f5f7fa; cursor: not-allowed; }\n .multi-select .placeholder { color: #c0c4cc; font-size: 13px; padding: 4px 0; }\n .multi-select .arrow {\n position: absolute; right: 8px; top: 50%; transform: translateY(-50%);\n color: #c0c4cc; display: inline-flex; transition: transform .2s;\n }\n .multi-select.focused .arrow { transform: translateY(-50%) rotate(180deg); color: #3D61E3; }\n .multi-select .tag {\n display: inline-flex; align-items: center; gap: 2px;\n background: #f0f2f5; border-radius: 3px; padding: 0 6px; height: 20px;\n font-size: 12px; color: #606266; line-height: 20px;\n }\n .multi-select .tag .tag-close {\n display: inline-flex; cursor: pointer; color: #909399; margin-left: 2px; line-height: 1;\n }\n .multi-select .tag .tag-close:hover { color: #3D61E3; }\n .multi-select-dropdown {\n position: absolute; z-index: 100; background: #fff; left: 0; top: 100%; margin-top: 4px;\n border: 1px solid #e4e7ed; border-radius: 3px;\n box-shadow: 0 4px 12px rgba(0,0,0,.12); min-width: 240px; max-height: 140px; overflow-y: auto;\n }\n .multi-select-option {\n padding: 4px 12px; font-size: 13px; color: #606266; cursor: pointer;\n transition: background .2s;\n }\n .multi-select-option:hover { background: #f5f7fa; }\n .multi-select-option.selected { color: #3D61E3; font-weight: 500; }\n\n .modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 9000; display: flex; align-items: center; justify-content: center; }\n .modal { background: #fff; border-radius: 6px; width: 520px; max-width: 90vw; box-shadow: 0 12px 32px rgba(0,0,0,.12); display: flex; flex-direction: column; }\n .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px 12px; border-bottom: 1px solid #e4e7ed; }\n .modal-title { font-size: 14px; font-weight: 600; color: #303133; }\n .modal-close { background: none; border: none; font-size: 18px; cursor: pointer; color: #909399; padding: 0; line-height: 1; }\n .modal-close:hover { color: #3D61E3; }\n .modal-body { padding: 20px; }\n .modal-body textarea { min-height: 120px; }\n .modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid #e4e7ed; }\n .modal-footer button { padding: 6px 16px; font-size: 12px; border-radius: 3px; cursor: pointer; border: 1px solid #dcdfe6; background: #fff; color: #606266; }\n .modal-footer button:hover { color: #3D61E3; border-color: #a0cfff; }\n .modal-footer button.primary { background: #3D61E3; border-color: #3D61E3; color: #fff; }\n .modal-footer button.primary:hover { background: #2D4CB8; border-color: #2D4CB8; }\n .correct-hint-dialog { width: 520px; max-width: min(90vw, 520px); }\n .correct-hint-dialog .modal-header { padding: 18px 20px 14px; }\n .correct-hint-dialog .modal-title { font-size: 16px; font-weight: 700; color: #303133; }\n .correct-hint-dialog .modal-close { display: none; }\n .correct-hint-dialog .modal-body {\n padding: 32px 28px 20px;\n font-size: 14px;\n line-height: 1.8;\n color: #303133;\n text-align: center;\n }\n .correct-hint-copy { max-width: 420px; margin: 0 auto; }\n .correct-hint-highlight { color: #4c6fff; }\n .correct-hint-dialog .modal-footer {\n justify-content: center;\n gap: 12px;\n padding: 0 28px 28px;\n border-top: none;\n }\n .correct-hint-dialog .modal-footer button {\n min-width: 120px;\n height: 36px;\n padding: 0 18px;\n font-size: 14px;\n border-radius: 4px;\n }\n `]\n\n @property({ type: Number, attribute: 'order-index' }) 'order-index' = 0\n @property({ type: String, attribute: 'subject-prefix' }) 'subject-prefix'?: string\n @property({ type: Boolean, attribute: 'is-edit' }) 'is-edit' = false\n @property({ type: Boolean, attribute: 'is-save' }) 'is-save' = false\n @property({ type: Boolean, attribute: 'is-set' }) 'is-set' = false\n @property({ type: Boolean, attribute: 'is-set-correct-answer' }) 'is-set-correct-answer' = false\n @property({ type: Boolean, attribute: 'lock-answer-key' }) lockAnswerKey = false\n @property({ type: Boolean, attribute: 'is-key' }) 'is-key' = false\n @property({ type: Boolean, attribute: 'show-action' }) 'show-action' = true\n @property({ type: Boolean, attribute: 'show-add' }) 'show-add' = true\n @property({ type: Boolean, attribute: 'hide-add-rich-text' }) 'hide-add-rich-text' = false\n @property({ type: Boolean, attribute: 'show-rich-text' }) 'show-rich-text' = false\n @property({ type: Boolean, attribute: 'show-delete-action' }) 'show-delete-action' = true\n @property({ type: Boolean, attribute: 'show-save-action' }) 'show-save-action' = true\n @property({ type: Boolean, reflect: true }) sorting = false\n @property({ type: Boolean, attribute: 'show-answer-setting' }) 'show-answer-setting' = false\n @property({ type: Boolean, attribute: 'show-key' }) 'show-key' = false\n @property({ type: Boolean, attribute: 'show-analysis' }) 'show-analysis' = false\n @property({ attribute: 'question-type', reflect: true }) type: AnswerType = 'single'\n @property({ type: Number, attribute: 'answer-check-type' }) 'answer-check-type' = 1\n @property({ type: Number, attribute: 'exam-answer-relation-type' }) 'exam-answer-relation-type' = 0\n @property({ type: String, attribute: 'rich-text-content' }) 'rich-text-content' = ''\n @property({ type: String }) analysis = ''\n @property({ type: Number, attribute: 'least-answer-count' }) 'least-answer-count': number | null = null\n @property({ type: String, attribute: 'exam-expand' }) 'exam-expand' = ''\n @property({ type: String, attribute: 'custom-id' }) 'custom-id' = ''\n @property({ type: Number, attribute: 'exam-id' }) 'exam-id' = 0\n @property({ type: String, attribute: 'category-id' }) 'category-id' = ''\n @property({ type: Object, attribute: 'upload-image' }) 'upload-image': (file: File) => Promise<string> = async (file: File) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = e => resolve(e.target?.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n @property({ type: Array, attribute: 'answer-list' })\n get 'answer-list'() { return this._answers }\n\n set 'answer-list'(v: any) {\n // 编辑模式下不接受外部更新,避免覆盖用户正在编辑的内容\n if (this['is-edit']) {\n return\n }\n const arr = Array.isArray(v) ? v : []\n this._answers = arr.length\n ? arr.map((a: any) => this._normalizeAnswerItem(a))\n : [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n this.requestUpdate('answer-list')\n }\n\n // ============ 业务接口 Props ============\n /**\n * 标签列表 - 用于关联题目的标签信息\n * @type {TagItem[]}\n * @description 业务系统传入已选择的标签列表\n */\n @property({ type: Array, attribute: 'tag-list' }) 'tag-list': TagItem[] = []\n /**\n * 分类列表 - 可用于题目的分类选项\n * @type {Category[]}\n * @description 业务系统传入可选的分类列表\n */\n @property({ type: Array, attribute: 'category-list' }) 'category-list': Category[] = []\n /**\n * AI 推荐答案 - AI 根据题目内容推荐的答案\n * @type {string}\n * @description AI 返回的推荐答案,格式如 \"1. 选项A\\n2. 选项B\"\n */\n @property({ type: String, attribute: 'ai-answer' }) 'ai-answer' = ''\n /**\n * 图片/视频资源列表 - 题目附带的媒体资源\n * @type {Resource[]}\n * @description 题目附带图片或视频资源\n */\n @property({ type: Array, attribute: 'resource-list' }) 'resource-list': Resource[] = []\n /**\n * 是否显示标签功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示标签选择 UI\n */\n @property({ type: Boolean, attribute: 'show-tag' }) 'show-tag' = false\n /**\n * 是否显示分类功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示分类选择 UI\n */\n @property({ type: Boolean, attribute: 'show-category' }) 'show-category' = false\n /**\n * 是否显示 AI 推荐功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示 AI 推荐答案 UI\n */\n @property({ type: Boolean, attribute: 'show-ai' }) 'show-ai' = false\n /**\n * 是否显示资源功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示图片/视频资源 UI\n */\n @property({ type: Boolean, attribute: 'show-resource' }) 'show-resource' = false\n /**\n * 是否显示跳题功能\n * @type {boolean}\n * @default false\n * @description 业务功能开关,控制是否显示跳题逻辑设置入口\n */\n @property({ type: Boolean, attribute: 'show-jump' }) 'show-jump' = false\n /**\n * 跳题状态 - 是否已设置跳题逻辑\n * @type {boolean}\n * @default false\n * @description 标记当前题目是否已设置跳题逻辑\n */\n @property({ type: Boolean, attribute: 'has-jump' }) 'has-jump' = false\n /**\n * 题库搜索接口地址\n * @type {string}\n * @description 题库模糊搜索接口地址,用于题库搜索功能\n */\n @property({ type: String, attribute: 'search-api' }) 'search-api' = ''\n /**\n * 题库搜索回调函数\n * @type {Function}\n * @param {string} query - 搜索关键词\n * @param {number} answerType - 题目类型:0-单选, 1-多选\n * @returns {Promise<SearchResult[]>} 搜索结果列表\n * @description 题库搜索的回调函数,由业务系统实现搜索逻辑\n */\n @property({ type: Object, attribute: 'search-handler' }) 'search-handler'?: (query: string, answerType: number) => Promise<SearchResult[]>\n\n // 双向绑定支持\n @property({ type: String, attribute: 'model-value' }) 'model-value' = ''\n @property({ type: Boolean, attribute: 'use-model' }) 'use-model' = false\n\n @state() private _answers: Answer[] = [\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n { title: '', isCorrect: false }, { title: '', isCorrect: false },\n ]\n\n @property({ type: String }) title = ''\n\n @state() private _title = ''\n @state() private _analysis = ''\n @state() private _richText = ''\n @state() private _showRichText = false\n @state() private _leastAnswerCount: number | null = null\n @state() private _answerCheckType = 1\n @state() private _isKey = false\n @state() private _orderList: string[] = []\n @state() private _selectedTagList: TagItem[] = []\n @state() private _categoryId = ''\n @state() private _searchResults: SearchResult[] = []\n @state() private _searchOpen = false\n @state() private _searchLoading = false\n @state() private _sortDropdownOpen = false\n @state() private _imageViewerOpen = false\n @state() private _imageViewerIndex = 0\n @state() private _videoViewerOpen = false\n @state() private _correctHintDialogOpen = false\n @state() private _hasShownCorrectHint = false\n @state() private _changeTypeDialogOpen = false\n\n private _searchTimer: number | null = null\n private _searchToken = 0\n\n private readonly TITLE_MAX = 200\n private readonly ANSWER_MAX = 100\n\n connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._handleDocumentClick)\n this._syncExternalProps()\n }\n\n firstUpdated() {\n this._syncExternalProps()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._handleDocumentClick)\n if (this._searchTimer) {\n window.clearTimeout(this._searchTimer)\n this._searchTimer = null\n }\n }\n\n private _handleDocumentClick = (e: MouseEvent) => {\n const path = e.composedPath()\n const wrapper = this.shadowRoot?.querySelector('.multi-select-wrapper')\n const searchWrap = this.shadowRoot?.querySelector('.search-wrap')\n if (wrapper && !path.includes(wrapper)) {\n this._sortDropdownOpen = false\n }\n if (searchWrap && !path.includes(searchWrap)) {\n this._searchOpen = false\n }\n this.requestUpdate()\n }\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('is-edit') && this['is-edit']) { this._syncProps() }\n if (!this['is-edit'] && (changed.has('title') || changed.has('answer-list') || changed.has('analysis') || changed.has('least-answer-count') || changed.has('answer-check-type') || changed.has('tag-list') || changed.has('category-id') || changed.has('rich-text-content'))) {\n this._syncExternalProps()\n }\n if (changed.has('is-key')) {\n this._isKey = this['is-key']\n }\n if (changed.has('tag-list')) {\n this._selectedTagList = Array.isArray(this['tag-list']) ? this['tag-list'].map(item => ({ ...item })) : []\n }\n if (changed.has('category-id')) {\n this._categoryId = this['category-id'] ? String(this['category-id']) : ''\n }\n if (changed.has('exam-expand') || changed.has('answer-list')) { this._syncExamExpand() }\n if (changed.has('model-value') && this['use-model']) {\n this._title = this['model-value']\n }\n }\n\n private _supportsLeastAnswerCount(answerType: AnswerType = this.type) {\n return answerType === 'multiple' || answerType === 'sort'\n }\n\n private _normalizeLeastAnswerCount(value: unknown, answerType: AnswerType = this.type): number | null {\n if (!this._supportsLeastAnswerCount(answerType) || value === '' || value === null || value === undefined) {\n return null\n }\n const count = Number(value)\n return Number.isFinite(count) && count > 0 ? count : null\n }\n\n private _leastAnswerCountSuffix(value: number | null, answerType: AnswerType = this.type) {\n if (!this._supportsLeastAnswerCount(answerType) || value === null) {\n return ''\n }\n return `,至少选${value}项${answerType === 'sort' ? '并排序' : ''}`\n }\n\n private _normalizeAnswerItem(answer: any): Answer {\n const next: Answer = {\n ...answer,\n title: trimText(answer?.title ?? answer?.answer ?? ''),\n isCorrect: !!answer?.isCorrect,\n }\n const answerId = answer?.answerId ?? answer?.examAnswerId\n if (answerId !== undefined) {\n next.answerId = answerId\n }\n return next\n }\n\n private _syncExternalProps() {\n this._title = this.title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this._normalizeLeastAnswerCount(this['least-answer-count'])\n this._answerCheckType = this['answer-check-type'] || 1\n this._isKey = this['is-key']\n this._selectedTagList = Array.isArray(this['tag-list']) ? this['tag-list'].map(item => ({ ...item })) : []\n this._categoryId = this['category-id'] ? String(this['category-id']) : ''\n this._richText = this['rich-text-content'] || ''\n this._showRichText = !!this['rich-text-content']\n if (this['answer-list']?.length) {\n this._answers = this['answer-list'].map((a: any) => this._normalizeAnswerItem(a))\n }\n }\n\n private _syncProps() {\n this._title = (this as any).title || ''\n this._analysis = this.analysis || ''\n this._leastAnswerCount = this._normalizeLeastAnswerCount(this['least-answer-count'])\n this._answerCheckType = this['answer-check-type'] || 1\n this._isKey = this['is-key']\n this._selectedTagList = Array.isArray(this['tag-list']) ? this['tag-list'].map(item => ({ ...item })) : []\n this._categoryId = this['category-id'] ? String(this['category-id']) : ''\n this._richText = this['rich-text-content'] || ''\n this._showRichText = !!this['rich-text-content']\n if (this['answer-list']?.length) {\n this._answers = this['answer-list'].map((a: any) => this._normalizeAnswerItem(a))\n }\n this._syncExamExpand()\n }\n\n private _syncExamExpand() {\n if (!this['exam-expand'] || !this['answer-list']?.length) { return }\n const ids = this['exam-expand'].split(',')\n const answers = this['answer-list'] as any[]\n this._orderList = ids.map((id) => {\n const index = answers.findIndex((answer, answerIndex) =>\n String(answer.answerId ?? answer.orderIndex ?? (answerIndex + 1)) === String(id),\n )\n return index >= 0 ? this._label(index) : ''\n }).filter(Boolean)\n }\n\n private _emit(name: string, detail?: unknown) {\n this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail: detail ?? null }))\n }\n\n private _searchAnswerType() {\n if (this.type === 'single') { return 0 }\n if (this.type === 'multiple') { return 1 }\n return 5\n }\n\n private _queueSearch(query: string) {\n if (this._searchTimer) {\n window.clearTimeout(this._searchTimer)\n this._searchTimer = null\n }\n const keyword = query.trim()\n if (!keyword || (!this['search-api'] && typeof this['search-handler'] !== 'function')) {\n this._searchResults = []\n this._searchOpen = false\n this._searchLoading = false\n return\n }\n this._searchTimer = window.setTimeout(() => {\n void this._runSearch(keyword)\n }, 300)\n }\n\n private async _runSearch(query: string) {\n const currentToken = ++this._searchToken\n this._searchLoading = true\n this._searchOpen = true\n this.requestUpdate()\n try {\n let result: SearchResult[] = []\n if (typeof this['search-handler'] === 'function') {\n result = await this['search-handler'](query, this._searchAnswerType())\n }\n else if (this['search-api']) {\n const params = new URLSearchParams({\n searchKey: query,\n answerType: String(this._searchAnswerType()),\n })\n const response = await fetch(`${this['search-api']}${this['search-api'].includes('?') ? '&' : '?'}${params.toString()}`)\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`)\n }\n const payload = await response.json()\n const list = Array.isArray(payload) ? payload : Array.isArray(payload?.data) ? payload.data : []\n result = list.map((item: any) => ({\n ...item,\n value: item?.value || item?.title || '',\n }))\n }\n if (currentToken !== this._searchToken) { return }\n this._searchResults = Array.isArray(result) ? result : []\n }\n catch (error: any) {\n if (currentToken !== this._searchToken) { return }\n this._searchResults = []\n showToast(error?.message || '题库搜索失败')\n }\n finally {\n if (currentToken === this._searchToken) {\n this._searchLoading = false\n this.requestUpdate()\n }\n }\n }\n\n private _selectSearchResult(item: SearchResult) {\n const selectedTitle = item.value || item.title || ''\n this._title = selectedTitle\n this._searchResults = []\n this._searchOpen = false\n if (this['use-model']) {\n this.dispatchEvent(new CustomEvent('update:modelValue', {\n bubbles: true,\n composed: true,\n detail: this._title,\n }))\n }\n this._emit('title-select', {\n ...item,\n id: item.id ?? item.examId ?? item.questionId,\n title: item.title || selectedTitle,\n value: selectedTitle,\n customId: this['custom-id'] || '',\n })\n }\n\n private _applyAiAnswer() {\n if (!this['ai-answer']?.trim()) {\n showToast('暂无 AI 推荐答案')\n return\n }\n const aiTitles = this['ai-answer']\n .split(/\\r?\\n/)\n .map(line => normalizeTitle(line))\n .filter(Boolean)\n let matched = 0\n if (this.type === 'single') {\n let selected = false\n this._answers = this._answers.map((answer) => {\n const shouldSelect = !selected && aiTitles.includes(normalizeTitle(answer.title || ''))\n if (shouldSelect) {\n selected = true\n matched++\n }\n return { ...answer, isCorrect: shouldSelect }\n })\n }\n else {\n this._answers = this._answers.map((answer) => {\n const shouldSelect = aiTitles.includes(normalizeTitle(answer.title || ''))\n if (shouldSelect) { matched++ }\n return { ...answer, isCorrect: shouldSelect }\n })\n }\n if (!matched) {\n showToast('未找到匹配的选项,请检查选项内容是否一致')\n return\n }\n this.requestUpdate()\n }\n\n private _onCategoryChange(value: string) {\n this._categoryId = value\n this._emit('category-change', {\n value,\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n })\n }\n\n private _setRelation(item: Answer, answerIndex: number) {\n const answer = item.customAnswerId\n ? { ...item }\n : { ...item, customAnswerId: item.answerId || uid() }\n this._answers = this._answers.map((current, index) => index === answerIndex ? answer : current)\n this.requestUpdate()\n this._emit('set-relation', {\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n answerIndex,\n answer,\n })\n }\n\n private _relationLength(relations: any[] = []) {\n return relations.reduce((count, item) => count + (Array.isArray(item?.relationAnswers) ? item.relationAnswers.length : 0), 0)\n }\n\n private _emitEditResultItem(item: Answer, answerIndex: number) {\n this._emit('edit-result-item', {\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n answerIndex,\n answer: { ...item },\n resultItem: item.resultItem || '',\n })\n }\n\n private _resultSlotName(index: number) {\n return `business-result-item-${index}`\n }\n\n private _imageResources() {\n return (this['resource-list'] || [])\n .filter(item => item.resourceType === 1)\n .map(item => item.resource.middle || item.resource.url)\n .filter(Boolean) as string[]\n }\n\n private _videoResource() {\n return (this['resource-list'] || []).find(item => item.resourceType === 2)?.resource || null\n }\n\n private _openImageViewer(index = 0) {\n if (!this._imageResources().length) { return }\n this._imageViewerIndex = index\n this._imageViewerOpen = true\n }\n\n private _closeImageViewer() {\n this._imageViewerOpen = false\n }\n\n private _moveImage(step: number) {\n const images = this._imageResources()\n if (!images.length) { return }\n this._imageViewerIndex = (this._imageViewerIndex + step + images.length) % images.length\n }\n\n private _openVideoViewer() {\n if (!this._videoResource()?.url) { return }\n this._videoViewerOpen = true\n }\n\n private _closeVideoViewer() {\n this._videoViewerOpen = false\n }\n\n private _label(i: number) { return String.fromCharCode(65 + i) }\n\n private get _titlePlaceholder() {\n return this.type === 'single' ? '单选题' : this.type === 'multiple' ? '多选题' : '排序题'\n }\n\n private _setCorrect(item: Answer, val: boolean) {\n if (this.lockAnswerKey) { return }\n item.isCorrect = val\n this.requestUpdate()\n }\n\n private _onTitleInput(e: Event) {\n const el = e.target as HTMLTextAreaElement\n if (el.value.length > this.TITLE_MAX) { el.value = el.value.slice(0, this.TITLE_MAX) }\n this._title = el.value\n this._queueSearch(this._title)\n // 双向绑定:通知外部更新\n if (this['use-model']) {\n this.dispatchEvent(new CustomEvent('update:modelValue', {\n bubbles: true,\n composed: true,\n detail: this._title,\n }))\n }\n }\n\n private _onAnswerInput(e: Event, idx: number) {\n const el = e.target as HTMLInputElement\n if (el.value.length > this.ANSWER_MAX) { el.value = el.value.slice(0, this.ANSWER_MAX) }\n this._answers[idx].title = el.value\n this.requestUpdate()\n }\n\n private _addAnswer(index: number) {\n const arr = [...this._answers]\n arr.splice(index + 1, 0, { title: '', isCorrect: false, customAnswerId: uid() })\n this._answers = arr\n }\n\n private _deleteAnswer(index: number) {\n if (this._answers.length < 3) { return }\n this._answers = this._answers.filter((_, i) => i !== index)\n }\n\n private _toggleSortItem(letter: string) {\n const idx = this._orderList.indexOf(letter)\n if (idx >= 0) {\n this._orderList = this._orderList.filter(l => l !== letter)\n }\n else {\n this._orderList = [...this._orderList, letter]\n }\n this.requestUpdate()\n }\n\n private _removeSortItem(letter: string) {\n this._orderList = this._orderList.filter(l => l !== letter)\n this.requestUpdate()\n }\n\n private _getSortOrder(index: number): number | null {\n const pos = this._orderList.indexOf(this._label(index))\n return pos >= 0 ? pos + 1 : null\n }\n\n private _sortAnswerValue(letter: string) {\n const index = letter.charCodeAt(0) - 65\n const answer = this._answers[index] as any\n return answer?.answerId ?? index + 1\n }\n\n private _rowMeta() {\n return {\n customId: this['custom-id'] || undefined,\n answerType: this.type,\n orderIndex: this['order-index'],\n }\n }\n\n private _collectSnapshot(): SubjectSnapshot {\n const answers = (this['is-edit'] ? this._answers : this['answer-list'] || []).map((answer: any) => ({\n ...answer,\n title: trimText(answer?.title ?? answer?.answer ?? ''),\n isCorrect: !!answer?.isCorrect,\n resultItem: trimText(answer?.resultItem ?? ''),\n }))\n const orderList = this['is-edit']\n ? [...this._orderList]\n : (() => {\n const expand = this['exam-expand']\n if (!expand) { return [] }\n return expand.split(',').map((id: string) => {\n const index = (this['answer-list'] as any[])?.findIndex((answer, answerIndex) =>\n String(answer.answerId ?? answer.orderIndex ?? (answerIndex + 1)) === String(id),\n )\n return index >= 0 ? this._label(index) : ''\n }).filter(Boolean)\n })()\n return {\n title: trimText(this['is-edit'] ? this._title : (this as any).title || ''),\n answers,\n analysis: trimText(this['is-edit'] ? this._analysis : this.analysis || ''),\n leastAnswerCount: this['is-edit']\n ? this._leastAnswerCount\n : this._normalizeLeastAnswerCount(this['least-answer-count']),\n selectedTagList: Array.isArray(this._selectedTagList) ? [...this._selectedTagList] : [],\n examExpand: this['is-edit']\n ? orderList.map((letter: string) => this._sortAnswerValue(letter)).join(',')\n : (this['exam-expand'] || ''),\n showRichText: this['is-edit'] ? this._showRichText : !!this['rich-text-content'],\n richText: this['is-edit'] ? this._richText : this['rich-text-content'] || '',\n orderList,\n }\n }\n\n private _validateSnapshot(snapshot: SubjectSnapshot, answerType: AnswerType = this.type) {\n const row = this._rowMeta()\n const errors: SubjectError[] = []\n\n if (!snapshot.title) {\n errors.push(new SubjectError('题目标题不能为空!', 'EMPTY_TITLE', 'title', row))\n }\n let isSetCorrectAnswer = false\n let correctAnswerCount = 0\n\n snapshot.answers.forEach((answer, index) => {\n if (!answer.title?.trim()) {\n errors.push(new SubjectError(`选项${String.fromCharCode(65 + index)}未填写`, 'ANSWER_EMPTY', 'answers', row))\n }\n if (answerType !== 'sort' && answer.isCorrect) {\n isSetCorrectAnswer = true\n correctAnswerCount++\n }\n })\n\n const titleSet = new Set(snapshot.answers.map(answer => answer.title))\n if (titleSet.size !== snapshot.answers.length && snapshot.answers.length > 0) {\n errors.push(new SubjectError('选项不能重复', 'DUPLICATE_ANSWERS', 'answers', row))\n }\n\n if (answerType === 'single' && correctAnswerCount > 1) {\n errors.push(new SubjectError(\n '此题为单选题,设置了多个推荐/正确选项,请保存时确认是否切换为多选题',\n 'SINGLE_MULTI_CORRECT',\n 'answers',\n row,\n ))\n }\n\n if (answerType === 'multiple') {\n if (correctAnswerCount === 1) {\n errors.push(new SubjectError('请设置至少两个推荐/正确选项', 'CORRECT_COUNT_INVALID', 'answers', row))\n }\n if (correctAnswerCount > 0) {\n isSetCorrectAnswer = true\n }\n if (isSetCorrectAnswer && snapshot.leastAnswerCount !== null && correctAnswerCount < snapshot.leastAnswerCount) {\n errors.push(new SubjectError('至少选几项与推荐/正确选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'answers', row))\n }\n }\n\n if (answerType === 'sort') {\n isSetCorrectAnswer = snapshot.orderList.length > 0\n if (snapshot.leastAnswerCount !== null && snapshot.orderList.length < snapshot.leastAnswerCount) {\n errors.push(new SubjectError('至少选几项与推荐/正确选项数不符', 'LEAST_ANSWER_COUNT_INVALID', 'orderList', row))\n }\n }\n\n return {\n errors,\n isSetCorrectAnswer,\n correctAnswerCount,\n }\n }\n\n private _serialize(answerType: AnswerType = this.type) {\n const snapshot = this._collectSnapshot()\n const { errors, isSetCorrectAnswer } = this._validateSnapshot(snapshot, answerType)\n if (errors.length) {\n throw errors[0]\n }\n const result: any = {\n answerType: String(answerType),\n examTypeEnum: String(answerType),\n title: snapshot.title,\n answers: snapshot.answers.map((answer, index) => {\n const relationType = answer.resultItem\n ? 1\n : (Array.isArray(answer.answerRelations) && answer.answerRelations.length ? 2 : null)\n const next: any = { ...answer, orderIndex: index + 1, answer: answer.title, relationType }\n if (answer.answerId !== undefined) {\n next.examAnswerId = answer.answerId\n }\n if (relationType === null) {\n delete next.relationType\n }\n return next\n }),\n examExpand: snapshot.examExpand,\n analysis: snapshot.analysis,\n isSetCorrectAnswer,\n examRichTextContent: snapshot.showRichText ? snapshot.richText : '',\n }\n if (this['exam-answer-relation-type']) {\n result.examAnswerRelationType = this['exam-answer-relation-type']\n }\n if (this._supportsLeastAnswerCount(answerType)) {\n result.leastAnswerCount = snapshot.leastAnswerCount\n }\n if (this['custom-id']) { result.customId = this['custom-id'] }\n return result\n }\n\n private _shouldShowCorrectHint() {\n if (this.type === 'sort') {\n return !this._orderList.length\n }\n return !this._answers.some(answer => !!answer.isCorrect)\n }\n\n private async _finalizeSave() {\n try {\n const data = await this.toJSON()\n this._emit('save', data)\n }\n catch (err: any) {\n showToast(err.message)\n }\n }\n\n async toJSON(): Promise<any> {\n return Promise.resolve(this._serialize())\n }\n\n validate(): SubjectError[] {\n return this._validateSnapshot(this._collectSnapshot()).errors\n }\n\n setResultItem(answerIndex: number, resultItem: string) {\n if (answerIndex < 0 || answerIndex >= this._answers.length) {\n return\n }\n this._answers = this._answers.map((answer, index) => index === answerIndex\n ? { ...answer, resultItem: resultItem || '' }\n : answer)\n this.requestUpdate()\n }\n\n setAnswerRelation(customAnswerId: string, answerRelations: any) {\n if (!customAnswerId) {\n return\n }\n this._answers = this._answers.map((answer) => {\n const currentId = String(answer.customAnswerId ?? answer.answerId ?? '')\n return currentId === String(customAnswerId)\n ? { ...answer, answerRelations }\n : answer\n })\n this.requestUpdate()\n }\n\n private _renderCorrectHintDialog() {\n if (!this._correctHintDialogOpen) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => { this._correctHintDialogOpen = false }}>\n <div class=\"modal correct-hint-dialog\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">温馨提示</span>\n </div>\n <div class=\"modal-body\">\n <div class=\"correct-hint-copy\">\n 为了收集更全面、有价值的数据,建议您为问卷每题设定<span class=\"correct-hint-highlight\">推荐/正确选项</span>。这将助力深入分析,让调研结果更精准、有意义。\n </div>\n </div>\n <div class=\"modal-footer\">\n <button @click=${async () => {\n this._hasShownCorrectHint = true\n this._correctHintDialogOpen = false\n await this._finalizeSave()\n }}>完成编辑</button>\n <button class=\"primary\" @click=${() => { this._correctHintDialogOpen = false }}>去设置</button>\n </div>\n </div>\n </div>\n `\n }\n\n private _renderChangeTypeDialog() {\n if (!this._changeTypeDialogOpen) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => { this._changeTypeDialogOpen = false }}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">提示</span>\n <button class=\"modal-close\" @click=${() => { this._changeTypeDialogOpen = false }}>&#x2715;</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"value-text\">此题为单选题,设置了多个推荐/正确选项,是否切换成多选题?</div>\n </div>\n <div class=\"modal-footer\">\n <button @click=${() => { this._changeTypeDialogOpen = false }}>取消</button>\n <button class=\"primary\" @click=${() => {\n try {\n const data = this._serialize('multiple')\n this._changeTypeDialogOpen = false\n this._emit('save', data)\n }\n catch (error: any) {\n showToast(error?.message || '保存失败')\n }\n }}>切换</button>\n </div>\n </div>\n </div>\n `\n }\n\n private _renderSearchDropdown() {\n if (!this['is-edit'] || (!this._searchOpen && !this._searchLoading)) { return '' }\n return html`\n <div class=\"search-dropdown\">\n ${this._searchLoading\n ? html`<div class=\"search-empty\">搜索中...</div>`\n : this._searchResults.length\n ? this._searchResults.map(item => html`\n <div class=\"search-item\" @click=${() => this._selectSearchResult(item)}>${item.value || item.title}</div>\n `)\n : html`<div class=\"search-empty\">暂无匹配题目</div>`}\n </div>\n `\n }\n\n private _renderCategorySection() {\n if (!this['show-category']) { return '' }\n return html`\n <div class=\"flex-items-start section-row\">\n <div class=\"label\"><span>分类:</span></div>\n <div style=\"flex:1\">\n ${this['is-edit']\n ? html`\n <select class=\"el-select\" .value=${String(this._categoryId)}\n @change=${(e: Event) => this._onCategoryChange((e.target as HTMLSelectElement).value)}>\n <option value=\"\">选择分类</option>\n ${this['category-list'].map(item => html`\n <option value=${String(item.categoryId)} ?selected=${String(item.categoryId) === String(this._categoryId)}>${item.title}</option>\n `)}\n </select>\n `\n : html`<span class=\"value-text\">${this['category-list'].find(item => String(item.categoryId) === String(this._categoryId))?.title || '未选择分类'}</span>`}\n </div>\n </div>\n `\n }\n\n private _renderAiSection() {\n if (!this['show-ai'] || !['single', 'multiple'].includes(this.type)) { return '' }\n return html`\n <div class=\"flex-items-start section-row\">\n <div class=\"label\"><span>AI推荐:</span></div>\n <div style=\"flex:1\">\n <span class=\"value-text\">${this['ai-answer'] || '暂无'}</span>\n ${this['is-edit']\n ? html`<div style=\"margin-top:8px\"><span class=\"el-link\" @click=${() => this._applyAiAnswer()}>一键勾选</span></div>`\n : ''}\n </div>\n </div>\n `\n }\n\n private _renderResourceSection() {\n if (!this['show-resource']) { return '' }\n const images = this._imageResources()\n const video = this._videoResource()\n return html`\n <div class=\"flex-items-start section-row\">\n <div class=\"label\"><span>资源:</span></div>\n <div style=\"flex:1\">\n <div class=\"resource-summary\">\n 图片 ${images.length} 张${video ? ',含视频资源' : ''}\n </div>\n <div class=\"resource-actions\">\n ${images.length ? html`<span class=\"el-link\" @click=${() => this._openImageViewer(0)}>查看图片</span>` : ''}\n ${video?.url ? html`<span class=\"el-link\" @click=${() => this._openVideoViewer()}>查看视频</span>` : ''}\n ${!images.length && !video?.url ? html`<span class=\"muted-text\">暂无资源</span>` : ''}\n </div>\n ${images.length\n ? html`\n <div class=\"resource-thumbs\">\n ${images.slice(0, 4).map((src, index) => html`\n <img class=\"resource-thumb\" src=${src} alt=\"resource\" @click=${() => this._openImageViewer(index)} />\n `)}\n </div>\n `\n : ''}\n </div>\n </div>\n `\n }\n\n private _renderImageViewer() {\n if (!this._imageViewerOpen) { return '' }\n const images = this._imageResources()\n const current = images[this._imageViewerIndex]\n if (!current) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => this._closeImageViewer()}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">图片预览</span>\n <button class=\"modal-close\" @click=${() => this._closeImageViewer()}>&#x2715;</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"media-stage\"><img src=${current} alt=\"resource-preview\" /></div>\n </div>\n <div class=\"modal-footer\">\n <div class=\"media-footer\">\n <span class=\"muted-text\">${this._imageViewerIndex + 1} / ${images.length}</span>\n <div class=\"group\">\n ${images.length > 1 ? html`<button @click=${() => this._moveImage(-1)}>上一张</button>` : ''}\n ${images.length > 1 ? html`<button @click=${() => this._moveImage(1)}>下一张</button>` : ''}\n <button class=\"primary\" @click=${() => this._closeImageViewer()}>关闭</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n private _renderVideoViewer() {\n const video = this._videoResource()\n if (!this._videoViewerOpen || !video?.url) { return '' }\n return html`\n <div class=\"modal-backdrop\" @click=${() => this._closeVideoViewer()}>\n <div class=\"modal\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal-header\">\n <span class=\"modal-title\">视频预览</span>\n <button class=\"modal-close\" @click=${() => this._closeVideoViewer()}>&#x2715;</button>\n </div>\n <div class=\"modal-body\">\n <div class=\"media-stage\">\n <video src=${video.url} controls playsinline></video>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"primary\" @click=${() => this._closeVideoViewer()}>关闭</button>\n </div>\n </div>\n </div>\n `\n }\n\n private async _save(e?: Event) {\n e?.stopImmediatePropagation()\n const errors = this.validate()\n const convertWarning = errors.find(error => error.code === 'SINGLE_MULTI_CORRECT')\n const blockingErrors = errors.filter(error => error.code !== 'SINGLE_MULTI_CORRECT')\n if (blockingErrors.length) {\n showToast(blockingErrors[0].message)\n return\n }\n if (convertWarning) {\n this._changeTypeDialogOpen = true\n return\n }\n if (!this._hasShownCorrectHint && this._shouldShowCorrectHint()) {\n this._correctHintDialogOpen = true\n return\n }\n await this._finalizeSave()\n }\n\n private _renderPreview() {\n const typeSuffix = this.type === 'single'\n ? '(单选题)'\n : `(${this._titlePlaceholder}${this._leastAnswerCountSuffix(this._normalizeLeastAnswerCount(this['least-answer-count']))})`\n const answers = this['answer-list'] as Answer[]\n const previewTitle = joinSubjectTitle(\n resolveSubjectPrefix(this['subject-prefix'], `${this['order-index'] + 1}.`),\n (this as any).title || '',\n )\n return html`\n <div class=\"preview\">\n <div><span class=\"title\">${previewTitle}${typeSuffix}</span></div>\n ${this['show-rich-text'] && this['rich-text-content'] ? html`<div class=\"rich-text\" .innerHTML=${this['rich-text-content']}></div>` : ''}\n <div class=\"preview-answer\">\n ${answers.map((a, i) => html`\n <label class=\"radio\">\n <input type=\"${this.type === 'sort' ? 'checkbox' : 'radio'}\" .checked=${!!a.isCorrect} disabled />\n <span class=\"order\">${this._label(i)}.</span> ${a.title}\n ${this.type !== 'sort' && a.isCorrect ? html`<span class=\"correct\">(推荐/正确选项)</span>` : ''}\n ${this['exam-answer-relation-type'] === 1 && this.type !== 'sort'\n ? html`<span class=\"correct\">(${a.resultItem ? '已设置结果项' : '未设置结果项'})</span>`\n : ''}\n ${this['exam-answer-relation-type'] === 2 && this.type !== 'sort'\n ? html`<span class=\"correct\">(${Array.isArray(a.answerRelations) && a.answerRelations.length ? `关联了${this._relationLength(a.answerRelations)}项` : '未设置关联'})</span>`\n : ''}\n </label>\n `)}\n </div>\n ${this['show-category'] && this._categoryId\n ? html`<div class=\"section-row\"><span class=\"value-text\">分类:${this['category-list'].find(item => String(item.categoryId) === String(this._categoryId))?.title || this._categoryId}</span></div>`\n : ''}\n ${this['show-resource'] ? this._renderResourceSection() : ''}\n </div>\n `\n }\n\n private _renderSorting() {\n const title = trimText(this['is-edit'] ? this._title : (this as any).title || '') || '未命名题目'\n const orderText = joinSubjectTitle(\n resolveSubjectPrefix(this['subject-prefix'], `${this['order-index'] + 1}. `),\n title,\n )\n return renderSortingCard(orderText, SubjectTypeLabel[this.type] || this.type)\n }\n\n private _renderEdit() {\n return html`\n <div class=\"flex-items-start\">\n <div class=\"label\"><span>题目:</span></div>\n <div style=\"flex:1\">\n <div class=\"el-input search-wrap\">\n <textarea rows=\"2\" .value=${this._title}\n maxlength=${this.TITLE_MAX}\n @input=${(e: Event) => this._onTitleInput(e)}\n placeholder=\"【${this._titlePlaceholder}】请输入问题\"></textarea>\n <span class=\"char-counter\">${this._title.length}/${this.TITLE_MAX}</span>\n ${this._renderSearchDropdown()}\n </div>\n </div>\n </div>\n\n ${['multiple', 'sort'].includes(this.type)\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>设置:</span></div>\n <select class=\"el-select\" .value=${this._leastAnswerCount === null ? '' : String(this._leastAnswerCount)} ?disabled=${this.lockAnswerKey}\n @change=${(e: Event) => {\n const value = (e.target as HTMLSelectElement).value\n this._leastAnswerCount = this._normalizeLeastAnswerCount(value)\n }}>\n <option value=\"\">至少选择几项</option>\n ${Array.from({ length: Math.max(0, this._answers.length - 1) }, (_, i) => i + 2).map(n => html`\n <option value=${n} ?selected=${this._leastAnswerCount === n}>至少选择${n}项</option>\n `)}\n </select>\n </div>\n `\n : ''}\n\n <div class=\"answer-list\">\n ${this._answers.map((a, i) => html`\n <div class=\"answer-item\">\n <span class=\"label\">${this._label(i)}.</span>\n <div class=\"input\">\n <input type=\"text\" .value=${a.title}\n maxlength=${this.ANSWER_MAX}\n @input=${(e: Event) => this._onAnswerInput(e, i)}\n placeholder=\"选项${this._label(i)}\" />\n <span class=\"char-counter\">${a.title.length}/${this.ANSWER_MAX}</span>\n </div>\n\n ${this.type === 'sort' && this._getSortOrder(i) !== null\n ? html`<span class=\"sort-badge\">第${this._getSortOrder(i)}位</span>`\n : ''}\n\n ${['single', 'multiple'].includes(this.type)\n ? html`\n <label class=\"correct ${a.isCorrect ? 'is-correct' : ''}\">\n <input type=\"checkbox\" .checked=${a.isCorrect} ?disabled=${this.lockAnswerKey}\n @change=${(e: Event) => this._setCorrect(a, (e.target as HTMLInputElement).checked)} />\n 推荐/正确选项\n </label>\n `\n : ''}\n\n <span class=\"icon\"\n @click=${() => this._addAnswer(i)}>\n ${iconPlus}\n </span>\n <span class=\"icon ${this._answers.length < 3 ? 'disabled' : ''}\"\n @click=${() => this._deleteAnswer(i)}>\n ${iconRemove}\n </span>\n\n ${this['exam-answer-relation-type'] === 1 && this.type !== 'sort'\n ? html`\n <slot name=${this._resultSlotName(i)}>\n <button class=\"el-link\" @click=${() => this._emitEditResultItem(a, i)}>\n ${a.resultItem ? '编辑结果' : '添加结果'}\n </button>\n </slot>\n `\n : ''}\n\n ${this['exam-answer-relation-type'] === 2 && this.type !== 'sort'\n ? html`\n <button class=\"el-link\" @click=${() => this._setRelation(a, i)}>\n ${Array.isArray(a.answerRelations) && a.answerRelations.length ? `关联了${this._relationLength(a.answerRelations)}项` : '关联检查'}\n </button>\n `\n : ''}\n\n </div>\n `)}\n </div>\n\n ${this.type === 'sort'\n ? html`\n <div class=\"flex-items-center\" style=\"margin-top:12px\">\n <div class=\"label\"><span>排序答案:</span></div>\n <div style=\"flex:1\">\n <div class=\"multi-select-wrapper\">\n <div class=\"multi-select ${this._sortDropdownOpen ? 'focused' : ''} ${this.lockAnswerKey ? 'disabled' : ''}\"\n @click=${() => { if (!this.lockAnswerKey) { this._sortDropdownOpen = !this._sortDropdownOpen; this.requestUpdate() } }}>\n ${this._orderList.length > 0\n ? this._orderList.map(l => html`\n <span class=\"tag\">\n ${l}\n <span class=\"tag-close\" @click=${(e: Event) => {\n if (this.lockAnswerKey) { return }\n e.stopPropagation()\n this._removeSortItem(l)\n }}>&#x2715;</span>\n </span>\n `)\n : html`<span class=\"placeholder\">请按顺序选择排序答案</span>`\n }\n <span class=\"arrow\">${iconArrow}</span>\n </div>\n ${this._sortDropdownOpen\n ? html`\n <div class=\"multi-select-dropdown\">\n ${this._answers.map((_, i) => html`\n <div class=\"multi-select-option ${this._orderList.includes(this._label(i)) ? 'selected' : ''}\"\n @click=${() => {\n if (this.lockAnswerKey) { return }\n this._toggleSortItem(this._label(i))\n this.requestUpdate()\n }}>\n ${this._label(i)}\n </div>\n `)}\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `\n : ''}\n\n <slot name=\"business-tag\"></slot>\n\n ${this._renderCategorySection()}\n\n ${this._renderAiSection()}\n\n ${this._renderResourceSection()}\n\n ${this['show-rich-text'] && this._showRichText\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>副文本:</span></div>\n <div style=\"flex:1\">\n <slot name=\"sub-text\">\n <qxs-blocksuite-editor\n .content=${this._richText}\n .upload-image=${this['upload-image']}\n ?is-edit=${true}\n @input=${(e: CustomEvent) => { this._richText = (e.target as any).getContent() }}\n ></qxs-blocksuite-editor>\n </slot>\n ${!this['show-action']\n ? html`<div class=\"flex-justify-end\" style=\"margin-top:8px\"><span class=\"el-link danger\" @click=${() => { this._showRichText = false; this._richText = '' }}>删除富文本</span></div>`\n : ''}\n </div>\n </div>\n `\n : ''}\n\n ${this['show-analysis']\n ? html`\n <div class=\"flex-items-start\" style=\"margin-top:12px\">\n <div class=\"label\"><span>解析:</span></div>\n <div style=\"flex:1\">\n <textarea rows=\"2\" .value=${this._analysis}\n @input=${(e: Event) => { this._analysis = (e.target as HTMLTextAreaElement).value }}\n placeholder=\"请输入题目解析\"></textarea>\n </div>\n </div>\n `\n : ''}\n `\n }\n\n render() {\n if (this.sorting) {\n return this._renderSorting()\n }\n\n const content = this['is-edit']\n ? html`<div slot=\"edit\">${this._renderEdit()}</div>`\n : html`<div slot=\"preview\">${this._renderPreview()}</div>`\n\n return html`\n <qxs-subject-layout .show-edit=${this['is-edit']}>\n ${content}\n ${this['show-action']\n ? html`\n <qxs-subject-action\n .is-edit=${this['is-edit']}\n .is-set=${this['is-set']}\n .show-add=${this['show-add']}\n .show-rich-text=${this['show-rich-text'] && this._showRichText}\n .hide-add-rich-text=${!this['show-rich-text'] || this['hide-add-rich-text']}\n .show-delete-action=${this['show-delete-action']}\n .show-save-action=${this['show-save-action']}\n .show-jump=${this['show-jump']}\n @delete=${() => this._emit('delete')}\n @save=${this._save}\n @edit=${() => this._emit('edit')}\n @move=${(e: CustomEvent) => this._emit('move', e.detail)}\n @jump=${() => this._emit('jump', {\n customId: this['custom-id'] || '',\n examId: this['exam-id'] || 0,\n answerType: this.type,\n })}\n @add=${(e: CustomEvent) => this._emit('add', e.detail)}\n @on-show-rich-text=${() => {\n this._showRichText = !this._showRichText\n if (!this._showRichText) {\n this._richText = ''\n }\n }}\n ></qxs-subject-action>\n `\n : ''}\n <slot name=\"action\"></slot>\n </qxs-subject-layout>\n ${this._renderCorrectHintDialog()}\n ${this._renderChangeTypeDialog()}\n ${this._renderImageViewer()}\n ${this._renderVideoViewer()}\n `\n }\n}\n\nexport function register() {}\n"],"names":["SubjectError","Error","constructor","message","code","arguments","length","undefined","field","row","super","this","name","from","options","iconPlus","html","iconRemove","iconArrow","normalizeTitle","text","replace","toLowerCase","trimText","value","String","trim","trimCommaSeparatedText","split","map","item","filter","Boolean","join","showToast","msg","el","document","createElement","textContent","Object","assign","style","position","top","left","transform","padding","borderRadius","fontSize","color","background","zIndex","boxShadow","transition","opacity","body","appendChild","setTimeout","remove","QxsSubjectSingle","LitElement","lockAnswerKey","sorting","type","analysis","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","_answers","title","isCorrect","_title","_analysis","_richText","_showRichText","_leastAnswerCount","_answerCheckType","_isKey","_orderList","_selectedTagList","_categoryId","_searchResults","_searchOpen","_searchLoading","_sortDropdownOpen","_imageViewerOpen","_imageViewerIndex","_videoViewerOpen","_correctHintDialogOpen","_hasShownCorrectHint","_changeTypeDialogOpen","_searchTimer","_searchToken","TITLE_MAX","ANSWER_MAX","_handleDocumentClick","path","composedPath","wrapper","shadowRoot","querySelector","searchWrap","includes","requestUpdate","v","arr","Array","isArray","a","_normalizeAnswerItem","connectedCallback","addEventListener","_syncExternalProps","firstUpdated","disconnectedCallback","removeEventListener","window","clearTimeout","willUpdate","changed","has","_syncProps","_syncExamExpand","_supportsLeastAnswerCount","answerType","_normalizeLeastAnswerCount","count","Number","isFinite","_leastAnswerCountSuffix","answer","next","answerId","examAnswerId","ids","answers","id","index","findIndex","answerIndex","orderIndex","_label","_emit","detail","dispatchEvent","CustomEvent","bubbles","composed","_searchAnswerType","_queueSearch","query","keyword","_runSearch","currentToken","params","URLSearchParams","searchKey","response","fetch","toString","ok","status","payload","json","data","error","_selectSearchResult","selectedTitle","examId","questionId","customId","_applyAiAnswer","aiTitles","line","matched","selected","shouldSelect","_onCategoryChange","_setRelation","customAnswerId","uid","current","_relationLength","reduce","relationAnswers","_emitEditResultItem","resultItem","_resultSlotName","_imageResources","resourceType","resource","middle","url","_videoResource","find","_openImageViewer","_closeImageViewer","_moveImage","step","images","_openVideoViewer","_closeVideoViewer","i","fromCharCode","_titlePlaceholder","_setCorrect","val","_onTitleInput","slice","_onAnswerInput","idx","_addAnswer","splice","_deleteAnswer","_","_toggleSortItem","letter","indexOf","l","_removeSortItem","_getSortOrder","pos","_sortAnswerValue","charCodeAt","_rowMeta","_collectSnapshot","orderList","expand","leastAnswerCount","selectedTagList","examExpand","showRichText","richText","_validateSnapshot","snapshot","errors","push","isSetCorrectAnswer","correctAnswerCount","forEach","Set","size","_serialize","examTypeEnum","relationType","answerRelations","examRichTextContent","examAnswerRelationType","_shouldShowCorrectHint","some","_finalizeSave","toJSON","err","validate","setResultItem","setAnswerRelation","_renderCorrectHintDialog","stopPropagation","_renderChangeTypeDialog","_renderSearchDropdown","_renderCategorySection","categoryId","_renderAiSection","_renderResourceSection","video","src","_renderImageViewer","_renderVideoViewer","_save","stopImmediatePropagation","convertWarning","blockingErrors","_renderPreview","typeSuffix","previewTitle","joinSubjectTitle","resolveSubjectPrefix","_renderSorting","orderText","renderSortingCard","SubjectTypeLabel","_renderEdit","Math","max","n","checked","getContent","render","content","styles","sortingCardStyles","css","__decorateClass","property","attribute","prototype","reflect","state","safeCustomElement"],"mappings":"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"}