Commit 953a86b7 authored by 黄同智's avatar 黄同智

文件上传的公共组件,路由完善,图片上传弹窗表单,脚本上传弹窗表单

parent 47abd066
...@@ -136,6 +136,9 @@ $spacing-values: (); ...@@ -136,6 +136,9 @@ $spacing-values: ();
.border-fff { border: 1px solid #fff; } .border-fff { border: 1px solid #fff; }
// ----- 背景颜色 ----- // ----- 背景颜色 -----
.bgmr {
background: #f8fafc;
}
.bg-none { background: none; } .bg-none { background: none; }
.bg-000 { background: #000; } .bg-000 { background: #000; }
.bg-111 { background: #1f1f1f; } .bg-111 { background: #1f1f1f; }
...@@ -154,6 +157,7 @@ $spacing-values: (); ...@@ -154,6 +157,7 @@ $spacing-values: ();
.bg-fff { background: #fff; } .bg-fff { background: #fff; }
.bg-main { background: rgba(var(--main-color), 1); } .bg-main { background: rgba(var(--main-color), 1); }
// ---- 颜色 ----- // ---- 颜色 -----
.color-000 { color: #000; } .color-000 { color: #000; }
.color-999 { color: #999; } .color-999 { color: #999; }
......
<template>
<div class="file-upload-wrapper" :style="wrapperStyle">
<el-upload
ref="uploadRef"
class="avatar-uploader"
:action="action"
:headers="headers"
:data="data"
:name="name"
:multiple="multiple"
:limit="limit"
:show-file-list="showFileList"
:list-type="listType"
:accept="accept"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-error="handleError"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:file-list="fileList"
>
<!-- 自定义上传触发器插槽,无插槽内容则使用默认加号 -->
<slot v-if="!hasFile" name="trigger">
<div class="upload-btn">
<span>+</span>
</div>
</slot>
<!-- 图片预览弹窗 -->
<el-dialog v-model="dialogVisible" title="图片预览" width="30%" align-center>
<img w-full :src="dialogImageUrl" alt="预览图片" style="object-fit: contain;" />
</el-dialog>
</el-upload>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch, ComputedRef } from 'vue';
import type { UploadProps, UploadUserFile, UploadFile } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
const props = defineProps({
action: {
type: String,
default: '',
},
headers: {
type: Object,
default: () => ({}),
},
data: {
type: Object,
default: () => ({}),
},
name: {
type: String,
default: 'file',
},
multiple: {
type: Boolean,
default: false,
},
limit: {
type: Number,
default: Infinity,
},
listType: {
type: String,
default: 'picture-card',
},
accept: {
type: String,
default: '.jpg,.jpeg,.png,.gif,.webp',
},
maxSize: {
type: Number,
default: 5,
},
showFileList: {
type: Boolean,
default: true,
},
btnText: {
type: String,
default: '上传',
},
/** 上传卡片宽度 px */
width: {
type: Number,
default: 100,
},
/** 上传卡片高度 px,不传则默认等于 width */
height: {
type: Number,
default: undefined,
},
});
const emit = defineEmits<{
'update:modelValue': [files: UploadUserFile[]];
success: [response: any, file: UploadFile];
error: [error: any, file: UploadFile];
}>();
const modelValue = defineModel<any>({ default: [] });
const uploadRef = ref<InstanceType<typeof import('element-plus').ElUpload>>();
const dialogImageUrl = ref('');
const dialogVisible = ref(false);
// 内部文件列表
const fileList = ref<UploadUserFile[]>([...modelValue.value]);
const hasFile: ComputedRef<boolean> = computed(() => fileList.value.length > 0);
// 计算最终宽高,height不存在则和width保持一致
const wrapperStyle = computed(() => {
const h = props.height ?? props.width;
return {
'--upload-width': `${props.width}px`,
'--upload-height': `${h}px`,
};
});
// 同步外部 v-model → 内部列表
watch(
modelValue,
(val) => {
fileList.value = Array.isArray(val) ? [...val] : [];
},
{ deep: true }
);
// 内部列表变更同步到父组件
watch(
fileList,
(val) => {
emit('update:modelValue', [...val]);
},
{ deep: true }
);
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
const ext = rawFile.name.substring(rawFile.name.lastIndexOf('.') + 1);
const allowExts = props.accept.split(',').map((e) => e.trim().replace('.', '').toLowerCase());
if (allowExts.length && !allowExts.includes(ext.toLowerCase())) {
ElMessage.warning(`仅支持 ${props.accept} 格式文件`);
return false;
}
const maxBytes = props.maxSize * 1024 * 1024;
if (rawFile.size > maxBytes) {
ElMessage.warning(`文件不能超过 ${props.maxSize}MB`);
return false;
}
return true;
};
const handleSuccess: UploadProps['onSuccess'] = (response, file) => {
if (response.code === 200) {
file.url = response.data;
if (!props.multiple) {
fileList.value = [file];
}
}
emit('success', response, file);
};
const handleError: UploadProps['onError'] = (error, file) => {
ElMessage.error(`上传失败:${file.name}`);
emit('error', error, file);
};
const handleRemove: UploadProps['onRemove'] = () => {
// 可扩展外部事件
};
const beforeRemove: UploadProps['beforeRemove'] = async () => {
try {
await ElMessageBox.confirm('确定移除该文件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
return true;
} catch {
return false;
}
};
const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
dialogImageUrl.value = uploadFile.url ?? '';
dialogVisible.value = true;
};
defineExpose({
uploadRef,
submit: () => uploadRef.value?.submit(),
clearFiles: () => uploadRef.value?.clearFiles(),
});
</script>
<style scoped lang="scss">
.file-upload-wrapper {
display: inline-block;
--upload-width: 100px;
--upload-height: 100px;
.avatar-uploader {
:deep(.el-upload--picture-card) {
width: var(--upload-width);
height: var(--upload-height);
border-radius: 6px;
border: 1px dashed #dcdfe6;
transition: all 0.3s;
&:hover {
border-color: rgba(var(--main-color), 0.4);
background-color: rgba(var(--main-color), 0.05);
}
}
:deep(.el-upload-list--picture-card .el-upload-list__item) {
width: var(--upload-width);
height: var(--upload-height);
border-radius: 6px;
}
}
.upload-btn {
width: var(--upload-width);
height: var(--upload-height);
display: flex;
align-items: center;
justify-content: center;
color: #888;
font-size: 28px;
}
}
</style>
\ No newline at end of file
<template>
<div>
<el-upload v-if="listType === 'drap'" class="upload-demo" drag
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" :multiple="multiple" :limit="limit"
:accept="accept" :showFileList="showFileList">
<slot v-if="!hasFile" name="trigger">
<span>⬆️</span>
<div class="el-upload__text">
拖拽文件到这里 <em>点击上传</em>
</div>
</slot>
</el-upload>
<div v-else class="file-upload-wrapper" :style="wrapperStyle">
<el-upload ref="uploadRef" class="avatar-uploader" :action="action" :headers="headers" :data="data"
:multiple="multiple" :limit="limit" :show-file-list="showFileList" :list-type="listType"
:accept="accept" :before-upload="beforeUpload" :on-success="handleSuccess" :on-error="handleError"
:on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove"
:file-list="fileList">
<slot v-if="!hasFile" name="trigger">
<div class="upload-btn">
<span>+</span>
</div>
</slot>
</el-upload>
</div>
<!-- 图片预览弹窗 -->
<el-dialog v-model="dialogVisible" title="图片预览" width="30%" align-center>
<img w-full :src="dialogImageUrl" alt="预览图片" style="object-fit: contain;" />
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch, ComputedRef } from 'vue';
import type { UploadProps, UploadUserFile, UploadFile } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
const props = defineProps({
action: {
type: String,
default: '',
},
headers: {
type: Object,
default: () => ({}),
},
data: {
type: Object,
default: () => ({}),
},
multiple: {
type: Boolean,
default: false,
},
limit: {
type: Number,
default: Infinity,
},
listType: {
type: String,
default: 'picture-card',
},
accept: {
type: String,
default: '.jpg,.jpeg,.png,.gif,.webp',
},
maxSize: {
type: Number,
default: 5,
},
showFileList: {
type: Boolean,
default: true,
},
/** 上传卡片宽度 px */
width: {
type: Number,
default: 100,
},
/** 上传卡片高度 px,不传则默认等于 width */
height: {
type: Number,
default: undefined,
},
});
const emit = defineEmits<{
'update:modelValue': [files: UploadUserFile[]];
success: [response: any, file: UploadFile];
error: [error: any, file: UploadFile];
}>();
const modelValue = defineModel<any>({ default: [] });
const uploadRef = ref<InstanceType<typeof import('element-plus').ElUpload>>();
const dialogImageUrl = ref('');
const dialogVisible = ref(false);
// 内部文件列表
const fileList = ref<UploadUserFile[]>([...modelValue.value]);
const hasFile: ComputedRef<boolean> = computed(() => fileList.value.length > 0);
// 计算最终宽高,height不存在则和width保持一致
const wrapperStyle = computed(() => {
const h = props.height ?? props.width;
return {
'--upload-width': `${props.width}px`,
'--upload-height': `${h}px`,
};
});
// 同步外部 v-model → 内部列表
watch(
modelValue,
(val) => {
fileList.value = Array.isArray(val) ? [...val] : [];
},
{ deep: true }
);
// 内部列表变更同步到父组件
watch(
fileList,
(val) => {
emit('update:modelValue', [...val]);
},
{ deep: true }
);
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
const ext = rawFile.name.substring(rawFile.name.lastIndexOf('.') + 1);
const allowExts = props.accept.split(',').map((e) => e.trim().replace('.', '').toLowerCase());
if (allowExts.length && !allowExts.includes(ext.toLowerCase())) {
ElMessage.warning(`仅支持 ${props.accept} 格式文件`);
return false;
}
const maxBytes = props.maxSize * 1024 * 1024;
if (rawFile.size > maxBytes) {
ElMessage.warning(`文件不能超过 ${props.maxSize}MB`);
return false;
}
return true;
};
const handleSuccess: UploadProps['onSuccess'] = (response, file) => {
if (response.code === 200) {
file.url = response.data;
if (!props.multiple) {
fileList.value = [file];
}
}
emit('success', response, file);
};
const handleError: UploadProps['onError'] = (error, file) => {
ElMessage.error(`上传失败:${file.name}`);
emit('error', error, file);
};
const handleRemove: UploadProps['onRemove'] = () => {
// 可扩展外部事件
};
const beforeRemove: UploadProps['beforeRemove'] = async () => {
try {
await ElMessageBox.confirm('确定移除该文件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
return true;
} catch {
return false;
}
};
const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
dialogImageUrl.value = uploadFile.url ?? '';
dialogVisible.value = true;
};
defineExpose({
uploadRef,
submit: () => uploadRef.value?.submit(),
clearFiles: () => uploadRef.value?.clearFiles(),
});
</script>
<style scoped lang="scss">
:deep(.upload-demo) {
.el-upload-dragger {
background-color: rgba(var(--main-color), 0.04);
}
}
.file-upload-wrapper {
display: inline-block;
--upload-width: 100px;
--upload-height: 100px;
.avatar-uploader {
:deep(.el-upload--picture-card) {
width: var(--upload-width);
height: var(--upload-height);
border-radius: 6px;
border: 1px dashed #dcdfe6;
transition: all 0.3s;
&:hover {
border-color: rgba(var(--main-color), 0.4);
background-color: rgba(var(--main-color), 0.05);
}
}
:deep(.el-upload-list--picture-card .el-upload-list__item) {
width: var(--upload-width);
height: var(--upload-height);
border-radius: 6px;
}
}
.upload-btn {
width: var(--upload-width);
height: var(--upload-height);
display: flex;
align-items: center;
justify-content: center;
color: #888;
font-size: 28px;
}
}
</style>
\ No newline at end of file
...@@ -39,6 +39,12 @@ const routes = [ ...@@ -39,6 +39,12 @@ const routes = [
meta: { title: '成片管理', icon: '', affix: true } meta: { title: '成片管理', icon: '', affix: true }
}, },
{ {
path: 'clip/detail/:id', // 动态参数 :id
name: 'ClipDetail',
component: ()=> import('@/views/resource/clip/detail.vue'),
meta: { title: '成片详情', hidden: true } // hidden: true 表示不在左侧菜单显示
},
{
path: 'material', path: 'material',
name: 'Material', name: 'Material',
component: ()=> import('@/views/resource/material/index.vue'), component: ()=> import('@/views/resource/material/index.vue'),
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
<div class="mb-20 flex"> <div class="mb-20 flex">
<el-button @click="switchCheck">{{ isCheck ? '取消选择' : '请选择' }}</el-button> <el-button @click="switchCheck">{{ isCheck ? '取消选择' : '请选择' }}</el-button>
<el-button type="primary">上传文件</el-button> <el-button type="primary">上传文件</el-button>
<div class="round-6 bg-fff p-4 ml-12 flex gap-2" style="border: 1px solid #ddd;"> <div class="round-6 bg-fff p-4 ml-12 flex gap-6" style="border: 1px solid #ddd;">
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 1 ? 'active' : ''" link @click="btnIndex = 1"> <div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 1 ? 'active' : ''" link @click="btnIndex = 1">
<SvgIcon name="HD" size="18" class="iconscoal" :color="btnIndex === 1? 'rgba(var(--main-color), 1)': ''" /> <SvgIcon name="HD" size="18" class="iconscoal" :color="btnIndex === 1? 'rgba(var(--main-color), 1)': '#888'" />
</div> </div>
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 2 ? 'active' : ''" link @click="btnIndex = 2"> <div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 2 ? 'active' : ''" link @click="btnIndex = 2">
<SvgIcon name="redraw" size="18" class="iconscoal" :color="btnIndex === 2? 'rgba(var(--main-color), 1)': ''"/> <SvgIcon name="redraw" size="18" class="iconscoal" :color="btnIndex === 2? 'rgba(var(--main-color), 1)': '#888'"/>
</div> </div>
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 3 ? 'active' : ''" link @click="btnIndex = 3"> <div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 3 ? 'active' : ''" link @click="btnIndex = 3">
<SvgIcon name="room" size="18" class="iconscoal" :color="btnIndex === 3? 'rgba(var(--main-color), 1)': ''"/> <SvgIcon name="room" size="18" class="iconscoal" :color="btnIndex === 3? 'rgba(var(--main-color), 1)': '#888'"/>
</div> </div>
</div> </div>
</div> </div>
......
<template>
<div class="bgmr vh100 p-20">
<div class="flex gap-20">
<el-card class="flex-1 round-12" shadow="hover">
<div class="flex gap-60">
<div class="flex-1">
<div>
<div class="font-bold flex justify-between">
<span>平台 UI 遮挡排查蒙版</span>
<span class="fs-12 color-888 fw-500">预审防遮挡违规</span>
</div>
<div class="bg-eee flex gap-10 mt-10 round-4 p-4">
<div v-for="(item, index) in ptTabs" :key="index" @click="ptIndex = index"
class="round-4 py-4 px-10 pointer"
:class="ptIndex === index ? 'bg-main color-fff' : ''">
<span>{{ item.label }}</span>
</div>
</div>
</div>
<div class="mt-40">
<div class="font-bold flex justify-between">
<span>秒级高光镜头拆解 (点击跳帧)</span>
<span class="fs-12 color-888 fw-500">黄金15秒爆款结构</span>
</div>
<div class="mt-4">
<div class="mt-10 round-4">
<div v-for="(item, index) in jtTabs" :key="index" @click="ptIndex = index"
class="round-4 py-4 px-10 pointer flex-item mb-10"
:class="ptIndex === index ? 'active' : ''">
<div class="fs-12 fw-600">{{ item.label }}</div>
<div class="fs-10 mt-4">{{ item.desc }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="phone h-600 bg-000 round-40 p-4">
<div class="bg-fff h-full round-38"></div>
</div>
</div>
</el-card>
<el-card class="flex-1 round-12">
<div class="flex justify-between pb-10" style="border-bottom: 1px solid #eee;">
<div class="flex-items-center">
<div class="w-36 h-36 bg-main round-6"></div>
<div class="ml-10">
<div class="fw-600">梦畅AIGC / 默认部门 / 默认分组</div>
<div class="fs-12 color-888">
<span>发布时间: 2025-04-02 12:06:28</span>
<span class="ml-20">剪辑时间: 2025-05-02</span>
</div>
</div>
</div>
<el-button type="primary" round>权限监测</el-button>
</div>
<div class="bg-eee flex gap-10 mt-20 round-4 p-4">
<div v-for="(item, index) in ptTabs" :key="index" @click="ptIndex = index"
class="round-4 py-4 px-10 pointer" :class="ptIndex === index ? 'bg-main color-fff' : ''">
<span>{{ item.label }}</span>
</div>
</div>
<div class="flex flex-col gap-20 mt-20">
<div class="flex-items-center">
<div class="w-100 color-666">成片区</div>
<div class="flex-1 color-000">
<span>女士内衣</span>
<el-button type="primary" text>修改</el-button>
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">视频标题</div>
<div class="flex-1 color-000">
<span>0730-8835-鲁月园-复古耳环动态奢感视频.mp4</span>
<el-button type="primary" text>修改</el-button>
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">公共标签</div>
<div class="flex-1 color-000">
<el-tag type="success">仙侠穿越</el-tag>
<el-tag type="success">视频卡</el-tag>
<el-tag type="success">隐式陪叫</el-tag>
<el-button type="primary" text>+ 添加公共标签</el-button>
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">个人标签</div>
<div class="flex-1 color-000">
<el-tag type="success">仙侠穿越</el-tag>
<el-tag type="success">视频卡</el-tag>
<el-tag type="success">隐式</el-tag>
<el-button type="primary" text>+ 添加个人标签</el-button>
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">关联脚本</div>
<div class="flex-1 color-000">
<el-button type="primary" text>查看脚本(1)</el-button>
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">视频状态</div>
<div class="flex-1 color-000">
<el-tag type="warning">待审核</el-tag>
<el-button type="primary" text>修改</el-button>
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">视频备注</div>
<div class="flex-1 color-000">
<el-input type="textarea" rows="2" />
</div>
</div>
<div class="flex-items-center">
<div class="w-100 color-666">附件</div>
<div class="flex-1 color-000">
<el-button type="primary" text>+ 添加附件</el-button>
</div>
</div>
</div>
<div style="border-top: 1px solid #eee;" class="pt-16 mt-10">
<el-button type="primary" plain>分享</el-button>
<el-button type="primary" plain>操作记录</el-button>
<el-button type="primary" plain>下载源码视频</el-button>
<el-button type="primary" plain>更多</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const ptIndex = ref(0)
const ptTabs = ref([
{ label: '抖音样式', value: 0 },
{ label: '抖音橱窗', value: 1 },
{ label: '视频号样式', value: 2 },
{ label: '隐藏样式', value: 3 },
])
const jtTabs = ref([
{ label: '0~3s 黄金Hook', desc: '复古古法金耳环特写' },
{ label: '3~6s 黄金Hook', desc: '夏日古人打瞌睡宽度' },
{ label: '6-9s 黄金Hook', desc: '微距看看时候来' },
{ label: '9~12s 黄金Hook', desc: '直播间买一赠一' },
{ label: '12~15s 黄金Hook', desc: '点击下方小黄车' },
])
</script>
<style scoped lang="scss">
.flex-item {
background-color: rgba(var(--main-color), .1);
color: rgba(var(--main-color), 1);
// flex: 0 0 calc((100% - 10px * 2) / 3);
}
.active {
background-color: rgba(var(--main-color), 1);
color: #fff;
}
.bg-eee {
background-color: #f0f4f7;
}
.phone {
width: 320px;
}
</style>
\ No newline at end of file
...@@ -2,13 +2,30 @@ ...@@ -2,13 +2,30 @@
<div class="p-20"> <div class="p-20">
<Classify /> <Classify />
<div class="mt-20"> <div class="mt-20">
<div class="mb-20"> <div class="mb-20 flex">
<el-button @click="switchCheck">{{ isCheck ? '取消选择' : '请选择' }}</el-button> <el-button @click="switchCheck">{{ isCheck ? '取消选择' : '请选择' }}</el-button>
<el-button type="primary" @click="openDialog">上传文件</el-button> <el-button type="primary" @click="openDialog">上传文件</el-button>
<div class="round-6 bg-fff p-4 ml-12 flex gap-6" style="border: 1px solid #ddd;">
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 1 ? 'active' : ''" link
@click="btnIndex = 1">
<SvgIcon name="HD" size="18" class="iconscoal"
:color="btnIndex === 1 ? 'rgba(var(--main-color), 1)' : '#888'" />
</div>
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 2 ? 'active' : ''" link
@click="btnIndex = 2">
<SvgIcon name="redraw" size="18" class="iconscoal"
:color="btnIndex === 2 ? 'rgba(var(--main-color), 1)' : '#888'" />
</div>
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 3 ? 'active' : ''" link
@click="btnIndex = 3">
<SvgIcon name="room" size="18" class="iconscoal"
:color="btnIndex === 3 ? 'rgba(var(--main-color), 1)' : '#888'" />
</div>
</div>
</div> </div>
<div class="flex flex-wrap gap-20"> <div class="flex flex-wrap gap-20">
<el-checkbox-group v-model="checkedList" class="flex flex-wrap gap-20 w-full"> <el-checkbox-group v-model="checkedList" class="flex flex-wrap gap-20 w-full">
<div v-for="(item, index) in list" :key="index" <div v-for="(item, index) in list" :key="index" @click="goDetail(item)"
class="w-200 bg-fff round-12 relative hidden flex-item" class="w-200 bg-fff round-12 relative hidden flex-item"
:class="{ 'is-selected': checkedList.includes(item.id) }"> :class="{ 'is-selected': checkedList.includes(item.id) }">
<Item :item="item" :isCheck="isCheck" /> <Item :item="item" :isCheck="isCheck" />
...@@ -22,21 +39,27 @@ ...@@ -22,21 +39,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { useRouter } from 'vue-router'
import Classify from '../components/Classify.vue'; import Classify from '../components/Classify.vue';
import Item from '@/views/resource/components/VideoItem.vue' import Item from '@/views/resource/components/VideoItem.vue'
import UploadVideoDialog from './components/UploadVideoDialog.vue'; import UploadVideoDialog from './components/UploadVideoDialog.vue';
const router = useRouter()
const checkedList = ref<any>([]) const checkedList = ref<any>([])
const isCheck = ref(false) const isCheck = ref(false)
const btnIndex = ref(0)
const list = ref([{ id: '1' }, { id: '2' }, { id: '3' }]); const list = ref([{ id: '1' }, { id: '2' }, { id: '3' }]);
const switchCheck = () => { const switchCheck = () => {
isCheck.value = !isCheck.value isCheck.value = !isCheck.value
checkedList.value = [] checkedList.value = []
} }
const goDetail = (item: any) => {
router.push(`/resource/clip/detail/${item.id}`)
}
// 上传视频的弹窗内容 // 上传视频的弹窗内容
const dialogVisible =ref(false) const dialogVisible = ref(false)
const openDialog = () => { const openDialog = () => {
dialogVisible.value = true; dialogVisible.value = true;
}; };
...@@ -50,6 +73,11 @@ const openDialog = () => { ...@@ -50,6 +73,11 @@ const openDialog = () => {
aspect-ratio: 1 / 1.5; aspect-ratio: 1 / 1.5;
} }
.active {
background-color: rgba(var(--main-color), 0.1);
}
/* 1600px 以下:一行 5 个 */ /* 1600px 以下:一行 5 个 */
@media (max-width: 2100px) { @media (max-width: 2100px) {
...@@ -77,6 +105,7 @@ const openDialog = () => { ...@@ -77,6 +105,7 @@ const openDialog = () => {
.is-selected { .is-selected {
box-shadow: 0 0 2px 2px rgb(var(--main-color)); box-shadow: 0 0 2px 2px rgb(var(--main-color));
} }
.el-checkbox-group { .el-checkbox-group {
font-size: inherit; font-size: inherit;
line-height: inherit; line-height: inherit;
......
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
<div class="mt-20"> <div class="mt-20">
<div class="mb-20 flex"> <div class="mb-20 flex">
<el-button @click="switchCheck">{{ isCheck ? '取消选择' : '请选择' }}</el-button> <el-button @click="switchCheck">{{ isCheck ? '取消选择' : '请选择' }}</el-button>
<el-button type="primary">上传文件</el-button> <el-button type="primary" @click="openDialog">上传文件</el-button>
<div class="round-6 bg-fff p-4 ml-12 flex gap-2" style="border: 1px solid #ddd;"> <div class="round-6 bg-fff p-4 ml-12 flex gap-6" style="border: 1px solid #ddd;">
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 1 ? 'active' : ''" link @click="btnIndex = 1"> <div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 1 ? 'active' : ''" link @click="btnIndex = 1">
<SvgIcon name="HD" size="18" class="iconscoal" :color="btnIndex === 1? 'rgba(var(--main-color), 1)': ''" /> <SvgIcon name="HD" size="18" class="iconscoal" :color="btnIndex === 1? 'rgba(var(--main-color), 1)': '#888'" />
</div> </div>
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 2 ? 'active' : ''" link @click="btnIndex = 2"> <div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 2 ? 'active' : ''" link @click="btnIndex = 2">
<SvgIcon name="redraw" size="18" class="iconscoal" :color="btnIndex === 2? 'rgba(var(--main-color), 1)': ''"/> <SvgIcon name="redraw" size="18" class="iconscoal" :color="btnIndex === 2? 'rgba(var(--main-color), 1)': '#888'"/>
</div> </div>
<div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 3 ? 'active' : ''" link @click="btnIndex = 3"> <div class="round-6 w-24 h-24 flex-center pointer" :class="btnIndex === 3 ? 'active' : ''" link @click="btnIndex = 3">
<SvgIcon name="room" size="18" class="iconscoal" :color="btnIndex === 3? 'rgba(var(--main-color), 1)': ''"/> <SvgIcon name="room" size="18" class="iconscoal" :color="btnIndex === 3? 'rgba(var(--main-color), 1)': '#888'"/>
</div> </div>
</div> </div>
</div> </div>
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
</el-checkbox-group> </el-checkbox-group>
</div> </div>
</div> </div>
<UploadDialog v-model:visible="dialogVisible" />
</div> </div>
</template> </template>
...@@ -34,6 +35,7 @@ ...@@ -34,6 +35,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import Classify from '../components/Classify.vue'; import Classify from '../components/Classify.vue';
import Item from '@/views/resource/image/components/Item.vue' import Item from '@/views/resource/image/components/Item.vue'
import UploadDialog from './components/UploadDialog.vue';
const checkedList = ref<any>([]) const checkedList = ref<any>([])
const btnIndex = ref(0) const btnIndex = ref(0)
...@@ -44,6 +46,14 @@ const switchCheck = () => { ...@@ -44,6 +46,14 @@ const switchCheck = () => {
isCheck.value = !isCheck.value isCheck.value = !isCheck.value
checkedList.value = [] checkedList.value = []
} }
// 上传视频的弹窗内容
const dialogVisible =ref(false)
const openDialog = () => {
dialogVisible.value = true;
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
......
This diff is collapsed.
<template> <template>
<div class="p-20"> <div class="p-20">
<Classify /> <Classify />
<div class="mt-20">
<el-button type="primary" @click="openDialog">上传文件</el-button>
</div>
<section class="mt-20 p-10 bg-fff round-12"> <section class="mt-20 p-10 bg-fff round-12">
<el-table :data="tableData" style="width: 100%" size="large" @selection-change="handleSelectionChange"> <el-table :data="tableData" style="width: 100%" size="large" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
...@@ -40,13 +43,14 @@ ...@@ -40,13 +43,14 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</section> </section>
<UploadDialog v-model:visible="dialogVisible" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import Classify from '../components/Classify.vue'; import Classify from '../components/Classify.vue';
import { ElButton } from 'element-plus'; import UploadDialog from './UploadDialog.vue';
const tableData = [ const tableData = [
{ {
...@@ -67,9 +71,14 @@ const tableData = [ ...@@ -67,9 +71,14 @@ const tableData = [
}, },
] ]
const selectedChecks = ref([]) const selectedChecks = ref([])
const handleSelectionChange = (val: any)=>{ const handleSelectionChange = (val: any) => {
console.log(44444, val) console.log(44444, val)
} }
// 上传视频的弹窗内容
const dialogVisible =ref(false)
const openDialog = () => {
dialogVisible.value = true;
};
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment