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;
......
<template>
<el-dialog v-model="visible" title="Shipping address" width="1000" modal-class="xxxxx" align-center
:before-close="handleClose">
<template #title>
<div class="fs-18 font-bold py-10 pl-20">图片上传</div>
</template>
<div class="h-700 over-auto px-20 pb-20">
<el-form ref="formRef" :model="form" label-width="100">
<el-card shadow="hover">
<div class="flex gap-10 mb-10">
<div class="color-888 py-4 px-10 round-6 pointer"
:class="form.typeImg === 0 ? 'color-main' : ''"
:style="{ border: form.typeImg === 0 ? '1px solid rgba(var(--main-color), 0.5)' : '1px solid #ddd' }"
@click="form.typeImg = 0">
<div class="font-bold">发布图组</div>
<div class="fs-12">多张图片为一组</div>
</div>
<div class="color-888 py-4 px-10 round-6 pointer"
:class="form.typeImg === 1 ? 'color-main' : ''"
:style="{ border: form.typeImg === 1 ? '1px solid rgba(var(--main-color), 0.5)' : '1px solid #ddd' }"
@click="form.typeImg = 1">
<div class="font-bold">发布多张图片</div>
<div class="fs-12">每张图片单独一组</div>
</div>
</div>
<div v-if="form.typeImg === 0" class="mb-10">
<div class="flex gap-10">
<div class="h-30 round-4 flex-center fs-12 px-10 pointer"
v-for="(tab, index) in form.groupImgs" :key="index" @click="tabIndex = (index as number)"
:class="tabIndex === index ? 'color-main' : ''"
:style="{ boxShadow: tabIndex === index ? '0 0 0 1px rgba(var(--main-color), 0.5)' : 'none', backgroundColor: tabIndex === index ? '#fff' : '#eee' }">
分组{{ (index as number) + 1 }}
</div>
<div class="w-30 h-30 round-4 flex-center bg-eee border-ddd pointer" @click="addGroup">
+
</div>
</div>
</div>
<FileUpload list-type="drap"/>
</el-card>
<el-card shadow="hover" class="mt-10">
<section class="flex justify-between">
<div class="flex-items-center">
<div class="w-36 h-36 round-6 bg-000"></div>
<div class="ml-10">
<div class="fs-16 font-bold">图片信息</div>
<div class="fs-12 color-888">填写图片分类、命名</div>
</div>
</div>
<div class="flex-items-center gap-10">
<el-select v-model="mouldType" placeholder="选择预设模板" style="width: 200px" clearable>
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
<el-button type="primary">+ 存为预设模板</el-button>
</div>
</section>
<section class="mt-20">
<div class="title mb-20">基础信息</div>
<!-- <el-form-item label="视频分区" prop="name">
<el-radio-group v-model="form.name">
<el-radio :value="1">成片</el-radio>
<el-radio :value="2">素材</el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="图片分类" prop="name">
<el-cascader v-model="form.name" :options="videoOptions" placeholder="请选择视频分类" clearable
class="w-full" />
</el-form-item>
<el-form-item label="图片名称" prop="name">
<el-input v-model="form.name" type="text" placeholder="请输入图片名称" :maxlength="20" />
</el-form-item>
<el-form-item label="关联任务" prop="name">
<el-select v-model="form.name" placeholder="请选择关联任务" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="关联脚本" prop="name">
<el-select v-model="form.name" placeholder="请选择关联脚本" clearable>
<template #header>
<div class="flex justify-between">
<span class="font-bold color-888">任务关联脚本</span>
<el-button type="primary" link>从脚本库选择</el-button>
</div>
</template>
<el-option v-for="item in scriptOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</section>
<section class="mt-20">
<div class="title mb-20">标签信息</div>
<el-form-item label="公共标签" prop="name">
<el-cascader v-model="form.name" :options="tagComOptions" placeholder="请选择公共标签" clearable
class="w-full" :props="props" />
</el-form-item>
<el-form-item label="个人标签" prop="name">
<el-cascader v-model="form.name" :options="tagSelfOptions" placeholder="请选择个人标签" clearable
class="w-full" :props="props" />
</el-form-item>
</section>
<section class="mt-20">
<div class="title mb-20">时间设置 <span class="fs-12 color-888 fw-500 ml-10">剪辑时间、授权有效期</span>
</div>
<el-form-item label="授权有效期" prop="name">
<el-date-picker v-model="form.daterange" type="daterange" placeholder="请选择授权有效期" />
</el-form-item>
</section>
<section class="mt-20">
<div class="title mb-20">其他信息 <span class="fs-12 color-888 fw-500 ml-10">补充说明</span></div>
<el-form-item label="图片说明" prop="name">
<el-input v-model="form.name" :rows="2" type="textarea" placeholder="请输入图片说明" />
</el-form-item>
</section>
</el-card>
<el-card shadow="hover" class="mt-10">
<section class="flex justify-between">
<div class="flex-items-center">
<div class="w-36 h-36 round-6 bg-000"></div>
<div class="ml-10">
<div class="fs-16 font-bold">权限设置</div>
<div class="fs-12 color-888">设置查看权限、定时权限变更和消息提醒</div>
</div>
</div>
<div class="flex-items-center gap-10">
<el-select v-model="mouldType" placeholder="选择预设模板" style="width: 200px" clearable>
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
<el-button type="primary">+ 存为预设模板</el-button>
</div>
</section>
<section class="mt-20">
<div class="title mb-20">基础信息</div>
<el-form-item label="视频查看权限" prop="name">
<div>
<el-radio-group v-model="form.name">
<el-radio :value="1">公开(默认)</el-radio>
<el-radio :value="2">团队成员</el-radio>
<el-radio :value="3">小组成员</el-radio>
<el-radio :value="4">公共资源</el-radio>
<el-radio :value="5">指定范围</el-radio>
</el-radio-group>
<div class="fs-12 color-888">控制图片上传后哪些人可以查看该图片。</div>
</div>
</el-form-item>
<div class="flex">
<div class="flex-1">
<el-form-item label="指定团队" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="flex-1">
<el-form-item label="指定小组" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="flex-1">
<el-form-item label="指定人员" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</div>
</div>
</section>
<section class="mt-20">
<div class="title mb-20">定期权限<span class="fs-12 color-888 fw-500 ml-10">可选,到期后自动修改查看权限</span>
</div>
<el-form-item label="修改日期" prop="name">
<el-date-picker v-model="form.name" type="date" placeholder="请选择修改日期" />
<span class="fs-12 color-888 ml-10">将在所选日期 00:00 自动修改视频查看权限</span>
</el-form-item>
</section>
<section class="mt-20">
<div class="title mb-20">消息提醒</div>
<el-form-item label="接收人" prop="name">
<el-select v-model="form.name" placeholder="请选择接收人" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="消息内容" prop="name">
<el-input v-model="form.name" :rows="2" type="textarea" placeholder="请输入消息内容" />
</el-form-item>
</section>
</el-card>
</el-form>
</div>
<template #footer>
<div class="px-20 pb-10 pt-10" style="border-top: 1px solid #eee;">
<el-button @click="handleConfirm">发布后,相同配置继续上传</el-button>
<!-- <el-button type="primary" @click="handleConfirm" plain>图片上传完毕,自动发布</el-button> -->
<el-button type="primary" @click="handleConfirm">发布</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import FileUpload from '@/components/Upload/index.vue'
const visible = defineModel<boolean>('visible', { required: true });
// 表单大类
const form = reactive<any>({
typeImg: 0,
imgs: [],
groupImgs: [
{ imgs: [] },
{ imgs: [] },
],
name: '',
daterange: [],
goodNums: 866
})
const formRef = ref<any>(null)
const tabIndex = ref(0)
const addGroup = ()=>{
form.groupImgs.push({ imgs: [] })
}
const videoOptions = ref([
{
value: '1',
label: '爆款素材',
children: [
{
value: '1-1',
label: '服饰内衣',
},
{
value: '1-2',
label: '美妆护肤',
},
{
value: '1-3',
label: '日用百货',
},
],
},
])
const taskOptions = ref([
{ label: '生成一布短剧', value: '1' },
{ label: '电商产品图片模版', value: '2' }
])
const scriptOptions = ref([
{ label: '脚本-汽车图片', value: '1' },
{ label: '脚本-电商产品', value: '2' }
])
const tagComOptions = ref([
{
value: '1',
label: '爆款素材',
children: [
{
value: '1-1',
label: '服饰内衣',
},
{
value: '1-2',
label: '美妆护肤',
},
{
value: '1-3',
label: '日用百货',
},
],
},
])
const tagSelfOptions = ref([
{
value: '1',
label: '爆款素材',
children: [
{
value: '1-1',
label: '服饰内衣',
},
{
value: '1-2',
label: '美妆护肤',
},
{
value: '1-3',
label: '日用百货',
},
],
},
])
const props = { multiple: true }
// 模版信息
const mouldType = ref('')
const options = ref([
{ label: '电商成片', value: 1 },
{ label: '混剪二创视频', value: 2 },
])
// 弹窗的取消和确定
const handleClose = (done: () => void) => {
if (!formRef.value) return;
formRef.value.resetFields();
done();
};
const handleConfirm = () => {
visible.value = false; // 关闭弹窗
};
</script>
<style lang="scss" scoped>
.title {
position: relative;
padding-left: 10px;
font-weight: bold;
&::before {
content: '';
position: absolute;
left: 0;
top: 4px;
height: 14px;
width: 4px;
border-radius: 10px;
background-color: rgb(var(--main-color));
}
}
</style>
<style>
.el-dialog {
border-radius: 10px;
padding: 0 !important;
}
.el-dialog__footer {
padding: 0 !important;
}
</style>
\ No newline at end of file
...@@ -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">
......
<template>
<el-dialog v-model="visible" title="Shipping address" width="1200" modal-class="xxxxx" align-center
:before-close="handleClose">
<template #title>
<div class="fs-18 font-bold py-10 pl-20">视频上传</div>
</template>
<div class="h-700 over-auto px-20 pb-20">
<el-form ref="formRef" :model="form" label-width="100">
<el-card shadow="hover" class="mt-10">
<section class="flex justify-between">
<div class="flex-items-center">
<div class="w-36 h-36 round-6 bg-000"></div>
<div class="ml-10">
<div class="fs-16 font-bold">脚本信息</div>
<div class="fs-12 color-888">填写脚本的基本信息</div>
</div>
</div>
<div class="flex-items-center gap-10">
<el-select v-model="mouldType" placeholder="选择预设模板" style="width: 200px" clearable>
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
<el-button type="primary">+ 存为预设模板</el-button>
</div>
</section>
<section class="mt-20">
<div class="title mb-20">基础信息</div>
<el-form-item label="脚本分类" prop="name">
<el-cascader v-model="form.name" :options="videoOptions" placeholder="请选择视频分类" clearable
class="w-full" />
</el-form-item>
<el-form-item label="脚本标题" prop="name">
<el-input v-model="form.name" placeholder="请输入脚本标题" clearable />
</el-form-item>
<el-form-item label="关联任务" prop="name">
<el-select v-model="form.name" placeholder="请选择关联任务" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</section>
<section class="mt-20">
<div class="title mb-20">标签信息</div>
<el-form-item label="公共标签" prop="name">
<el-cascader v-model="form.name" :options="tagComOptions" placeholder="请选择公共标签" clearable
class="w-full" :props="props" />
</el-form-item>
<el-form-item label="个人标签" prop="name">
<el-cascader v-model="form.name" :options="tagSelfOptions" placeholder="请选择个人标签" clearable
class="w-full" :props="props" />
</el-form-item>
</section>
</el-card>
<el-card shadow="hover" class="mt-10">
<section class="flex justify-between">
<div class="flex-items-center">
<div class="w-36 h-36 round-6 bg-000"></div>
<div class="ml-10">
<div class="fs-16 font-bold">填写脚本</div>
<div class="fs-12 color-888">填写脚本</div>
</div>
</div>
<span class="fs-12 color-888">AI仿写免费次数200000/200000</span>
</section>
<section class="mt-20">
<el-form-item label="脚本模板" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<div class="flex round-6 listbox mb-20">
<div class="font-bold flex-center a px-10">
画面时间轴
</div>
<div class="flex-1 hidden">
<el-table :data="form.list" style="width: 100%" border>
<el-table-column label="画面时间点 (秒)" align="center" width="200">
<template #default="{ row, $index }">
<el-form-item :prop="`list.${$index}.content1`"
:rules="{ required: true, message: '此项必填', trigger: 'blur' }"
label-position="top">
<el-input v-model="row.content1" type="textarea" :rows="5"
placeholder="例如:0~3s" class="inputborder" style="resize: none;" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="台词/对白" align="center" width="300">
<template #default="{ row, $index }">
<el-form-item :prop="`list.${$index}.content2`"
:rules="{ required: true, message: '此项必填', trigger: 'blur' }"
label-position="top">
<el-input v-model="row.content2" type="textarea" :rows="5"
placeholder="请输入台词或口播文本" class="inputborder"
style="resize: none;" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="画面镜头" align="center" width="300">
<template #default="{ row, $index }">
<el-form-item :prop="`list.${$index}.content3`"
:rules="{ required: true, message: '此项必填', trigger: 'blur' }"
label-position="top">
<el-input v-model="row.content3" type="textarea" :rows="2"
placeholder="描写画面特写/分镜镜头" class="inputborder"
style="resize: none;" />
<el-upload class="avatar-uploader w-60 h-60 mt-4 flex-center round-4"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
:show-file-list="false">
<img v-if="row.content5" :src="row.content5" class="avatar" />
<span v-else>+</span>
</el-upload>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="画面注意事项" align="center" width="200">
<template #default="{ row, $index }">
<el-form-item :prop="`list.${$index}.content4`"
:rules="{ required: true, message: '此项必填', trigger: 'blur' }"
label-position="top">
<el-input v-model="row.content4" type="textarea" :rows="5"
placeholder="灯光、道具或动作注意项" class="inputborder"
style="resize: none;" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="{ $index }">
<el-button type="danger" size="small"
@click="removeRow($index)">删除</el-button>
<br>
<el-button type="primary" size="small" @click="addRow($index)">新增</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<el-form-item label="视频格式" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in scriptOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="视频尺寸" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in scriptOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="字幕类型" prop="name">
<el-input v-model="form.name" placeholder="请输入字幕类型,如:内嵌字幕/挂载字幕/无字幕" :maxlength="10" />
</el-form-item>
<el-form-item label="视频画质" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in scriptOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="BGM" prop="name">
<el-input v-model="form.name" placeholder="请输入BGM信息/背景音乐名称" :maxlength="20" />
</el-form-item>
</section>
</el-card>
<el-card shadow="hover" class="mt-10">
<section class="flex justify-between">
<div class="flex-items-center">
<div class="w-36 h-36 round-6 bg-000"></div>
<div class="ml-10">
<div class="fs-16 font-bold">更多设置</div>
<div class="fs-12 color-888">更多设置</div>
</div>
</div>
<div class="flex-items-center gap-10">
<el-select v-model="mouldType" placeholder="选择预设模板" style="width: 200px" clearable>
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
<el-button type="primary">+ 存为预设模板</el-button>
</div>
</section>
<section class="mt-20">
<el-form-item label="谁可以看" prop="name">
<div>
<el-radio-group v-model="form.name">
<el-radio :value="1">公开</el-radio>
<el-radio :value="2">团队成员</el-radio>
<el-radio :value="3">小组成员</el-radio>
<el-radio :value="4">公共资源</el-radio>
<el-radio :value="5">指定范围</el-radio>
</el-radio-group>
<div class="fs-12 color-888">控制视频上传后哪些人可以查看该视频。</div>
</div>
</el-form-item>
<!-- 指定范围 -->
<div class="flex">
<div class="flex-1">
<el-form-item label="指定团队" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="flex-1">
<el-form-item label="指定小组" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="flex-1">
<el-form-item label="指定人员" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</div>
</div>
<el-form-item label="修改日期" prop="name">
<el-date-picker v-model="form.name" type="date" placeholder="请选择修改日期" />
<span class="fs-12 color-888 ml-10">将在所选日期 00:00 自动修改视频查看权限</span>
</el-form-item>
<el-form-item label="提醒谁看" prop="name">
<el-select v-model="form.name" placeholder="请选择" clearable>
<el-option v-for="item in taskOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="并发送消息" prop="name">
<el-input v-model="form.name" :rows="2" type="textarea" placeholder="请输入消息" />
</el-form-item>
</section>
</el-card>
</el-form>
</div>
<template #footer>
<div class="px-20 pb-10 pt-10" style="border-top: 1px solid #eee;">
<el-button @click="handleConfirm">发布后,相同配置继续上传</el-button>
<el-button type="primary" @click="handleConfirm">发布</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
const visible = defineModel<boolean>('visible', { required: true });
// 表单大类
const form = reactive<any>({
name: '',
daterange: [],
goodNums: 866,
list: [
{ content1: '', content2: '', content3: '', content4: '', content5: '' }
]
})
const formRef = ref<any>(null)
// 表格内容
const removeRow = (index: number) => {
if (form.list.length > 1) {
form.list.splice(index, 1);
} else {
alert('至少保留一行');
}
};
const addRow = (index: number) => {
const newRow = {
content1: '',
content2: '',
content3: '',
content4: '',
content5: ''
};
form.list.splice(index + 1, 0, newRow);
}
// 模版信息
const mouldType = ref('')
const options = ref([
{ label: '电商成片', value: 1 },
{ label: '混剪二创视频', value: 2 },
])
// 弹窗的取消和确定
const handleClose = (done: () => void) => {
if (!formRef.value) return;
formRef.value.resetFields();
done();
};
const handleConfirm = () => {
visible.value = false; // 关闭弹窗
};
const props = { multiple: true }
// 下拉数据
const videoOptions = ref([
{
value: '1',
label: '爆款素材',
children: [
{
value: '1-1',
label: '服饰内衣',
},
{
value: '1-2',
label: '美妆护肤',
},
{
value: '1-3',
label: '日用百货',
},
],
},
])
const taskOptions = ref([
{ label: '生成一布短剧', value: '1' },
{ label: '电商产品图片模版', value: '2' }
])
const scriptOptions = ref([
{ label: '脚本-汽车图片', value: '1' },
{ label: '脚本-电商产品', value: '2' }
])
const tagComOptions = ref([
{
value: '1',
label: '爆款素材',
children: [
{
value: '1-1',
label: '服饰内衣',
},
{
value: '1-2',
label: '美妆护肤',
},
{
value: '1-3',
label: '日用百货',
},
],
},
])
const tagSelfOptions = ref([
{
value: '1',
label: '爆款素材',
children: [
{
value: '1-1',
label: '服饰内衣',
},
{
value: '1-2',
label: '美妆护肤',
},
{
value: '1-3',
label: '日用百货',
},
],
},
])
</script>
<style lang="scss" scoped>
.title {
position: relative;
padding-left: 10px;
font-weight: bold;
&::before {
content: '';
position: absolute;
left: 0;
top: 4px;
height: 14px;
width: 4px;
border-radius: 10px;
background-color: rgb(var(--main-color));
}
}
.listbox {
border: 1px solid rgba(var(--main-color), .5);
.a {
writing-mode: vertical-rl;
background-color: rgba(var(--main-color), .1);
}
:deep(.inputborder) {
.el-textarea__inner {
box-shadow: none;
resize: none !important;
}
}
.avatar-uploader {
box-shadow: 0 0 0 1px rgba(var(--main-color), .5);
background-color: rgba(var(--main-color), .05);
}
.w20 {
width: 20%;
}
}
</style>
<style>
.el-dialog {
border-radius: 10px;
padding: 0 !important;
}
.el-dialog__footer {
padding: 0 !important;
}
</style>
\ No newline at end of file
<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