| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // èå¤å表 |
| | | export function attendancerecordslist(data) { |
| | | return request({ |
| | | url: '/project/attendancerecords/list', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // èå¤ä¿®æ¹ |
| | | export function attendancerecordsedit(data) { |
| | | return request({ |
| | | url: '/project/attendancerecords/edit', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // èå¤ä¿®æ¹ |
| | | export function attendancerecordsadd(data) { |
| | | return request({ |
| | | url: '/project/attendancerecords/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // èå¤è¯¦æ
|
| | | export function attendancerecordsInfo(id) { |
| | | return request({ |
| | | url: '/project/attendancerecords/getInfo/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | // å é¤ |
| | | export function attendancerecordsDel(id) { |
| | | return request({ |
| | | url: '/project/attendancerecords/remove/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ä¼è®®å表 |
| | | export function meetinglist(data) { |
| | | return request({ |
| | | url: '/project/meeting/list', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // ä¼è®®çºªè¦ä¿®æ¹ |
| | | export function meetingedit(data) { |
| | | return request({ |
| | | url: '/project/meeting/edit', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // ä¼è®®çºªè¦ä¿®æ¹ |
| | | export function meetingadd(data) { |
| | | return request({ |
| | | url: '/project/meeting/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // ä¼è®®çºªè¦è¯¦æ
|
| | | export function meetingInfo(id) { |
| | | return request({ |
| | | url: '/project/meeting/getInfo/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | // å é¤ |
| | | export function meetingDel(id) { |
| | | return request({ |
| | | url: '/project/meeting/remove/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | // å¯¼åºæç®å¨å®ç®¡ç |
| | | export function exporremeeting(query) { |
| | | return request({ |
| | | url: '/project/meeting/export', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export * from "./studies"; |
| | | export * from "./conference"; |
| | | export * from "./checkingIn"; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // è¿ä¿®å表 |
| | | export function recordslist(data) { |
| | | return request({ |
| | | url: '/project/records/list', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // è¿ä¿®ä¿®æ¹ |
| | | export function recordsedit(data) { |
| | | return request({ |
| | | url: '/project/records/edit', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // è¿ä¿®ä¿®æ¹ |
| | | export function recordsadd(data) { |
| | | return request({ |
| | | url: '/project/records/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // è¿ä¿®è¯¦æ
|
| | | export function recordsInfo(id) { |
| | | return request({ |
| | | url: '/project/records/getInfo/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | // å é¤ |
| | | export function recordsDel(id) { |
| | | return request({ |
| | | url: '/project/records/remove/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | // å¯¼åºæç®å¨å®ç®¡ç |
| | | export function exporrecords(query) { |
| | | return request({ |
| | | url: '/project/records/export', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="åºå·®è®°å½" name="businessTripList"> |
| | | <personal-business-trip-table |
| | | :data="businessTripData" |
| | | :loading="loading" |
| | | /> |
| | | <person-business :data="businessTripData" :loading="loading" /> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="æ¥åè§å¾" name="calendar"> |
| | | <attendance-calendar |
| | |
| | | |
| | | generatePersonalAttendanceData() { |
| | | const data = []; |
| | | const currentMonth = 12; // 12æ |
| | | const currentMonth = 4; // 12æ |
| | | |
| | | for (let day = 1; day <= 31; day++) { |
| | | if (Math.random() > 0.2) { |
| | | // 80%çåºå¤ç |
| | | data.push({ |
| | | id: day, |
| | | date: `2024-${currentMonth |
| | | date: `2026-${currentMonth |
| | | .toString() |
| | | .padStart(2, "0")}-${day.toString().padStart(2, "0")}`, |
| | | checkIn: `08:${String(Math.floor(Math.random() * 30)).padStart( |
| | |
| | | return [ |
| | | { |
| | | id: 1, |
| | | tripNumber: "BT202412001", |
| | | tripNumber: "BT202612001", |
| | | startCity: "å京", |
| | | endCity: "䏿µ·", |
| | | startDate: "2024-12-05", |
| | | endDate: "2024-12-08", |
| | | startDate: "2026-04-05", |
| | | endDate: "2026-04-08", |
| | | distance: 1200, |
| | | purpose: "客æ·ä¼è®®", |
| | | status: "已宿" |
| | | }, |
| | | { |
| | | id: 2, |
| | | tripNumber: "BT202412002", |
| | | tripNumber: "BT202612002", |
| | | startCity: "å京", |
| | | endCity: "广å·", |
| | | startDate: "2024-12-15", |
| | | endDate: "2024-12-18", |
| | | startDate: "2026-04-012", |
| | | endDate: "2026-04-16", |
| | | distance: 1900, |
| | | purpose: "项ç®è°ç ", |
| | | status: "已宿" |
| | |
| | | <template> |
| | | <div class="attendance-calendar"> |
| | | <el-calendar v-model="calendarValue"> |
| | | <template #date-cell="{ data }"> |
| | | <!-- <el-button @click="refreshCalendar" size="small" type="primary" |
| | | >å·æ°</el-button |
| | | > --> |
| | | |
| | | <!-- Element UI çæ¥åç»ä»¶ --> |
| | | <el-calendar v-model="value"> |
| | | <template slot="dateCell" slot-scope="{ date, data }"> |
| | | <div class="calendar-date"> |
| | | <div class="date-number">{{ data.day.split('-')[2] }}</div> |
| | | <div class="date-number"> |
| | | {{ |
| | | data.day |
| | | .split("-") |
| | | .slice(1) |
| | | .join("-") |
| | | }} |
| | | </div> |
| | | <!-- <div style="font-size: 10px; color: #666;">{{ data.day }}</div> --> |
| | | <div class="date-events"> |
| | | <!-- Element UI ä¸ä½¿ç¨ææ§½ä½ç¨å --> |
| | | <div |
| | | v-for="event in getDateEvents(data.day)" |
| | | :key="event.id" |
| | |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'AttendanceCalendar', |
| | | name: "AttendanceCalendar", |
| | | props: { |
| | | attendanceData: Array, |
| | | businessTripData: Array |
| | | }, |
| | | data() { |
| | | return { |
| | | calendarValue: new Date() |
| | | value: new Date(), // Element UI ä½¿ç¨ value |
| | | localAttendanceData: [], |
| | | localBusinessTripData: [] |
| | | }; |
| | | }, |
| | | watch: { |
| | | attendanceData: { |
| | | immediate: true, |
| | | handler(val) { |
| | | this.localAttendanceData = val || []; |
| | | console.log("è夿°æ®:", this.localAttendanceData); |
| | | this.$nextTick(() => { |
| | | this.$forceUpdate(); // Vue 2 çå¼ºå¶æ´æ° |
| | | }); |
| | | } |
| | | }, |
| | | businessTripData: { |
| | | immediate: true, |
| | | handler(val) { |
| | | this.localBusinessTripData = val || []; |
| | | console.log("åºå·®æ°æ®:", this.localBusinessTripData); |
| | | this.$nextTick(() => { |
| | | this.$forceUpdate(); |
| | | }); |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | console.log("Calendar mounted with Vue 2.6.12"); |
| | | this.testMethod(); |
| | | }, |
| | | methods: { |
| | | refreshCalendar() { |
| | | console.log("æå¨å·æ°æ¥å"); |
| | | this.$forceUpdate(); |
| | | }, |
| | | testMethod() { |
| | | console.log("æµè¯æ¹æ³æ¯å¦å¯è°ç¨"); |
| | | console.log("getDateEvents æµè¯:", this.getDateEvents("2024-01-15")); |
| | | }, |
| | | getDateEvents(date) { |
| | | const events = [] |
| | | console.log("getDateEvents 被è°ç¨, æ¥æ:", date); |
| | | console.log("å½åè夿°æ®:", this.localAttendanceData); |
| | | console.log("å½ååºå·®æ°æ®:", this.localBusinessTripData); |
| | | |
| | | // æ£æ¥åºå¤è®°å½ |
| | | const attendance = this.attendanceData.find(item => item.date === date) |
| | | const events = []; |
| | | |
| | | // è夿°æ® |
| | | const attendance = (this.localAttendanceData || []).find(item => { |
| | | return item && item.date === date; |
| | | }); |
| | | |
| | | if (attendance) { |
| | | events.push({ |
| | | id: `attendance-${date}`, |
| | | type: 'attendance', |
| | | text: `${attendance.checkIn}-${attendance.checkOut}` |
| | | }) |
| | | type: "attendance", |
| | | text: `${attendance.checkIn || "--"}-${attendance.checkOut || "--"}` |
| | | }); |
| | | } |
| | | |
| | | // æ£æ¥åºå·®è®°å½ |
| | | const businessTrip = this.businessTripData.find(item => |
| | | date >= item.startDate && date <= item.endDate |
| | | ) |
| | | // åºå·®æ°æ® |
| | | const businessTrip = (this.localBusinessTripData || []).find(item => { |
| | | return item && date >= item.startDate && date <= item.endDate; |
| | | }); |
| | | |
| | | if (businessTrip) { |
| | | events.push({ |
| | | id: `business-trip-${date}`, |
| | | type: 'business-trip', |
| | | text: `åºå·®: ${businessTrip.endCity}` |
| | | }) |
| | | type: "business-trip", |
| | | text: `åºå·®: ${businessTrip.endCity || ""}` |
| | | }); |
| | | } |
| | | |
| | | return events |
| | | console.log("æ¾å°çäºä»¶:", events); |
| | | return events; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | |
| | | .calendar-date { |
| | | height: 100%; |
| | | padding: 8px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | |
| | | .date-number { |
| | | font-weight: bold; |
| | | margin-bottom: 4px; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .date-events { |
| | |
| | | align-items: center; |
| | | margin-bottom: 2px; |
| | | font-size: 12px; |
| | | padding: 2px 4px; |
| | | border-radius: 2px; |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | .event-item.attendance { |
| | | background-color: #f0f9eb; |
| | | color: #67c23a; |
| | | } |
| | | |
| | | .event-item.business-trip { |
| | | background-color: #ecf5ff; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .event-dot { |
| | |
| | | .event-item.business-trip .event-dot { |
| | | background-color: #409eff; |
| | | } |
| | | |
| | | ::v-deep .el-calendar-table .el-calendar-day { |
| | | height: 115px; |
| | | } |
| | | .event-text { |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | flex: 1; |
| | | } |
| | | </style> |
| | |
| | | }, |
| | | computed: { |
| | | filteredData() { |
| | | |
| | | let data = this.data.filter(item => { |
| | | const nameMatch = !this.filters.employeeName || |
| | | item.employeeName.includes(this.filters.employeeName) |
| | |
| | | // åå·¥è夿°æ® - éè¦è¡¥å
宿´æä»½çæ°æ® |
| | | attendanceData: [ |
| | | // 12æ1-4æ¥ |
| | | { id: 1, date: '2024-12-01', checkIn: '08:30', checkOut: '18:00', status: 'present', workHours: 9.5 }, |
| | | { id: 2, date: '2024-12-02', checkIn: '09:15', checkOut: '18:00', status: 'late', workHours: 8.75 }, |
| | | { id: 3, date: '2024-12-03', checkIn: '08:45', checkOut: '17:30', status: 'present', workHours: 8.75 }, |
| | | { id: 4, date: '2024-12-04', checkIn: '08:25', checkOut: '18:10', status: 'present', workHours: 9.75 }, |
| | | { id: 1, date: '2026-04-01', checkIn: '08:30', checkOut: '18:00', status: 'present', workHours: 9.5 }, |
| | | { id: 2, date: '2026-04-02', checkIn: '09:15', checkOut: '18:00', status: 'late', workHours: 8.75 }, |
| | | { id: 3, date: '2026-04-03', checkIn: '08:45', checkOut: '17:30', status: 'present', workHours: 8.75 }, |
| | | { id: 4, date: '2026-04-04', checkIn: '08:25', checkOut: '18:10', status: 'present', workHours: 9.75 }, |
| | | |
| | | // 12æ5-8æ¥ï¼5å·ç¼ºå¤ï¼5-8å·åºå·®ï¼ |
| | | { id: 5, date: '2024-12-05', checkIn: null, checkOut: null, status: 'absent', workHours: 0 }, |
| | | { id: 6, date: '2024-12-06', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 7, date: '2024-12-07', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 8, date: '2024-12-08', checkIn: '08:40', checkOut: '17:45', status: 'present', workHours: 9.0 }, |
| | | { id: 5, date: '2026-04-05', checkIn: null, checkOut: null, status: 'absent', workHours: 0 }, |
| | | { id: 6, date: '2026-04-06', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 7, date: '2026-04-07', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 8, date: '2026-04-08', checkIn: '08:40', checkOut: '17:45', status: 'present', workHours: 9.0 }, |
| | | |
| | | // 12æ9-14æ¥ |
| | | { id: 9, date: '2024-12-09', checkIn: '08:35', checkOut: '18:05', status: 'present', workHours: 9.5 }, |
| | | { id: 10, date: '2024-12-10', checkIn: '09:05', checkOut: '17:50', status: 'late', workHours: 8.75 }, |
| | | { id: 11, date: '2024-12-11', checkIn: '08:50', checkOut: '18:15', status: 'present', workHours: 9.5 }, |
| | | { id: 12, date: '2024-12-12', checkIn: '08:30', checkOut: '17:40', status: 'present', workHours: 9.0 }, |
| | | { id: 13, date: '2024-12-13', checkIn: '08:55', checkOut: '18:00', status: 'present', workHours: 9.0 }, |
| | | { id: 14, date: '2024-12-14', checkIn: '08:45', checkOut: '17:50', status: 'present', workHours: 9.0 }, |
| | | { id: 9, date: '2026-04-09', checkIn: '08:35', checkOut: '18:05', status: 'present', workHours: 9.5 }, |
| | | { id: 10, date: '2026-04-10', checkIn: '09:05', checkOut: '17:50', status: 'late', workHours: 8.75 }, |
| | | { id: 11, date: '2026-04-11', checkIn: '08:50', checkOut: '18:15', status: 'present', workHours: 9.5 }, |
| | | { id: 12, date: '2026-04-12', checkIn: '08:30', checkOut: '17:40', status: 'present', workHours: 9.0 }, |
| | | { id: 13, date: '2026-04-13', checkIn: '08:55', checkOut: '18:00', status: 'present', workHours: 9.0 }, |
| | | { id: 14, date: '2026-04-14', checkIn: '08:45', checkOut: '17:50', status: 'present', workHours: 9.0 }, |
| | | |
| | | // 12æ15-18æ¥ï¼åºå·®ï¼ |
| | | { id: 15, date: '2024-12-15', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 16, date: '2024-12-16', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 17, date: '2024-12-17', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 18, date: '2024-12-18', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 15, date: '2026-04-15', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 16, date: '2026-04-16', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 17, date: '2026-04-17', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | { id: 18, date: '2026-04-18', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, |
| | | |
| | | // 12æ19-24æ¥ |
| | | { id: 19, date: '2024-12-19', checkIn: '08:35', checkOut: '18:05', status: 'present', workHours: 9.5 }, |
| | | { id: 20, date: '2024-12-20', checkIn: '08:40', checkOut: '17:55', status: 'present', workHours: 9.25 }, |
| | | { id: 21, date: '2024-12-21', checkIn: null, checkOut: null, status: 'absent', workHours: 0 }, // å¨å
|
| | | { id: 22, date: '2024-12-22', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, // åºå·® |
| | | { id: 23, date: '2024-12-23', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, // åºå·® |
| | | { id: 24, date: '2024-12-24', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, // åºå·® |
| | | { id: 19, date: '2026-04-19', checkIn: '08:35', checkOut: '18:05', status: 'present', workHours: 9.5 }, |
| | | { id: 20, date: '2026-04-20', checkIn: '08:40', checkOut: '17:55', status: 'present', workHours: 9.25 }, |
| | | { id: 21, date: '2026-04-21', checkIn: null, checkOut: null, status: 'absent', workHours: 0 }, // å¨å
|
| | | { id: 22, date: '2026-04-22', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, // åºå·® |
| | | { id: 23, date: '2026-04-23', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, // åºå·® |
| | | { id: 24, date: '2026-04-24', checkIn: null, checkOut: null, status: 'trip', workHours: 0 }, // åºå·® |
| | | |
| | | // 12æ25-31æ¥ |
| | | { id: 25, date: '2024-12-25', checkIn: '08:50', checkOut: '17:45', status: 'present', workHours: 8.75 }, |
| | | { id: 26, date: '2024-12-26', checkIn: '09:10', checkOut: '17:40', status: 'late', workHours: 8.5 }, |
| | | { id: 27, date: '2024-12-27', checkIn: '08:35', checkOut: '18:00', status: 'present', workHours: 9.25 }, |
| | | { id: 28, date: '2024-12-28', checkIn: '08:45', checkOut: '17:50', status: 'present', workHours: 9.0 }, |
| | | { id: 29, date: '2024-12-29', checkIn: null, checkOut: null, status: 'absent', workHours: 0 }, // 卿¥ |
| | | { id: 30, date: '2024-12-30', checkIn: '08:30', checkOut: '17:30', status: 'present', workHours: 9.0 }, |
| | | { id: 31, date: '2024-12-31', checkIn: '08:40', checkOut: '16:00', status: 'present', workHours: 7.5 } |
| | | { id: 25, date: '2026-04-25', checkIn: '08:50', checkOut: '17:45', status: 'present', workHours: 8.75 }, |
| | | { id: 26, date: '2026-04-26', checkIn: '09:10', checkOut: '17:40', status: 'late', workHours: 8.5 }, |
| | | { id: 27, date: '2026-04-27', checkIn: '08:35', checkOut: '18:00', status: 'present', workHours: 9.25 }, |
| | | { id: 28, date: '2026-04-28', checkIn: '08:45', checkOut: '17:50', status: 'present', workHours: 9.0 }, |
| | | { id: 29, date: '2026-04-29', checkIn: null, checkOut: null, status: 'absent', workHours: 0 }, // 卿¥ |
| | | { id: 30, date: '2026-04-30', checkIn: '08:30', checkOut: '17:30', status: 'present', workHours: 9.0 }, |
| | | { id: 31, date: '2026-04-31', checkIn: '08:40', checkOut: '16:00', status: 'present', workHours: 7.5 } |
| | | ], |
| | | |
| | | // åºå·®æ°æ® - éè¦è°æ´æ¥æèå´å¹é
|
| | |
| | | tripNumber: 'BT202412001', |
| | | startCity: 'å京', |
| | | endCity: '䏿µ·', |
| | | startDate: '2024-12-05', |
| | | endDate: '2024-12-07', // è°æ´ä¸º7å·ç»æ |
| | | startDate: '2026-04-05', |
| | | endDate: '2026-04-07', // è°æ´ä¸º7å·ç»æ |
| | | distance: 1200, |
| | | purpose: '客æ·ä¼è®®', |
| | | status: 'completed' |
| | |
| | | tripNumber: 'BT202412002', |
| | | startCity: 'å京', |
| | | endCity: '广å·', |
| | | startDate: '2024-12-15', |
| | | endDate: '2024-12-18', |
| | | startDate: '2026-04-15', |
| | | endDate: '2026-04-18', |
| | | distance: 1900, |
| | | purpose: '项ç®è°ç ', |
| | | status: 'completed' |
| | |
| | | tripNumber: 'BT202412003', |
| | | startCity: 'å京', |
| | | endCity: 'æ·±å³', |
| | | startDate: '2024-12-22', |
| | | endDate: '2024-12-24', |
| | | startDate: '2026-04-22', |
| | | endDate: '2026-04-24', |
| | | distance: 1950, |
| | | purpose: 'ææ¯äº¤æµ', |
| | | status: 'completed' |
| | |
| | | <div class="meeting-management"> |
| | | <!-- 页é¢å¤´é¨ --> |
| | | <div class="page-header"> |
| | | <h2>ä¼è®®ç®¡ç</h2> |
| | | <div class="header-actions"> |
| | | <el-button type="primary" icon="el-icon-plus" @click="handleAdd"> |
| | | æ°å»ºä¼è®® |
| | |
| | | style="width: 150px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¶é´èå´"> |
| | | <el-form-item label="ä¼è®®å¼å§æ¶é´èå´"> |
| | | <el-date-picker |
| | | v-model="queryParams.dateRange" |
| | | type="daterange" |
| | |
| | | clearable |
| | | placeholder="è¯·éæ©" |
| | | > |
| | | <el-option label="å¾
å¼å§" value="pending" /> |
| | | <el-option label="è¿è¡ä¸" value="ongoing" /> |
| | | <el-option label="å·²ç»æ" value="completed" /> |
| | | <el-option label="已忶" value="cancelled" /> |
| | | <el-option label="å¾
å¼å§" value="1" /> |
| | | <el-option label="è¿è¡ä¸" value="2" /> |
| | | <el-option label="å·²ç»æ" value="3" /> |
| | | <el-option label="已忶" value="4" /> |
| | | <el-option label="å¾
å®¡æ ¸" value="0" /> |
| | | <el-option label="å·²éè¿" value="1" /> |
| | | <el-option label="已驳å" value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼è®®ä¸»é¢"> |
| | | <el-input |
| | | v-model="queryParams.title" |
| | | placeholder="请è¾å
¥ä¼è®®ä¸»é¢" |
| | | clearable |
| | | style="width: 150px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">æ¥è¯¢</el-button> |
| | |
| | | style="width: 100%" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <!-- <el-table-column prop="id" label="ID" width="80" fixed /> --> |
| | | <el-table-column prop="id" label="ID" width="80" fixed align="center" /> |
| | | <el-table-column |
| | | prop="title" |
| | | align="center" |
| | |
| | | fixed |
| | | > |
| | | <template #default="scope"> |
| | | <el-button type="text" @click="handleView(scope.row)"> |
| | | <el-button type="text" @click="handleView(scope.row.id)"> |
| | | {{ scope.row.title }} |
| | | </el-button> |
| | | </template> |
| | |
| | | width="120" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag :type="getMeetingTypeTag(scope.row.meetingType)"> |
| | | {{ getMeetingTypeText(scope.row.meetingType) }} |
| | | <el-tag :type="getMeetingTypeTag(scope.row.typeId)"> |
| | | {{ getMeetingTypeText(scope.row.typeId) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | align="center" |
| | | prop="status" |
| | | label="ç¶æ" |
| | | label="ä¼è®®ç¶æ" |
| | | width="100" |
| | | fixed="right" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag :type="getStatusTag(scope.row.status)"> |
| | | {{ getStatusText(scope.row.status) }} |
| | | <el-tag :type="getMeetingStatusTag(scope.row.status)"> |
| | | {{ getMeetingStatusText(scope.row.status) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="participants" |
| | | label="åä¼äººå" |
| | | align="center" |
| | | width="180" |
| | | show-overflow-tooltip |
| | | > |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.participants.join(", ") }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | prop="organizerName" |
| | | label="ç»ç»è
" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | align="center" |
| | | prop="location" |
| | | prop="locationName" |
| | | label="ä¼è®®å°ç¹" |
| | | width="150" |
| | | /> |
| | |
| | | size="mini" |
| | | type="text" |
| | | @click="handleViewMinutes(scope.row)" |
| | | :disabled="!scope.row.meetingMinutes" |
| | | :disabled="!scope.row.recordcontent" |
| | | > |
| | | {{ scope.row.meetingMinutes ? "æ¥ç纪è¦" : "ææ " }} |
| | | {{ scope.row.recordcontent ? "æ¥ç纪è¦" : "ææ " }} |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="å®¡æ ¸ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getApprovalStatusTag(scope.row.approvalStatus)"> |
| | | {{ getApprovalStatusText(scope.row.approvalStatus) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="200" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button size="mini" type="text" @click="handleView(scope.row)"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleView(scope.row.id)" |
| | | > |
| | | æ¥ç |
| | | </el-button> |
| | | <el-button size="mini" type="text" @click="handleEdit(scope.row)"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleEdit(scope.row.id)" |
| | | :disabled="scope.row.delFlag === 1" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleCopy(scope.row)" |
| | | @click="handleCopy(scope.row.id)" |
| | | style="color: #67C23A;" |
| | | :disabled="scope.row.delFlag === 1" |
| | | > |
| | | å¤å¶ |
| | | </el-button> |
| | |
| | | type="text" |
| | | @click="handleDelete(scope.row)" |
| | | style="color: #F56C6C;" |
| | | :disabled="scope.row.delFlag === 1" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | |
| | | <!-- å页 --> |
| | | <div class="pagination-container"> |
| | | <el-pagination |
| | | :current-page="pagination.currentPage" |
| | | :current-page="pagination.pageNum" |
| | | :page-size="pagination.pageSize" |
| | | :total="pagination.total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- ä¼è®®çºªè¦å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | title="ä¼è®®çºªè¦" |
| | | :visible.sync="minutesDialogVisible" |
| | | width="700px" |
| | | > |
| | | <div v-if="currentRecord.meetingMinutes"> |
| | | <div v-if="currentRecord.recordcontent"> |
| | | <el-alert |
| | | title="ä¼è®®çºªè¦è¯¦æ
" |
| | | type="info" |
| | |
| | | <div |
| | | style="white-space: pre-line; line-height: 1.6; max-height: 300px; overflow-y: auto;" |
| | | > |
| | | {{ currentRecord.meetingMinutes }} |
| | | {{ currentRecord.recordcontent }} |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | |
| | | <div |
| | | class="minutes-attachments" |
| | | v-if=" |
| | | currentRecord.minutesAttachments && |
| | | currentRecord.minutesAttachments.length > 0 |
| | | currentRecord.recordattachment && |
| | | parseAttachments(currentRecord.recordattachment).length > 0 |
| | | " |
| | | > |
| | | <el-divider content-position="left">ä¼è®®çºªè¦éä»¶</el-divider> |
| | | <div class="attachment-list"> |
| | | <div |
| | | v-for="file in currentRecord.minutesAttachments" |
| | | :key="file.id" |
| | | v-for="file in parseAttachments(currentRecord.recordattachment)" |
| | | :key="file.id || file.name" |
| | | class="attachment-item" |
| | | > |
| | | <el-link |
| | |
| | | class="file-link" |
| | | > |
| | | <i |
| | | :class="getFileIcon(file.type)" |
| | | :class="getFileIcon(file.type || file.name)" |
| | | style="margin-right: 8px;" |
| | | ></i> |
| | | {{ file.name }} |
| | | <span class="file-size">({{ formatFileSize(file.size) }})</span> |
| | | <span class="file-size" v-if="file.size" |
| | | >({{ formatFileSize(file.size) }})</span |
| | | > |
| | | </el-link> |
| | | </div> |
| | | </div> |
| | |
| | | style="margin-top: 16px; color: #909399; font-size: 12px;" |
| | | > |
| | | <span |
| | | >å建æ¶é´: |
| | | {{ formatDateTime(currentRecord.minutesCreateTime) }}</span |
| | | >è®°å½æ¶é´: {{ formatDateTime(currentRecord.recorderTime) }}</span |
| | | > |
| | | <span style="margin-left: 16px;" |
| | | >å建人: {{ currentRecord.minutesCreator || "ç³»ç»" }}</span |
| | | >è®°å½äºº: {{ currentRecord.recorderBy || "æªæå®" }}</span |
| | | > |
| | | </div> |
| | | </div> |
| | |
| | | <el-button @click="minutesDialogVisible = false">å
³é</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="handleEdit(currentRecord)" |
| | | v-if="currentRecord.meetingMinutes" |
| | | @click="handleEdit(currentRecord.id)" |
| | | v-if="currentRecord.recordcontent" |
| | | > |
| | | ç¼è¾çºªè¦ |
| | | </el-button> |
| | | </span> |
| | | </el-dialog> |
| | | |
| | | <!-- æ¥ç详æ
å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="`ä¼è®®è¯¦æ
- ${currentRecord.title || ''}`" |
| | |
| | | width="800px" |
| | | :before-close="handleDetailClose" |
| | | > |
| | | <el-descriptions :column="2" border v-if="currentRecord"> |
| | | <el-descriptions :column="2" border v-if="currentRecord.id"> |
| | | <el-descriptions-item label="ä¼è®®ç¼å·">{{ |
| | | currentRecord.meetingNumber |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®ä¸»é¢">{{ |
| | | currentRecord.title |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®ç±»å"> |
| | | <el-tag :type="getMeetingTypeTag(currentRecord.meetingType)"> |
| | | {{ getMeetingTypeText(currentRecord.meetingType) }} |
| | | <el-tag :type="getMeetingTypeTag(currentRecord.typeId)"> |
| | | {{ getMeetingTypeText(currentRecord.typeId) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="åä¼äººå" :span="2"> |
| | | <el-tag |
| | | v-for="participant in currentRecord.participants" |
| | | :key="participant" |
| | | type="info" |
| | | size="small" |
| | | style="margin-right: 8px; margin-bottom: 8px;" |
| | | > |
| | | {{ participant }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®å°ç¹">{{ |
| | | currentRecord.location |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®ç¶æ"> |
| | | <el-tag :type="getStatusTag(currentRecord.status)"> |
| | | {{ getStatusText(currentRecord.status) }} |
| | | <el-tag :type="getMeetingStatusTag(currentRecord.status)"> |
| | | {{ getMeetingStatusText(currentRecord.status) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç»ç»è
">{{ |
| | | currentRecord.organizerName || currentRecord.createBy |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®å°ç¹">{{ |
| | | currentRecord.locationName || currentRecord.locationId |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¼å§æ¶é´">{{ |
| | | formatDateTime(currentRecord.startTime) |
| | | }}</el-descriptions-item> |
| | |
| | | <el-descriptions-item label="æç»æ¶é´">{{ |
| | | calculateDuration(currentRecord) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å建人">{{ |
| | | currentRecord.creator |
| | | <el-descriptions-item label="å®¡æ ¸ç¶æ"> |
| | | <el-tag :type="getApprovalStatusTag(currentRecord.approvalStatus)"> |
| | | {{ getApprovalStatusText(currentRecord.approvalStatus) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å®¡æ ¸äºº">{{ |
| | | currentRecord.approverBy || "æªå®¡æ ¸" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å®¡æ ¸æ¶é´">{{ |
| | | currentRecord.approvalTime |
| | | ? formatDateTime(currentRecord.approvalTime) |
| | | : "æªå®¡æ ¸" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®æ¦è¦" :span="2"> |
| | | {{ currentRecord.summary }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®å
容" :span="2"> |
| | | <div |
| | | v-html="currentRecord.content" |
| | | style="white-space: pre-line; max-height: 300px; overflow-y: auto;" |
| | | > |
| | | {{ currentRecord.content }} |
| | | </div> |
| | | ></div> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ä¼è®®è¯¦æ
éä»¶" :span="2"> |
| | | |
| | | <!-- ä¼è®®éä»¶ --> |
| | | <el-descriptions-item label="ä¼è®®éä»¶" :span="2"> |
| | | <div class="detail-attachments"> |
| | | <div |
| | | v-if=" |
| | | currentRecord.detailAttachments && |
| | | currentRecord.detailAttachments.length > 0 |
| | | currentRecord.attachment && |
| | | parseAttachments(currentRecord.attachment).length > 0 |
| | | " |
| | | class="attachment-grid" |
| | | > |
| | | <div |
| | | v-for="file in currentRecord.detailAttachments" |
| | | :key="file.id" |
| | | v-for="file in parseAttachments(currentRecord.attachment)" |
| | | :key="file.id || file.name" |
| | | class="attachment-card" |
| | | > |
| | | <el-card shadow="hover" class="file-card"> |
| | | <div class="file-content"> |
| | | <i :class="getFileIcon(file.type)" class="file-icon"></i> |
| | | <i |
| | | :class="getFileIcon(file.type || file.name)" |
| | | class="file-icon" |
| | | ></i> |
| | | <div class="file-info"> |
| | | <div class="file-name" :title="file.name"> |
| | | {{ file.name }} |
| | | </div> |
| | | <div class="file-meta"> |
| | | <span class="file-size">{{ |
| | | <span class="file-size" v-if="file.size">{{ |
| | | formatFileSize(file.size) |
| | | }}</span> |
| | | <span class="file-time">{{ |
| | | formatDateTime(file.uploadTime) |
| | | }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="file-actions"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreview(file)" |
| | | >é¢è§</el-button |
| | | > |
| | | <div class="file-actions" v-if="file.url"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | |
| | | </div> |
| | | </div> |
| | | <div v-else class="no-attachment"> |
| | | <el-empty |
| | | description="ææ ä¼è®®è¯¦æ
éä»¶" |
| | | :image-size="50" |
| | | ></el-empty> |
| | | <el-empty description="ææ ä¼è®®éä»¶" :image-size="50"></el-empty> |
| | | </div> |
| | | </div> |
| | | </el-descriptions-item> |
| | | |
| | | <!-- ä¼è®®æ¦è¦éä»¶ --> |
| | | <el-descriptions-item label="ä¼è®®æ¦è¦éä»¶" :span="2"> |
| | | <div class="summary-attachments"> |
| | | <div |
| | | v-if=" |
| | | currentRecord.summaryAttachments && |
| | | currentRecord.summaryAttachments.length > 0 |
| | | " |
| | | class="attachment-list" |
| | | > |
| | | <div |
| | | v-for="file in currentRecord.summaryAttachments" |
| | | :key="file.id" |
| | | class="attachment-item" |
| | | > |
| | | <el-link |
| | | type="primary" |
| | | :href="file.url" |
| | | target="_blank" |
| | | class="file-link" |
| | | > |
| | | <i |
| | | :class="getFileIcon(file.type)" |
| | | style="margin-right: 8px;" |
| | | ></i> |
| | | {{ file.name }} |
| | | <span class="file-size" |
| | | >({{ formatFileSize(file.size) }})</span |
| | | > |
| | | </el-link> |
| | | </div> |
| | | </div> |
| | | <div v-else class="no-attachment"> |
| | | <el-empty |
| | | description="ææ ä¼è®®æ¦è¦éä»¶" |
| | | :image-size="50" |
| | | ></el-empty> |
| | | </div> |
| | | </div> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å建人">{{ |
| | | currentRecord.createBy |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å建æ¶é´">{{ |
| | | formatDateTime(currentRecord.createTime) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ´æ°äºº">{{ |
| | | currentRecord.updateBy |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ´æ°æ¶é´">{{ |
| | | formatDateTime(currentRecord.updateTime) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="夿³¨" :span="2">{{ |
| | | currentRecord.remark || "æ " |
| | | }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <span slot="footer"> |
| | | <el-button @click="detailDialogVisible = false">å
³é</el-button> |
| | | <el-button type="primary" @click="handleEdit(currentRecord)" |
| | | >ç¼è¾</el-button |
| | | <el-button |
| | | type="primary" |
| | | @click="handleEdit(currentRecord.id)" |
| | | :disabled="currentRecord.delFlag === 1" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | </span> |
| | | </el-dialog> |
| | | |
| | |
| | | <el-input v-model="editForm.title" placeholder="请è¾å
¥ä¼è®®ä¸»é¢" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ä¼è®®ç±»å" prop="meetingType"> |
| | | <el-form-item label="ä¼è®®ç±»å" prop="typeId"> |
| | | <el-select |
| | | v-model="editForm.meetingType" |
| | | v-model="editForm.typeId" |
| | | placeholder="è¯·éæ©ä¼è®®ç±»å" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="ç§ç ä¼è®®" value="research" /> |
| | | <el-option label="æ¥å¸¸ä¼è®®" value="daily" /> |
| | | <el-option label="项ç®ä¼è®®" value="project" /> |
| | | <el-option label="é¨é¨ä¼è®®" value="department" /> |
| | | <el-option label="è¯å®¡ä¼è®®" value="review" /> |
| | | <el-option label="ç§ç ä¼è®®" :value="1" /> |
| | | <el-option label="æ¥å¸¸ä¼è®®" :value="2" /> |
| | | <el-option label="项ç®ä¼è®®" :value="3" /> |
| | | <el-option label="é¨é¨ä¼è®®" :value="4" /> |
| | | <el-option label="è¯å®¡ä¼è®®" :value="5" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="åä¼äººå" prop="participants"> |
| | | <el-form-item label="ä¼è®®å°ç¹" prop="locationId"> |
| | | <el-select |
| | | v-model="editForm.participants" |
| | | multiple |
| | | filterable |
| | | placeholder="è¯·éæ©åä¼äººå" |
| | | v-model="editForm.locationId" |
| | | placeholder="è¯·éæ©ä¼è®®å°ç¹" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | | :key="user.id" |
| | | :label="user.name" |
| | | :value="user.name" |
| | | /> |
| | | <el-option label="第ä¸ä¼è®®å®¤" :value="1" /> |
| | | <el-option label="第äºä¼è®®å®¤" :value="2" /> |
| | | <el-option label="第ä¸ä¼è®®å®¤" :value="3" /> |
| | | <el-option label="线ä¸ä¼è®®" :value="4" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ä¼è®®å°ç¹" prop="location"> |
| | | <el-input v-model="editForm.location" placeholder="请è¾å
¥ä¼è®®å°ç¹" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼è®®è¯¦æ
éä»¶"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="section-title">ä¼è®®ç¸å
³èµæ</div> |
| | | <div class="upload-tip">ä¸ä¼ ä¼è®®è®¨è®ºææãèæ¯èµæçç¸å
³æä»¶</div> |
| | | <el-upload |
| | | class="detail-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleDetailFileChange" |
| | | :file-list="editForm.detailAttachments" |
| | | :limit="10" |
| | | multiple |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | ä¸ä¼ 详æ
éä»¶ |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | æ¯æææ¡£ãå¾ççæ ¼å¼ï¼å个æä»¶ä¸è¶
è¿20MB |
| | | </div> |
| | | </el-upload> |
| | | <div |
| | | v-if=" |
| | | editForm.detailAttachments && |
| | | editForm.detailAttachments.length > 0 |
| | | " |
| | | class="uploaded-files" |
| | | > |
| | | <div |
| | | v-for="(file, index) in editForm.detailAttachments" |
| | | :key="file.uid || index" |
| | | class="file-item" |
| | | > |
| | | <span class="file-name">{{ file.name }}</span> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleRemoveDetailFile(index)" |
| | | style="color: #F56C6C;" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ä¼è®®æ¦è¦" prop="summary"> |
| | | <el-input |
| | | v-model="editForm.summary" |
| | | type="textarea" |
| | | :rows="2" |
| | | placeholder="请è¾å
¥ä¼è®®æ¦è¦" |
| | | maxlength="200" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <!-- ä¼è®®æ¦è¦éä»¶ä¸ä¼ --> |
| | | <el-form-item label="ä¼è®®æ¦è¦éä»¶"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="section-title">ä¼è®®çºªè¦ææ</div> |
| | | <div class="upload-tip">ä¸ä¼ ä¼è®®çºªè¦ãå³è®®æä»¶çç¸å
³ææ</div> |
| | | <el-upload |
| | | class="summary-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleSummaryFileChange" |
| | | :file-list="editForm.summaryAttachments" |
| | | :limit="5" |
| | | multiple |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | ä¸ä¼ æ¦è¦éä»¶ |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | æ¯æPDFãWordçææ¡£æ ¼å¼ï¼å个æä»¶ä¸è¶
è¿10MB |
| | | </div> |
| | | </el-upload> |
| | | <div |
| | | v-if=" |
| | | editForm.summaryAttachments && |
| | | editForm.summaryAttachments.length > 0 |
| | | " |
| | | class="uploaded-files" |
| | | > |
| | | <div |
| | | v-for="(file, index) in editForm.summaryAttachments" |
| | | :key="file.uid || index" |
| | | class="file-item" |
| | | > |
| | | <span class="file-name">{{ file.name }}</span> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleRemoveSummaryFile(index)" |
| | | style="color: #F56C6C;" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¼å§æ¶é´" prop="startTime"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form-item label="æåæé" prop="reminderMinutes"> |
| | | <el-input-number |
| | | v-model="editForm.reminderMinutes" |
| | | :min="0" |
| | | :max="1440" |
| | | :step="5" |
| | | controls-position="right" |
| | | style="width: 100%" |
| | | > |
| | | <template #append>åé</template> |
| | | </el-input-number> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ä¼è®®æ¦è¦" prop="summary"> |
| | | <el-input |
| | | v-model="editForm.summary" |
| | |
| | | v-model="editForm.content" |
| | | type="textarea" |
| | | :rows="6" |
| | | placeholder="请è¾å
¥ä¼è®®å
·ä½å
容" |
| | | placeholder="请è¾å
¥ä¼è®®å
·ä½å
å®¹ï¼æ¯æHTMLæ ¼å¼ï¼" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <!-- ä¼è®®çºªè¦éä»¶ä¸ä¼ --> |
| | | <el-form-item label="ä¼è®®çºªè¦éä»¶"> |
| | | <el-form-item label="ä¼è®®éä»¶"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="upload-tip">ä¸ä¼ ä¼è®®ç¸å
³èµææä»¶</div> |
| | | <el-upload |
| | | class="attachment-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleAttachmentChange" |
| | | :file-list="editForm.attachmentFiles" |
| | | :limit="10" |
| | | multiple |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | ä¸ä¼ ä¼è®®éä»¶ |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | æ¯æææ¡£ãå¾ççæ ¼å¼ï¼å个æä»¶ä¸è¶
è¿20MB |
| | | </div> |
| | | </el-upload> |
| | | <div |
| | | v-if=" |
| | | editForm.attachmentFiles && editForm.attachmentFiles.length > 0 |
| | | " |
| | | class="uploaded-files" |
| | | > |
| | | <div |
| | | v-for="(file, index) in editForm.attachmentFiles" |
| | | :key="file.uid || index" |
| | | class="file-item" |
| | | > |
| | | <span class="file-name">{{ file.name }}</span> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleRemoveAttachmentFile(index)" |
| | | style="color: #F56C6C;" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <el-divider>ä¼è®®çºªè¦ï¼å¯ä¼åè¡¥å
ï¼</el-divider> |
| | | |
| | | <el-form-item label="纪è¦å
容" prop="recordcontent"> |
| | | <el-input |
| | | v-model="editForm.recordcontent" |
| | | type="textarea" |
| | | :rows="6" |
| | | placeholder="请è¾å
¥ä¼è®®çºªè¦å
容ï¼å
æ¬ä¼è®®å³è®®ãè¡å¨è®¡åã责任人çä¿¡æ¯" |
| | | maxlength="1000" |
| | | show-word-limit |
| | | /> |
| | | <div style="color: #909399; font-size: 12px; margin-top: 4px;"> |
| | | æç¤ºï¼å¯è®°å½ä¼è®®è®¨è®ºè¦ç¹ãå³è®®äºé¡¹ãè¡å¨è®¡åç |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="纪è¦éä»¶"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="upload-tip">ä¸ä¼ ä¸ä¼è®®çºªè¦ç¸å
³çè¡¥å
ææ</div> |
| | | <el-upload |
| | | class="minutes-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleMinutesFileChange" |
| | | :file-list="editForm.minutesAttachments" |
| | | :on-change="handleMinutesAttachmentChange" |
| | | :file-list="editForm.recordattachmentFiles" |
| | | :limit="5" |
| | | multiple |
| | | > |
| | |
| | | </el-upload> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼è®®çºªè¦" prop="meetingMinutes"> |
| | | |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input |
| | | v-model="editForm.meetingMinutes" |
| | | v-model="editForm.remark" |
| | | type="textarea" |
| | | :rows="6" |
| | | placeholder="请è¾å
¥ä¼è®®çºªè¦å
容ï¼å
æ¬ä¼è®®å³è®®ãè¡å¨è®¡åã责任人çä¿¡æ¯" |
| | | maxlength="1000" |
| | | show-word-limit |
| | | :rows="2" |
| | | placeholder="请è¾å
¥å¤æ³¨ä¿¡æ¯" |
| | | /> |
| | | <div style="color: #909399; font-size: 12px; margin-top: 4px;"> |
| | | æç¤ºï¼å¯è®°å½ä¼è®®è®¨è®ºè¦ç¹ãå³è®®äºé¡¹ãè¡å¨è®¡åç |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { |
| | | meetinglist, |
| | | meetingedit, |
| | | meetingadd, |
| | | meetingInfo, |
| | | meetingDel, |
| | | exporremeeting |
| | | } from "@/api/officeManagementApi"; |
| | | |
| | | export default { |
| | | name: "MeetingManagement", |
| | | data() { |
| | | return { |
| | | // æ¥è¯¢åæ° |
| | | queryParams: { |
| | | title: "", |
| | | meetingType: "", |
| | | location: "", |
| | | dateRange: [], |
| | |
| | | }, |
| | | // å页忰 |
| | | pagination: { |
| | | currentPage: 1, |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | total: 0 |
| | | }, |
| | |
| | | // å¯¹è¯æ¡æ¾ç¤ºç¶æ |
| | | detailDialogVisible: false, |
| | | editDialogVisible: false, |
| | | minutesDialogVisible: false, |
| | | // å½åæä½è®°å½ |
| | | currentRecord: {}, |
| | | // ç¼è¾ç¶æ |
| | | isEditing: false, |
| | | // è¡¨æ ¼æ°æ® |
| | | tableData: [], |
| | | // ç¨æ·å表ï¼ç¨äºéæ©åä¼äººåï¼ |
| | | userList: [ |
| | | { id: 1, name: "å¼ ä¸" }, |
| | | { id: 2, name: "æå" }, |
| | | { id: 3, name: "çäº" }, |
| | | { id: 4, name: "èµµå
" }, |
| | | { id: 5, name: "é±ä¸" }, |
| | | { id: 6, name: "åå
«" }, |
| | | { id: 7, name: "å¨ä¹" }, |
| | | { id: 8, name: "å´å" } |
| | | ], |
| | | minutesDialogVisible: false, // ä¼è®®çºªè¦å¯¹è¯æ¡æ¾ç¤ºç¶æ |
| | | |
| | | // ç¼è¾è¡¨åæ°æ® |
| | | editForm: { |
| | | title: "", |
| | | meetingType: "", |
| | | participants: [], |
| | | location: "", |
| | | startTime: "", |
| | | endTime: "", |
| | | summary: "", |
| | | content: "", |
| | | attachments: [], |
| | | detailAttachments: [], // ä¼è®®è¯¦æ
éä»¶ |
| | | summaryAttachments: [], // ä¼è®®æ¦è¦éä»¶ |
| | | minutesAttachments: [] // ä¼è®®çºªè¦éä»¶ |
| | | }, |
| | | editForm: this.getDefaultFormData(), |
| | | // 表åéªè¯è§å |
| | | editRules: { |
| | | title: [{ required: true, message: "请è¾å
¥ä¼è®®ä¸»é¢", trigger: "blur" }], |
| | | meetingType: [ |
| | | typeId: [ |
| | | { required: true, message: "è¯·éæ©ä¼è®®ç±»å", trigger: "change" } |
| | | ], |
| | | participants: [ |
| | | { required: true, message: "è¯·éæ©åä¼äººå", trigger: "change" } |
| | | ], |
| | | location: [ |
| | | { required: true, message: "请è¾å
¥ä¼è®®å°ç¹", trigger: "blur" } |
| | | locationId: [ |
| | | { required: true, message: "è¯·éæ©ä¼è®®å°ç¹", trigger: "change" } |
| | | ], |
| | | startTime: [ |
| | | { required: true, message: "è¯·éæ©å¼å§æ¶é´", trigger: "change" } |
| | |
| | | content: [ |
| | | { required: true, message: "请è¾å
¥ä¼è®®å
容", trigger: "blur" } |
| | | ], |
| | | meetingMinutes: [ |
| | | { |
| | | max: 1000, |
| | | message: "ä¼è®®çºªè¦é¿åº¦ä¸è½è¶
è¿1000个å符", |
| | | trigger: "blur" |
| | | } |
| | | reminderMinutes: [ |
| | | { required: true, message: "请è¾å
¥æåæéæ¶é´", trigger: "blur" } |
| | | ] |
| | | } |
| | | }; |
| | |
| | | async loadData() { |
| | | this.loading = true; |
| | | try { |
| | | // 模æAPIè°ç¨ |
| | | await new Promise(resolve => setTimeout(resolve, 500)); |
| | | const params = { |
| | | pageNum: this.pagination.pageNum, |
| | | pageSize: this.pagination.pageSize, |
| | | ...this.queryParams |
| | | }; |
| | | |
| | | // çææ¨¡ææ°æ® |
| | | this.tableData = this.generateMockData(); |
| | | this.pagination.total = this.tableData.length; |
| | | // å¤çæ¶é´èå´æ¥è¯¢ |
| | | if ( |
| | | this.queryParams.dateRange && |
| | | this.queryParams.dateRange.length === 2 |
| | | ) { |
| | | params.startTime = this.queryParams.dateRange[0]; |
| | | params.endTime = this.queryParams.dateRange[1]; |
| | | } |
| | | |
| | | const response = await meetinglist(params); |
| | | |
| | | if (response.code === 200) { |
| | | this.tableData = response.rows || []; |
| | | this.pagination.total = response.total || 0; |
| | | } else { |
| | | this.$message.error(response.msg || "è·åæ°æ®å¤±è´¥"); |
| | | } |
| | | } catch (error) { |
| | | console.error("å è½½æ°æ®å¤±è´¥:", error); |
| | | this.$message.error("æ°æ®å 载失败"); |
| | |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | getFileIcon(fileType) { |
| | | |
| | | // è·åæä»¶å¾æ |
| | | getFileIcon(fileName) { |
| | | if (!fileName) return "el-icon-document"; |
| | | const ext = fileName |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | const iconMap = { |
| | | pdf: "el-icon-document", |
| | | doc: "el-icon-document", |
| | |
| | | zip: "el-icon-folder", |
| | | rar: "el-icon-folder" |
| | | }; |
| | | return iconMap[fileType] || "el-icon-document"; |
| | | return iconMap[ext] || "el-icon-document"; |
| | | }, |
| | | |
| | | // æ¥çä¼è®®çºªè¦ |
| | | handleViewMinutes(record) { |
| | | this.currentRecord = { ...record }; |
| | | this.minutesDialogVisible = true; |
| | | }, |
| | | |
| | | // çææ¨¡ææ°æ® |
| | | generateMockData() { |
| | | const meetingTypes = [ |
| | | "research", |
| | | "daily", |
| | | "project", |
| | | "department", |
| | | "review" |
| | | ]; |
| | | const statuses = ["pending", "ongoing", "completed", "cancelled"]; |
| | | const participantsPool = [ |
| | | "å¼ ä¸", |
| | | "æå", |
| | | "çäº", |
| | | "èµµå
", |
| | | "é±ä¸", |
| | | "åå
«", |
| | | "å¨ä¹", |
| | | "å´å" |
| | | ]; |
| | | |
| | | // ä¼è®®çºªè¦ç¤ºä¾å
容 |
| | | const minutesExamples = [ |
| | | `ä¼è®®å³è®®ï¼ |
| | | 1. 项ç®è®¡åè°æ´è³ä¸å¨ä¸æ£å¼å¯å¨ |
| | | 2. ææ¯æ¹æ¡ç±å¼ ä¸è´è´£å®å |
| | | 3. ä¸å¨è¿è¡ææ¯è¯å®¡ä¼è®® |
| | | |
| | | è¡å¨è®¡åï¼ |
| | | - æåï¼åå¤ææ¯ææ¡£ï¼æªæ¢å¨äºï¼ |
| | | - çäºï¼åè°èµæºåé
ï¼æªæ¢å¨åï¼ |
| | | - å
¨ä½ï¼åå ææ¯å¹è®ï¼å¨ä¸ä¸åï¼`, |
| | | |
| | | `讨论è¦ç¹ï¼ |
| | | 1. å½å项ç®è¿åº¦æ£å¸¸ï¼éå 强质éç®¡æ§ |
| | | 2. 客æ·åé¦é®é¢éè¦ä¼å
å¤ç |
| | | 3. ä¸é¶æ®µå·¥ä½éç¹æç¡® |
| | | |
| | | ä»»å¡åé
ï¼ |
| | | â
已宿ï¼éæ±åæãææ¯æ¹æ¡ |
| | | ð· è¿è¡ä¸ï¼å¼å宿½ï¼è´è´£äººï¼èµµå
ï¼ |
| | | â³ å¾
å¼å§ï¼æµè¯éªæ¶`, |
| | | |
| | | `éè¦å³è®®ï¼ |
| | | ⢠éè¿é¢ç®è°æ´æ¹æ¡ |
| | | â¢ ç¡®å®æ°æåå å
¥æ¶é´ |
| | | ⢠æ¹å设å¤éè´ç³è¯· |
| | | |
| | | åç»å®æï¼ |
| | | ð
䏿¬¡ä¼è®®æ¶é´ï¼2024-01-15 14:00 |
| | | ð ä¼è®®å°ç¹ï¼ç¬¬ä¸ä¼è®®å®¤ |
| | | ð¥ å¿
é¡»åä¼äººåï¼å¼ ä¸ãæå` |
| | | ]; |
| | | |
| | | return Array.from({ length: 10 }, (_, index) => { |
| | | const participantCount = Math.floor(Math.random() * 5) + 2; |
| | | const participants = []; |
| | | for (let i = 0; i < participantCount; i++) { |
| | | const randomIndex = Math.floor( |
| | | Math.random() * participantsPool.length |
| | | ); |
| | | participants.push(participantsPool[randomIndex]); |
| | | // è§£æéä»¶JSON |
| | | parseAttachments(attachmentJson) { |
| | | if (!attachmentJson) return []; |
| | | try { |
| | | if (typeof attachmentJson === "string") { |
| | | return JSON.parse(attachmentJson); |
| | | } |
| | | |
| | | const uniqueParticipants = [...new Set(participants)]; |
| | | const startTime = new Date(); |
| | | startTime.setDate( |
| | | startTime.getDate() + Math.floor(Math.random() * 30) - 15 |
| | | ); |
| | | startTime.setHours( |
| | | 9 + Math.floor(Math.random() * 8), |
| | | Math.floor(Math.random() * 4) * 15, |
| | | 0 |
| | | ); |
| | | |
| | | const endTime = new Date(startTime); |
| | | endTime.setHours( |
| | | startTime.getHours() + Math.floor(Math.random() * 3) + 1 |
| | | ); |
| | | |
| | | // éæºå³å®æ¯å¦æä¼è®®çºªè¦ï¼60%æ¦çæçºªè¦ï¼ |
| | | const hasMinutes = Math.random() > 0.4; |
| | | const meetingMinutes = hasMinutes |
| | | ? minutesExamples[Math.floor(Math.random() * minutesExamples.length)] |
| | | : ""; |
| | | const hasDetailAttachments = Math.random() > 0.5; |
| | | const hasSummaryAttachments = Math.random() > 0.6; |
| | | const hasMinutesAttachments = Math.random() > 0.7; |
| | | return { |
| | | id: index + 1, |
| | | title: `å
³äº${ |
| | | ["ç§ç 项ç®", "æ¥å¸¸å·¥ä½", "ææ¯è¯å®¡", "é¨é¨åè°"][ |
| | | Math.floor(Math.random() * 4) |
| | | ] |
| | | }çä¼è®®`, |
| | | // æ·»å åç±»åéä»¶ |
| | | detailAttachments: hasDetailAttachments ? [ |
| | | { |
| | | id: `detail-${index}-1`, |
| | | name: `ä¼è®®ææ-${index}.pdf`, |
| | | type: 'pdf', |
| | | size: 2048000, |
| | | url: '/api/files/meeting-material.pdf', |
| | | uploadTime: new Date(startTime.getTime() - 3600000).toISOString() |
| | | }, |
| | | { |
| | | id: `detail-${index}-2`, |
| | | name: `èæ¯èµæ-${index}.docx`, |
| | | type: 'docx', |
| | | size: 1024000, |
| | | url: '/api/files/background.docx', |
| | | uploadTime: new Date(startTime.getTime() - 7200000).toISOString() |
| | | } |
| | | ] : [], |
| | | |
| | | summaryAttachments: hasSummaryAttachments ? [ |
| | | { |
| | | id: `summary-${index}-1`, |
| | | name: `ä¼è®®çºªè¦-${index}.pdf`, |
| | | type: 'pdf', |
| | | size: 512000, |
| | | url: '/api/files/meeting-summary.pdf', |
| | | uploadTime: new Date(startTime.getTime() + 3600000).toISOString() |
| | | } |
| | | ] : [], |
| | | |
| | | minutesAttachments: hasMinutesAttachments ? [ |
| | | { |
| | | id: `minutes-${index}-1`, |
| | | name: `è¡¥å
ææ-${index}.jpg`, |
| | | type: 'jpg', |
| | | size: 1024000, |
| | | url: '/api/files/supplement.jpg', |
| | | uploadTime: new Date(startTime.getTime() + 7200000).toISOString() |
| | | } |
| | | ] : [], |
| | | meetingType: |
| | | meetingTypes[Math.floor(Math.random() * meetingTypes.length)], |
| | | participants: uniqueParticipants, |
| | | location: ["第ä¸ä¼è®®å®¤", "第äºä¼è®®å®¤", "第ä¸ä¼è®®å®¤", "线ä¸ä¼è®®"][ |
| | | Math.floor(Math.random() * 4) |
| | | ], |
| | | startTime: startTime.toISOString(), |
| | | endTime: endTime.toISOString(), |
| | | summary: `æ¬æ¬¡ä¼è®®ä¸»è¦è®¨è®º${ |
| | | ["项ç®è¿å±", "ææ¯é¾é¢", "å·¥ä½è®¡å", "é®é¢åè°"][ |
| | | Math.floor(Math.random() * 4) |
| | | ] |
| | | }çç¸å
³äºå®`, |
| | | content: `ä¼è®®è¯¦ç»å
容ï¼\n1. è®®é¢ä¸è®¨è®º\n2. è®®é¢äºåæ\n3. ä¸ä¸æ¥å·¥ä½è®¡å\n4. ä»»å¡åé
`, |
| | | meetingMinutes: meetingMinutes, |
| | | minutesCreateTime: hasMinutes |
| | | ? new Date(startTime.getTime() + 3600000).toISOString() |
| | | : "", |
| | | minutesCreator: hasMinutes ? participants[0] : "", |
| | | status: statuses[Math.floor(Math.random() * statuses.length)], |
| | | creator: "ç³»ç»ç®¡çå", |
| | | attachments: [] |
| | | }; |
| | | }); |
| | | return attachmentJson; |
| | | } catch (error) { |
| | | console.error("è§£æé件失败:", error); |
| | | return []; |
| | | } |
| | | }, |
| | | |
| | | // è·åä¼è®®ç±»åæ ç¾æ ·å¼ |
| | | getMeetingTypeTag(type) { |
| | | getMeetingTypeTag(typeId) { |
| | | const typeMap = { |
| | | research: "primary", |
| | | daily: "success", |
| | | project: "warning", |
| | | department: "info", |
| | | review: "danger" |
| | | 1: "primary", // ç§ç ä¼è®® |
| | | 2: "success", // æ¥å¸¸ä¼è®® |
| | | 3: "warning", // 项ç®ä¼è®® |
| | | 4: "info", // é¨é¨ä¼è®® |
| | | 5: "danger" // è¯å®¡ä¼è®® |
| | | }; |
| | | return typeMap[type] || "info"; |
| | | return typeMap[typeId] || "info"; |
| | | }, |
| | | |
| | | // è·åä¼è®®ç±»åææ¬ |
| | | getMeetingTypeText(type) { |
| | | getMeetingTypeText(typeId) { |
| | | const textMap = { |
| | | research: "ç§ç ä¼è®®", |
| | | daily: "æ¥å¸¸ä¼è®®", |
| | | project: "项ç®ä¼è®®", |
| | | department: "é¨é¨ä¼è®®", |
| | | review: "è¯å®¡ä¼è®®" |
| | | 1: "ç§ç ä¼è®®", |
| | | 2: "æ¥å¸¸ä¼è®®", |
| | | 3: "项ç®ä¼è®®", |
| | | 4: "é¨é¨ä¼è®®", |
| | | 5: "è¯å®¡ä¼è®®" |
| | | }; |
| | | return textMap[type] || type; |
| | | return textMap[typeId] || "å
¶ä»"; |
| | | }, |
| | | |
| | | // è·åç¶ææ ç¾æ ·å¼ |
| | | getStatusTag(status) { |
| | | // è·åä¼è®®ç¶ææ ç¾æ ·å¼ |
| | | getMeetingStatusTag(status) { |
| | | const statusMap = { |
| | | pending: "primary", |
| | | ongoing: "success", |
| | | completed: "info", |
| | | cancelled: "danger" |
| | | 1: "primary", // å¾
å¼å§ |
| | | 2: "success", // è¿è¡ä¸ |
| | | 3: "info", // å·²ç»æ |
| | | 4: "danger" // 已忶 |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }, |
| | | |
| | | // è·åç¶æææ¬ |
| | | getStatusText(status) { |
| | | // è·åä¼è®®ç¶æææ¬ |
| | | getMeetingStatusText(status) { |
| | | const textMap = { |
| | | pending: "å¾
å¼å§", |
| | | ongoing: "è¿è¡ä¸", |
| | | completed: "å·²ç»æ", |
| | | cancelled: "已忶" |
| | | 1: "å¾
å¼å§", |
| | | 2: "è¿è¡ä¸", |
| | | 3: "å·²ç»æ", |
| | | 4: "已忶" |
| | | }; |
| | | return textMap[status] || status; |
| | | return textMap[status] || "æªç¥"; |
| | | }, |
| | | |
| | | // è·åå®¡æ ¸ç¶ææ ç¾æ ·å¼ |
| | | getApprovalStatusTag(status) { |
| | | const statusMap = { |
| | | 0: "warning", // å¾
å®¡æ ¸ |
| | | 1: "success", // å·²éè¿ |
| | | 2: "danger" // 已驳å |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }, |
| | | |
| | | // è·åå®¡æ ¸ç¶æææ¬ |
| | | getApprovalStatusText(status) { |
| | | const textMap = { |
| | | 0: "å¾
å®¡æ ¸", |
| | | 1: "å·²éè¿", |
| | | 2: "已驳å" |
| | | }; |
| | | return textMap[status] || "æªå®¡æ ¸"; |
| | | }, |
| | | |
| | | // æ ¼å¼åæ¥ææ¶é´ |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return ""; |
| | | const date = new Date(dateTime); |
| | | return date.toLocaleString("zh-CN"); |
| | | return dateTime.replace("T", " "); |
| | | }, |
| | | |
| | | // 计ç®ä¼è®®æç»æ¶é´ |
| | |
| | | } |
| | | }, |
| | | |
| | | // æ ¼å¼åæä»¶å¤§å° |
| | | formatFileSize(bytes) { |
| | | if (!bytes) return "0 B"; |
| | | const k = 1024; |
| | | const sizes = ["B", "KB", "MB", "GB"]; |
| | | const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| | | return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; |
| | | }, |
| | | |
| | | // æ¥è¯¢å¤ç |
| | | handleQuery() { |
| | | this.pagination.currentPage = 1; |
| | | this.pagination.pageNum = 1; |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | handleReset() { |
| | | this.queryParams = { |
| | | title: "", |
| | | meetingType: "", |
| | | location: "", |
| | | dateRange: [], |
| | | status: "" |
| | | }; |
| | | this.pagination.currentPage = 1; |
| | | this.pagination.pageNum = 1; |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // æ¥ç详æ
|
| | | handleView(record) { |
| | | this.currentRecord = { ...record }; |
| | | this.detailDialogVisible = true; |
| | | async handleView(id) { |
| | | try { |
| | | const response = await meetingInfo(id); |
| | | if (response.code === 200) { |
| | | this.currentRecord = response.data || {}; |
| | | this.detailDialogVisible = true; |
| | | } else { |
| | | this.$message.error(response.msg || "è·å详æ
失败"); |
| | | } |
| | | } catch (error) { |
| | | console.error("è·å详æ
失败:", error); |
| | | this.$message.error("è·å详æ
失败"); |
| | | } |
| | | }, |
| | | |
| | | // æ°å¢è®°å½ |
| | |
| | | }, |
| | | |
| | | // ç¼è¾è®°å½ |
| | | handleEdit(record) { |
| | | this.isEditing = true; |
| | | this.currentRecord = record; |
| | | this.editForm = { ...record }; |
| | | this.editDialogVisible = true; |
| | | this.detailDialogVisible = false; |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | | }); |
| | | async handleEdit(id) { |
| | | try { |
| | | const response = await meetingInfo(id); |
| | | if (response.code === 200) { |
| | | this.isEditing = true; |
| | | this.currentRecord = response.data || {}; |
| | | this.editForm = { ...response.data }; |
| | | |
| | | // è§£æéä»¶ |
| | | if (this.editForm.attachment) { |
| | | this.editForm.attachmentFiles = this.parseAttachments( |
| | | this.editForm.attachment |
| | | ); |
| | | } |
| | | if (this.editForm.recordattachment) { |
| | | this.editForm.recordattachmentFiles = this.parseAttachments( |
| | | this.editForm.recordattachment |
| | | ); |
| | | } |
| | | |
| | | this.editDialogVisible = true; |
| | | this.detailDialogVisible = false; |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | | }); |
| | | } else { |
| | | this.$message.error(response.msg || "è·åè®°å½å¤±è´¥"); |
| | | } |
| | | } catch (error) { |
| | | console.error("è·åè®°å½å¤±è´¥:", error); |
| | | this.$message.error("è·åè®°å½å¤±è´¥"); |
| | | } |
| | | }, |
| | | |
| | | // å¤å¶è®°å½ |
| | | handleCopy(record) { |
| | | this.isEditing = false; |
| | | const copiedRecord = { ...record }; |
| | | delete copiedRecord.id; |
| | | copiedRecord.title = copiedRecord.title + "ï¼å¤å¶ï¼"; |
| | | this.editForm = copiedRecord; |
| | | this.editDialogVisible = true; |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | | }); |
| | | async handleCopy(id) { |
| | | try { |
| | | const response = await meetingInfo(id); |
| | | if (response.code === 200) { |
| | | this.isEditing = false; |
| | | const copiedRecord = { ...response.data }; |
| | | |
| | | // ç§»é¤IDï¼çææ°è®°å½ |
| | | delete copiedRecord.id; |
| | | delete copiedRecord.meetingNumber; |
| | | copiedRecord.title = copiedRecord.title + "ï¼å¤å¶ï¼"; |
| | | copiedRecord.parentMeetingId = id; |
| | | |
| | | // è§£æéä»¶ |
| | | if (copiedRecord.attachment) { |
| | | copiedRecord.attachmentFiles = this.parseAttachments( |
| | | copiedRecord.attachment |
| | | ); |
| | | } |
| | | if (copiedRecord.recordattachment) { |
| | | copiedRecord.recordattachmentFiles = this.parseAttachments( |
| | | copiedRecord.recordattachment |
| | | ); |
| | | } |
| | | |
| | | this.editForm = copiedRecord; |
| | | this.editDialogVisible = true; |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | | }); |
| | | } else { |
| | | this.$message.error(response.msg || "è·åè®°å½å¤±è´¥"); |
| | | } |
| | | } catch (error) { |
| | | console.error("è·åè®°å½å¤±è´¥:", error); |
| | | this.$message.error("è·åè®°å½å¤±è´¥"); |
| | | } |
| | | }, |
| | | |
| | | // å é¤è®°å½ |
| | | handleDelete(record) { |
| | | this.$confirm("ç¡®å®è¦å é¤è¿æ¡ä¼è®®è®°å½åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }) |
| | | .then(() => { |
| | | // 模æå é¤æä½ |
| | | this.tableData = this.tableData.filter(item => item.id !== record.id); |
| | | this.pagination.total = this.tableData.length; |
| | | async handleDelete(record) { |
| | | try { |
| | | await this.$confirm("ç¡®å®è¦å é¤è¿æ¡ä¼è®®è®°å½åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }); |
| | | |
| | | const response = await meetingDel(record.id); |
| | | if (response.code === 200) { |
| | | this.$message.success("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | // æ°å¢æ¹æ³ï¼æ ¼å¼åæä»¶å¤§å° |
| | | formatFileSize(bytes) { |
| | | if (!bytes) return "0 B"; |
| | | const k = 1024; |
| | | const sizes = ["B", "KB", "MB", "GB"]; |
| | | const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| | | return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; |
| | | this.loadData(); |
| | | } else { |
| | | this.$message.error(response.msg || "å é¤å¤±è´¥"); |
| | | } |
| | | } catch (error) { |
| | | if (error !== "cancel") { |
| | | console.error("å é¤å¤±è´¥:", error); |
| | | this.$message.error("å é¤å¤±è´¥"); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // åç±»åæä»¶ä¸ä¼ å¤ç |
| | | handleDetailFileChange(file, fileList) { |
| | | this.editForm.detailAttachments = fileList; |
| | | // æä»¶ä¸ä¼ å¤ç |
| | | handleAttachmentChange(file, fileList) { |
| | | this.editForm.attachmentFiles = fileList; |
| | | }, |
| | | |
| | | handleSummaryFileChange(file, fileList) { |
| | | this.editForm.summaryAttachments = fileList; |
| | | }, |
| | | |
| | | handleMinutesFileChange(file, fileList) { |
| | | this.editForm.minutesAttachments = fileList; |
| | | handleMinutesAttachmentChange(file, fileList) { |
| | | this.editForm.recordattachmentFiles = fileList; |
| | | }, |
| | | |
| | | // å é¤å·²ä¸ä¼ çæä»¶ |
| | | handleRemoveDetailFile(index) { |
| | | this.editForm.detailAttachments.splice(index, 1); |
| | | handleRemoveAttachmentFile(index) { |
| | | this.editForm.attachmentFiles.splice(index, 1); |
| | | }, |
| | | |
| | | handleRemoveSummaryFile(index) { |
| | | this.editForm.summaryAttachments.splice(index, 1); |
| | | }, |
| | | |
| | | // æä»¶é¢è§åä¸è½½ |
| | | handlePreview(file) { |
| | | // å®ç°æä»¶é¢è§é»è¾ |
| | | this.$message.info(`é¢è§æä»¶: ${file.name}`); |
| | | }, |
| | | |
| | | // æä»¶ä¸è½½ |
| | | handleDownload(file) { |
| | | // å®ç°æä»¶ä¸è½½é»è¾ |
| | | const link = document.createElement("a"); |
| | | link.href = file.url; |
| | | link.download = file.name; |
| | | link.click(); |
| | | this.$message.success(`å¼å§ä¸è½½: ${file.name}`); |
| | | if (file.url) { |
| | | const link = document.createElement("a"); |
| | | link.href = file.url; |
| | | link.download = file.name; |
| | | link.click(); |
| | | this.$message.success(`å¼å§ä¸è½½: ${file.name}`); |
| | | } else { |
| | | this.$message.warning("æä»¶å°åä¸åå¨"); |
| | | } |
| | | }, |
| | | |
| | | // ä¿åè®°å½ |
| | | async handleSave() { |
| | | try { |
| | | const valid = await this.$refs.editForm.validate(); |
| | | if (!valid) return; |
| | | |
| | | this.saveLoading = true; |
| | | // 模æAPIè°ç¨ |
| | | await new Promise(resolve => setTimeout(resolve, 1000)); |
| | | // éªè¯æ¶é´ |
| | | if (this.editForm.startTime && this.editForm.endTime) { |
| | | if ( |
| | | new Date(this.editForm.endTime) <= new Date(this.editForm.startTime) |
| | | ) { |
| | | this.$message.error("ç»ææ¶é´å¿
é¡»æäºå¼å§æ¶é´"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | this.$message.success(this.isEditing ? "ä¿åæå" : "æ°å¢æå"); |
| | | this.editDialogVisible = false; |
| | | this.loadData(); |
| | | this.saveLoading = true; |
| | | |
| | | // å¤çéä»¶ |
| | | const formData = { ...this.editForm }; |
| | | |
| | | if (formData.attachmentFiles) { |
| | | formData.attachment = JSON.stringify( |
| | | formData.attachmentFiles.map(file => ({ |
| | | name: file.name, |
| | | url: file.url || "", |
| | | size: file.size || 0, |
| | | type: file.type || file.name.split(".").pop() |
| | | })) |
| | | ); |
| | | } |
| | | |
| | | if (formData.recordattachmentFiles) { |
| | | formData.recordattachment = JSON.stringify( |
| | | formData.recordattachmentFiles.map(file => ({ |
| | | name: file.name, |
| | | url: file.url || "", |
| | | size: file.size || 0, |
| | | type: file.type || file.name.split(".").pop() |
| | | })) |
| | | ); |
| | | } |
| | | |
| | | // æ¸
çæä»¶åè¡¨åæ®µ |
| | | delete formData.attachmentFiles; |
| | | delete formData.recordattachmentFiles; |
| | | |
| | | let response; |
| | | if (this.isEditing) { |
| | | response = await meetingedit(formData); |
| | | } else { |
| | | response = await meetingadd(formData); |
| | | } |
| | | |
| | | if (response.code === 200) { |
| | | this.$message.success(this.isEditing ? "ä¿åæå" : "æ°å¢æå"); |
| | | this.editDialogVisible = false; |
| | | this.loadData(); |
| | | } else { |
| | | this.$message.error( |
| | | response.msg || (this.isEditing ? "ä¿å失败" : "æ°å¢å¤±è´¥") |
| | | ); |
| | | } |
| | | } catch (error) { |
| | | console.error("ä¿å失败:", error); |
| | | this.$message.error("æä½å¤±è´¥"); |
| | | this.$message.error(this.isEditing ? "ä¿å失败" : "æ°å¢å¤±è´¥"); |
| | | } finally { |
| | | this.saveLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // æä»¶ä¸ä¼ å¤ç |
| | | handleFileChange(file, fileList) { |
| | | this.editForm.attachments = fileList; |
| | | }, |
| | | |
| | | // å
³é详æ
å¯¹è¯æ¡ |
| | |
| | | handleEditClose() { |
| | | this.editDialogVisible = false; |
| | | this.currentRecord = {}; |
| | | this.editForm = this.getDefaultFormData(); |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | | }); |
| | |
| | | |
| | | // å¯¼åºæ°æ® |
| | | exportData() { |
| | | this.$message.success("导åºåè½å¼åä¸"); |
| | | const queryParams = this.queryParams; |
| | | this.$modal |
| | | .confirm("æ¯å¦ç¡®è®¤å¯¼åºææä¼è®®çºªè¦æ°æ®é¡¹ï¼") |
| | | .then(() => { |
| | | return exporremeeting(queryParams); |
| | | }) |
| | | .then(response => { |
| | | this.$download.name(response.msg); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | |
| | | // å页大å°åå |
| | | handleSizeChange(size) { |
| | | this.pagination.pageSize = size; |
| | | this.pagination.currentPage = 1; |
| | | this.pagination.pageNum = 1; |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // å½å页åå |
| | | handleCurrentChange(page) { |
| | | this.pagination.currentPage = page; |
| | | this.pagination.pageNum = page; |
| | | this.loadData(); |
| | | }, |
| | | |
| | |
| | | console.log("æåºåå:", sort); |
| | | }, |
| | | |
| | | // æ´æ°é»è®¤è¡¨åæ°æ® |
| | | // è·åé»è®¤è¡¨åæ°æ® |
| | | getDefaultFormData() { |
| | | return { |
| | | id: null, |
| | | title: "", |
| | | meetingType: "", |
| | | participants: [], |
| | | location: "", |
| | | typeId: null, |
| | | locationId: null, |
| | | startTime: "", |
| | | endTime: "", |
| | | summary: "", |
| | | content: "", |
| | | meetingMinutes: "", |
| | | minutesCreateTime: "", |
| | | minutesCreator: "", |
| | | detailAttachments: [], |
| | | summaryAttachments: [], |
| | | minutesAttachments: [] |
| | | attachment: null, |
| | | attachmentFiles: [], |
| | | status: 1, // é»è®¤å¾
å¼å§ |
| | | isRecurring: 0, |
| | | recurringPattern: null, |
| | | parentMeetingId: null, |
| | | reminderMinutes: 30, |
| | | recordcontent: "", |
| | | recordattachment: null, |
| | | recordattachmentFiles: [], |
| | | recorderBy: "", |
| | | remark: "", |
| | | approvalStatus: 0 // é»è®¤å¾
å®¡æ ¸ |
| | | }; |
| | | } |
| | | } |
| | |
| | | .minutes-meta { |
| | | border-top: 1px solid #e4e7ed; |
| | | padding-top: 12px; |
| | | } |
| | | |
| | | /* ä¼è®®çºªè¦ææ¬åºåæ ·å¼ */ |
| | | .minutes-textarea { |
| | | font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace; |
| | | font-size: 13px; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | /* ååºå¼è°æ´ */ |
| | |
| | | |
| | | .file-icon { |
| | | font-size: 24px; |
| | | color: #409EFF; |
| | | color: #409eff; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | |
| | | <div class="training-management"> |
| | | <!-- 页é¢å¤´é¨ --> |
| | | <div class="page-header"> |
| | | <h2>è¿ä¿®ç®¡ç</h2> |
| | | <div class="header-actions"> |
| | | <el-button type="primary" icon="el-icon-plus" @click="handleAdd"> |
| | | æ°å¢è¿ä¿®è®°å½ |
| | |
| | | <el-table-column prop="id" label="ID" width="80" fixed /> |
| | | <el-table-column prop="name" label="å§å" width="100" fixed> |
| | | <template #default="scope"> |
| | | <el-button type="text" @click="handleView(scope.row)"> |
| | | <el-button type="text" @click="handleView(scope.row.id)"> |
| | | {{ scope.row.name }} |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="gender" label="æ§å«" width="80"> |
| | | <el-table-column prop="sex" label="æ§å«" width="80"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.gender === 'ç·' ? 'primary' : 'danger'" size="small"> |
| | | {{ scope.row.gender }} |
| | | <el-tag :type="scope.row.sex === 'ç·' ? 'primary' : 'danger'" size="small"> |
| | | {{ scope.row.sex }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="trainingStartDate" label="è¿ä¿®å¼å§æ¶é´" width="120" /> |
| | | <el-table-column prop="trainingEndDate" label="è¿ä¿®ç»ææ¶é´" width="120" /> |
| | | <el-table-column prop="trainingStartDate" label="è¿ä¿®å¼å§æ¶é´" width="120"> |
| | | <template #default="scope"> |
| | | {{ formatDate(scope.row.trainingStartDate) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="trainingEndDate" label="è¿ä¿®ç»ææ¶é´" width="120"> |
| | | <template #default="scope"> |
| | | {{ formatDate(scope.row.trainingEndDate) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="trainingMajor" label="è¿ä¿®ä¸ä¸" width="120" /> |
| | | <el-table-column prop="idCard" label="身份è¯å·" width="180" show-overflow-tooltip /> |
| | | <el-table-column prop="technicalTitle" label="ææ¯èç§°" width="120" /> |
| | | <el-table-column prop="professionalField" label="ä»äºä¸ä¸" width="120" /> |
| | | <el-table-column prop="profession" label="ä»äºä¸ä¸" width="120" /> |
| | | <el-table-column prop="workYears" label="å·¥ä½å¹´é" width="100" sortable /> |
| | | <el-table-column prop="graduateSchool" label="æ¯ä¸é¢æ ¡" width="150" show-overflow-tooltip /> |
| | | <el-table-column prop="graduationSchool" label="æ¯ä¸é¢æ ¡" width="150" show-overflow-tooltip /> |
| | | <el-table-column prop="workUnit" label="æå¨åä½" width="150" show-overflow-tooltip /> |
| | | |
| | | <el-table-column prop="status" label="ç¶æ" width="100" fixed="right"> |
| | | <el-table-column prop="recordStatus" label="ç¶æ" width="100" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getStatusTag(scope.row.status)"> |
| | | {{ scope.row.status }} |
| | | <el-tag :type="getStatusTag(scope.row.recordStatus)"> |
| | | {{ scope.row.recordStatus || 'è¿è¡ä¸' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="180" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button size="mini" type="text" @click="handleView(scope.row)"> |
| | | <el-button size="mini" type="text" @click="handleView(scope.row.id)"> |
| | | æ¥ç |
| | | </el-button> |
| | | <el-button size="mini" type="text" @click="handleEdit(scope.row)"> |
| | | <el-button size="mini" type="text" @click="handleEdit(scope.row.id)"> |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleCopy(scope.row)" |
| | | @click="handleCopy(scope.row.id)" |
| | | style="color: #67C23A;" |
| | | > |
| | | å¤å¶ |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleDelete(scope.row)" |
| | | style="color: #F56C6C;" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | <!-- å页 --> |
| | | <div class="pagination-container"> |
| | | <el-pagination |
| | | :current-page="pagination.currentPage" |
| | | :current-page="pagination.pageNum" |
| | | :page-size="pagination.pageSize" |
| | | :total="pagination.total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | |
| | | width="900px" |
| | | :before-close="handleDetailClose" |
| | | > |
| | | <el-descriptions :column="2" border v-if="currentRecord"> |
| | | <el-descriptions :column="2" border v-if="currentRecord.id"> |
| | | <el-descriptions-item label="å§å">{{ currentRecord.name }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ§å«">{{ currentRecord.gender }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ§å«">{{ currentRecord.sex }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¹´é¾">{{ currentRecord.age }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¦å">{{ currentRecord.education }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç±»å"> |
| | |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="身份è¯å·">{{ currentRecord.idCard }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ¯ä¸é¢æ ¡">{{ currentRecord.graduateSchool }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ¯ä¸é¢æ ¡">{{ currentRecord.graduationSchool }}</el-descriptions-item> |
| | | <el-descriptions-item label="æå¨åä½">{{ currentRecord.workUnit }}</el-descriptions-item> |
| | | <el-descriptions-item label="ææ¯èç§°">{{ currentRecord.technicalTitle }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä»äºä¸ä¸">{{ currentRecord.professionalField }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä»äºä¸ä¸">{{ currentRecord.profession }}</el-descriptions-item> |
| | | <el-descriptions-item label="å·¥ä½å¹´é">{{ currentRecord.workYears }}å¹´</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç®æ ">{{ currentRecord.trainingObjective }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®å¼å§æ¶é´">{{ currentRecord.trainingStartDate }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç»ææ¶é´">{{ currentRecord.trainingEndDate }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç®æ ">{{ currentRecord.trainingGoal }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®å¼å§æ¶é´">{{ formatDate(currentRecord.trainingStartDate) }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç»ææ¶é´">{{ formatDate(currentRecord.trainingEndDate) }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ä¸ä¸">{{ currentRecord.trainingMajor }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä»äºå·¥ä½æ
åµ" :span="2"> |
| | | {{ currentRecord.workSituation }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç§ç®åç®ç" :span="2"> |
| | | {{ currentRecord.trainingSubject }} |
| | | <el-descriptions-item label="è¿ä¿®ç§ç®" :span="2"> |
| | | {{ currentRecord.applySubject }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è¿ä¿®ç®ç" :span="2"> |
| | | {{ currentRecord.applyPurpose }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="主è¦å¦å" :span="2"> |
| | | <div style="white-space: pre-line;">{{ currentRecord.mainEducation }}</div> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="主è¦å·¥ä½ç»å" :span="2"> |
| | | <div style="white-space: pre-line;">{{ currentRecord.workExperience }}</div> |
| | | <div style="white-space: pre-line;">{{ currentRecord.mainExperience }}</div> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å建æ¶é´">{{ formatDateTime(currentRecord.createTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ´æ°æ¶é´">{{ formatDateTime(currentRecord.updateTime) }}</el-descriptions-item> |
| | | <!-- <el-descriptions-item label="夿³¨" :span="2">{{ currentRecord.remark }}</el-descriptions-item> --> |
| | | </el-descriptions> |
| | | <span slot="footer"> |
| | | <el-button @click="detailDialogVisible = false">å
³é</el-button> |
| | | <el-button type="primary" @click="handleEdit(currentRecord)">ç¼è¾</el-button> |
| | | <el-button type="primary" @click="handleEdit(currentRecord.id)">ç¼è¾</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ§å«" prop="gender"> |
| | | <el-radio-group v-model="editForm.gender"> |
| | | <el-form-item label="æ§å«" prop="sex"> |
| | | <el-radio-group v-model="editForm.sex"> |
| | | <el-radio label="ç·">ç·</el-radio> |
| | | <el-radio label="女">女</el-radio> |
| | | </el-radio-group> |
| | |
| | | <el-input v-model="editForm.idCard" placeholder="请è¾å
¥èº«ä»½è¯å·" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="æ¯ä¸é¢æ ¡" prop="graduateSchool"> |
| | | <el-input v-model="editForm.graduateSchool" placeholder="请è¾å
¥æ¯ä¸é¢æ ¡" /> |
| | | <el-form-item label="æ¯ä¸é¢æ ¡" prop="graduationSchool"> |
| | | <el-input v-model="editForm.graduationSchool" placeholder="请è¾å
¥æ¯ä¸é¢æ ¡" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="æå¨åä½" prop="workUnit"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»äºä¸ä¸" prop="professionalField"> |
| | | <el-input v-model="editForm.professionalField" placeholder="请è¾å
¥ä»äºä¸ä¸" /> |
| | | <el-form-item label="ä»äºä¸ä¸" prop="profession"> |
| | | <el-input v-model="editForm.profession" placeholder="请è¾å
¥ä»äºä¸ä¸" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | v-model="editForm.workYears" |
| | | :min="0" |
| | | :max="50" |
| | | :precision="1" |
| | | :step="0.5" |
| | | controls-position="right" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="è¿ä¿®ç®æ " prop="trainingObjective"> |
| | | <el-form-item label="è¿ä¿®ç®æ " prop="trainingGoal"> |
| | | <el-input |
| | | v-model="editForm.trainingObjective" |
| | | v-model="editForm.trainingGoal" |
| | | type="textarea" |
| | | :rows="2" |
| | | placeholder="请è¾å
¥è¿ä¿®ç®æ " |
| | |
| | | v-model="editForm.trainingStartDate" |
| | | type="date" |
| | | placeholder="éæ©å¼å§æ¥æ" |
| | | value-format="yyyy-MM-dd" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | |
| | | v-model="editForm.trainingEndDate" |
| | | type="date" |
| | | placeholder="éæ©ç»ææ¥æ" |
| | | value-format="yyyy-MM-dd" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | |
| | | <el-input v-model="editForm.trainingMajor" placeholder="请è¾å
¥è¿ä¿®ä¸ä¸" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="è¿ä¿®ç§ç®" prop="applySubject"> |
| | | <el-input |
| | | v-model="editForm.applySubject" |
| | | type="textarea" |
| | | :rows="2" |
| | | placeholder="请è¾å
¥æ¬æ¬¡ç³è¯·è¿ä¿®ç§ç®" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="è¿ä¿®ç®ç" prop="applyPurpose"> |
| | | <el-input |
| | | v-model="editForm.applyPurpose" |
| | | type="textarea" |
| | | :rows="2" |
| | | placeholder="请è¾å
¥è¿ä¿®ç®çè¦æ±" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ä»äºå·¥ä½æ
åµ" prop="workSituation"> |
| | | <el-input |
| | | v-model="editForm.workSituation" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥ä»äºå·¥ä½æ
åµ" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="è¿ä¿®ç§ç®åç®ç" prop="trainingSubject"> |
| | | <el-input |
| | | v-model="editForm.trainingSubject" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥æ¬æ¬¡ç³è¯·è¿ä¿®ä½ç§ç§ç®åç®çè¦æ±" |
| | | /> |
| | | </el-form-item> |
| | | |
| | |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="主è¦å·¥ä½ç»å" prop="workExperience"> |
| | | <el-form-item label="主è¦å·¥ä½ç»å" prop="mainExperience"> |
| | | <el-input |
| | | v-model="editForm.workExperience" |
| | | v-model="editForm.mainExperience" |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请è¾å
¥ä¸»è¦å·¥ä½ç»åï¼æ¯è¡ä¸æ¡ï¼" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <!-- <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input |
| | | v-model="editForm.remark" |
| | | type="textarea" |
| | | :rows="2" |
| | | placeholder="请è¾å
¥å¤æ³¨ä¿¡æ¯" |
| | | /> |
| | | </el-form-item> --> |
| | | </el-form> |
| | | |
| | | <span slot="footer"> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { recordslist, recordsedit, recordsadd, recordsInfo, recordsDel,exporrecords } from "@/api/officeManagementApi"; |
| | | |
| | | export default { |
| | | name: 'TrainingManagement', |
| | | data() { |
| | |
| | | }, |
| | | // å页忰 |
| | | pagination: { |
| | | currentPage: 1, |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | total: 0 |
| | | }, |
| | |
| | | // è¡¨æ ¼æ°æ® |
| | | tableData: [], |
| | | // ç¼è¾è¡¨åæ°æ® |
| | | editForm: { |
| | | name: '', |
| | | gender: 'ç·', |
| | | age: 25, |
| | | education: '', |
| | | trainingType: '', |
| | | idCard: '', |
| | | graduateSchool: '', |
| | | workUnit: '', |
| | | technicalTitle: '', |
| | | professionalField: '', |
| | | workYears: 0, |
| | | trainingObjective: '', |
| | | trainingStartDate: '', |
| | | trainingEndDate: '', |
| | | trainingMajor: '', |
| | | workSituation: '', |
| | | trainingSubject: '', |
| | | mainEducation: '', |
| | | workExperience: '' |
| | | }, |
| | | editForm: this.getDefaultFormData(), |
| | | // 表åéªè¯è§å |
| | | editRules: { |
| | | name: [{ required: true, message: '请è¾å
¥å§å', trigger: 'blur' }], |
| | | gender: [{ required: true, message: 'è¯·éæ©æ§å«', trigger: 'change' }], |
| | | sex: [{ required: true, message: 'è¯·éæ©æ§å«', trigger: 'change' }], |
| | | age: [{ required: true, message: '请è¾å
¥å¹´é¾', trigger: 'blur' }], |
| | | education: [{ required: true, message: 'è¯·éæ©å¦å', trigger: 'change' }], |
| | | trainingType: [{ required: true, message: 'è¯·éæ©è¿ä¿®ç±»å', trigger: 'change' }], |
| | | idCard: [{ required: true, message: '请è¾å
¥èº«ä»½è¯å·', trigger: 'blur' }] |
| | | idCard: [ |
| | | { required: true, message: '请è¾å
¥èº«ä»½è¯å·', trigger: 'blur' }, |
| | | { pattern: /^\d{17}[\dXx]$/, message: '请è¾å
¥æ£ç¡®ç身份è¯å·', trigger: 'blur' } |
| | | ], |
| | | trainingStartDate: [{ required: true, message: 'è¯·éæ©è¿ä¿®å¼å§æ¶é´', trigger: 'change' }], |
| | | trainingEndDate: [{ required: true, message: 'è¯·éæ©è¿ä¿®ç»ææ¶é´', trigger: 'change' }] |
| | | } |
| | | } |
| | | }, |
| | |
| | | async loadData() { |
| | | this.loading = true |
| | | try { |
| | | // 模æAPIè°ç¨ |
| | | await new Promise(resolve => setTimeout(resolve, 500)) |
| | | const params = { |
| | | pageNum: this.pagination.pageNum, |
| | | pageSize: this.pagination.pageSize, |
| | | ...this.queryParams |
| | | } |
| | | |
| | | // çææ¨¡ææ°æ® |
| | | this.tableData = this.generateMockData() |
| | | this.pagination.total = this.tableData.length |
| | | // å¤çæ¶é´èå´æ¥è¯¢ |
| | | if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) { |
| | | params.startDate = this.queryParams.dateRange[0] |
| | | params.endDate = this.queryParams.dateRange[1] |
| | | } |
| | | |
| | | const response = await recordslist(params) |
| | | |
| | | if (response.code === 200) { |
| | | this.tableData = response.rows || [] |
| | | this.pagination.total = response.total || 0 |
| | | } else { |
| | | this.$message.error(response.msg || 'è·åæ°æ®å¤±è´¥') |
| | | } |
| | | } catch (error) { |
| | | console.error('å è½½æ°æ®å¤±è´¥:', error) |
| | | this.$message.error('æ°æ®å 载失败') |
| | |
| | | this.loading = false |
| | | } |
| | | }, |
| | | // çææ¨¡ææ°æ® |
| | | generateMockData() { |
| | | const names = ['å¼ ä¸', 'æå', 'çäº', 'èµµå
', 'é±ä¸', 'åå
«', 'å¨ä¹', 'å´å'] |
| | | const trainingTypes = ['professional', 'management', 'education', 'skill'] |
| | | const statuses = ['è¿è¡ä¸', '已宿', 'å¾
å®¡æ ¸', '已忶'] |
| | | |
| | | return Array.from({ length: 10 }, (_, index) => ({ |
| | | id: index + 1, |
| | | name: names[Math.floor(Math.random() * names.length)], |
| | | gender: Math.random() > 0.5 ? 'ç·' : '女', |
| | | age: 25 + Math.floor(Math.random() * 20), |
| | | education: ['å士', 'ç¡å£«', 'æ¬ç§', '大ä¸'][Math.floor(Math.random() * 4)], |
| | | trainingType: trainingTypes[Math.floor(Math.random() * trainingTypes.length)], |
| | | idCard: '11010119900101' + (1000 + index).toString().slice(-4), |
| | | graduateSchool: ['å京大å¦', 'æ¸
å大å¦', '夿¦å¤§å¦', '䏿µ·äº¤é大å¦'][Math.floor(Math.random() * 4)], |
| | | workUnit: ['éå²å¤§å¦éå±å»é¢', 'éå²å¸å¸ç«å»é¢', 'å±±ä¸å¤§å¦é½é²å»é¢', 'éå²å¸ä¸å¿å»é¢'][Math.floor(Math.random() * 4)], |
| | | technicalTitle: ['主任å»å¸', 'å¯ä¸»ä»»å»å¸', '主治å»å¸', 'ä½é¢å»å¸'][Math.floor(Math.random() * 4)], |
| | | professionalField: ['å¿è¡ç®¡å
ç§', 'ç¥ç»å¤ç§', 'å¿ç§', 'å¦äº§ç§'][Math.floor(Math.random() * 4)], |
| | | workYears: 5 + Math.floor(Math.random() * 20), |
| | | trainingObjective: 'æåä¸ä¸ææ¯å临åºè½å', |
| | | trainingStartDate: '2024-' + (Math.floor(Math.random() * 12) + 1).toString().padStart(2, '0') + '-01', |
| | | trainingEndDate: '2024-' + (Math.floor(Math.random() * 12) + 1).toString().padStart(2, '0') + '-28', |
| | | trainingMajor: '临åºå»å¦', |
| | | workSituation: 'å¨ä¸´åºä¸çº¿å·¥ä½ï¼è´è´£æ£è
è¯ç', |
| | | trainingSubject: 'é«çº§å¿è¡ç®¡ä»å
¥æ²»çææ¯', |
| | | mainEducation: '2005-2009 大å¦å»å¦é¨ 临åºå»å¦æ¬ç§\n2009-2012 大å¦å»å¦é¨ ç¡å£«', |
| | | workExperience: '2012-2015 ååå»é¢ ä½é¢å»å¸\n2015-2020 ååå»é¢ 主治å»å¸', |
| | | status: statuses[Math.floor(Math.random() * statuses.length)] |
| | | })) |
| | | }, |
| | | // è·åè¿ä¿®ç±»åæ ç¾æ ·å¼ |
| | | getTrainingTypeTag(type) { |
| | | const typeMap = { |
| | |
| | | } |
| | | return typeMap[type] || 'info' |
| | | }, |
| | | |
| | | // è·åè¿ä¿®ç±»åææ¬ |
| | | getTrainingTypeText(type) { |
| | | const textMap = { |
| | |
| | | } |
| | | return textMap[type] || type |
| | | }, |
| | | |
| | | // è·åç¶ææ ç¾æ ·å¼ |
| | | getStatusTag(status) { |
| | | const statusMap = { |
| | | 'è¿è¡ä¸': 'primary', |
| | | '已宿': 'success', |
| | | 'å¾
å®¡æ ¸': 'warning', |
| | | '已忶': 'danger' |
| | | '已忶': 'danger', |
| | | 'æ£å¸¸': 'success', |
| | | 'å é¤': 'danger' |
| | | } |
| | | return statusMap[status] || 'info' |
| | | }, |
| | | |
| | | // æ ¼å¼åæ¥æ |
| | | formatDate(date) { |
| | | if (!date) return '' |
| | | return date.split(' ')[0] |
| | | }, |
| | | |
| | | // æ ¼å¼åæ¥ææ¶é´ |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return '' |
| | | return dateTime.replace('T', ' ') |
| | | }, |
| | | |
| | | // æ¥è¯¢å¤ç |
| | | handleQuery() { |
| | | this.pagination.currentPage = 1 |
| | | this.pagination.pageNum = 1 |
| | | this.loadData() |
| | | }, |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | handleReset() { |
| | | this.queryParams = { |
| | |
| | | technicalTitle: '', |
| | | dateRange: [] |
| | | } |
| | | this.pagination.currentPage = 1 |
| | | this.pagination.pageNum = 1 |
| | | this.loadData() |
| | | }, |
| | | |
| | | // æ¥ç详æ
|
| | | handleView(record) { |
| | | this.currentRecord = { ...record } |
| | | this.detailDialogVisible = true |
| | | async handleView(id) { |
| | | try { |
| | | const response = await recordsInfo(id) |
| | | if (response.code === 200) { |
| | | this.currentRecord = response.data || {} |
| | | this.detailDialogVisible = true |
| | | } else { |
| | | this.$message.error(response.msg || 'è·å详æ
失败') |
| | | } |
| | | } catch (error) { |
| | | console.error('è·å详æ
失败:', error) |
| | | this.$message.error('è·å详æ
失败') |
| | | } |
| | | }, |
| | | |
| | | // æ°å¢è®°å½ |
| | | handleAdd() { |
| | | this.isEditing = false |
| | |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate() |
| | | }) |
| | | }, |
| | | |
| | | // ç¼è¾è®°å½ |
| | | handleEdit(record) { |
| | | this.isEditing = true |
| | | this.currentRecord = record |
| | | this.editForm = { ...record } |
| | | this.editDialogVisible = true |
| | | this.detailDialogVisible = false |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate() |
| | | }) |
| | | async handleEdit(id) { |
| | | try { |
| | | const response = await recordsInfo(id) |
| | | if (response.code === 200) { |
| | | this.isEditing = true |
| | | this.currentRecord = response.data || {} |
| | | this.editForm = { ...response.data } |
| | | this.editDialogVisible = true |
| | | this.detailDialogVisible = false |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate() |
| | | }) |
| | | } else { |
| | | this.$message.error(response.msg || 'è·åè®°å½å¤±è´¥') |
| | | } |
| | | } catch (error) { |
| | | console.error('è·åè®°å½å¤±è´¥:', error) |
| | | this.$message.error('è·åè®°å½å¤±è´¥') |
| | | } |
| | | }, |
| | | |
| | | // å¤å¶è®°å½ |
| | | handleCopy(record) { |
| | | this.isEditing = false |
| | | const copiedRecord = { ...record } |
| | | delete copiedRecord.id |
| | | copiedRecord.name = copiedRecord.name + 'ï¼å¤å¶ï¼' |
| | | this.editForm = copiedRecord |
| | | this.editDialogVisible = true |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate() |
| | | }) |
| | | async handleCopy(id) { |
| | | try { |
| | | const response = await recordsInfo(id) |
| | | if (response.code === 200) { |
| | | this.isEditing = false |
| | | const copiedRecord = { ...response.data } |
| | | delete copiedRecord.id |
| | | copiedRecord.name = copiedRecord.name + 'ï¼å¤å¶ï¼' |
| | | copiedRecord.isCopy = 1 |
| | | copiedRecord.originalId = id |
| | | this.editForm = copiedRecord |
| | | this.editDialogVisible = true |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate() |
| | | }) |
| | | } else { |
| | | this.$message.error(response.msg || 'è·åè®°å½å¤±è´¥') |
| | | } |
| | | } catch (error) { |
| | | console.error('è·åè®°å½å¤±è´¥:', error) |
| | | this.$message.error('è·åè®°å½å¤±è´¥') |
| | | } |
| | | }, |
| | | |
| | | // ä¿åè®°å½ |
| | | async handleSave() { |
| | | try { |
| | |
| | | if (!valid) return |
| | | |
| | | this.saveLoading = true |
| | | // 模æAPIè°ç¨ |
| | | await new Promise(resolve => setTimeout(resolve, 1000)) |
| | | |
| | | this.$message.success(this.isEditing ? 'ä¿åæå' : 'æ°å¢æå') |
| | | this.editDialogVisible = false |
| | | this.loadData() |
| | | // éªè¯ç»ææ¶é´ä¸è½æ©äºå¼å§æ¶é´ |
| | | if (this.editForm.trainingStartDate && this.editForm.trainingEndDate) { |
| | | if (this.editForm.trainingEndDate < this.editForm.trainingStartDate) { |
| | | this.$message.error('ç»ææ¶é´ä¸è½æ©äºå¼å§æ¶é´') |
| | | this.saveLoading = false |
| | | return |
| | | } |
| | | } |
| | | |
| | | let response |
| | | if (this.isEditing) { |
| | | // ç¼è¾ |
| | | response = await recordsedit(this.editForm) |
| | | } else { |
| | | // æ°å¢ |
| | | response = await recordsadd(this.editForm) |
| | | } |
| | | |
| | | if (response.code === 200) { |
| | | this.$message.success(this.isEditing ? 'ä¿åæå' : 'æ°å¢æå') |
| | | this.editDialogVisible = false |
| | | this.loadData() |
| | | } else { |
| | | this.$message.error(response.msg || (this.isEditing ? 'ä¿å失败' : 'æ°å¢å¤±è´¥')) |
| | | } |
| | | } catch (error) { |
| | | console.error('ä¿å失败:', error) |
| | | this.$message.error('æä½å¤±è´¥') |
| | | this.$message.error(this.isEditing ? 'ä¿å失败' : 'æ°å¢å¤±è´¥') |
| | | } finally { |
| | | this.saveLoading = false |
| | | } |
| | | }, |
| | | |
| | | // å é¤è®°å½ |
| | | async handleDelete(row) { |
| | | try { |
| | | await this.$confirm('ç¡®å®è¦å é¤è¿æ¡è®°å½åï¼', 'æç¤º', { |
| | | type: 'warning', |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶' |
| | | }) |
| | | |
| | | const response = await recordsDel(row.id) |
| | | if (response.code === 200) { |
| | | this.$message.success('å 餿å') |
| | | this.loadData() |
| | | } else { |
| | | this.$message.error(response.msg || 'å é¤å¤±è´¥') |
| | | } |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | console.error('å é¤å¤±è´¥:', error) |
| | | this.$message.error('å é¤å¤±è´¥') |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // å
³é详æ
å¯¹è¯æ¡ |
| | | handleDetailClose() { |
| | | this.detailDialogVisible = false |
| | | this.currentRecord = {} |
| | | }, |
| | | |
| | | // å
³éç¼è¾å¯¹è¯æ¡ |
| | | handleEditClose() { |
| | | this.editDialogVisible = false |
| | | this.currentRecord = {} |
| | | this.editForm = this.getDefaultFormData() |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate() |
| | | }) |
| | | }, |
| | | |
| | | // å¯¼åºæ°æ® |
| | | exportData() { |
| | | this.$message.success('导åºåè½å¼åä¸') |
| | | const queryParams = this.queryParams; |
| | | this.$modal |
| | | .confirm("æ¯å¦ç¡®è®¤å¯¼åºææè¿ä¿®ç®¡çæ°æ®é¡¹ï¼") |
| | | .then(() => { |
| | | return exporrecords(queryParams); |
| | | }) |
| | | .then((response) => { |
| | | this.$download.name(response.msg); |
| | | }) |
| | | .catch(() => { }); |
| | | }, |
| | | |
| | | // å页大å°åå |
| | | handleSizeChange(size) { |
| | | this.pagination.pageSize = size |
| | | this.pagination.currentPage = 1 |
| | | this.pagination.pageNum = 1 |
| | | this.loadData() |
| | | }, |
| | | |
| | | // å½å页åå |
| | | handleCurrentChange(page) { |
| | | this.pagination.currentPage = page |
| | | this.pagination.pageNum = page |
| | | this.loadData() |
| | | }, |
| | | |
| | | // æåºåå |
| | | handleSortChange(sort) { |
| | | console.log('æåºåå:', sort) |
| | | // è¿éå¯ä»¥æ·»å æåºé»è¾ |
| | | // è¿éå¯ä»¥æ·»å æåºé»è¾ï¼å¦æéè¦çè¯ |
| | | }, |
| | | |
| | | // è·åé»è®¤è¡¨åæ°æ® |
| | | getDefaultFormData() { |
| | | return { |
| | | id: null, |
| | | name: '', |
| | | gender: 'ç·', |
| | | sex: 'ç·', |
| | | age: 25, |
| | | education: '', |
| | | trainingType: '', |
| | | idCard: '', |
| | | graduateSchool: '', |
| | | graduationSchool: '', |
| | | workUnit: '', |
| | | technicalTitle: '', |
| | | professionalField: '', |
| | | profession: '', |
| | | workYears: 0, |
| | | trainingObjective: '', |
| | | trainingGoal: '', |
| | | trainingStartDate: '', |
| | | trainingEndDate: '', |
| | | trainingMajor: '', |
| | | workSituation: '', |
| | | trainingSubject: '', |
| | | applySubject: '', |
| | | applyPurpose: '', |
| | | mainEducation: '', |
| | | workExperience: '' |
| | | mainExperience: '', |
| | | remark: '', |
| | | isCopy: 0, |
| | | originalId: null |
| | | } |
| | | } |
| | | } |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { relativesList, relativesEdit } from "@/api/businessApi"; |
| | | import { relativesList, relativesEdit, relativesAdd } from "@/api/businessApi"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | |
| | | export default { |
| | |
| | | ? detailData.organdecision |
| | | : detailData.organdecision.split(","); |
| | | } |
| | | console.log(this.organdecision,'this.organdecision'); |
| | | |
| | | console.log(this.organdecision, "this.organdecision"); |
| | | |
| | | // å¤çéä»¶æ°æ® - ä»assessannexåæ®µè§£æJSONå¹¶æç±»ååç±» |
| | | this.processAssessannexData(); |
| | |
| | | organdecisionOther: this.organdecisionOther |
| | | // assessannexåæ®µå·²å¨updateAssessannexField䏿´æ° |
| | | }; |
| | | |
| | | const response = await relativesEdit(saveData); |
| | | let response = null; |
| | | if (saveData.id) { |
| | | response = await relativesEdit(saveData); |
| | | } else { |
| | | response = await relativesAdd(saveData); |
| | | } |
| | | |
| | | if (response.code === 200) { |
| | | this.$message.success("ä¿åæå"); |
| | |
| | | if (Array.isArray(response.data)) { |
| | | // 妿è¿åçæ¯æ°ç» |
| | | this.confirmationList = response.data; |
| | | this.total = response.data.length; |
| | | this.total = response.total; |
| | | } else if (response.data.rows) { |
| | | // 妿è¿åçæ¯åé¡µæ°æ®ç»æ |
| | | this.confirmationList = response.data.rows; |
| | | this.total = response.data.total; |
| | | this.total = response.total; |
| | | } else if (Array.isArray(response.data.list)) { |
| | | // 妿è¿åçæ¯liståæ®µ |
| | | this.confirmationList = response.data.list; |
| | | this.total = response.data.total || response.data.list.length; |
| | | this.total = response.total; |
| | | } else { |
| | | // å
¶ä»æ°æ®ç»æï¼å°è¯ç´æ¥ä½¿ç¨data |
| | | this.confirmationList = response.data; |