This commit is contained in:
username 2024-06-23 17:28:19 +08:00
parent 3cc7577049
commit 14c8964a0c
16 changed files with 1076 additions and 364 deletions

823
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,13 +8,20 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^1.0.2",
"axios": "^1.6.8",
"core-js": "^3.8.3",
"dayjs": "^1.11.10",
"element-ui": "^2.15.14",
"masonry-layout": "^4.2.2",
"quill": "^1.3.7",
"quill-image-drop-module": "^1.0.3",
"quill-image-extend-module": "^1.1.2",
"quill-image-resize-module": "^3.0.0",
"vue": "^2.6.14",
"vue-lazyload": "^3.0.0",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
},
@ -31,7 +38,7 @@
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^8.0.3",
"eslint-plugin-vue": "^7.0.0",
"less": "^4.0.0",
"less-loader": "^8.0.0",
"vue-template-compiler": "^2.6.14"

View File

@ -3,6 +3,7 @@
<main>
<router-view />
<trigger></trigger>
<el-backtop :right="100" :bottom="100" />
</main>
<footer>
<basePage></basePage>

27
src/api/backlog.js Normal file
View File

@ -0,0 +1,27 @@
import request from '../utils/request'
// 获取内容
export function backlogList (data) {
return request({
url: '/backlogList',
method: 'get',
data
})
}
// 新增内容
export function addBacklog (data) {
return request({
url: '/addBacklog',
method: 'post',
data
})
}
// 删除内容
export function deleteBacklog (id) {
return request({
url: '/deleteBacklog/' + id,
method: 'delete'
})
}

View File

