| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- <template>
- <div class="webpage-input">
- <div class="title">{{ lang.ssInsertLearn }}</div>
- <div class="description">{{ lang.ssPickLearn }}</div>
-
- <!-- 当列表为空时显示上传提示 -->
- <div v-if="webpageList.length === 0" class="empty-state">
- <div class="empty-icon">📚</div>
- <div class="empty-title">{{ lang.ssNoLearn }}</div>
- <div class="empty-desc">{{ lang.ssNeedUpload }}</div>
- </div>
-
- <!-- 当有内容时显示列表 -->
- <div v-else class="webpage-list">
- <div
- v-for="(webpage, index) in webpageList"
- :key="index"
- class="webpage-item"
- :class="{ active: selectedIndex === index }"
- @click="toggleWebpageSelection(index)"
- >
- <div class="webpage-info">
- <div class="webpage-title">
- <span class="type-tag" :class="getTypeClass(webpage.type)">{{ getTypeLabel(webpage.type) }}</span>
- {{ webpage.title }}
- </div>
- <div class="webpage-url">{{ webpage.url }}</div>
- </div>
- <div class="webpage-status">
- <div v-if="selectedIndex === index" class="selected-icon">✓</div>
- </div>
- </div>
- </div>
-
- <div class="btns">
- <Button @click="emit('close')" style="margin-right: 10px;">{{ lang.ssCancel }}</Button>
- <Button
- v-if="webpageList.length > 0"
- type="primary"
- @click="insertWebpage()"
- :disabled="selectedIndex === null"
- >
- {{ lang.ssConfirm }}
- </Button>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref } from 'vue'
- import message from '@/utils/message'
- import Button from '@/components/Button.vue'
- import { lang } from '@/main'
- interface Webpage {
- type: number
- title: string
- url: string
- }
- interface Props {
- webpageList: Webpage[]
- }
- const props = withDefaults(defineProps<Props>(), {
- webpageList: () => []
- })
- const emit = defineEmits<{
- (event: 'insertWebpage', payload: { url: string, type: number }): void
- (event: 'close'): void
- }>()
- const selectedIndex = ref<number | null>(null)
- const toggleWebpageSelection = (index: number) => {
- if (selectedIndex.value === index) {
- // 如果点击已选中的网页,则取消选择
- selectedIndex.value = null
- }
- else {
- // 否则选择新网页
- selectedIndex.value = index
- }
- }
- const insertWebpage = () => {
- if (selectedIndex.value === null) {
- return message.error(lang.ssPickWebFirst)
- }
-
- // 根据选中的index获取对应的链接
- const selectedWebpage = props.webpageList[selectedIndex.value]
- if (selectedWebpage) {
- emit('insertWebpage', { url: selectedWebpage.url, type: selectedWebpage.type })
- }
- }
- // 获取类型标签
- const getTypeLabel = (type: number) => {
- const typeMap: Record<number, string> = {
- 45: lang.ssChoiceQ,
- 15: lang.ssQATest,
- 72: lang.ssAiApp,
- 73: lang.ssHPage,
- 81: lang.ssHPage,
- 74: lang.ssVideo,
- 75: lang.lang == 'cn' ? lang.ssBiliVideo : lang.ssYouTube,
- 76: lang.ssCreative,
- 77: lang.ssEnglishSpeakingTool,
- 78: lang.ssVote,
- 79: lang.ssPhoto,
- }
- return typeMap[type] || lang.ssUnknown
- }
- // 获取类型样式类
- const getTypeClass = (type: number) => {
- const classMap: Record<number, string> = {
- 45: 'type-choice',
- 15: 'type-question',
- 72: 'type-ai',
- 73: 'type-h5',
- 74: 'type-video',
- 75: 'type-bilibili',
- 76: 'type-app-center'
- }
- return classMap[type] || 'type-default'
- }
- </script>
- <style lang="scss" scoped>
- .webpage-input {
- width: 480px;
- padding: 10px;
- }
- .title {
- font-size: 16px;
- font-weight: 600;
- margin-bottom: 8px;
- color: #333;
- }
- .description {
- font-size: 14px;
- color: #666;
- margin-bottom: 15px;
- }
- .empty-state {
- text-align: center;
- padding: 40px 20px;
- color: #666;
- }
- .empty-icon {
- font-size: 48px;
- margin-bottom: 16px;
- }
- .empty-title {
- font-size: 16px;
- font-weight: 500;
- color: #333;
- margin-bottom: 8px;
- }
- .empty-desc {
- font-size: 14px;
- color: #999;
- margin-bottom: 24px;
- }
- .webpage-list {
- max-height: 250px; /* 设置最大高度,大约显示5个项目 */
- overflow-y: auto;
- margin: 15px 0;
- border: 1px solid #e0e0e0;
- border-radius: 6px;
-
- /* 自定义滚动条样式 */
- &::-webkit-scrollbar {
- width: 6px;
- }
-
- &::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 3px;
- }
-
- &::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 3px;
-
- &:hover {
- background: #a8a8a8;
- }
- }
- }
- .webpage-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 12px 16px;
- border-bottom: 1px solid #f0f0f0;
- cursor: pointer;
- transition: all 0.2s ease;
- height: 50px; /* 固定每个项目的高度 */
- box-sizing: border-box;
-
- &:last-child {
- border-bottom: none;
- }
-
- &:hover {
- background-color: #f8f9fa;
- }
-
- &.active {
- background-color: #e3f2fd;
- border-left: 3px solid #2196f3;
- }
- }
- .webpage-info {
- flex: 1;
- min-width: 0;
- }
- .webpage-title {
- font-size: 14px;
- font-weight: 500;
- color: #333;
- margin-bottom: 4px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- display: flex;
- align-items: center;
- gap: 8px;
- }
- .type-tag {
- padding: 2px 6px;
- border-radius: 4px;
- font-size: 11px;
- font-weight: 500;
- color: #fff;
- white-space: nowrap;
- flex-shrink: 0;
-
- &.type-choice {
- background-color: #4caf50;
- }
-
- &.type-question {
- background-color: #ff9800;
- }
-
- &.type-ai {
- background-color: #2196f3;
- }
-
- &.type-h5 {
- background-color: #9c27b0;
- }
-
- &.type-video {
- background-color: #f44336;
- }
-
- &.type-bilibili {
- background-color: #fb7299;
- }
-
- &.type-default {
- background-color: #757575;
- }
-
- &.type-app-center {
- background-color: #673ab7;
- }
- }
- .webpage-url {
- font-size: 12px;
- color: #666;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .webpage-status {
- margin-left: 12px;
- }
- .selected-icon {
- color: #2196f3;
- font-weight: bold;
- font-size: 16px;
- }
- .btns {
- margin-top: 15px;
- text-align: right;
- }
- </style>
|