prepare
This commit is contained in:
221
src/App.vue
Normal file
221
src/App.vue
Normal file
@@ -0,0 +1,221 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { open } from "@tauri-apps/plugin-dialog";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { Document, VideoPlay, CircleCheck } from '@element-plus/icons-vue';
|
||||
|
||||
// Navigation
|
||||
const activeMenu = ref("preparation");
|
||||
|
||||
// Preparation Data
|
||||
const workingDir = ref("");
|
||||
const templateDir = ref("");
|
||||
const selectedDate = ref<Date | null>(new Date());
|
||||
const currentDir = ref("");
|
||||
const videoNamePrefix = ref("");
|
||||
|
||||
// Actions
|
||||
const selectWorkingDir = async () => {
|
||||
const selected = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
});
|
||||
if (selected) {
|
||||
workingDir.value = selected as string;
|
||||
}
|
||||
};
|
||||
|
||||
const selectTemplateDir = async () => {
|
||||
const selected = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
});
|
||||
if (selected) {
|
||||
templateDir.value = selected as string;
|
||||
}
|
||||
};
|
||||
|
||||
const selectCurrentDir = async () => {
|
||||
const selected = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
});
|
||||
if (selected) {
|
||||
currentDir.value = selected as string;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = async () => {
|
||||
if (!workingDir.value || !templateDir.value || !selectedDate.value) {
|
||||
ElMessage.error("请填写完整信息(工作目录、模板目录、日期)");
|
||||
return;
|
||||
}
|
||||
|
||||
const date = selectedDate.value;
|
||||
const mm = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(date.getDate()).padStart(2, '0');
|
||||
const folderName = `${mm}${dd}视频`;
|
||||
|
||||
try {
|
||||
const newPath = await invoke<string>("copy_directory", {
|
||||
templatePath: templateDir.value,
|
||||
targetPath: workingDir.value,
|
||||
newFolderName: folderName,
|
||||
});
|
||||
|
||||
ElMessage.success("目录拷贝并重命名成功!");
|
||||
|
||||
// Update Section 2
|
||||
currentDir.value = newPath;
|
||||
// Auto-update prefix is handled by watcher
|
||||
} catch (error) {
|
||||
ElMessage.error(`错误: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
// Reactivity for Current Directory
|
||||
watch(currentDir, (newPath) => {
|
||||
if (!newPath) return;
|
||||
|
||||
// Check if path ends with "ddmm视频"
|
||||
// Robust split for Windows/Unix paths
|
||||
const dirName = newPath.split(/[/\\]/).pop();
|
||||
|
||||
if (!dirName) return;
|
||||
|
||||
const regex = /^(\d{2})(\d{2})视频$/; // matches mmdd视频
|
||||
const match = dirName.match(regex);
|
||||
|
||||
if (match) {
|
||||
const mm = match[1];
|
||||
const dd = match[2];
|
||||
const year = new Date().getFullYear();
|
||||
// Format: AI-yyyyddmm-
|
||||
videoNamePrefix.value = `AI-${year}${mm}${dd}-`;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-container class="layout-container" style="height: 100vh">
|
||||
<el-aside width="200px" style="background-color: #fff; border-right: 1px solid #dcdfe6;">
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
class="el-menu-vertical-demo"
|
||||
@select="(index: string) => activeMenu = index"
|
||||
style="border-right: none;"
|
||||
>
|
||||
<el-menu-item index="preparation">
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>准备</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="review">
|
||||
<el-icon><VideoPlay /></el-icon>
|
||||
<span>审核</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="check">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
<span>检查</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
|
||||
<el-main>
|
||||
<div v-if="activeMenu === 'preparation'">
|
||||
<h2>准备工作</h2>
|
||||
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>新建任务</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="工作目录">
|
||||
<el-input v-model="workingDir" placeholder="请选择工作目录" readonly>
|
||||
<template #append>
|
||||
<el-button @click="selectWorkingDir">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="分类模板">
|
||||
<el-input v-model="templateDir" placeholder="请选择分类模板" readonly>
|
||||
<template #append>
|
||||
<el-button @click="selectTemplateDir">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="selectedDate"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleCopy" style="width: 100%">拷贝并重命名</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>当前任务</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="当前目录">
|
||||
<el-input v-model="currentDir" placeholder="请选择或生成目录" readonly>
|
||||
<template #append>
|
||||
<el-button @click="selectCurrentDir">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="文件前缀">
|
||||
<el-input v-model="videoNamePrefix" placeholder="AI-yyyyddmm-" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-else-if="activeMenu === 'review'">
|
||||
<h2>审核</h2>
|
||||
<el-empty description="功能待定" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="activeMenu === 'check'">
|
||||
<h2>检查</h2>
|
||||
<el-empty description="功能待定" />
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
.layout-container {
|
||||
height: 100vh;
|
||||
}
|
||||
.box-card {
|
||||
max-width: 800px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
1
src/assets/vue.svg
Normal file
1
src/assets/vue.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
14
src/main.ts
Normal file
14
src/main.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { createApp } from "vue";
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
import App from "./App.vue";
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
|
||||
app.use(ElementPlus)
|
||||
app.mount("#app");
|
||||
7
src/vite-env.d.ts
vendored
Normal file
7
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module "*.vue" {
|
||||
import type { DefineComponent } from "vue";
|
||||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
Reference in New Issue
Block a user