Merge remote-tracking branch 'origin/MeetingJerry' into merge/1

# Conflicts:
#	public/background.jpg
#	src/assets/avatar.jpg
#	src/router/authentication.js
#	src/views/authentication/Login.vue
#	src/views/authentication/Register.vue
This commit is contained in:
高子兴 2024-07-06 07:41:11 +08:00
commit d77a0f458d
6 changed files with 429 additions and 23 deletions

View File

@ -1,9 +1,24 @@
// import MeetingList from '../views/meeting-management/MeetingList.vue'
// import MeetingDetail from '../views/meeting-management/MeetingDetail.vue'
// import MeetingEdit from '../views/meeting-management/MeetingEdit.vue'
// meetingManagementRoutes.js
import MeetingManagement from "/src/views/meeting-management/MeetingManagement.vue";
import AddMeeting from "/src/views/meeting-management/AddMeeting.vue";
import EditMeeting from "/src/views/meeting-management/EditMeeting.vue";
export default [
// { path: '/meetings', component: MeetingList },
// { path: '/meetings/:id', component: MeetingDetail },
// { path: '/meetings/:id/edit', component: MeetingEdit }
]
const routes = [
{
path: '/Meeting',
name: 'MeetingManagement',
component: MeetingManagement
},
{
path: '/Meeting/add',
name: 'AddMeeting',
component: AddMeeting
},
{
path: '/Meeting/edit/:id',
name: 'EditMeeting',
component: EditMeeting
}
];
export default routes;

View File

@ -0,0 +1,42 @@
import axios from 'axios';
class MeetingService {
getAllMeetings() {
return axios.get(`/api/meetings/listAll`);
}
getMeetingById(id) {
// 使用 POST 方法并传递请求体
return axios.post(`/api/meetings/getMeetingById`, { id });
}
createMeeting(meeting) {
return axios.post(`/api/meetings/addMeeting`, meeting);
}
updateMeeting(id, meeting) {
// Convert meeting object to a map
const meetingMap = {
id: id,
name: meeting.name,
organizer: meeting.organizer,
startTime: meeting.startTime,
endTime: meeting.endTime,
content: meeting.content,
status: meeting.status
};
return axios.post(`/api/meetings/updateMeeting`, meetingMap);
}
deleteMeeting(id) {
// 使用 POST 方法并传递请求体
return axios.post(`/api/meetings/deleteMeeting`, { id });
}
searchMeetings(params) {
// 使用 POST 方法并传递请求体
return axios.post(`/api/meetings/searchMeetings`, params);
}
}
export default new MeetingService();

View File

@ -1,27 +1,96 @@
import MeetingService from '../services/meetingService';
const state = {
meetings: []
}
meetings: [],
currentMeeting: null
};
const mutations = {
setMeetings(state, meetings) {
state.meetings = meetings
}
state.meetings = meetings;
},
setCurrentMeeting(state, meeting) {
state.currentMeeting = meeting;
}
};
const actions = {
fetchMeetings({ commit }) {
// 模拟API调用
const meetings = [
{ id: 1, title: 'Meeting 1' },
{ id: 2, title: 'Meeting 2' }
]
commit('setMeetings', meetings)
async fetchMeetings({ commit }) {
try {
const response = await MeetingService.getAllMeetings();
commit('setMeetings', response.data);
} catch (error) {
console.error('Failed to fetch meetings:', error);
}
},
async searchMeetings({ commit }, params) {
try {
const formattedparams = {
name: params.name,
organizer: params.organizer,
startTime: params.startTime,
};
const response = await MeetingService.searchMeetings(formattedparams);
commit('setMeetings', response.data);
} catch (error) {
console.error('Failed to search meetings:', error);
}
},
async fetchMeetingById({ commit }, id) {
try {
const response = await MeetingService.getMeetingById(id);
commit('setCurrentMeeting', response.data);
} catch (error) {
console.error('Failed to fetch meeting:', error);
}
},
async createMeeting({ dispatch }, meeting) {
try {
const formattedMeeting = {
name: meeting.name,
organizer: meeting.organizer,
startTime: meeting.startTime,
endTime: meeting.endTime,
content: meeting.content,
status: 'Scheduled' // 确保状态为 'Scheduled'
};
await MeetingService.createMeeting(formattedMeeting);
dispatch('fetchMeetings');
} catch (error) {
console.error('Failed to create meeting:', error);
}
},
async editMeeting({ dispatch }, meeting) {
try {
const formattedMeeting = {
name: meeting.name,
organizer: meeting.organizer,
startTime: meeting.startTime,
endTime: meeting.endTime,
content: meeting.content,
status: 'Scheduled' // 确保状态为 'Scheduled'
};
await MeetingService.updateMeeting(meeting.id, formattedMeeting);
dispatch('fetchMeetings');
} catch (error) {
console.error('Failed to update meeting:', error);
}
},
async deleteMeeting({ dispatch }, id) {
try {
await MeetingService.deleteMeeting(id);
dispatch('fetchMeetings');
} catch (error) {
console.error('Failed to delete meeting:', error);
}
}
};
const getters = {
allMeetings: state => state.meetings
}
allMeetings: state => state.meetings,
currentMeeting: state => state.currentMeeting
};
export default {
namespaced: true,
@ -29,4 +98,4 @@ export default {
mutations,
actions,
getters
}
};

View File

