parent
cdfd97ab47
commit
7e0b3b9682
@ -1,72 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ContentBase>
|
|
||||||
<div class="file-item" v-for="item in items" :key="item.name">
|
|
||||||
<div class="file-item">
|
|
||||||
<div @dblclick="handledouleclick(item.name,item.type)" class="file-item-icon">
|
|
||||||
<img v-if="item.type==='folder'" src="@/assets/folder_icon.png" alt="">
|
|
||||||
<img v-else src="@/assets/file_icon.png" alt="">
|
|
||||||
</div>
|
|
||||||
<div class="file-item-title">
|
|
||||||
{{ item.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ContentBase>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ContentBase from './ContentBase';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ContentShow',
|
|
||||||
components:{
|
|
||||||
ContentBase,
|
|
||||||
},
|
|
||||||
props:{
|
|
||||||
items:{
|
|
||||||
type:Object,
|
|
||||||
required:true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup(props,context){
|
|
||||||
const handledouleclick = (name,type) => {
|
|
||||||
context.emit("handledoubleclick",name,type);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
handledouleclick,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.file-item{
|
|
||||||
width: 8vw;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-item {
|
|
||||||
width: 8vw;
|
|
||||||
height: 8vw;
|
|
||||||
overflow: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0.1vw 1vw 0.1vw;
|
|
||||||
border: 0.1vh solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-item-icon > img {
|
|
||||||
width: 6vw;
|
|
||||||
height: 6vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.file-item-title{
|
|
||||||
width: 6vw;
|
|
||||||
height: 4vw;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
font-size: 1.2vw;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -0,0 +1,92 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="leftclick()" @dblclick="doubleclick()" @contextmenu.stop.prevent="rightclick($event)"
|
||||||
|
:class="{ 'file-item-selected' : is_selected }"
|
||||||
|
>
|
||||||
|
<div class="file-item-icon" >
|
||||||
|
<img src="@/assets/file_icon.png" alt="">
|
||||||
|
</div>
|
||||||
|
<FileTitle>
|
||||||
|
{{ item.name }}
|
||||||
|
</FileTitle>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import FileTitle from './FileTitle.vue';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FileFiled',
|
||||||
|
components:{
|
||||||
|
FileTitle,
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
item:{
|
||||||
|
type:Object,
|
||||||
|
required:true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props,context){
|
||||||
|
let store = useStore();
|
||||||
|
let is_selected = ref(false);
|
||||||
|
|
||||||
|
const leftclick = () => {
|
||||||
|
is_selected.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rightclick = (event) => {
|
||||||
|
context.emit('filerightclick',{
|
||||||
|
item:props.item,
|
||||||
|
menuposition:{
|
||||||
|
top: event.clientY + 'px',
|
||||||
|
left: event.clientX + 'px',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const doubleclick = () => {
|
||||||
|
store.commit('forwardPath',props.item.name + '/');
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
leftclick,
|
||||||
|
rightclick,
|
||||||
|
doubleclick,
|
||||||
|
is_selected,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.file-item {
|
||||||
|
width: 8vw;
|
||||||
|
height: 8vw;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 0.1vw 1vw 0.1vw;
|
||||||
|
border: 0.1vh solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item-icon > img {
|
||||||
|
width: 6vw;
|
||||||
|
height: 6vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-item-title{
|
||||||
|
width: 6vw;
|
||||||
|
height: 4vw;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 1.2vw;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item-selected {
|
||||||
|
border: 0.1vh solid #99d1ff;
|
||||||
|
background: #cce8ff;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-item-title">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FileTitle',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.file-item {
|
||||||
|
width: 8vw;
|
||||||
|
height: 8vw;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 0.1vw 1vw 0.1vw;
|
||||||
|
border: 0.1vh solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item-icon > img {
|
||||||
|
width: 6vw;
|
||||||
|
height: 6vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-item-title{
|
||||||
|
width: 6vw;
|
||||||
|
height: 4vw;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 1.2vw;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item-selected {
|
||||||
|
border: 0.1vh solid #99d1ff;
|
||||||
|
background: #cce8ff;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="leftclick()" @dblclick="doubleclick()" @contextmenu.stop.prevent="rightclick($event)"
|
||||||
|
:class="{ 'file-item-selected' : is_selected }"
|
||||||
|
>
|
||||||
|
<div class="file-item-icon" >
|
||||||
|
<img src="@/assets/folder_icon.png" alt="">
|
||||||
|
</div>
|
||||||
|
<FileTitle>
|
||||||
|
{{ item.name }}
|
||||||
|
</FileTitle>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FileTitle from './FileTitle.vue';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FolderFiled',
|
||||||
|
components:{
|
||||||
|
FileTitle,
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
item:{
|
||||||
|
type:Object,
|
||||||
|
required:true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props,context){
|
||||||
|
let store = useStore();
|
||||||
|
let is_selected = ref(false);
|
||||||
|
const leftclick = () => {
|
||||||
|
is_selected.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rightclick = (event) => {
|
||||||
|
context.emit('filerightclick',{
|
||||||
|
item:props.item,
|
||||||
|
menuposition:{
|
||||||
|
top: event.clientY + 'px',
|
||||||
|
left: event.clientX + 'px',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const doubleclick = () => {
|
||||||
|
store.commit('forwardPath',props.item.name + '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
leftclick,
|
||||||
|
rightclick,
|
||||||
|
doubleclick,
|
||||||
|
is_selected,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.file-item {
|
||||||
|
width: 8vw;
|
||||||
|
height: 8vw;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 0.1vw 1vw 0.1vw;
|
||||||
|
border: 0.1vh solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item-icon > img {
|
||||||
|
width: 6vw;
|
||||||
|
height: 6vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-item-title{
|
||||||
|
width: 6vw;
|
||||||
|
height: 4vw;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 1.2vw;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item-selected {
|
||||||
|
border: 0.1vh solid #99d1ff;
|
||||||
|
background: #cce8ff;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ul v-if="menutype === 'filemenu'" class="file-menu" :style="{top:menuposition.top,left:menuposition.left}">
|
||||||
|
<li>
|
||||||
|
<div @click="open_file">
|
||||||
|
打开
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
复制
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
粘贴
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
重命名
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
删除
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul v-else class="context-menu" :style="{top:menuposition.top,left:menuposition.left}">
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
新建
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
刷新
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>
|
||||||
|
粘贴
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li @click="turn_back">
|
||||||
|
后退
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
// import { computed } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name:"RightMenu",
|
||||||
|
props:{
|
||||||
|
menuposition:{
|
||||||
|
type:Object,
|
||||||
|
required:true,
|
||||||
|
},
|
||||||
|
menutype:{
|
||||||
|
type:String,
|
||||||
|
required:true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props,context){
|
||||||
|
const open_file = () => {
|
||||||
|
context.emit('open_file');
|
||||||
|
}
|
||||||
|
|
||||||
|
const turn_back = () => {
|
||||||
|
|
||||||
|
context.emit('turn_back');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
open_file,
|
||||||
|
turn_back,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.file-menu {
|
||||||
|
/* 菜单样式 */
|
||||||
|
background-color: pink;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
position: fixed;
|
||||||
|
padding: 0; /* 移除默认的内边距 */
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
/* 其他样式 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-menu > li {
|
||||||
|
padding: 10px; /* 添加内边距以确保内容不紧贴边框 */
|
||||||
|
text-align: left; /* 内容左对齐 */
|
||||||
|
width: 100%; /* 列表项占据父容器的全部宽度 */
|
||||||
|
box-sizing: border-box; /* 包含内边距和边框在内计算元素的总宽度 */
|
||||||
|
background-color: #f9f9f9; /* 可选:为列表项添加背景色 */
|
||||||
|
border-bottom: 1px solid #ddd; /* 可选:为列表项添加底部边框 */
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu {
|
||||||
|
/* 菜单样式 */
|
||||||
|
background-color: pink;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
position: fixed;
|
||||||
|
padding: 0; /* 移除默认的内边距 */
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
/* 其他样式 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu > li {
|
||||||
|
padding: 10px; /* 添加内边距以确保内容不紧贴边框 */
|
||||||
|
text-align: left; /* 内容左对齐 */
|
||||||
|
width: 100%; /* 列表项占据父容器的全部宽度 */
|
||||||
|
box-sizing: border-box; /* 包含内边距和边框在内计算元素的总宽度 */
|
||||||
|
background-color: #f9f9f9; /* 可选:为列表项添加背景色 */
|
||||||
|
border-bottom: 1px solid #ddd; /* 可选:为列表项添加底部边框 */
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<ContentBase>
|
||||||
|
<div class="row justify-content-md-center">
|
||||||
|
<div class="col-3">
|
||||||
|
<form @submit.prevent="login">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="username" class="form-label">用户名</label>
|
||||||
|
<input v-model="username" type="text" class="form-control" id="username">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">密码</label>
|
||||||
|
<input v-model="password" type="password" class="form-control" id="password">
|
||||||
|
</div>
|
||||||
|
<div class="error-message">{{ error_message }}</div>
|
||||||
|
<button type="submit" class="btn btn-primary">登录</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ContentBase>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentBase from '../components/ContentBase';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
import router from '@/router/index.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LoginView',
|
||||||
|
components: {
|
||||||
|
ContentBase,
|
||||||
|
},
|
||||||
|
setup(){
|
||||||
|
let store = useStore();
|
||||||
|
let username = ref('123');
|
||||||
|
let password = ref('123');
|
||||||
|
let error_message = ref('');
|
||||||
|
|
||||||
|
const login = () => {
|
||||||
|
// http://47.106.113.194:8000/token/
|
||||||
|
store.dispatch('login',{
|
||||||
|
username:username.value,
|
||||||
|
password:password.value,
|
||||||
|
success(){
|
||||||
|
error_message.value = '';
|
||||||
|
router.push({name:'home'});
|
||||||
|
},
|
||||||
|
error(){
|
||||||
|
error_message.value = "用户名或密码错误";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
error_message,
|
||||||
|
login,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<ContentBase>
|
||||||
|
404
|
||||||
|
</ContentBase>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentBase from '../components/ContentBase';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'NotFoundView',
|
||||||
|
components: {
|
||||||
|
ContentBase,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<ContentBase>
|
||||||
|
<div class="row justify-content-md-center">
|
||||||
|
<div class="col-3">
|
||||||
|
<form @submit.prevent="register">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="username" class="form-label">用户名</label>
|
||||||
|
<input v-model="username" type="text" class="form-control" id="username">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">密码</label>
|
||||||
|
<input v-model="password" type="password" class="form-control" id="password">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">确认密码</label>
|
||||||
|
<input v-model="password_confirm" type="password" class="form-control" id="password_confirm">
|
||||||
|
</div>
|
||||||
|
<div class="error-message">{{ error_message }}</div>
|
||||||
|
<button type="submit" class="btn btn-primary">注册</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ContentBase>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentBase from '../components/ContentBase';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
import $ from 'jquery';
|
||||||
|
import router from '@/router/index.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'RegisterView',
|
||||||
|
components: {
|
||||||
|
ContentBase,
|
||||||
|
},
|
||||||
|
setup(){
|
||||||
|
let store = useStore();
|
||||||
|
let username = ref('');
|
||||||
|
let password = ref('');
|
||||||
|
let password_confirm = ref('');
|
||||||
|
let error_message = '';
|
||||||
|
|
||||||
|
const register = () => {
|
||||||
|
$.ajax({
|
||||||
|
url:'http://47.106.113.194:8000/register/',
|
||||||
|
type:'post',
|
||||||
|
data:{
|
||||||
|
username:username.value,
|
||||||
|
password:password.value,
|
||||||
|
password_confirm:password_confirm.value,
|
||||||
|
},
|
||||||
|
success(resp){
|
||||||
|
console.log(resp);
|
||||||
|
if (resp.result === 'success'){
|
||||||
|
store.dispatch('login',{
|
||||||
|
username:username.value,
|
||||||
|
password:password.value,
|
||||||
|
success(){
|
||||||
|
error_message = '';
|
||||||
|
router.push({name:'home'});
|
||||||
|
},
|
||||||
|
error(){
|
||||||
|
error_message = "系统异常";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error_message = resp.result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
password_confirm,
|
||||||
|
error_message,
|
||||||
|
register,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<ContentBase>
|
||||||
|
<div>
|
||||||
|
{{ $store.state.user.username }}
|
||||||
|
</div>
|
||||||
|
</ContentBase>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentBase from '../components/ContentBase';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UserProfileView',
|
||||||
|
components: {
|
||||||
|
ContentBase,
|
||||||
|
},
|
||||||
|
setup(){
|
||||||
|
let store = useStore();
|
||||||
|
return {
|
||||||
|
store,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
|
|
Loading…
Reference in new issue