10 changed files with 345 additions and 94 deletions
-
13package-lock.json
-
4package.json
-
13src/api/homeApi.js
-
5src/api/index.js
-
86src/assets/base.css
-
6src/assets/main.css
-
25src/main.js
-
7src/router/index.js
-
276src/views/ActivityManagement.vue
@ -0,0 +1,13 @@ |
|||
import service from "."; |
|||
const homeApi = { |
|||
//分页查询
|
|||
getHomeData(PageNo,PageSize) { |
|||
return service.post("/api/activity",{ |
|||
params:{ |
|||
PageNo, |
|||
PageSize |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
export default homeApi; |
@ -0,0 +1,5 @@ |
|||
import axios from "axios"; |
|||
const service = axios.create({ |
|||
baseURL:"http://192.168.8.235:8000" |
|||
}); |
|||
export default service; |
@ -1,86 +0,0 @@ |
|||
/* color palette from <https://github.com/vuejs/theme> */ |
|||
:root { |
|||
--vt-c-white: #ffffff; |
|||
--vt-c-white-soft: #f8f8f8; |
|||
--vt-c-white-mute: #f2f2f2; |
|||
|
|||
--vt-c-black: #181818; |
|||
--vt-c-black-soft: #222222; |
|||
--vt-c-black-mute: #282828; |
|||
|
|||
--vt-c-indigo: #2c3e50; |
|||
|
|||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29); |
|||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12); |
|||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); |
|||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); |
|||
|
|||
--vt-c-text-light-1: var(--vt-c-indigo); |
|||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66); |
|||
--vt-c-text-dark-1: var(--vt-c-white); |
|||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64); |
|||
} |
|||
|
|||
/* semantic color variables for this project */ |
|||
:root { |
|||
--color-background: var(--vt-c-white); |
|||
--color-background-soft: var(--vt-c-white-soft); |
|||
--color-background-mute: var(--vt-c-white-mute); |
|||
|
|||
--color-border: var(--vt-c-divider-light-2); |
|||
--color-border-hover: var(--vt-c-divider-light-1); |
|||
|
|||
--color-heading: var(--vt-c-text-light-1); |
|||
--color-text: var(--vt-c-text-light-1); |
|||
|
|||
--section-gap: 160px; |
|||
} |
|||
|
|||
@media (prefers-color-scheme: dark) { |
|||
:root { |
|||
--color-background: var(--vt-c-black); |
|||
--color-background-soft: var(--vt-c-black-soft); |
|||
--color-background-mute: var(--vt-c-black-mute); |
|||
|
|||
--color-border: var(--vt-c-divider-dark-2); |
|||
--color-border-hover: var(--vt-c-divider-dark-1); |
|||
|
|||
--color-heading: var(--vt-c-text-dark-1); |
|||
--color-text: var(--vt-c-text-dark-2); |
|||
} |
|||
} |
|||
|
|||
*, |
|||
*::before, |
|||
*::after { |
|||
box-sizing: border-box; |
|||
margin: 0; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
body { |
|||
min-height: 100vh; |
|||
color: var(--color-text); |
|||
background: var(--color-background); |
|||
transition: |
|||
color 0.5s, |
|||
background-color 0.5s; |
|||
line-height: 1.6; |
|||
font-family: |
|||
Inter, |
|||
-apple-system, |
|||
BlinkMacSystemFont, |
|||
'Segoe UI', |
|||
Roboto, |
|||
Oxygen, |
|||
Ubuntu, |
|||
Cantarell, |
|||
'Fira Sans', |
|||
'Droid Sans', |
|||
'Helvetica Neue', |
|||
sans-serif; |
|||
font-size: 15px; |
|||
text-rendering: optimizeLegibility; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
@ -1,9 +1,14 @@ |
|||
import { createRouter, createWebHistory } from 'vue-router' |
|||
import ActivityManagement from '@/views/ActivityManagement.vue' |
|||
|
|||
const router = createRouter({ |
|||
history: createWebHistory(import.meta.env.BASE_URL), |
|||
routes: [ |
|||
|
|||
{ |
|||
path: '/', |
|||
name: 'activityManagement', |
|||
component: ActivityManagement, |
|||
}, |
|||
], |
|||
}) |
|||
|
|||
|
@ -0,0 +1,276 @@ |
|||
<template> |
|||
<el-container> |
|||
<el-header> |
|||
<h1>活动管理后台</h1> |
|||
</el-header> |
|||
|
|||
<el-main> |
|||
<el-row justify="start" align="middle"> |
|||
<el-col :span="24" class="header-actions"> |
|||
<el-button type="danger" @click="openAddActivityDialog">添加活动</el-button> |
|||
</el-col> |
|||
</el-row> |
|||
<el-table :data="paginatedActivities" style="width: 100%"> |
|||
<!-- <el-table-column label="序号" type="index" width="80" align="center" header-align="center"> |
|||
<template #default="{ $index }"> |
|||
{{ $index + 1 }} |
|||
</template> |
|||
</el-table-column> --> |
|||
<el-table-column type="index" :index="indexMethod" width="80" label="活动标题" /> |
|||
<el-table-column prop="title" label="活动标题" /> |
|||
<el-table-column prop="detail" label="活动详情" /> |
|||
<el-table-column prop="visit_count" label="访问人数" width="120" /> |
|||
<el-table-column prop="vote_count" label="投票人数" width="120" /> |
|||
<el-table-column prop="start" label="活动开始时间" /> |
|||
<el-table-column prop="end" label="活动结束时间" /> |
|||
<el-table-column prop="created_at" label="活动创建时间" /> |
|||
<el-table-column prop="status" label="活动状态"> |
|||
<template #default="scope"> |
|||
<span v-if="scope.row.status === 1">未开始</span> |
|||
<span v-if="scope.row.status === 2">进行中</span> |
|||
<span v-if="scope.row.status === 3">已结束</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column label="操作" width="180"> |
|||
<template #default="scope"> |
|||
<div class="operation-buttons"> |
|||
<el-button size="mini" type="default" @click="editActivity(scope.row)">修改</el-button> |
|||
<el-button size="mini" type="primary" @click="viewDetails(scope.row)">查看详情</el-button> |
|||
</div> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<div class="pagination-container"> |
|||
<el-pagination background layout="prev, pager, next" :total="total" :page-size="itemsPerPage" |
|||
v-model:current-page="currentPage" @current-change="handlePageChange"> |
|||
</el-pagination> |
|||
</div> |
|||
</el-main> |
|||
|
|||
<!-- 添加活动对话框开始 --> |
|||
<el-dialog v-model="showAddActivityDialog" title="添加活动"> |
|||
<el-form :model="newActivity" ref="activityForm" label-width="120px"> |
|||
<el-form-item label="活动标题" :rules="[{ required: true, message: '请输入活动标题' }]"> |
|||
<el-input v-model="newActivity.title"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="活动详情" :rules="[{ required: true, message: '请输入活动详情' }]"> |
|||
<el-input type="textarea" v-model="newActivity.details"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="活动图标"> |
|||
<el-upload action="#" list-type="picture-card" :on-preview="handlePictureCardPreview" |
|||
:on-remove="handleRemove" :on-success="handleSuccess" :before-upload="beforeUpload"> |
|||
<el-icon class="avatar-uploader-icon"> |
|||
<Plus /> |
|||
</el-icon> |
|||
</el-upload> |
|||
</el-form-item> |
|||
<el-form-item label="活动时间" :locale="zhCn" :rules="[{ required: true, message: '请选择活动时间' }]"> |
|||
<el-date-picker v-model="newActivity.date" type="datetimerange" start-placeholder="开始日期" |
|||
end-placeholder="结束日期"></el-date-picker> |
|||
</el-form-item> |
|||
<el-form-item label="活动网址" :rules="[{ required: true, message: '请输入活动网址' }]"> |
|||
<el-input v-model="newActivity.url"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="选择市场" :rules="[{ required: true, message: '请选择活动面向的市场' }]"> |
|||
<el-select v-model="newActivity.market" placeholder="请选择市场"> |
|||
<el-option label="市场1" value="market1"></el-option> |
|||
<el-option label="市场2" value="market2"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="客户权限" :rules="[{ required: true, message: '请选择面向客户的级别' }]"> |
|||
<el-radio-group v-model="newActivity.clientLevel"> |
|||
<el-radio label="非网">非网</el-radio> |
|||
<el-radio label="半年版">半年版</el-radio> |
|||
<el-radio label="终免">终免</el-radio> |
|||
</el-radio-group> |
|||
</el-form-item> |
|||
</el-form> |
|||
<span slot="footer" class="dialog-footer"> |
|||
<el-button @click="showAddActivityDialog = false">取 消</el-button> |
|||
<el-button type="primary" @click="addActivity">确 定</el-button> |
|||
</span> |
|||
</el-dialog> |
|||
<!-- 添加活动对话框结束 --> |
|||
</el-container> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, computed } from 'vue'; |
|||
import { ElMessage } from 'element-plus'; |
|||
import zhCn from 'element-plus/es/locale/lang/zh-cn' |
|||
import homeApi from '@/api/homeApi'; |
|||
|
|||
|
|||
function indexMethod(index){ |
|||
return itemsPerPage*(currentPage.value-1)+index+1; |
|||
} |
|||
//定义假id |
|||
const fakeId = ref(1); |
|||
|
|||
// 活动列表数据 |
|||
const activities = ref([]); |
|||
|
|||
// 分页获取所有活动 |
|||
function getAllActivities(currentPage, itemsPerPage) { |
|||
homeApi.getHomeData(currentPage, itemsPerPage) |
|||
.then(response => { |
|||
activities.value = response.data.data.list; |
|||
total.value = response.data.data.total; |
|||
console.log(activities.value); |
|||
console.log(total.value); |
|||
}); |
|||
}; |
|||
|
|||
// 默认第1页 |
|||
const currentPage = ref(1); |
|||
// 每页10条数据 |
|||
const itemsPerPage = 10; |
|||
//总条目数 |
|||
const total = ref(0); |
|||
getAllActivities(currentPage.value, itemsPerPage); |
|||
|
|||
|
|||
// 分页处理活动数据 |
|||
const paginatedActivities = computed(() => { |
|||
const start = (currentPage.value - 1) * itemsPerPage; |
|||
const end = start + itemsPerPage; |
|||
return activities.value.slice(start, end); |
|||
}); |
|||
|
|||
// 当前页改变时触发的事件 |
|||
const handlePageChange = (newPage) => { |
|||
getAllActivities(newPage, itemsPerPage); |
|||
}; |
|||
|
|||
// 添加的活动 |
|||
const newActivity = ref({ |
|||
id: null, |
|||
title: '', |
|||
details: '', |
|||
date: '', |
|||
url: '', |
|||
market: '', |
|||
clientLevel: '' |
|||
}); |
|||
|
|||
// 展示添加活动对话框 |
|||
const showAddActivityDialog = ref(false); |
|||
|
|||
// 添加新活动的方法 |
|||
const addActivity = () => { |
|||
newActivity.value.id = activities.value.length + 1; |
|||
newActivity.value.create_at = new Date().toISOString().split('T')[0]; // 设置当前时间为创建时间 |
|||
activities.value.push({ ...newActivity.value }); |
|||
newActivity.value = { |
|||
id: null, |
|||
title: '', |
|||
details: '', |
|||
date: '', |
|||
url: '', |
|||
market: '', |
|||
clientLevel: '' |
|||
}; |
|||
showAddActivityDialog.value = true; |
|||
ElMessage.success('活动添加成功'); |
|||
}; |
|||
|
|||
// 修改活动的方法 |
|||
const editActivity = (activity) => { |
|||
newActivity.value = { ...activity }; |
|||
showAddActivityDialog.value = true; |
|||
}; |
|||
|
|||
// 查看详情 |
|||
const viewDetails = (activity) => { |
|||
ElMessage.info(`活动ID: ${activity.id}, 活动标题: ${activity.title}, 日期: ${activity.start} - ${activity.end}, 访问人数: ${activity.visit_count}`); |
|||
}; |
|||
|
|||
const handlePictureCardPreview = (file) => { |
|||
console.log('Preview:', file); |
|||
}; |
|||
|
|||
const handleRemove = (file, fileList) => { |
|||
console.log('Remove:', file, fileList); |
|||
}; |
|||
|
|||
const handleSuccess = (response, file, fileList) => { |
|||
console.log('Success:', response, file, fileList); |
|||
}; |
|||
|
|||
const beforeUpload = (file) => { |
|||
const isJPG = file.type === 'image/jpeg'; |
|||
const isPNG = file.type === 'image/png'; |
|||
const isLt2M = file.size / 1024 / 1024 < 2; |
|||
|
|||
if (!isJPG && !isPNG) { |
|||
ElMessage.error('上传头像图片只能是 JPG 或 PNG 格式!'); |
|||
} |
|||
if (!isLt2M) { |
|||
ElMessage.error('上传头像图片大小不能超过 2MB!'); |
|||
} |
|||
return isJPG || isPNG && isLt2M; |
|||
}; |
|||
|
|||
// 状态对应的样式类 |
|||
const statusClassMap = { |
|||
'进行中': 'status-active', |
|||
'已完成': 'status-finished', |
|||
}; |
|||
|
|||
// 根据活动状态获取对应的样式类 |
|||
const getStatusClass = (status) => { |
|||
return statusClassMap[status] || 'status-default'; |
|||
}; |
|||
|
|||
// 打开添加活动对话框 |
|||
const openAddActivityDialog = () => { |
|||
newActivity.value = { |
|||
id: null, |
|||
title: '', |
|||
details: '', |
|||
date: '', |
|||
url: '', |
|||
market: '', |
|||
clientLevel: '' |
|||
}; |
|||
showAddActivityDialog.value = true; |
|||
}; |
|||
</script> |
|||
|
|||
<style> |
|||
.header-actions { |
|||
margin-left: 20px; |
|||
/* 调整按钮与标题之间的距离 */ |
|||
} |
|||
|
|||
.pagination-container { |
|||
position: absolute; |
|||
display: flex; |
|||
justify-content: center; |
|||
margin-top: 10rem; |
|||
left: 45%; |
|||
} |
|||
|
|||
.dialog-footer { |
|||
text-align: right; |
|||
} |
|||
|
|||
.operation-buttons { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.status-active { |
|||
color: #409eff; |
|||
} |
|||
|
|||
.status-finished { |
|||
color: #6c757d; |
|||
text-decoration: line-through; |
|||
} |
|||
|
|||
.status-default { |
|||
color: #000; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue