Files
platform/ruoyi/uploadPath/appResource/html/upload.html
2025-03-25 18:27:39 +08:00

347 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文件上传管理系统</title>
<link rel="stylesheet" href="./index.css" />
<style>
.container {
display: flex;
height: 100vh;
padding: 20px;
box-sizing: border-box;
gap: 20px;
}
.left-panel {
width: 300px;
padding: 20px;
border-right: 1px solid #ebeef5;
overflow-y: auto;
}
.right-panel {
flex: 1;
padding: 20px;
}
.checkbox-group {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 15px;
}
.action-bar {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
/* 拖拽上传区域样式 */
.upload-area {
height: 300px;
border: 2px dashed #dcdfe6;
border-radius: 6px;
background-color: #f5f7fa;
margin-bottom: 20px;
}
.upload-area .el-upload {
width: 100% !important;
height: 100% !important;
display: flex;
align-items: center;
justify-content: center;
}
.upload-area:hover {
border-color: #409eff;
}
.submit-btn {
width: 100%;
margin-top: 10px;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<!-- 左侧选择面板 -->
<div class="left-panel">
<h3>选择主题</h3>
<el-select
v-model="selectedTheme"
placeholder="请选择主题"
@change="handleThemeChange"
style="width: 100%; margin-bottom: 20px"
>
<el-option
v-for="item in themeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<div class="action-bar">
<el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
@change="handleCheckAllChange"
>
全选({{ userIds.length }}
</el-checkbox>
<el-button
type="primary"
@click="downloadTemplateFile"
size="small"
>
下载模板
</el-button>
</div>
<div v-loading="loading" class="checkbox-group">
<template v-if="currentList.length">
<el-checkbox
v-for="item in currentList"
:key="item.userId"
v-model="userIds"
:label="item.userId"
class="checkbox-item"
>
{{ item.username }}
</el-checkbox>
</template>
<div v-else class="el-upload__tip">{{ listStatusText }}</div>
</div>
</div>
<!-- 右侧上传面板 -->
<div v-loading="uploadLoading" class="right-panel">
<h3 style="margin-bottom: 15px">文件上传区域</h3>
<el-upload
ref="uploadRef"
class="upload-area"
drag
action="#"
:auto-upload="false"
:on-change="handleFileChange"
:limit="1"
:on-exceed="handleExceed"
:on-remove="handleFileRemove"
accept=".zip"
>
<div class="el-upload__text">
<i
class="el-icon-upload"
style="font-size: 40px; color: #409eff"
></i>
<div style="margin-top: 10px">
将文件拖到此处,或<em style="color: #409eff">点击上传</em>
</div>
</div>
</el-upload>
<el-button
type="primary"
class="submit-btn"
@click="submitUpload"
:disabled="!uploadFile"
:loading="uploadLoading"
>
确认上传
</el-button>
</div>
</div>
</div>
</body>
<script src="./vue.global.js"></script>
<script src="./index.full.js"></script>
<script>
const { createApp } = Vue;
const app = createApp({
data() {
return {
baseUrl: "http://192.168.110.3:9099",
themeOptions: [],
selectedTheme: "",
currentList: [],
userIds: [],
loading: false,
uploadLoading: false,
listStatusText: "请先选择主题",
userId: "",
checkAll: false,
isIndeterminate: false,
uploadFile: null,
};
},
mounted() {
const protocol = window.location.protocol;
const host = window.location.host;
this.baseUrl = `${protocol}//${host}`; // 动态获取基础 URL
// 获取 URL 中的 userId 参数
const urlParams = new URLSearchParams(window.location.search);
this.userId = urlParams.get("userId");
// console.log("userId", this.userId);
this.getRecruitList();
},
methods: {
// 初始化加载主题列表
async getRecruitList() {
this.loading = true;
try {
const response = await this.ajaxRequest({
url: `/ruoyi/app/bgt/recruit/htmlList?userId=${this.userId}`,
method: "GET",
});
this.themeOptions = response.data.map((item) => ({
value: item.id,
label: item.recruitName,
}));
// 自动选中第一个主题
if (this.themeOptions.length > 0) {
this.selectedTheme = this.themeOptions[0].value;
this.handleThemeChange(this.selectedTheme);
}
} finally {
this.loading = false;
}
},
// 主题切换处理
async handleThemeChange(val) {
this.loading = true;
try {
const response = await this.ajaxRequest({
url: `/ruoyi/app/bgt/apply/htmlList?recruitId=${val}`,
method: "GET",
});
this.currentList = response.data;
this.userIds = [];
} finally {
this.loading = false;
}
},
// 文件超出限制处理
handleExceed(files) {
this.$refs.uploadRef.clearFiles();
const file = files[0];
file.uid = ElementPlus.genFileId();
this.$refs.uploadRef.handleStart(file);
this.uploadFile = file;
},
// 文件变化处理
handleFileChange(file) {
console.log("文件", file.raw?.type);
if (
file.raw?.type != "application/zip" &&
file.raw?.type != "application/x-zip-compressed"
) {
this.$refs.uploadRef.handleRemove(file);
ElementPlus.ElMessage.warning("仅支持ZIP格式文件");
return;
}
this.uploadFile = file.raw;
},
// 文件删除处理
handleFileRemove(file) {
this.uploadFile = null;
ElementPlus.ElMessage.success("文件已删除");
},
// 提交上传
async submitUpload() {
if (!this.uploadFile) return;
if (this.themeOptions && this.themeOptions.length == 0) {
ElementPlus.ElMessage.error(`请先选择招工主题`);
return;
}
const formData = new FormData();
formData.append("file", this.uploadFile);
formData.append("recruitId", this.selectedTheme);
formData.append("userId", this.userId);
this.uploadLoading = true;
try {
const res = await this.ajaxRequest({
url: "/ruoyi/upload-zip",
method: "POST",
body: formData,
});
this.$refs.uploadRef.clearFiles();
this.uploadFile = null;
if (res.code == 200) {
ElementPlus.ElMessage.success("上传成功");
} else {
ElementPlus.ElMessage.error(`${res.msg}`);
}
} catch (error) {
ElementPlus.ElMessage.error(`${error}`);
} finally {
this.uploadLoading = false;
}
},
handleCheckAllChange(val) {
this.userIds = val ? this.currentList.map((i) => i.userId) : [];
},
async downloadTemplateFile() {
try {
const response = await this.ajaxRequest({
url: "/ruoyi/download-folders",
method: "POST",
body: { recruitId: this.selectedTheme, userIds: this.userIds },
isDownload: true,
});
const temp = this.themeOptions.find(
(item) => item.value == this.selectedTheme
);
const link = document.createElement("a");
link.href = URL.createObjectURL(new Blob([response]));
link.setAttribute(
"download",
`${this.selectedTheme}_${temp.label}.zip`
); // 设置文件名
link.click();
} catch (error) {
ElementPlus.ElMessage.error("下载失败");
}
},
async ajaxRequest(options) {
const config = {
method: options.method,
headers: options.headers || {},
};
if (options.body) {
if (options.body instanceof FormData) {
config.body = options.body;
} else {
config.headers["Content-Type"] = "application/json";
config.body = JSON.stringify(options.body);
}
}
const response = await fetch(this.baseUrl + options.url, config);
if (!response.ok) throw new Error(response.statusText);
return options.isDownload ? response.arrayBuffer() : response.json();
},
},
watch: {
userIds(newVal) {
const total = this.currentList.length;
this.checkAll = newVal.length === total && total > 0;
this.isIndeterminate = newVal.length > 0 && newVal.length < total;
},
},
});
app.use(ElementPlus);
app.mount("#app");
</script>
</html>