|
@@ -15,7 +15,10 @@
|
|
|
</span>
|
|
</span>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item class="submit-but">
|
|
<el-form-item class="submit-but">
|
|
|
- <el-button type="primary" icon="el-icon-s-promotion" size="mini" @click="submitForm">提交解析</el-button>
|
|
|
|
|
|
|
+ <el-button type="primary" icon="el-icon-s-promotion" :loading="subLoading" size="mini"
|
|
|
|
|
+ @click="submitForm"
|
|
|
|
|
+ >提交解析
|
|
|
|
|
+ </el-button>
|
|
|
<el-button icon="el-icon-refresh" size="mini" @click="reset">重置地址</el-button>
|
|
<el-button icon="el-icon-refresh" size="mini" @click="reset">重置地址</el-button>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
@@ -24,12 +27,18 @@
|
|
|
<div slot="header" class="clearfix">
|
|
<div slot="header" class="clearfix">
|
|
|
<span>作品信息</span>
|
|
<span>作品信息</span>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="video-info">
|
|
|
|
|
|
|
+ <div class="video-info" v-if="type === 0">
|
|
|
|
|
+ <div v-if="data.desc === undefined" class="empty-state">
|
|
|
|
|
+ <svg-icon icon-class="video" class="empty-icon"/>
|
|
|
|
|
+ <p class="empty-text">暂无解析数据</p>
|
|
|
|
|
+ <p class="empty-hint">请在上方输入视频地址并点击提交解析</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<div class="info-header" v-if="data.avatar || data.nickname">
|
|
<div class="info-header" v-if="data.avatar || data.nickname">
|
|
|
<el-avatar :src="data.avatar" :size="56" shape="square" class="author-avatar" v-if="data.avatar"/>
|
|
<el-avatar :src="data.avatar" :size="56" shape="square" class="author-avatar" v-if="data.avatar"/>
|
|
|
<div class="author-meta" v-if="data.nickname || data.signature">
|
|
<div class="author-meta" v-if="data.nickname || data.signature">
|
|
|
<div class="author-name" v-if="data.nickname">{{ data.nickname }}</div>
|
|
<div class="author-name" v-if="data.nickname">{{ data.nickname }}</div>
|
|
|
- <div class="author-signature" v-if="data.signature" >{{ data.signature }}</div>
|
|
|
|
|
|
|
+ <div class="author-signature" v-if="data.signature">{{ data.signature }}</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -76,14 +85,81 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="video-info batch-view" v-if="type === 1">
|
|
|
|
|
+ <div v-if="batchData.length === 0" class="empty-state">
|
|
|
|
|
+ <svg-icon icon-class="video" class="empty-icon"/>
|
|
|
|
|
+ <p class="empty-text">暂无解析数据</p>
|
|
|
|
|
+ <p class="empty-hint">请在上方输入视频地址并点击提交解析</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-else class="batch-grid">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(item, index) in batchData"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="batch-card"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="card-body">
|
|
|
|
|
+ <div class="author-row" v-if="item.avatar || item.nickname">
|
|
|
|
|
+ <el-avatar :src="item.avatar" :size="36" shape="square" class="card-avatar" v-if="item.avatar"/>
|
|
|
|
|
+ <div class="author-info">
|
|
|
|
|
+ <div class="nickname" v-if="item.nickname">{{ item.nickname }}</div>
|
|
|
|
|
+ <div class="unique-id" v-if="item.unique_id">@{{ item.unique_id }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="desc-preview" v-if="item.desc">
|
|
|
|
|
+ {{ item.desc }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <video_play
|
|
|
|
|
+ v-if="item.play_addr !== undefined "
|
|
|
|
|
+ style="height: 300px"
|
|
|
|
|
+ :video_url="item.play_addr"
|
|
|
|
|
+ :poster="item.cover"
|
|
|
|
|
+ ></video_play>
|
|
|
|
|
+ <div v-else class="preview-placeholder">
|
|
|
|
|
+ <svg-icon icon-class="video" class="placeholder-icon"/>
|
|
|
|
|
+ <p class="placeholder-text">暂无可预览的视频</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stats-row">
|
|
|
|
|
+ <div class="stat-mini" v-if="item.digg_count !== undefined">
|
|
|
|
|
+ <svg-icon icon-class="like" class="mini-icon"/>
|
|
|
|
|
+ <span class="mini-value">{{ formatNumber(item.digg_count) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-mini" v-if="item.comment_count !== undefined">
|
|
|
|
|
+ <svg-icon icon-class="comment" class="mini-icon"/>
|
|
|
|
|
+ <span class="mini-value">{{ formatNumber(item.comment_count) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-mini" v-if="item.collect_count !== undefined">
|
|
|
|
|
+ <svg-icon icon-class="collect" class="mini-icon"/>
|
|
|
|
|
+ <span class="mini-value">{{ formatNumber(item.collect_count) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-mini" v-if="item.share_count !== undefined">
|
|
|
|
|
+ <svg-icon icon-class="share" class="mini-icon"/>
|
|
|
|
|
+ <span class="mini-value">{{ formatNumber(item.share_count) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</el-card>
|
|
</el-card>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
- <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
|
|
|
|
|
|
+ <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8" v-if="type === 0">
|
|
|
<el-card shadow="never">
|
|
<el-card shadow="never">
|
|
|
<div slot="header" class="clearfix">
|
|
<div slot="header" class="clearfix">
|
|
|
<span>视频预览</span>
|
|
<span>视频预览</span>
|
|
|
</div>
|
|
</div>
|
|
|
- <video_play style="height: 80vh" :video_url="data.play_addr" :poster="data.cover"></video_play>
|
|
|
|
|
|
|
+ <video_play
|
|
|
|
|
+ v-if="data.play_addr !== undefined "
|
|
|
|
|
+ style="height: 80vh"
|
|
|
|
|
+ :video_url="data.play_addr"
|
|
|
|
|
+ :poster="data.cover"
|
|
|
|
|
+ ></video_play>
|
|
|
|
|
+ <div v-else class="preview-placeholder">
|
|
|
|
|
+ <svg-icon icon-class="video" class="placeholder-icon"/>
|
|
|
|
|
+ <p class="placeholder-text">暂无可预览的视频</p>
|
|
|
|
|
+ </div>
|
|
|
</el-card>
|
|
</el-card>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
@@ -99,6 +175,7 @@ export default {
|
|
|
components: { NexoRadio, Video_play },
|
|
components: { NexoRadio, Video_play },
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
|
|
+ subLoading: false,
|
|
|
type: 0,
|
|
type: 0,
|
|
|
radioOptions: [
|
|
radioOptions: [
|
|
|
{ label: '孤品 · 深度对谈', value: 0 },
|
|
{ label: '孤品 · 深度对谈', value: 0 },
|
|
@@ -110,7 +187,8 @@ export default {
|
|
|
{ required: true, message: '请输入需要解析的视频地址', trigger: 'blur' }
|
|
{ required: true, message: '请输入需要解析的视频地址', trigger: 'blur' }
|
|
|
]
|
|
]
|
|
|
},
|
|
},
|
|
|
- data: {}
|
|
|
|
|
|
|
+ data: {},
|
|
|
|
|
+ batchData: []
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
watch: {
|
|
watch: {
|
|
@@ -121,12 +199,29 @@ export default {
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
submitForm() {
|
|
submitForm() {
|
|
|
|
|
+ this.subLoading = true
|
|
|
console.log('submitForm', this.form)
|
|
console.log('submitForm', this.form)
|
|
|
this.form.type = this.type
|
|
this.form.type = this.type
|
|
|
|
|
+ this.data = {}
|
|
|
|
|
+ this.batchData = []
|
|
|
this.$refs['form'].validate((valid) => {
|
|
this.$refs['form'].validate((valid) => {
|
|
|
if (valid) {
|
|
if (valid) {
|
|
|
parse(this.form).then(response => {
|
|
parse(this.form).then(response => {
|
|
|
- this.data = response.data
|
|
|
|
|
|
|
+ if (this.type === 0) {
|
|
|
|
|
+ this.data = response.data
|
|
|
|
|
+ this.$message.success('解析成功')
|
|
|
|
|
+ } else if (this.type === 1) {
|
|
|
|
|
+ this.batchData = Array.isArray(response.data) ? response.data : [response.data]
|
|
|
|
|
+ const successCount = this.batchData.filter(item => !item.error).length
|
|
|
|
|
+ const failCount = this.batchData.filter(item => item.error).length
|
|
|
|
|
+ if (failCount > 0) {
|
|
|
|
|
+ this.$message.warning(`解析完成:成功 ${successCount} 个,失败 ${failCount} 个`)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$message.success(`成功解析 ${successCount} 个视频`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ this.subLoading = false
|
|
|
})
|
|
})
|
|
|
} else {
|
|
} else {
|
|
|
console.log('error submit!!')
|
|
console.log('error submit!!')
|
|
@@ -139,6 +234,18 @@ export default {
|
|
|
type: 0,
|
|
type: 0,
|
|
|
videoUrl: 'https://www.douyin.com/jingxuan?modal_id=7643814124878656421'
|
|
videoUrl: 'https://www.douyin.com/jingxuan?modal_id=7643814124878656421'
|
|
|
}
|
|
}
|
|
|
|
|
+ this.data = {}
|
|
|
|
|
+ this.batchData = []
|
|
|
|
|
+ },
|
|
|
|
|
+ formatNumber(num) {
|
|
|
|
|
+ if (num === undefined || num === null) return '0'
|
|
|
|
|
+ if (num >= 10000) {
|
|
|
|
|
+ return (num / 10000).toFixed(1) + 'w'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (num >= 1000) {
|
|
|
|
|
+ return (num / 1000).toFixed(1) + 'k'
|
|
|
|
|
+ }
|
|
|
|
|
+ return num.toString()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -320,4 +427,215 @@ export default {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+.preview-indicator {
|
|
|
|
|
+ float: right;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #409eff;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.preview-placeholder {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ height: 80vh;
|
|
|
|
|
+ background: linear-gradient(135deg, rgba(64, 158, 255, 0.03) 0%, rgba(103, 194, 58, 0.03) 100%);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+
|
|
|
|
|
+ .placeholder-icon {
|
|
|
|
|
+ width: 80px;
|
|
|
|
|
+ height: 80px;
|
|
|
|
|
+ color: #dcdfe6;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .placeholder-text {
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.batch-view {
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.batch-grid {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+ padding: 4px;
|
|
|
|
|
+
|
|
|
|
|
+ .batch-card {
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ border-color: #0138c6;
|
|
|
|
|
+ box-shadow: 0 6px 20px rgba(64, 158, 255, 0.15);
|
|
|
|
|
+ transform: translateY(-4px);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .card-body {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+
|
|
|
|
|
+ .author-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ padding: 8px;
|
|
|
|
|
+ background: linear-gradient(135deg, rgba(64, 158, 255, 0.04) 0%, rgba(103, 194, 58, 0.04) 100%);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+
|
|
|
|
|
+ .card-avatar {
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .author-info {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+
|
|
|
|
|
+ .nickname {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #303133;
|
|
|
|
|
+ line-height: 1.3;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .unique-id {
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ color: #409eff;
|
|
|
|
|
+ margin-top: 2px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .desc-preview {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #606266;
|
|
|
|
|
+ line-height: 1.6;
|
|
|
|
|
+ max-height: 60px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ display: -webkit-box;
|
|
|
|
|
+ -webkit-line-clamp: 3;
|
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
|
+ word-break: break-word;
|
|
|
|
|
+ padding: 8px;
|
|
|
|
|
+ background: rgba(245, 247, 250, 0.5);
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stats-row {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(2, 1fr);
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+
|
|
|
|
|
+ .stat-mini {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+ padding: 6px 8px;
|
|
|
|
|
+ background: linear-gradient(135deg, rgba(64, 158, 255, 0.05) 0%, rgba(103, 194, 58, 0.05) 100%);
|
|
|
|
|
+ border: 1px solid rgba(64, 158, 255, 0.1);
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ transition: all 0.2s ease;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ transform: scale(1.02);
|
|
|
|
|
+ border-color: rgba(64, 158, 255, 0.25);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .mini-icon {
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ color: #606266;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .mini-value {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #303133;
|
|
|
|
|
+ font-family: 'Barlow-Medium', 'HarmonyOS_Sans_SC_Medium', sans-serif;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-state {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ padding: 60px 20px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+
|
|
|
|
|
+ .empty-icon {
|
|
|
|
|
+ width: 80px;
|
|
|
|
|
+ height: 80px;
|
|
|
|
|
+ color: #dcdfe6;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .empty-text {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ margin: 0 0 8px 0;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .empty-hint {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #c0c4cc;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@keyframes pulse {
|
|
|
|
|
+ 0%, 100% {
|
|
|
|
|
+ box-shadow: 0 0 0 0 rgba(64, 158, 255, 0.4);
|
|
|
|
|
+ }
|
|
|
|
|
+ 50% {
|
|
|
|
|
+ box-shadow: 0 0 0 8px rgba(64, 158, 255, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 1200px) {
|
|
|
|
|
+ .batch-grid {
|
|
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 768px) {
|
|
|
|
|
+ .batch-grid {
|
|
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 480px) {
|
|
|
|
|
+ .batch-grid {
|
|
|
|
|
+ grid-template-columns: 1fr;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|