Compare commits
4 Commits
3cf483c422
...
9ad162a5b9
| Author | SHA1 | Date |
|---|---|---|
|
|
9ad162a5b9 | |
|
|
a4a5e7ce9b | |
|
|
34ad23db7a | |
|
|
585ed83a3f |
|
|
@ -26,8 +26,7 @@
|
|||
"@vue/cli-service": "~5.0.0",
|
||||
"element-plus": "^2.3.14",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"raw-loader": "^4.0.2"
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
|
|
@ -9331,58 +9330,6 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-loader": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
|
||||
"integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loader-utils": "^2.0.0",
|
||||
"schema-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-loader/node_modules/loader-utils": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
|
||||
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-loader/node_modules/schema-utils": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
|
||||
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "16.14.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@
|
|||
"@vue/cli-service": "~5.0.0",
|
||||
"element-plus": "^2.3.14",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"raw-loader": "^4.0.2"
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
|
|
|||
95
src/App.vue
95
src/App.vue
|
|
@ -1,13 +1,23 @@
|
|||
<template>
|
||||
<div id="navibar" class="pconly" >
|
||||
<div class="navi-item"><el-link @click="go('/')" id="logo">wordIn</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/select')" class="link">背诵</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/manage')" class="link">编辑单词本</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/manual')" class="link">使用说明</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/about')" class="link">关于</el-link></div>
|
||||
<div class="pconly">
|
||||
<div id="navibar">
|
||||
<div class="navi-item"><el-link @click="go('/')" id="logo">wordIn</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/select')" class="link">背诵</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/manage')" class="link">编辑单词本</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/manual')" class="link">使用说明</el-link></div>
|
||||
<div class="navi-item"><el-link @click="go('/about')" class="link">关于</el-link></div>
|
||||
</div>
|
||||
</div>
|
||||
<router-view style=""></router-view>
|
||||
<div class="mbonly">
|
||||
<div id="navibar">
|
||||
<div class="navi-item"><box-icon name="home-alt-2" @click="$router.push('/')" color="var(--text-color)" size="27px"></box-icon><div>主页</div></div>
|
||||
<div class="navi-item"><box-icon name="book-open" @click="$router.push('/select')" color="var(--text-color)" size="27px"></box-icon><div>背诵</div></div>
|
||||
<div class="navi-item"><box-icon name="folder" @click="$router.push('/manage')" color="var(--text-color)" size="27px"></box-icon><div>浏览</div></div>
|
||||
<div class="navi-item"><box-icon name="file" @click="$router.push('/manual')" color="var(--text-color)" size="27px"></box-icon><div>说明</div></div>
|
||||
<div class="navi-item"><box-icon name="info-circle" @click="$router.push('/about')" color="var(--text-color)" size="27px"></box-icon><div>关于</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<router-view style="margin-top: 10px;"></router-view>
|
||||
<!-- <div id="navibar" class="mbonly"></div> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -106,13 +116,19 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
#app{
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
html {
|
||||
--bg-color-solid:#e8e8e8;
|
||||
--bg-color: #ffffffae;
|
||||
--text-color: #464646;
|
||||
--bd-color: #bbbbbb99;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--bg-color-solid:#191919;
|
||||
--bg-color: #2a2a2a88;
|
||||
--text-color: #c0c0c0;
|
||||
--bd-color: #7f7f7f7c;
|
||||
|
|
@ -144,7 +160,8 @@ html.dark {
|
|||
color: var(--text-color);
|
||||
transition: .5s;
|
||||
}
|
||||
.card:hover{
|
||||
|
||||
.card:hover {
|
||||
box-shadow: var(--el-box-shadow);
|
||||
}
|
||||
|
||||
|
|
@ -168,25 +185,57 @@ html.bgimged .card {
|
|||
.para {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
.blured {
|
||||
filter: blur(10px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
#navibar {
|
||||
height: 60px;
|
||||
border-bottom: solid 1px var(--bd-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: var(--navi-bg-color);
|
||||
backdrop-filter: blur(10px);
|
||||
@media screen and (max-width: 500px) {
|
||||
#navibar {
|
||||
height: 55px;
|
||||
border-top: solid 1px var(--bd-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
background-color: var(--navi-bg-color);
|
||||
backdrop-filter: blur(10px);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navi-item {
|
||||
height: 100%;
|
||||
font-size: 11px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: baseline;
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
|
||||
.navi-item {
|
||||
height: 100%;
|
||||
font-size: 22px;
|
||||
display: flex;
|
||||
justify-content: baseline;
|
||||
margin-left: 20px;
|
||||
color: var(--text-color);
|
||||
@media screen and (min-width: 500px) {
|
||||
#navibar {
|
||||
height: 60px;
|
||||
border-bottom: solid 1px var(--bd-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: var(--navi-bg-color);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.navi-item {
|
||||
height: 100%;
|
||||
font-size: 22px;
|
||||
display: flex;
|
||||
justify-content: baseline;
|
||||
margin-left: 20px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
|
||||
#logo {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<div style="flex-grow: 2;margin:30px;" class="rowbox">
|
||||
<div style="font-size: 25px;color: var(--text-color);font-weight: 600;">欢迎使用</div>
|
||||
<div id="title">wordIn</div>
|
||||
<div>当前版本: 1.01 更新时间:2024年1月11日 10:43 AM</div>
|
||||
<div>当前版本: 1.02 Beta 2 <br/> 更新时间:2024年1月11日 5:07 PM</div>
|
||||
</div>
|
||||
<div style="flex-grow: 1;align-items: center;" class="colbox card">
|
||||
<router-link to="/select" class="button">
|
||||
|
|
@ -122,12 +122,12 @@ export default {
|
|||
color: var(--text-color);
|
||||
text-shadow: #00000057 5px 5px 20px;
|
||||
line-height: 100px;
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 800;
|
||||
font-weight: 600;
|
||||
color: var(--text-color);
|
||||
font-size: 35px;
|
||||
text-overflow: ellipsis;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div id="mask" v-if="visible">
|
||||
<div ref="bg" id="bg">
|
||||
<div id="content">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
<div id="close" @click="handleClose"><box-icon color="var(--text-color)" size="20px" name="x"></box-icon></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"CDiaLog",
|
||||
props:{
|
||||
"visible":{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handleClose(){
|
||||
this.$refs.bg.style.animation = "cui-dialog-disappear .3s ease-in";
|
||||
setTimeout(()=>this.$emit("update:visible",false),300);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes cui-dialog-appear {
|
||||
0%{
|
||||
opacity: 0%;
|
||||
transform: translate(-50%,-50%) scale(0.5);
|
||||
}
|
||||
100%{
|
||||
opacity: 100%;
|
||||
transform: translate(-50%,-50%) scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes cui-dialog-disappear {
|
||||
0%{
|
||||
opacity: 100%;
|
||||
transform: translate(-50%,-50%) scale(1);
|
||||
}
|
||||
100%{
|
||||
opacity: 0%;
|
||||
transform: translate(-50%,-50%) scale(0.5);
|
||||
}
|
||||
}
|
||||
@keyframes cui-dialog-blur{
|
||||
0%{
|
||||
backdrop-filter:blur(0px);
|
||||
}
|
||||
100%{
|
||||
backdrop-filter:blur(10px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
#mask{
|
||||
z-index: 500;
|
||||
position: absolute;
|
||||
top:0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
backdrop-filter: blur(10px);
|
||||
animation: cui-dialog-blur .5s ;
|
||||
}
|
||||
#bg{
|
||||
position: absolute;
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
max-width: 80%;
|
||||
border: solid var(--bd-color) 1px;
|
||||
background-color: var(--bg-color-solid);
|
||||
border-radius: 8px;
|
||||
transform: translate(-50%,-50%);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
animation: cui-dialog-appear .4s cubic-bezier(0, 0, 0.36, 1.29);
|
||||
}
|
||||
#content{
|
||||
padding: 20px;
|
||||
height: 100%;
|
||||
}
|
||||
#close{
|
||||
position: absolute;
|
||||
right:0;
|
||||
top: 0;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -4,6 +4,19 @@
|
|||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ set }} : {{ book }} ({{ id }}) </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-dropdown trigger="click">
|
||||
<el-button>
|
||||
操作<box-icon color="var(--text-color)" name='chevron-down' size="20px"></box-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="download"><box-icon color="var(--text-color)" name='download'
|
||||
size="20px"></box-icon>下载</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-page-header>
|
||||
<div class="colbox" id="main">
|
||||
<div style="flex-grow: 1;" class="card">
|
||||
|
|
@ -19,8 +32,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from 'axios';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
export default {
|
||||
name: "NoteEditor",
|
||||
|
|
@ -29,12 +41,19 @@ export default {
|
|||
table: [],
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
download(){
|
||||
this.$store.state.wordsets.fromArray(this.table,this.book,this.name);
|
||||
ElMessage("下载完毕");
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.set = this.$route.query.set;
|
||||
this.book = this.$route.query.book;
|
||||
this.id = this.$route.query.id;
|
||||
this.name = this.$route.query.name || "default";
|
||||
if (this.set && this.book && this.id) {
|
||||
axios.get("./wordset/detail", {
|
||||
this.$axios.get("wordset/detail", {
|
||||
params:{
|
||||
set: this.set, book: this.book, id: this.id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,31 @@
|
|||
<template>
|
||||
<div class="container" style="overflow: auto;">
|
||||
<el-page-header style="margin: 10px;" @back="this.$router.push('/manage');">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ name }} ({{ id }}) </span>
|
||||
</template>
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ name }} ({{ id }}) </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-dropdown trigger="click">
|
||||
<el-button>
|
||||
操作<box-icon color="var(--text-color)" name='chevron-down' size="20px"></box-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="del_set"><box-icon color="var(--text-color)" name='trash'
|
||||
size="20px"></box-icon>删除</el-dropdown-item>
|
||||
<el-dropdown-item @click="addTo"><box-icon color="var(--text-color)" name='plus'
|
||||
size="18px"></box-icon>添加到</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-page-header>
|
||||
<div class="colbox" id="main">
|
||||
<div class="rowbox">
|
||||
<div class="card">
|
||||
<div class="title">添加单词</div>
|
||||
<el-input ref="input1" autofocus @change="focusnext($refs.input2)" v-model="new_word.word"></el-input>
|
||||
<el-input ref="input1" autofocus @change="focusnext($refs.input2)"
|
||||
v-model="new_word.word"></el-input>
|
||||
<div class="colbox">
|
||||
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
|
||||
<el-input ref="input2" @change="focusnext($refs.input3)" v-model="new_word.trans"></el-input>
|
||||
|
|
@ -17,7 +33,8 @@
|
|||
<div class="colbox">
|
||||
<el-text class="mx-1" style="width: 80px;">词性:</el-text>
|
||||
<el-select ref="input3" v-model="new_word.type" class="m-2" placeholder="Select">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button @click="add_word()" type="primary">添加</el-button>
|
||||
|
|
@ -51,28 +68,54 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="word_editing" width="80%">
|
||||
<div class="title">修改单词</div>
|
||||
<el-input v-model="editing_word.word"></el-input>
|
||||
<div class="colbox">
|
||||
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
|
||||
<el-input v-model="editing_word.trans"></el-input>
|
||||
</div>
|
||||
<div class="colbox">
|
||||
<el-text class="mx-1" style="width: 80px;">词性:</el-text>
|
||||
<el-select v-model="editing_word.type" class="m-2" placeholder="Select">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button @click="save_word" type="primary">更改</el-button>
|
||||
</el-dialog>
|
||||
<CDialog v-model:visible="word_editing">
|
||||
<template #content>
|
||||
<div class="title">修改单词</div>
|
||||
<el-input v-model="editing_word.word"></el-input>
|
||||
<div class="colbox">
|
||||
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
|
||||
<el-input v-model="editing_word.trans"></el-input>
|
||||
</div>
|
||||
<div class="colbox">
|
||||
<el-text class="mx-1" style="width: 80px;">词性:</el-text>
|
||||
<el-select v-model="editing_word.type" class="m-2" placeholder="Select">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button @click="save_word" type="primary">更改</el-button>
|
||||
</template>
|
||||
</CDialog>
|
||||
<CDialog v-model:visible="select.visible">
|
||||
<template #content>
|
||||
<el-text class="mx-1 title">选择加入的单词本</el-text>
|
||||
<div class="colbox para">
|
||||
<div class="mid-text">分组:</div>
|
||||
<el-select v-model="select.set_class" class="m-2" placeholder="Select">
|
||||
<el-option v-for="item in $store.state.wordsets._allclass" :key="item" :label="item"
|
||||
:value="item" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="colbox para">
|
||||
<div class="mid-text">单词本:</div>
|
||||
<el-select v-model="select.id" class="m-2" placeholder="Select">
|
||||
<el-option v-for="item in $store.state.wordsets.getClass(select.set_class)" :key="item.id"
|
||||
:label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button @click="select.confirm(select.id)" type="primary">确认</el-button>
|
||||
</template>
|
||||
</CDialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import CDialog from '../UI/CDialog.vue'
|
||||
|
||||
export default {
|
||||
name: "NoteEditor",
|
||||
components: {
|
||||
CDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
new_word: {
|
||||
|
|
@ -90,8 +133,13 @@ export default {
|
|||
table: [],
|
||||
word_editing: false,
|
||||
new_name: "",
|
||||
name:"",
|
||||
id:""
|
||||
name: "",
|
||||
id: "",
|
||||
select: {
|
||||
visible: false,
|
||||
set_class: "",
|
||||
id: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -113,7 +161,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.table.push(Object.assign({}, this.new_word));
|
||||
this.$store.state.wordsets.saveSet(this.id,this.table);
|
||||
this.$store.state.wordsets.saveSet(this.id, this.table);
|
||||
ElMessage({
|
||||
message: `已添加 ${this.new_word.word} (${this.new_word.type})`,
|
||||
type: 'success',
|
||||
|
|
@ -143,7 +191,7 @@ export default {
|
|||
type: this.editing_word.type,
|
||||
trans: this.editing_word.trans,
|
||||
}
|
||||
this.$store.state.wordsets.saveSet(this.id,this.table);
|
||||
this.$store.state.wordsets.saveSet(this.id, this.table);
|
||||
ElMessage({
|
||||
message: `已保存更改`,
|
||||
type: 'success',
|
||||
|
|
@ -153,7 +201,7 @@ export default {
|
|||
change_name() {
|
||||
let old_name = this.name;
|
||||
this.name = this.new_name;
|
||||
this.$store.state.wordsets.renameSet(this.class_name,this.id,this.new_name);
|
||||
this.$store.state.wordsets.renameSet(this.class_name, this.id, this.new_name);
|
||||
ElMessage({
|
||||
message: `已更改 ${old_name} 为 ${this.name}`,
|
||||
type: 'success',
|
||||
|
|
@ -163,20 +211,42 @@ export default {
|
|||
del_word(index) {
|
||||
let word = this.table[index].word.concat();
|
||||
this.table.splice(index, 1);
|
||||
this.$store.state.wordsets.saveSet(this.id,this.table);
|
||||
this.$store.state.wordsets.saveSet(this.id, this.table);
|
||||
ElMessage({
|
||||
message: `已删除 ${word}`,
|
||||
type: 'warning',
|
||||
});
|
||||
},
|
||||
del_set() {
|
||||
ElMessageBox.confirm("确定要删除吗?")
|
||||
.then(() => {
|
||||
let index = this.$store.state.wordsets.getId(this.class_name, this.id);
|
||||
this.$store.state.wordsets.delSet(this.class_name, index);
|
||||
ElMessage(`已经删除 ${this.class_name} ${this.id}`);
|
||||
this.$router.push("/manage");
|
||||
});
|
||||
},
|
||||
addTo() {
|
||||
this.select.visible = true;
|
||||
this.select.confirm = (dest_id) => {
|
||||
if (this.id) {
|
||||
if(this.id != dest_id){
|
||||
let failed = this.$store.state.wordsets.addSetTo(this.id, dest_id);
|
||||
ElMessage(`已经添加到 ${dest_id}, 已经去除 ${failed} 个重复单词`);
|
||||
}
|
||||
else ElMessage(`请选择一个不同的单词本`);
|
||||
|
||||
}
|
||||
this.select.visible = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.class_name = this.$route.query.classname;
|
||||
this.id = this.$route.query.id;
|
||||
if(this.id){
|
||||
let status = this.$store.state.wordsets.getSetStatus(this.class_name,this.id);
|
||||
if(status){
|
||||
if (this.id) {
|
||||
let status = this.$store.state.wordsets.getSetStatus(this.class_name, this.id);
|
||||
if (status) {
|
||||
this.name = status.name;
|
||||
}
|
||||
this.table = this.$store.state.wordsets.getSet(this.id);
|
||||
|
|
@ -187,31 +257,31 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
@media screen and (max-width: 500px) {
|
||||
#main{
|
||||
#main {
|
||||
flex-direction: column;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.title{
|
||||
.title {
|
||||
font-size: 25px;
|
||||
min-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
.title{
|
||||
.title {
|
||||
font-size: 35px;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.container{
|
||||
.container {
|
||||
padding: 10px;
|
||||
height: calc(100% - 70px);
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#main{
|
||||
#main {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,46 +6,61 @@
|
|||
<span class="text-large font-600 mr-3"> 编辑单词本 </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="pconly">
|
||||
<el-button @click="manage_online_wordsets" type="primary"><box-icon color="white" name='world'
|
||||
size="20px"></box-icon>管理在线单词本</el-button>
|
||||
<el-button @click="export_set" type="success"><box-icon color="white" name='export'
|
||||
size="18px"></box-icon>导出</el-button>
|
||||
<el-button @click="import_set" type="warning"><box-icon color="white" name='import'
|
||||
size="18px"></box-icon>导入</el-button>
|
||||
<el-button @click="$router.push('/manage/new')" type="primary"><box-icon color="white"
|
||||
<div class="colbox">
|
||||
<el-button @click="$router.push('/manage/new')" type="success"><box-icon color="white"
|
||||
name='plus'></box-icon>新建单词本</el-button>
|
||||
<div class="pconly">
|
||||
<el-dropdown trigger="click" style="margin-left: 20px;">
|
||||
<el-button type="primary">
|
||||
更多<box-icon color="white" name='chevron-down' size="20px"></box-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="manage_online_wordsets"><box-icon color="white"
|
||||
name='world' size="20px"></box-icon>管理在线单词本</el-dropdown-item>
|
||||
<el-dropdown-item @click="export_set"><box-icon color="white" name='export'
|
||||
size="18px"></box-icon>导出</el-dropdown-item>
|
||||
<el-dropdown-item @click="import_set"><box-icon color="white" name='import'
|
||||
size="18px"></box-icon>导入</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-page-header>
|
||||
<div class="mbonly">
|
||||
<el-button @click="$router.push('/manage/new')" type="primary"><box-icon color="white"
|
||||
name='plus'></box-icon>新建单词本</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-container style="height:calc(100% - 200px);position: relative;">
|
||||
<el-aside id="sidebar">
|
||||
<div class="sidebar-title">
|
||||
|本地
|
||||
</div>
|
||||
<div v-for="class_name in $store.state.wordsets._allclass" :title="class_name" :key="class_name"
|
||||
@click="view(class_name)" class="sidebar-item">
|
||||
{{ class_name }}
|
||||
</div>
|
||||
<div class="sidebar-title">
|
||||
|在线
|
||||
</div>
|
||||
<div v-for="set in Object.keys(online_wordsets)" :key="set">
|
||||
<div v-for="(set_class, class_name) in online_wordsets[set]" :title="class_name" :key="class_name"
|
||||
@click="view_online(set, class_name)" class="sidebar-item">
|
||||
{{ class_name }}
|
||||
<el-aside id="aside">
|
||||
<div id="sidebar" class="sidebar-hidden">
|
||||
<div id="sidebar-content">
|
||||
<div class="sidebar-title">
|
||||
|本地
|
||||
</div>
|
||||
<div v-for="class_name in $store.state.wordsets._allclass" :title="class_name" :key="class_name"
|
||||
@click="view(class_name)" class="sidebar-item">
|
||||
{{ class_name }}
|
||||
</div>
|
||||
<div class="sidebar-title">
|
||||
|在线
|
||||
</div>
|
||||
<div v-for="set in Object.keys(online_wordsets)" :key="set">
|
||||
<div v-for="(set_class, class_name) in online_wordsets[set]" :title="class_name"
|
||||
:key="class_name" @click="view_online(set, class_name)" class="sidebar-item">
|
||||
{{ class_name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mbonly" id="show-sidebar" @click="taggle_sidebar">
|
||||
<box-icon name='list-ul' color="var(--text-color)"></box-icon>
|
||||
</div>
|
||||
</div>
|
||||
</el-aside>
|
||||
<el-main id="wordsets-container">
|
||||
<div id="sets-container">
|
||||
<div v-if="mode === 0" class="colbox wordclass">
|
||||
<div v-for="(wordset, index) in $store.state.wordsets.getClass(view_wordsets)" :key="index" class="wordset rowbox">
|
||||
<div v-for="(wordset, index) in $store.state.wordsets.getClass(view_wordsets)" :key="index"
|
||||
class="wordset rowbox">
|
||||
<div class="no">
|
||||
{{ index + 1 }}
|
||||
</div>
|
||||
|
|
@ -73,14 +88,12 @@
|
|||
创建日期:{{ (new Date(wordset.created)).toLocaleString() }}
|
||||
</div>
|
||||
<div class="option">
|
||||
<box-icon class="btn" name='show' color="var(--text-color)" @click="show(index)"></box-icon>
|
||||
<box-icon class="btn" name='show' color="var(--text-color)"
|
||||
@click="show(index, wordset.name)"></box-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mbonly" id="show-sidebar" @click="taggle_sidebar">
|
||||
<box-icon name='list-ul' color="var(--text-color)"></box-icon>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
|
@ -88,7 +101,6 @@
|
|||
|
||||
<script>
|
||||
import { ElNotification, ElMessage, ElMessageBox } from 'element-plus';
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: "SetList",
|
||||
|
|
@ -128,20 +140,20 @@ export default {
|
|||
del(class_name, id, index) {
|
||||
ElMessageBox.confirm("确定要删除吗?")
|
||||
.then(() => {
|
||||
this.$store.state.wordsets.delSet(class_name,index);
|
||||
this.$store.state.wordsets.delSet(class_name, index);
|
||||
ElMessage(`已经删除 ${class_name} ${id}`);
|
||||
});
|
||||
},
|
||||
edit(id) {
|
||||
this.$router.push({
|
||||
path: "./manage/edit",
|
||||
query: { id,classname:this.view_wordsets}
|
||||
query: { id, classname: this.view_wordsets }
|
||||
})
|
||||
},
|
||||
show(id) {
|
||||
show(id, name) {
|
||||
this.$router.push({
|
||||
path: "./manage/show",
|
||||
query: { set: this.viewing.set, book: this.viewing.book, id }
|
||||
query: { set: this.viewing.set, book: this.viewing.book, id, name }
|
||||
})
|
||||
},
|
||||
async export_set() {
|
||||
|
|
@ -164,8 +176,11 @@ export default {
|
|||
},
|
||||
taggle_sidebar() {
|
||||
let node = document.getElementById("sidebar");
|
||||
if (node.style.width === "180px") node.style.width = "0";
|
||||
else node.style.width = "180px";
|
||||
let class_name = "sidebar-hidden";
|
||||
if(node.classList.contains(class_name)){
|
||||
node.classList.remove(class_name);
|
||||
}
|
||||
else node.classList.add(class_name);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
|
@ -176,7 +191,7 @@ export default {
|
|||
this.view(first_set);
|
||||
}, 0);
|
||||
}
|
||||
axios.get("/wordset/list").then(
|
||||
this.$axios.get("wordset/list").then(
|
||||
(res) => {
|
||||
this.online_wordsets = res.data;
|
||||
}
|
||||
|
|
@ -203,9 +218,21 @@ export default {
|
|||
height: 70px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
#aside {
|
||||
width: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
position: absolute;
|
||||
width: 180px;
|
||||
margin-top: 20px;
|
||||
transition: .5s;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.sidebar-hidden{
|
||||
transform: translate(-100%,0);
|
||||
}
|
||||
|
||||
.wordset {
|
||||
|
|
@ -243,6 +270,7 @@ export default {
|
|||
}
|
||||
|
||||
#show-sidebar {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -250,9 +278,8 @@ export default {
|
|||
border-radius: 100%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
bottom: 0;
|
||||
right: -50px;
|
||||
color: var(--text-color);
|
||||
box-shadow: var(--el-box-shadow);
|
||||
background-color: var(--bg-color);
|
||||
|
|
@ -263,6 +290,7 @@ export default {
|
|||
#wordsets-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
#sets-container {
|
||||
|
|
@ -287,8 +315,15 @@ export default {
|
|||
height: 60px;
|
||||
}
|
||||
|
||||
#aside {
|
||||
width:180px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
width: 180px;
|
||||
animation: sidebar-enter ease-out .6s backwards;
|
||||
padding-left: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.wordset {
|
||||
|
|
@ -325,29 +360,30 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.wordset{
|
||||
.wordset {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
transition: .5s;
|
||||
border: solid 1px var(--bd-color);
|
||||
}
|
||||
|
||||
.wordset:hover{
|
||||
.wordset:hover {
|
||||
box-shadow: var(--el-box-shadow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#sidebar {
|
||||
background-color: var(--bg-color);
|
||||
background-color: var(--bg-color-solid);
|
||||
border-radius: 5px;
|
||||
height: calc(100% - 100px);
|
||||
border: 1px solid var(--bd-color);
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
#sidebar-content{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
animation: sidebar-enter ease-out .6s backwards;
|
||||
height: calc(100% - 100px);
|
||||
padding-left: 10px;
|
||||
margin: 10px;
|
||||
border: 1px solid var(--bd-color);
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
|
|
@ -418,4 +454,8 @@ html.bgimged .wordset {
|
|||
--el-collapse-content-bg-color: #FFFFFF00;
|
||||
--el-collapse-header-font-size: 18px;
|
||||
}
|
||||
|
||||
.el-aside {
|
||||
overflow: visible;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -83,7 +83,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
export default {
|
||||
|
|
@ -161,7 +160,7 @@ export default {
|
|||
}
|
||||
}
|
||||
document.addEventListener('keyup', this.key_listener);
|
||||
axios.get("/wordset/list").then((res, err) => {
|
||||
this.$axios.get("wordset/list").then((res, err) => {
|
||||
if (err) {
|
||||
ElMessage({
|
||||
message: "在线词库加载失败",
|
||||
|
|
@ -207,7 +206,8 @@ export default {
|
|||
/* margin: 20px; */
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
flex-direction: column;
|
||||
margin-top:10px;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 23px;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import axios from 'axios'
|
||||
import axios from './request.js'
|
||||
const limit = 10;
|
||||
export default class _history {
|
||||
constructor() {
|
||||
|
|
@ -81,7 +81,7 @@ export default class _history {
|
|||
else return this.handle_err("单词本不存在",err);
|
||||
}
|
||||
for (let i of history.onlinesets) {
|
||||
let res = await axios.get("/wordset/detail", {
|
||||
let res = await axios.get("wordset/detail", {
|
||||
params: i
|
||||
})
|
||||
if (res.status != 200) {
|
||||
|
|
@ -97,17 +97,17 @@ export default class _history {
|
|||
}
|
||||
else words = words.concat(...temp);
|
||||
}
|
||||
let arr = Array.from(new Array(words.length).keys());
|
||||
if(history.settings.shuffle){
|
||||
let seed = history.settings.seed;
|
||||
for (let i = this.total - 1; i > 0; i--) {
|
||||
[arr[i], arr[seed % i]] = [arr[seed % i], arr[i]];
|
||||
}
|
||||
}
|
||||
history.total = words.length;
|
||||
if(words.length <= 0){
|
||||
return this.handle_err("单词本为空",err);
|
||||
}
|
||||
history.total = words.length;
|
||||
let arr = Array.from(new Array(words.length).keys());
|
||||
if(history.settings.shuffle){
|
||||
let seed = history.settings.seed;
|
||||
for (let i = words.length - 1; i > 0; i--) {
|
||||
[arr[i], arr[seed % i]] = [arr[seed % i], arr[i]];
|
||||
}
|
||||
}
|
||||
this.save();
|
||||
if (typeof callback === 'function') {
|
||||
callback(words,history.current,arr,history.settings);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
import axios from 'axios'
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL:"./",
|
||||
timeout:6000,
|
||||
})
|
||||
|
||||
export default instance;
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import uuid from 'node-uuid';
|
||||
|
||||
|
||||
export default class _wordset {
|
||||
constructor() {
|
||||
this.sets = {};
|
||||
|
|
@ -40,6 +41,14 @@ export default class _wordset {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
getId(class_name,id){
|
||||
let set_class = this.sets[class_name];
|
||||
for(let index in set_class){
|
||||
if(set_class[index].id === id){
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
getSet(id) {
|
||||
let sets = JSON.parse(localStorage.getItem(id));
|
||||
if (sets) {
|
||||
|
|
@ -75,7 +84,7 @@ export default class _wordset {
|
|||
});
|
||||
localStorage.setItem(id, JSON.stringify([]));
|
||||
this.save();
|
||||
return;
|
||||
return id;
|
||||
}
|
||||
saveSet(id,data){
|
||||
localStorage.setItem(id, JSON.stringify(data));
|
||||
|
|
@ -92,6 +101,24 @@ export default class _wordset {
|
|||
}
|
||||
}
|
||||
}
|
||||
addSetTo(origin_id,dest_id){
|
||||
let origin_set = this.getSet(origin_id);
|
||||
let dest_set = this.getSet(dest_id);
|
||||
let set={};
|
||||
origin_set.forEach(element => {
|
||||
set[element.word] = element;
|
||||
});
|
||||
dest_set.forEach(element => {
|
||||
set[element.word] = element;
|
||||
});
|
||||
set = Object.values(set);
|
||||
this.saveSet(dest_id,set);
|
||||
return origin_set.length + dest_set.length - set.length;
|
||||
}
|
||||
fromArray(arr,class_name,name){
|
||||
let id = this.addSet(class_name,name);
|
||||
this.saveSet(id,arr);
|
||||
}
|
||||
async import_set(callback){
|
||||
let [fileHandle] = await window.showOpenFilePicker({
|
||||
types: [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
import {
|
||||
ElForm,
|
||||
ElButton,
|
||||
ElInput,
|
||||
ElCheckbox,
|
||||
ElDialog,
|
||||
ElTable,
|
||||
ElStep,
|
||||
ElLink,
|
||||
ElCard,
|
||||
ElCheckboxGroup,
|
||||
ElDropdown,
|
||||
ElFooter,
|
||||
ElMain,
|
||||
ElContainer,
|
||||
ElHeader,
|
||||
ElPageHeader,
|
||||
ElTabs,
|
||||
ElTabPane,
|
||||
ElSteps,
|
||||
ElSwitch,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
} from 'element-plus'
|
||||
|
||||
const element = {
|
||||
install: function(app) {
|
||||
app.use(ElForm)
|
||||
app.use(ElButton)
|
||||
app.use(ElInput)
|
||||
app.use(ElCheckbox)
|
||||
app.use(ElDialog)
|
||||
app.use(ElTable)
|
||||
app.use(ElStep)
|
||||
app.use(ElLink)
|
||||
app.use(ElCard)
|
||||
app.use(ElCheckboxGroup)
|
||||
app.use(ElDropdown)
|
||||
app.use(ElFooter)
|
||||
app.use(ElMain)
|
||||
app.use(ElContainer)
|
||||
app.use(ElHeader)
|
||||
app.use(ElPageHeader)
|
||||
app.use(ElTabPane)
|
||||
app.use(ElSteps)
|
||||
app.use(ElTabs)
|
||||
app.use(ElSwitch)
|
||||
app.use(ElSelect)
|
||||
app.use(ElOption)
|
||||
}
|
||||
}
|
||||
|
||||
export default element
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
import { createApp } from 'vue'
|
||||
import {createApp} from 'vue'
|
||||
import App from './App.vue'
|
||||
import { createStore } from 'vuex'
|
||||
import ElementPlus from 'element-plus'
|
||||
// import ElementPlus from 'element-plus'
|
||||
import element from './loader/el-loader'
|
||||
import 'element-plus/dist/index.css'
|
||||
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||
import 'boxicons'
|
||||
import router from './router.js'
|
||||
import axios from './js/request.js'
|
||||
|
||||
const app = createApp(App);
|
||||
const store = createStore({
|
||||
|
|
@ -13,6 +15,7 @@ const store = createStore({
|
|||
}
|
||||
});
|
||||
app.use(store);
|
||||
app.use(ElementPlus);
|
||||
app.use(element);
|
||||
app.use(router);
|
||||
app.config.globalProperties.$axios = axios;
|
||||
app.mount('#app');
|
||||
|
|
@ -23,6 +23,29 @@ wordIn 的前端代码已经开源 [Git Repository](https://git.zjueva.net/cast1
|
|||
|
||||
## 3.更新日志
|
||||
|
||||
### 1.0.2 Beta 2
|
||||
|
||||
1. 更新内容
|
||||
|
||||
- 减小了打包体积
|
||||
|
||||
2. Bug修复进度
|
||||
|
||||
- (解决中)自定义背景
|
||||
- (已解决)移动端UI错位问题
|
||||
|
||||
### 1.0.2 Beta 1
|
||||
|
||||
1. 更新内容
|
||||
|
||||
- 重写对话框组件
|
||||
- 增加了一些单词本管理功能
|
||||
|
||||
2. Bug修复进度
|
||||
|
||||
- (解决中)自定义背景
|
||||
- (解决中)移动端UI错位问题
|
||||
|
||||
### 1.0.1 Release
|
||||
|
||||
#### 1.0.1 是wordIn第一个正式版
|
||||
|
|
@ -42,6 +65,16 @@ wordIn 的前端代码已经开源 [Git Repository](https://git.zjueva.net/cast1
|
|||
- (已修复)查看之前的单词时溢出的错误
|
||||
- (解决中)手机端适配问题
|
||||
|
||||
#### Patch 1
|
||||
|
||||
- 增加了移动端底部导航栏
|
||||
- 修复了无法随机顺序问题
|
||||
|
||||
#### Patch 2
|
||||
|
||||
- 封装网络请求
|
||||
- 其他源码优化
|
||||
|
||||
### 1.0
|
||||
|
||||
#### 1.0 及之前的版本汇总
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ const path = require('path');
|
|||
module.exports = defineConfig({
|
||||
transpileDependencies: true,
|
||||
publicPath:"./",
|
||||
outputDir:"page",
|
||||
devServer: {
|
||||
proxy: 'https://localhost:443'
|
||||
proxy: 'https://app.cast1e.top/wordin'
|
||||
},
|
||||
chainWebpack: config => {
|
||||
config.module
|
||||
|
|
|
|||
Loading…
Reference in New Issue