@ -0,0 +1,57 @@
<template>
<el-form :model="meeting" label-width="120px" @submit.native.prevent="submitForm">
<el-form-item label="会议名称">
<el-input v-model="meeting.name"></el-input>
</el-form-item>
<el-form-item label="创建人">
<el-input v-model="meeting.organizer"></el-input>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker v-model="meeting.startTime" type="datetime" placeholder="选择时间"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="meeting.endTime" type="datetime" placeholder="选择时间"></el-date-picker>
</el-form-item>
<el-form-item label="会议内容">
<el-input type="textarea" v-model="meeting.content"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">确定</el-button>
<el-button @click="cancel">取消</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { mapActions } from 'vuex';
export default {
name: 'AddMeeting',
data() {
return {
meeting: {
name: '',
organizer: '',
startTime: '',
endTime: '',
content: '',
status: 'Scheduled' // 'Scheduled'
}
};
},
methods: {
...mapActions('meetingManagement', ['createMeeting']),
async submitForm() {
try {
await this.createMeeting(this.meeting);
this.$router.push({ name: 'MeetingManagement' });
} catch (error) {
console.error('Failed to create meeting:', error);
}
},
cancel() {
this.$router.push({ name: 'MeetingManagement' });
}
}
};
</script>

View File

@ -0,0 +1,61 @@
<template>
<el-form :model="meeting" label-width="120px" @submit.native.prevent="submitForm">
<el-form-item label="会议名称">
<el-input v-model="meeting.name"></el-input>
</el-form-item>
<el-form-item label="创建人">
<el-input v-model="meeting.organizer"></el-input>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker v-model="meeting.startTime" type="datetime" placeholder="选择时间"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="meeting.endTime" type="datetime" placeholder="选择时间"></el-date-picker>
</el-form-item>
<el-form-item label="会议内容">
<el-input type="textarea" v-model="meeting.content"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">确定</el-button>
<el-button @click="cancel">取消</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'EditMeeting',
data() {
return {
meeting: {
id: '',
name: '',
organizer: '',
startTime: '',
endTime: '',
content: '',
status: 'Active'
}
};
},
computed: {
...mapGetters('meetingManagement', ['currentMeeting'])
},
methods: {
...mapActions('meetingManagement', ['fetchMeetingById', 'editMeeting']),
async submitForm() {
await this.editMeeting(this.meeting);
this.$router.push({ name: 'MeetingManagement' });
},
cancel() {
this.$router.push({ name: 'MeetingManagement' });
}
},
async mounted() {
await this.fetchMeetingById(this.$route.params.id);
Object.assign(this.meeting, this.currentMeeting);
}
};
</script>

View File

@ -0,0 +1,162 @@
<template>
<div class="meeting-management">
<div class="header">
<el-input v-model="searchName" placeholder="会议名称" class="search-input"></el-input>
<el-input v-model="searchOrganizer" placeholder="创建人" class="search-input"></el-input>
<el-date-picker v-model="searchStartTime" type="datetime" placeholder="开始时间" class="search-input"></el-date-picker>
<el-button type="primary" @click="search">搜索</el-button>
<el-button type="primary" @click="goToAddMeeting">添加会议</el-button>
</div>
<el-table :data="allMeetings" style="width: 100%">
<el-table-column prop="id" label="会议ID" width="80"></el-table-column>
<el-table-column prop="name" label="会议名称"></el-table-column>
<el-table-column prop="organizer" label="组织者"></el-table-column>
<el-table-column prop="startTime" label="开始时间"></el-table-column>
<el-table-column prop="endTime" label="结束时间"></el-table-column>
<el-table-column prop="status" label="状态"></el-table-column>
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button @click="editMeeting(scope.row.id)" type="text">修改</el-button>
<el-button @click="confirmDelete(scope.row.id)" type="text" class="delete-button">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import axios from 'axios';
import MeetingService from "@services/meetingService.js";
import MeetingManagement from "@store/meetingManagement.js";
import meetingManagement from "@store/meetingManagement.js";
export default {
name: 'MeetingManagement',
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
searchName: '',
searchOrganizer: '',
searchStartTime: null,
allMeeting:''
};
},
computed: {
...mapGetters('meetingManagement', ['allMeetings'])
},
methods: {
...mapActions('meetingManagement', ['fetchMeetings', 'searchMeetings', 'deleteMeeting']),
goToAddMeeting() {
this.$router.push({ name: 'AddMeeting' });
},
editMeeting(id) {
this.$router.push({ name: 'EditMeeting', params: { id } });
},
confirmDelete(id) {
this.$confirm(
'是否确认删除会议管理编号为 "' + id + '" 的数据项?',
'系统提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
.then(() => {
this.deleteMeeting(id).then(() => {
this.fetchMeetings();
});
})
.catch(() => {});
},
handleSizeChange(val) {
this.pageSize = val;
this.fetchMeetings();
},
handleCurrentChange(val) {
this.currentPage = val;
this.fetchMeetings();
},
search() {
const params = {
name: this.searchName,
organizer: this.searchOrganizer,
startTime: this.searchStartTime ? this.searchStartTime.toISOString() : null
};
this.allMeeting = this.searchMeetings(params)
},
exportMeetings() {
axios
.post(
'/api/meetings/export',
{
name: this.searchName,
organizer: this.searchOrganizer,
startTime: this.searchStartTime ? this.searchStartTime.toISOString() : null
},
{ responseType: 'blob' }
)
.then(response => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'meetings.xlsx');
document.body.appendChild(link);
link.click();
})
.catch(error => {
console.error('导出失败', error);
});
}
},
mounted() {
this.fetchMeetings();
}
};
</script>
<style scoped>
.meeting-management {
padding: 20px;
background-color: #f5f5f5;
border-radius: 8px;
}
.header {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
}
.search-input {
margin-right: 10px;
}
.el-button {
margin-right: 10px;
}
.el-table {
background-color: #fff;
border-radius: 8px;
overflow: hidden;
}
.el-pagination {
margin-top: 20px;
text-align: center;
}
.delete-button {
color: #f56c6c;
}
.delete-button:hover {
color: #ff7875;
}
</style>