This commit is contained in:
username 2024-06-17 16:48:19 +08:00
parent 5415e64853
commit 3cc7577049
15 changed files with 436 additions and 95 deletions

9
src/api/JsList.js Normal file
View File

@ -0,0 +1,9 @@
import request from '../utils/request'
export function getlist (data) {
return request({
url: '/jsList',
method: 'get',
data
})
}

View File

@ -1,5 +1,6 @@
import request from '../utils/request'
// 获取列表内容
export function getlist (id) {
return request({
url: `/list/${id}`,
@ -7,3 +8,20 @@ export function getlist (id) {
params: { id }
})
}
// 添加内容到列表
export function addContentToList (id, content) {
return request({
url: `/list/${id}`,
method: 'post',
data: content
})
}
// 删除列表中的内容
export function deleteContentFromList (id, contentId) {
return request({
url: `/list/${id}/${contentId}`,
method: 'delete'
})
}

View File

@ -1,5 +1,6 @@
import request from '../utils/request'
// 获取标签列表
export function getTags (id) {
return request({
url: '/tags',
@ -9,3 +10,32 @@ export function getTags (id) {
}
})
}
// 添加标签
export function addTag (data) {
return request({
url: '/add-tags',
method: 'post',
data: {
title: data.title,
table_name: data.table_name
}
})
}
// 删除标签
export function deleteTag (id) {
return request({
url: '/tags/' + id,
method: 'delete'
})
}
// 修改标签
export function updateTag (id, data) {
return request({
url: '/tags/' + id,
method: 'put',
data
})
}

View File

@ -46,3 +46,69 @@
}
}
}
.main-content {
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
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;
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;
}

View File

