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