153 lines
2.7 KiB
Vue
153 lines
2.7 KiB
Vue
|
|
<template>
|
||
|
|
<transition name="slide">
|
||
|
|
<div v-if="show" class="side-panel">
|
||
|
|
<button @click="handleClose" class="close-btn"></button>
|
||
|
|
<el-button type="primary" @click="UpdateFileCOntent">保存修改</el-button>
|
||
|
|
<div class="content">
|
||
|
|
<h2>{{ fileName }}</h2>
|
||
|
|
<textarea
|
||
|
|
ref="textareaRef"
|
||
|
|
v-model="localContent"
|
||
|
|
cols="40"
|
||
|
|
rows="10"
|
||
|
|
spellcheck="false"
|
||
|
|
></textarea>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</transition>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, watch, nextTick } from "vue";
|
||
|
|
import { UpdateFileContentService } from "@/api/file";
|
||
|
|
import { ElMessage } from "element-plus";
|
||
|
|
|
||
|
|
const props = defineProps({
|
||
|
|
content: {
|
||
|
|
type: String,
|
||
|
|
default: "",
|
||
|
|
},
|
||
|
|
show: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
fileName: {
|
||
|
|
type: String,
|
||
|
|
default: "编辑代码",
|
||
|
|
},
|
||
|
|
fileID: {
|
||
|
|
type: Number,
|
||
|
|
default: 0,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const emit = defineEmits<{
|
||
|
|
(e: "close"): void;
|
||
|
|
}>();
|
||
|
|
|
||
|
|
const textareaRef = ref<HTMLTextAreaElement | null>(null);
|
||
|
|
const localContent = ref(props.content);
|
||
|
|
|
||
|
|
// 当props.content变化时同步到本地
|
||
|
|
watch(
|
||
|
|
() => props.content,
|
||
|
|
(newVal) => {
|
||
|
|
localContent.value = newVal;
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
// 当面板显示时自动聚焦到textarea
|
||
|
|
watch(
|
||
|
|
() => props.show,
|
||
|
|
async (newVal) => {
|
||
|
|
if (newVal) {
|
||
|
|
await nextTick();
|
||
|
|
textareaRef.value?.focus();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
const handleClose = () => {
|
||
|
|
emit("close");
|
||
|
|
};
|
||
|
|
|
||
|
|
const UpdateFileCOntent = async () => {
|
||
|
|
let req = {
|
||
|
|
token: localStorage.getItem("token"),
|
||
|
|
file_id: props.fileID,
|
||
|
|
file_content: localContent.value,
|
||
|
|
};
|
||
|
|
try {
|
||
|
|
let result = await UpdateFileContentService(req);
|
||
|
|
if (result["code"] === 0) {
|
||
|
|
ElMessage.success("修改成功");
|
||
|
|
} else {
|
||
|
|
ElMessage.error("修改失败");
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
console.log(e);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped lang="css">
|
||
|
|
.side-panel {
|
||
|
|
position: fixed;
|
||
|
|
top: 0;
|
||
|
|
right: 0;
|
||
|
|
width: 50%;
|
||
|
|
height: 100%;
|
||
|
|
background: white;
|
||
|
|
z-index: 1001;
|
||
|
|
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
|
||
|
|
padding: 20px;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
}
|
||
|
|
|
||
|
|
.close-btn {
|
||
|
|
position: absolute;
|
||
|
|
top: 10px;
|
||
|
|
right: 10px;
|
||
|
|
font-size: 24px;
|
||
|
|
background: none;
|
||
|
|
border: none;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: color 0.2s;
|
||
|
|
z-index: 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
.close-btn:hover {
|
||
|
|
color: #666;
|
||
|
|
}
|
||
|
|
|
||
|
|
.content {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
margin-top: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
textarea {
|
||
|
|
flex: 1;
|
||
|
|
width: 100%;
|
||
|
|
padding: 10px;
|
||
|
|
border: 1px solid #ddd;
|
||
|
|
border-radius: 4px;
|
||
|
|
resize: none;
|
||
|
|
font-family: monospace;
|
||
|
|
font-size: 14px;
|
||
|
|
line-height: 1.5;
|
||
|
|
tab-size: 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
.slide-enter-active,
|
||
|
|
.slide-leave-active {
|
||
|
|
transition: transform 0.3s ease;
|
||
|
|
}
|
||
|
|
.slide-enter-from,
|
||
|
|
.slide-leave-to {
|
||
|
|
transform: translateX(100%);
|
||
|
|
}
|
||
|
|
</style>
|