@ -42,6 +42,7 @@
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
img {
width: 100%;

View File

@ -15,6 +15,7 @@ export default {
.base {
width: 100%;
height: 100px;
margin-top: 40px;
background-color: palegreen;
}
</style>

View File

@ -4,6 +4,7 @@ import Login from '@/views/login'
import Home from '../views/Home.vue'
// import store from '@/store' // Vuex store
import NoteDetail from '@/views/particulars/paiListPage'
import NotFound from '@/views/404.vue'
Vue.use(VueRouter)
@ -59,6 +60,11 @@ const routes = [
path: '/detailPage',
name: 'detailPage',
component: (resolve) => require(['@/views/particulars/detailPage'], resolve)
},
{
path: '*',
name: 'NotFound',
component: NotFound
}
]

34
src/views/404.vue Normal file
View File

@ -0,0 +1,34 @@
<template>
<div class="not-found">
<h1>404</h1>
<p>页面找不到</p>
</div>
</template>
<script>
export default {
name: 'notFound',
data () {
return {
}
}
}
</script>
<style lang="less" scoped>
.not-found {
text-align: center;
margin-top: 100px;
}
h1 {
font-size: 100px;
color: #999;
}
p {
font-size: 24px;
color: #999;
}
</style>

View File

@ -128,7 +128,7 @@
import navigationBar from '@/components/navigationBar.vue'
import trigger from '@/components/trigger.vue'
import { getUserInfo, updateUserInfo } from '@/api/login'
import { mapState, mapActions } from 'vuex'
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
data () {
@ -145,7 +145,7 @@ export default {
dialogVisible: false,
imageUrl: '',
name: '',
avatar: require('@/assets/images/sub.jpg'), // Define the avatar property
avatar: require('@/assets/images/sub.jpg'),
newTodo: '',
todos: [],
selectedTodoIndex: null
@ -156,16 +156,8 @@ export default {
trigger
},
computed: {
...mapState({
username: state => state.username
})
},
created () {
this.$store.dispatch('loadUsernameFromLocalStorage')
const savedUsername = localStorage.getItem('name')
if (savedUsername) {
this.fetchUserInfo(savedUsername)
}
...mapState(['username']),
...mapGetters(['getUsername'])
},
methods: {
fetchUserInfo (username) {

View File

@ -10,7 +10,6 @@
<h3>
<router-link to="/">{{ item.title }}</router-link>
</h3>
<p class="time">{{ item.date }}</p>
</div>
</div>
</div>
@ -41,7 +40,7 @@
</div>
<div class="advertisement">
<h3>广告</h3>
<img src="../assets/images/table.png" alt="广告" />
<img src="../assets/images/sub.jpg" alt="广告" />
</div>
</div>
</div>
@ -51,44 +50,14 @@
</template>
<script>
import { getlist } from '@/api/JsList'
export default {
name: 'HoMe',
data () {
return {
currentIndex: 0, //
timer: null, //
contList: [
{
img: require('@/assets/images/789.jpg'),
title: '文章标题1',
date: '2024-04-24'
},
{
img: require('@/assets/images/789.jpg'),
title: '文章标题2',
date: '2024-04-24'
},
{
img: require('@/assets/images/789.jpg'),
title: '文章标题3',
date: '2024-04-24'
},
{
img: require('@/assets/images/789.jpg'),
title: '文章标题3',
date: '2024-04-24'
},
{
img: require('@/assets/images/789.jpg'),
title: '文章标题3',
date: '2024-04-24'
},
{
img: require('@/assets/images/789.jpg'),
title: '文章标题3',
date: '2024-04-24'
}
],
contList: [],
items: [
{ type: 'success', label: '后端技术' },
{ type: 'success', label: '前端技术' },
@ -115,7 +84,15 @@ export default {
]
}
},
created () {
this.fetchTags()
},
methods: {
fetchTags () {
getlist().then(res => {
this.contList = res.data
})
}
}
}
</script>

View File

@ -10,12 +10,15 @@
</header>
<div class="box-bd">
<ul class="clearfix">
<!-- v-for 循环中为每个项目添加一个删除按钮/图标 -->
<li v-for="(item, index) in items" :key="index">
<router-link :to="`/paiListPage/${index + 1}`">
<!-- 这里的index + 1对应着表的序号 -->
<img :src="item.url" :alt="item.title" />
<h4>{{ item.title }}</h4>
</router-link>
<!-- 删除按钮/图标 -->
<button class="delete-btn" @click="deleteItem(index)">删除</button>
</li>
</ul>
</div>
@ -30,33 +33,39 @@
<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"></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-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleAdd"> </el-button>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleAdd"></el-button>
</span>
</el-dialog>
<musIc />
</div>
</template>
<script>
import { getTags } from '@/api/tags'
import { getTags, addTag, deleteTag } from '@/api/tags'
export default {
data () {
return {
items: [],
dialogVisible: false,
form: {
addContent: ''
addContent: '',
tableName: ''
},
rules: {
addContent: [
{ required: true, message: '请输入标题', trigger: 'blur' }
]
],
tableName: [{ required: true, message: '请输入表名', trigger: 'blur' }]
}
}
},
@ -72,13 +81,67 @@ export default {
openDialog () {
this.dialogVisible = true
},
handleAdd () {
//
handleCancel () {
this.dialogVisible = false
this.form.addContent = ''
this.form.tableName = ''
this.$refs.form.resetFields()
},
/** 添加标签 */
handleAdd () {
this.$refs.form.validate((valid) => {
if (valid) {
const newTag = {
title: this.form.addContent,
table_name: this.form.tableName
}
console.log('Sending data:', newTag)
addTag(newTag)
.then(() => {
this.fetchTags()
this.dialogVisible = false
this.form.addContent = ''
this.form.tableName = ''
this.$message({
message: '添加成功',
type: 'success'
})
this.form.addContent = ''
this.handleCancel()
})
.catch((error) => {
console.error('添加标签失败:', error)
this.$message({
message: '添加标签失败',
type: 'error'
})
})
}
})
},
/** 删除标签 */
deleteItem (index) {
if (confirm('确定要删除此项目吗?')) {
//
deleteTag(this.items[index].id)
.then(() => {
//
this.items.splice(index, 1)
this.$message({
message: '项目删除成功',
type: 'success'
})
})
.catch((error) => {
console.error('删除项目时出错:', error)
//
this.$message({
message: '删除项目时出错',
type: 'error'
})
})
}
}
}
}
@ -92,6 +155,7 @@ export default {
li {
list-style: none;
position: relative;
}
a {
text-decoration: none;
@ -104,9 +168,6 @@ a {
.clearfix:after {
clear: both;
}
/* .clearfix {
*zoom:1;
} */
.clearfix img {
width: 100%;
height: 220px;
@ -124,7 +185,6 @@ a {
font-size: 20px;
color: #494949;
}
/* 把li 的父亲ul 修改的足够宽一行能装开5个盒子就不会换行了 */
.box-bd ul {
width: 1225px;
}
@ -151,18 +211,42 @@ a {
}
.box-bd ul li h4 {
margin: 20px 20px 20px 25px;
font-size: 14px;
font-size: 16px;
color: #050505;
font-weight: 400;
font-weight: 500;
text-align: center;
opacity: 0;
transition: all 0.3s;
}
.box-bd ul li:hover h4 {
color: #006cff;
opacity: 1;
}
.box-bd ul li .delete-btn {
position: absolute;
top: 0;
right: 0;
background-color: rgba(255, 106, 106, 0.2);
color: rgba(248, 146, 51, 0.897);
border: none;
width: 50px;
height: 30px;
cursor: pointer;
font-size: 16px;
//
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
opacity: 0;
}
.box-bd ul li:hover .delete-btn {
opacity:1;
}
.add {
position: fixed;
bottom: 100px;
bottom: 110px;
right: 20px;
button {

View File

@ -4,7 +4,7 @@
<navigationBar />
</header>
<div class="msg-all-contain">
<div class="msg-board-title">待办事项</div>
<div class="msg-board-title">留言板测试版</div>
<div class="msg-board">
<div class="msg-board-contain">
<div class="msg-head">

View File

@ -1,32 +1,72 @@
<template>
<div>
<h1>详情页</h1>
<div class="detail-page">
<div v-if="selectedItem" class="content-wrapper">
<h2>{{ selectedItem.title }}</h2>
<div v-html="selectedItem.content" class="content"></div>
</div>
<div v-else class="loading">
正在加载...
</div>
<shareBtn></shareBtn>
</div>
</template>
<script>
import { getSubject } from '@/api/subject'
import shareBtn from '@/components/shareBtn.vue'
export default {
name: 'detailPage',
data () {
return {
list: ''
selectedItem: null
}
},
components: {
shareBtn
},
created () {
this.getDeail()
},
methods: {
getDeail () {
getSubject().then(res => {
this.list = res.data
console.log(this.list)
})
}
this.selectedItem = this.$route.params.selectedItem //
}
}
</script>
<style>
<style scoped>
.detail-page {
padding: 20px;
max-width: 800px;
margin: 0 auto;
background-color: #f9f9f9;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.detail-page h1 {
font-size: 2em;
margin-bottom: 20px;
text-align: center;
color: #333;
}
.content-wrapper {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.content-wrapper h2 {
font-size: 1.5em;
margin-bottom: 15px;
color: #444;
}
.content {
font-size: 1em;
line-height: 1.6;
color: #666;
}
.loading {
font-size: 1.2em;
text-align: center;
color: #999;
}
</style>

View File

@ -2,12 +2,16 @@
<div>
<main class="main-content">
<div class="kecheng">
<div class="empty" v-if="!detailContent.length">暂无内容</div>
<!-- 添加额外的条件判断以避免未定义的情况 -->
<div class="empty" v-if="!detailContent || detailContent.length === 0">
暂无内容
</div>
<div class="con" v-for="(item, index) in paginatedContent" :key="index">
<div class="title" @click="pushDetailPage(item)">
<div class="title" @click="pushDetailPage(item, tableName)">
{{ item.title }}
</div>
<div class="content" v-html="item.content"></div>
<button @click="deleteContent(item.id)">删除</button>
</div>
</div>
<el-pagination
@ -16,16 +20,42 @@
:total="total"
:hide-on-single-page="conceal"
@current-change="handlePageChange"
style="margin: 20px 0 20px 500px;"
style="margin: 20px 0 20px 500px"
></el-pagination>
<button @click="showAddDialog">添加新内容</button>
<!-- 弹框 -->
<el-dialog title="添加新内容" :visible.sync="dialogVisible">
<el-form
:model="newContent"
:rules="rules"
ref="newContent"
label-width="100px"
class="demo-ruleForm"
>
</el-pagination>
<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>
</main>
<div class="fortter"></div>
</div>
</template>
<script>
import { getlist } from '@/api/list'
import { getlist, addContentToList, deleteContentFromList } from '@/api/list'
export default {
name: 'liSt',
@ -35,7 +65,17 @@ export default {
conceal: true, //
currentPage: 1, //
pageSize: 10, //
total: 0 //
total: 0, //
tableName: '', //
dialogVisible: false, //
newContent: {
title: '',
content: ''
}, //
rules: {
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
content: [{ required: true, message: '内容不能为空', trigger: 'blur' }]
}
}
},
created () {
@ -44,22 +84,22 @@ export default {
methods: {
fetchContent () {
const id = this.$route.params.id //
//
getlist(id, (this.currentPage - 1) * this.pageSize, this.pageSize)
getlist(id)
.then((response) => {
this.detailContent = response.data
this.total = response.data.length
this.detailContent = response.data || []
this.total = response.data.length || 0
this.tableName = response.data.tableName || ''
})
.catch((error) => {
console.error('获取内容时出错:', error)
})
},
// detailPage
pushDetailPage (item) {
// id
this.$router.push({
name: 'detailPage',
params: {
id: item.id // id
selectedItem: item //
}
})
},
@ -67,10 +107,52 @@ export default {
//
this.currentPage = newPage
this.fetchContent() //
},
showAddDialog () {
this.dialogVisible = true
},
addContent () {
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'
})
this.dialogVisible = false
this.newContent.title = ''
this.newContent.content = ''
this.fetchContent() //
})
.catch((error) => {
console.error('添加内容时出错:', error)
})
},
deleteContent (contentId) {
const id = this.$route.params.id //
deleteContentFromList(id, contentId)
.then((response) => {
this.$message({
message: '删除成功',
type: 'info'
})
this.fetchContent() //
})
.catch((error) => {
console.error('删除内容时出错:', error)
})
}
},
computed: {
paginatedContent () {
// detailContent
if (!Array.isArray(this.detailContent)) {
return []
}
// currentPage pageSize
const startIndex = (this.currentPage - 1) * this.pageSize
const endIndex = startIndex + this.pageSize
@ -82,4 +164,5 @@ export default {
<style lang="less" scoped>
@import url("@/assets/styles/compon.less");
</style>

View File

@ -185,7 +185,7 @@ export default {
this.pointerStyle = {
display: 'block',
top: `${rect.top + scrollTop - 85}px`,
left: `${rect.left + scrollLeft - 205}px`,
left: `${rect.left + scrollLeft - 105}px`,
width: `${rect.width + 30}px`,
height: `${rect.height + 30}px`,
borderColor: randomColor //