@ -18,6 +18,15 @@ export function addContentToList (id, content) {
})
}
// 修改列表内容
export function updateContentInList (id, contentId, content) {
return request({
url: `/list/${id}/${contentId}`,
method: 'put',
data: content
})
}
// 删除列表中的内容
export function deleteContentFromList (id, contentId) {
return request({

View File

@ -1,51 +1,87 @@
.kecheng {
width: 1200px;
margin: 20px auto;
width: 1200px;
margin: 20px auto;
.empty{
width: 100%;
height: 100px;
background-color: #f5f5f5;
text-align: center;
line-height: 100px;
font-size: 18px;
color: #999;
.empty {
width: 100%;
height: 100px;
background-color: #f5f5f5;
text-align: center;
line-height: 100px;
font-size: 18px;
color: #999;
}
.con {
width: 100%;
height: 100px;
background-color: #fff;
background-image: linear-gradient(90deg,
transparent 79px,
#abced4 79px,
#abced4 81px,
transparent 81px),
linear-gradient(#eee 0.1em, transparent 0.1em);
background-size: 100% 1.2em;
margin-bottom: 20px;
.title {
width: 900px;
height: 40px;
font-size: 26px;
font-weight: bold;
margin: 10px 0 0 85px;
cursor: pointer;
color: #007bff;
display: -webkit-box;
/* 需要组合这些属性来实现效果 */
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
/* 限制显示的行数例如3行 */
overflow: hidden;
float: left;
&:hover {
text-decoration: underline;
}
}
.con {
width: 100%;
height: 100px;
background-color: #fff;
background-image: linear-gradient(
90deg,
transparent 79px,
#abced4 79px,
#abced4 81px,
transparent 81px
),
linear-gradient(#eee 0.1em, transparent 0.1em);
background-size: 100% 1.2em;
margin-bottom: 20px;
.delete-btn {
background-color: #007bff;
color: white;
border: none;
width: 40px;
height: 40px;
border-radius: 50%;
cursor: pointer;
opacity: 0;
transition: all 0.3s ease;
margin-left: 100px;
.title {
width: 1100px;
height: 40px;
font-size: 24px;
margin: 10px 0 0 85px;
cursor: pointer;
&:hover{
background-color: #00ffff;
}
}
.content {
width: 1100px;
height: 40px;
text-indent: 2em;
margin-left: 80px;
overflow: hidden;
word-wrap: break-word; /* 适用于大多数浏览器 */
overflow-wrap: break-word; /* 适用于最新的浏览器 */
}
.content {
display: inline;
width: 800px;
text-indent: 2em;
margin: 0 0 0 60px;
display: -webkit-box;
/* 需要组合这些属性来实现效果 */
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
/* 限制显示的行数例如3行 */
overflow: hidden;
}
&:hover .delete-btn{
opacity: 1;
}
}
}
.main-content {
@ -55,60 +91,27 @@
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.kecheng {
margin-bottom: 20px;
}
.con {
background-color: #fff;
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.title {
font-size: 18px;
font-weight: bold;
margin-bottom: 5px;
cursor: pointer;
color: #007bff;
}
.title:hover {
text-decoration: underline;
}
.content {
font-size: 14px;
color: #333;
float: left;
}
button {
background-color: #007bff;
color: white;
.add-btn{
width: 100px;
height: 40px;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
input,
textarea {
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ccc;
border-radius: 4px;
}
input:focus,
textarea:focus {
border-color: #007bff;
outline: none;
border-radius: 10px;
background-color: rgb(60, 255, 0);
color: #f9f9f9;
font-weight: bold;
font-size: 18px;
cursor: pointer;
transition: all 0.3s ease;
&:hover{
background-color: rgb(200, 197, 0);
}
}
.dialog-footer{
.el-button{
margin-top: 50px;
}
}

View File

@ -0,0 +1,103 @@
<template>
<el-dialog title="添加新内容" :visible.sync="localVisible" @close="clearForm">
<el-form
:model="newContent"
:rules="rules"
ref="newContentForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="标题" prop="title">
<el-input v-model="newContent.title" placeholder="标题"></el-input>
</el-form-item>
<el-form-item label="内容">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="newContent.content"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="onCreated"
/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="submitForm('newContentForm')">添加</el-button>
</span>
</el-dialog>
</template>
<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
export default {
name: 'CustomEditor',
components: { Editor, Toolbar },
props: {
visible: {
type: Boolean,
required: true
}
},
data () {
return {
editor: null,
newContent: {
title: '',
content: ''
}, //
toolbarConfig: {},
editorConfig: { placeholder: '请输入内容...' },
mode: 'default', // or 'simple'
rules: {
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }]
},
localVisible: this.visible
}
},
watch: {
visible (newVal) {
this.localVisible = newVal
},
localVisible (newVal) {
this.$emit('update:visible', newVal)
}
},
methods: {
onCreated (editor) {
this.editor = Object.seal(editor) // Object.seal()
},
submitForm (formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('add-content', this.newContent)
this.clearForm()
} else {
console.error('表单验证失败')
return false
}
})
},
handleCancel () {
this.clearForm()
this.localVisible = false
},
clearForm () {
this.newContent = { title: '', content: '' }
}
},
beforeDestroy () {
const editor = this.editor
if (editor == null) return
editor.destroy() //
}
}
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>

View File

@ -178,23 +178,21 @@ export default {
width: 1200px;
height: 60px;
margin: 0 auto;
line-height: 60px;
p {
width: 88px;
height: 29px;
height: 60px;
font-size: 22px;
font-weight: bold;
color: #006cff;
float: left;
margin-left: 20px;
line-height: 60px;
}
.nackground {
width: 600px;
height: 60px;
float: left;
margin-left: 100px;
text-align: center;
li {
@ -203,6 +201,7 @@ export default {
align-items: center;
float: left;
margin-left: 40px;
line-height: 60px;
position: relative;
a {
@ -246,6 +245,7 @@ export default {
width: 380px;
height: 60px;
float: right;
line-height: 60px;
position: relative;
.out {

View File

@ -8,6 +8,16 @@ import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import navigationBar from '@/components/navigationBar.vue'
import music from '@/components/music.vue'
// 引入富文本组件
import QuillEditor from 'vue-quill-editor'
// 引入富文本组件样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(QuillEditor)
// 引入富文本组件
Vue.use(ElementUI)
Vue.component('navigationBar', navigationBar)
Vue.component('musIc', music)

View File

@ -18,7 +18,7 @@
<h3>其他操作</h3>
<hr />
<p @click="toggleBackground">切换背景</p>
<p>帮助与反馈</p>
<p @click="toggleTheme">帮助与反馈</p>
</div>
<trigger :visible.sync="isShow"></trigger>
</el-tab-pane>
@ -34,7 +34,7 @@
:class="{ selected: index === selectedTodoIndex }"
@click="selectTodo(index)"
>
{{ todo }}
{{ todo.content }}
</li>
</ul>
<div class="wtbDone-footer">
@ -58,7 +58,11 @@
</div>
<div class="form-item">
<label for="intro">介绍</label>
<input id="intro" v-model="form.intro" placeholder="请输入介绍" />
<input
id="intro"
v-model="form.intro"
placeholder="请输入介绍"
/>
</div>
<div class="form-item">
<label>性别</label>
@ -81,7 +85,11 @@
<option value="region2">地区2</option>
<option value="region3">地区3</option>
</select>
<select id="city" v-model="form.city" style="margin-left: 10px">
<select
id="city"
v-model="form.city"
style="margin-left: 10px"
>
<option value="city1">城市1</option>
<option value="city2">城市2</option>
<option value="city3">城市3</option>
@ -95,7 +103,9 @@
<div class="right-section">
<div class="avatar-section">
<img :src="avatar" alt="用户头像" class="avatar" />
<span class="change-avatar-btn" @click="changeAvatar">更换头像</span>
<span class="change-avatar-btn" @click="changeAvatar"
>更换头像</span
>
</div>
</div>
</div>
@ -125,10 +135,11 @@
</template>
<script>
import navigationBar from '@/components/navigationBar.vue'
import trigger from '@/components/trigger.vue'
import { getUserInfo, updateUserInfo } from '@/api/login'
import { mapState, mapGetters, mapActions } from 'vuex'
import navigationBar from '@/components/navigationBar.vue' //
import trigger from '@/components/trigger.vue' //
import { getUserInfo, updateUserInfo } from '@/api/login' //
import { backlogList, addBacklog, deleteBacklog } from '@/api/backlog' //
import { mapState, mapGetters, mapActions } from 'vuex' // vuex
export default {
data () {
@ -145,9 +156,9 @@ export default {
dialogVisible: false,
imageUrl: '',
name: '',
avatar: require('@/assets/images/sub.jpg'),
newTodo: '',
todos: [],
avatar: require('@/assets/images/sub2.jpg'),
newTodo: '', //
todos: [], //
selectedTodoIndex: null
}
},
@ -159,7 +170,11 @@ export default {
...mapState(['username']),
...mapGetters(['getUsername'])
},
created () {
this.fetchTodos() //
},
methods: {
//
fetchUserInfo (username) {
getUserInfo(username)
.then((res) => {
@ -183,6 +198,12 @@ export default {
toggleBackground () {
this.isShow = true
},
toggleTheme () {
this.$message({
message: '暂未开放,敬请期待!',
type: 'info'
})
},
...mapActions(['updateUsername']),
saveUserInfo () {
const currentUsername = localStorage.getItem('username') //
@ -218,27 +239,54 @@ export default {
console.log(updatedUserInfo)
},
//
fetchTodos () {
backlogList().then((res) => {
this.todos = res.data
})
},
//
handleAdd () {
if (this.newTodo.trim() !== '') {
this.todos.push(this.newTodo.trim())
this.newTodo = ''
this.$message.success('添加成功')
} else {
if (this.newTodo.trim() === '') {
this.$message.error('请输入待办事项')
return
}
addBacklog({ content: this.newTodo }).then((res) => {
if (res && res.status === 200) {
this.$message.success('添加成功')
this.fetchTodos()
this.newTodo = ''
} else {
this.$message.error('添加失败')
}
})
},
selectTodo (index) {
this.selectedTodoIndex = index
},
//
handleDelete () {
if (this.selectedTodoIndex !== null) {
this.todos.splice(this.selectedTodoIndex, 1)
this.selectedTodoIndex = null
this.$message.success('删除成功')
const selectedTodo = this.todos[this.selectedTodoIndex]
deleteBacklog(selectedTodo.id)
.then((res) => {
if (res && res.status === 200) {
this.$message.success('删除成功')
this.fetchTodos()
this.selectedTodoIndex = null
} else {
this.$message.error('删除失败')
}
})
.catch((error) => {
console.error('删除待办事项失败:', error)
this.$message.error('删除失败')
})
} else {
this.$message.error('请选择要删除的待办事项')
}
},
/** 更换头像 */
changeAvatar () {
this.dialogVisible = true
},
@ -308,7 +356,7 @@ ul {
width: 100%;
height: 40px;
line-height: 40px;
text-align: center;
text-indent: 2em;
background-color: #f5f5f5;
border-bottom: 1px solid #ddd;
cursor: pointer;

View File

@ -44,7 +44,7 @@
</div>
</div>
</div>
<el-backtop :right="100" :bottom="100" />
<musIc />
</div>
</template>

View File

@ -18,7 +18,7 @@
<h4>{{ item.title }}</h4>
</router-link>
<!-- 删除按钮/图标 -->
<button class="delete-btn" @click="deleteItem(index)">删除</button>
<button class="delete-btn" @click="deleteItem(index)">X</button>
</li>
</ul>
</div>
@ -33,10 +33,16 @@
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
<el-form ref="form" :model="form" label-width="80px" :rules="rules">
<el-form-item label="笔记标题" prop="addContent">
<el-input v-model="form.addContent" placeholder="请输入标题"></el-input>
<el-input
v-model="form.addContent"
placeholder="请输入标题"
></el-input>
</el-form-item>
<el-form-item label="表名" prop="tableName">
<el-input v-model="form.tableName" placeholder="请输入表名(英文)"></el-input>
<el-input
v-model="form.tableName"
placeholder="请输入表名(英文)"
></el-input>
</el-form-item>
</el-form>
@ -228,20 +234,21 @@ a {
position: absolute;
top: 0;
right: 0;
background-color: rgba(255, 106, 106, 0.2);
color: rgba(248, 146, 51, 0.897);
background-color: rgba(0, 0, 0, 0.2);
color: rgba(255, 255, 255, 0.897);
border: none;
width: 50px;
border-radius: 50%;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 16px;
//
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
transition: all 0.3s;
opacity: 0;
}
.box-bd ul li:hover .delete-btn {
opacity:1;
opacity: 1;
}
.add {

View File

@ -24,6 +24,15 @@ export default {
},
created () {
this.selectedItem = this.$route.params.selectedItem //
if (this.selectedItem) {
localStorage.setItem('selectedItem', JSON.stringify(this.selectedItem))
} else {
const savedItem = localStorage.getItem('selectedItem')
if (savedItem) {
this.selectedItem = JSON.parse(savedItem)
}
}
}
}
</script>

View File

@ -7,11 +7,13 @@
暂无内容
</div>
<div class="con" v-for="(item, index) in paginatedContent" :key="index">
<div class="title" @click="pushDetailPage(item, tableName)">
<div class="title" @click="pushDetailPage(item)">
{{ item.title }}
</div>
<div class="content" v-html="item.content"></div>
<button @click="deleteContent(item.id)">删除</button>
<button class="delete-btn" @click="deleteContent(item.id)">X</button>
<div class="content">
<span v-html="item.content"></span>
</div>
</div>
</div>
<el-pagination
@ -22,43 +24,26 @@
@current-change="handlePageChange"
style="margin: 20px 0 20px 500px"
></el-pagination>
<button @click="showAddDialog">添加新内容</button>
<button class="add-btn" @click="showAddDialog">添加新内容</button>
<!-- 弹框 -->
<el-dialog title="添加新内容" :visible.sync="dialogVisible">
<el-form
:model="newContent"
:rules="rules"
ref="newContent"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="标题" prop="title">
<el-input v-model="newContent.title" placeholder="标题"></el-input>
</el-form-item>
<el-form-item label="内容" prop="content">
<el-input
type="textarea"
v-model="newContent.content"
placeholder="内容"
></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addContent">添加</el-button>
</span>
</el-dialog>
<CustomEditor
:visible.sync="dialogVisible"
@add-content="addContent"
/>
</main>
<div class="fortter"></div>
<div class="footer"></div>
</div>
</template>
<script>
import { getlist, addContentToList, deleteContentFromList } from '@/api/list'
import CustomEditor from '@/components/CustomEditor'
export default {
name: 'liSt',
components: {
CustomEditor
},
data () {
return {
detailContent: [], //
@ -71,11 +56,7 @@ export default {
newContent: {
title: '',
content: ''
}, //
rules: {
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
content: [{ required: true, message: '内容不能为空', trigger: 'blur' }]
}
} //
}
},
created () {
@ -87,14 +68,13 @@ export default {
getlist(id)
.then((response) => {
this.detailContent = response.data || []
this.total = response.data.length || 0
this.total = this.detailContent.length || 0
this.tableName = response.data.tableName || ''
})
.catch((error) => {
console.error('获取内容时出错:', error)
})
},
// detailPage
pushDetailPage (item) {
this.$router.push({
name: 'detailPage',
@ -104,33 +84,35 @@ export default {
})
},
handlePageChange (newPage) {
//
this.currentPage = newPage
this.fetchContent() //
},
showAddDialog () {
this.dialogVisible = true
},
addContent () {
addContent (newContent) {
const id = this.$route.params.id //
if (!this.newContent.title || !this.newContent.content) {
alert('标题和内容不能为空')
return
}
addContentToList(id, this.newContent)
.then((response) => {
this.$message({
message: '添加成功',
type: 'success'
if (newContent.title === '' || newContent.content === '') {
this.$message({
message: '内容不能为空',
type: 'error'
})
} else {
addContentToList(id, newContent)
.then((response) => {
this.$message({
message: '添加成功',
type: 'success'
})
this.dialogVisible = false
this.fetchContent() //
})
this.dialogVisible = false
this.newContent.title = ''
this.newContent.content = ''
this.fetchContent() //
})
.catch((error) => {
console.error('添加内容时出错:', error)
})
.catch((error) => {
console.error('添加内容时出错:', error)
})
console.log('准备发送的数据:', newContent)
}
},
deleteContent (contentId) {
const id = this.$route.params.id //
@ -164,5 +146,4 @@ export default {
<style lang="less" scoped>
@import url("@/assets/styles/compon.less");
</style>

View File

@ -29,8 +29,6 @@
v-for="(item, index) in photos"
:key="index"
:class="item.sizeClass"
@mouseover="onMouseOver($event, item.sizeClass)"
@mouseleave="onMouseLeave"
@click="openImageViewer(item.src)"
ref="photoItems"
>
@ -171,29 +169,6 @@ export default {
closeImageViewer () {
this.showImageViewer = false
document.body.classList.remove('no-scroll') //
},
//
onMouseOver (event, sizeClass) {
const galleryItem = event.currentTarget
const rect = galleryItem.getBoundingClientRect()
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft
//
const randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16)
this.pointerStyle = {
display: 'block',
top: `${rect.top + scrollTop - 85}px`,
left: `${rect.left + scrollLeft - 105}px`,
width: `${rect.width + 30}px`,
height: `${rect.height + 30}px`,
borderColor: randomColor //
}
},
//
onMouseLeave () {
this.pointerStyle.display = 'none'
}
},
//

View File

@ -9,7 +9,7 @@
</path>
</svg>
<div class="ana">
<p>{{ user }}</p>
<p class="name">{{ user }}</p>
</div>
</div>
<div class="article" v-for="(item, index) in articleS" :key="index">
@ -136,7 +136,7 @@ export default {
backdrop-filter: blur(0px);
-webkit-backdrop-filter: blur(0px);
p {
.name {
text-align: center;
line-height: 50px;
font-size: 20px;
@ -200,13 +200,9 @@ export default {
.duce {
width: 100%;
height: 80px;
line-height: 30px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
// line-height: 30px;
word-break: break-all;
color: rgb(143, 143, 143);
color: rgb(0, 0, 0);
margin-top: 10px;
.content {
@ -214,8 +210,13 @@ export default {
font-weight: 400;
font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
width: 850px;
height: 60px;
height: 20px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}