提交 1aac5272 authored 作者: pengxiaohui's avatar pengxiaohui

后台接口调试

上级 9ccfdaee
module.exports = { module.exports = {
domain: 'dev.ezijing.com', domain: 'dev.ezijing.com',
url: 'https://live-broadcast2.ezijing.com/api', url: 'https://live-broadcast2.ezijing.com/api',
// url: 'https://test-microservices-live-api.ezijing.com',
// url: 'https://microservices-live-api.ezijing.com',
webpack: { webpack: {
externals: { externals: {
CKEDITOR: 'window.CKEDITOR', CKEDITOR: 'window.CKEDITOR',
...@@ -34,5 +36,6 @@ module.exports = { ...@@ -34,5 +36,6 @@ module.exports = {
ProvidePlugin: {}, ProvidePlugin: {},
others: { others: {
loginUrl: 'https://login2.ezijing.com/auth/login/index' loginUrl: 'https://login2.ezijing.com/auth/login/index'
// loginUrl: 'https://login.ezijing.com/auth/login/index'
} }
} }
...@@ -53,6 +53,21 @@ if ($GLOBAL.isDev === 'development') { ...@@ -53,6 +53,21 @@ if ($GLOBAL.isDev === 'development') {
pathRewrite: { pathRewrite: {
'^/api': '/' '^/api': '/'
} }
},
'/loginApi': {
target: 'https://learn-api2.ezijing.com/api/',
// target: 'https://learn-api.ezijing.com/api/',
selfHandleResponse: false,
secure: false,
changeOrigin: true,
followRedirects: true,
logLevel: 'info',
headers: {
'Referer': $GLOBAL.webConf.url
},
pathRewrite: {
'^/loginApi': '/'
}
} }
}, },
open: true, open: true,
......
import httpRequest from '@/utils/axios'
/**
* 操作日志
*/
export function operateLog(params) {
const logMsg = `操作人:${params.user.nickname},操作人id:${params.user.id},操作:${params.type}`
const data = {
detail: logMsg
}
httpRequest.post('/api/admin/live/v2/system/log/write', data).then(res => {
console.log(res)
}).catch(() => {})
}
/**
* 模糊搜索
*/
export function searchUserList(params) {
return httpRequest.get('/api/common/v1/sso-user/search', { params })
}
/**
* 创建腾讯用户
*/
export function createAccount(data) {
return httpRequest.post('/api/live/admin/v2/tencent/user', data)
}
/**
* 获取腾讯用户列表(分页)
*/
export function getAccountList(params) {
return httpRequest.get('/api/live/admin/v2/tencent/users', { params })
}
/**
* 获取腾讯用户列表(不分页)
*/
export function getAllAccountList() {
return httpRequest.get('/api/live/admin/v2/tencent/user/list')
}
/**
* 更新腾讯用户
*/
export function updateAccount(data) {
return httpRequest.put(`/api/live/admin/v2/tencent/user/${data.userid}/update`, data)
}
/**
* 删除腾讯用户
*/
export function deleteAccount(params) {
return httpRequest.delete(`/api/live/admin/v2/tencent/user/${params.userid}/delete`, params)
}
/**
* 创建会议
*/
export function createMeeting(data) {
return httpRequest.post('/api/live/admin/v2/tencent/meeting', data)
}
/**
* 创建会议
*/
export function updateMeeting(data) {
return httpRequest.put(`/api/live/admin/v2/tencent/meeting/${data.meeting_id}/update`, data)
}
/**
* 获取腾讯会议列表
*/
export function getMeetingList(params) {
return httpRequest.get('/api/live/admin/v2/tencent/meetings', { params })
}
/**
* 获取腾讯会议列表(不分页)
*/
export function getNonpagedMeetingList(params) {
return httpRequest.get('/api/live/admin/v2/tencent/meeting/list-by-day', { params })
}
/**
* 获取腾讯会议详情
*/
export function getMeetingDetails(params) {
return httpRequest.get(`/api/live/admin/v2/tencent/meeting/${params.meeting_id}/detail`, { params })
}
/**
* 通过会议code获取腾讯会议详情
*/
export function getMeetingDetailsByCode(params) {
return httpRequest.get(`/api/live/admin/v2/tencent/meeting/${params.meeting_code}/detail-code`, { params })
}
/**
* 取消(删除)会议
*/
export function cancelMeeting(params) {
return httpRequest.post(`/api/live/admin/v2/tencent/meeting/${params.meeting_id}/cancel`, params)
}
/**
* 终止会议
*/
export function stopMeeting(params) {
return httpRequest.post(`/api/live/admin/v2/tencent/meeting/${params.meeting_id}/dimiss`, params)
}
/**
* 获取回放地址
*/
export function getMeetingRecordAddr(params) {
return httpRequest.post(`/api/live/admin/v2/tencent/meeting/${params.meeting_id}/records/address`, params)
}
/**
* 导出参会人员
*/
export function exportParticipants(params) {
return httpRequest({
url: `/api/admin/live/v2/tencent/meeting/${params.meeting_id}/participants/export`,
method: 'get',
params,
responseType: 'blob'
})
}
import httpRequest from '@/utils/axios'
/**
* 操作日志
*/
export function operateLog(params) {
const logMsg = `操作人:${params.user.nickname},操作人id:${params.user.id},操作:${params.type}`
const data = {
detail: logMsg
}
httpRequest.post('/api/live/admin/v2/system/log/write', data).then(res => {
console.log(res)
}).catch(() => {})
}
/**
* 模糊搜索
*/
export function searchUserList(params) {
return httpRequest.get('/api/live/common/v1/sso-user/search', { params })
}
/**
* 获取当前用户的角色
*/
export function getUserRoles() {
return httpRequest.get('/api/live/admin/v2/user/roles')
}
/**
* 创建角色
*/
export function createRole(data) {
return httpRequest.post('/api/live/admin/v2/role', data)
}
/**
* 更新角色
*/
export function updateRole(params) {
return httpRequest.get(`/api/live/admin/v2/role/${params.role_id}/update`, { params })
}
/**
* 获取角色详情
*/
export function getRoleDetails(params) {
return httpRequest.get(`/api/live/admin/v2/role/${params.role_id}/detail`, { params })
}
/**
* 删除
*/
export function deleteRole(params) {
return httpRequest.get(`/api/live/admin/v2/role/${params.role_id}/delete`, { params })
}
/**
* 获取角色列表
*/
export function getRoles(params) {
return httpRequest.get('/api/live/admin/v2/roles', { params })
}
/**
* 分配角色给用户
*/
export function roleToUser(data) {
return httpRequest.post('/api/live/admin/v2/assign/roles-to-user', data)
}
/**
* 获取角色下的用户列表
*/
export function getUserListUnderRole(params) {
return httpRequest.get(`/api/live/admin/v2/role/${params.role_id}/users`, { params })
}
/**
* 从角色中移除用户
*/
export function romoveUserUnderRole(data) {
return httpRequest.post('/api/live/admin/v2/assign/remove-user-form-role', data)
}
/**
* 获取权限列表
*/
export function getPermissions(params) {
return httpRequest.get('/api/live/admin/v2/permissions', { params })
}
/**
* 分配权限给角色
*/
export function permissionToRole(data) {
return httpRequest.post('/api/live/admin/v2/assign/permission-to-role', data)
}
...@@ -25,9 +25,6 @@ import getDays from './getDays' ...@@ -25,9 +25,6 @@ import getDays from './getDays'
export default { export default {
props: { props: {
defaultDate: { defaultDate: {
validator: (value) => {
return typeof value === 'object' && (value === null || value instanceof Date)
}
}, },
type: { type: {
type: String, type: String,
...@@ -38,8 +35,8 @@ export default { ...@@ -38,8 +35,8 @@ export default {
return { return {
weekList: ['周', '一', '二', '三', '四', '五', '六'], weekList: ['周', '一', '二', '三', '四', '五', '六'],
dayList: [], dayList: [],
activeDate: [],
monthFirstDate: '', monthFirstDate: '',
activeDate: [],
rangeState: { rangeState: {
endDate: null, endDate: null,
selecting: false selecting: false
...@@ -68,6 +65,23 @@ export default { ...@@ -68,6 +65,23 @@ export default {
} }
}, },
watch: { watch: {
type: {
handler: function(nv) {
if (nv) {
this.activeDate = ''
this.rangeState = {
endDate: null,
selecting: false
}
this.rangeStartDate = null
this.rangeEndDate = null
this.rangeDates = []
this.selectFirstDate = null
this.selectLastDate = null
}
},
immediate: true
},
defaultDate: { defaultDate: {
handler: function(nv, ov) { handler: function(nv, ov) {
if (!nv) { if (!nv) {
...@@ -76,8 +90,9 @@ export default { ...@@ -76,8 +90,9 @@ export default {
this.setMonthFirstDate(_date) this.setMonthFirstDate(_date)
} else { } else {
if (Array.isArray(nv)) { if (Array.isArray(nv)) {
const d = nv[0] this.rangeStartDate = nv[0]
this.setMonthFirstDate(d) this.rangeEndDate = nv[1]
this.setMonthFirstDate(nv[0])
} else if (typeof nv === 'object' && this.type === 'date') { } else if (typeof nv === 'object' && this.type === 'date') {
this.setMonthFirstDate(nv) this.setMonthFirstDate(nv)
this.activeDate = nv this.activeDate = nv
......
<template>
<el-dialog :title="`会议号${details.meeting_code ? ':' + details.meeting_code : ''}`" :visible="dialogVisible" width="520" :close-on-click-modal="false" append-to-body center @close="dialogClose">
<el-form class="dialog-meeting-details" label-width="90px" ref="details">
<el-form-item label="会议主题:">
{{details.subject}}
</el-form-item>
<el-form-item label="会议时间:">
{{details.start_time | timeFormat('{y}-{m}-{d} {h}:{i}')}} - {{details.end_time | timeFormat('{h}:{i}')}}GMT+08:00)
</el-form-item>
<el-form-item label="会议链接:">
{{details.join_url}}
</el-form-item>
<el-form-item label="会议号:">
{{details.meeting_code}}
</el-form-item>
<el-form-item label="会议直播:" v-if="details.enable_live === 1">
{{details.live_config.live_addr}}
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="copyText">复制文字</el-button>
<el-button size="mini" @click="copyMeetingLink">复制参会地址</el-button>
<el-button size="mini" v-if="details.enable_live === 1" @click="copyLiveLink">复制直播地址</el-button>
<el-button type="primary" size="mini" @click="joinMeeting">进入会议</el-button>
</span>
</el-dialog>
</template>
<script>
import { dateFormat } from '@/utils/dateAlgs'
export default {
props: {
details: {
type: Object,
default: {}
},
dialogVisible: {
type: Boolean,
default: false
}
},
filters: {
timeFormat(val, fmt) {
fmt = fmt || '{y}年{m}月{d}日'
return dateFormat(val, fmt)
}
},
methods: {
dialogClose() {
this.$emit('update:dialogVisible', false)
},
copyText() {
const text = this.$refs.details.$el.innerText
this.copyFn(text)
},
copyMeetingLink() {
this.copyFn(this.details.join_url)
},
copyLiveLink() {
this.copyFn(this.details.live_config.live_addr)
},
copyFn(val) {
if (!val) return
const dom = document.createElement('textarea')
document.body.appendChild(dom)
dom.value = val
dom.select(); // 选择对象
document.execCommand('Copy');
this.$message({
message: '复制成功!',
type: 'success'
})
document.body.removeChild(dom)
},
joinMeeting() {
window.open(this.details.join_url, '_blank');
}
}
}
</script>
<style scoped>
::v-deep.el-dialog__header{
padding-top:14px;
}
::v-deep.el-dialog__headerbtn{
top:12px;
right:12px;
}
::v-deep.el-dialog__body{
padding:10px 0;
margin:0 20px;
border: 1px solid #DBDBDB;
}
::v-deep.el-dialog__footer{
padding-bottom:16px;
}
::v-deep.el-dialog .el-form-item{
margin:0;
}
</style>
\ No newline at end of file
<template> <template>
<div class="schedule-item" :style="{'min-width': minWidth}"> <div class="schedule-item" :style="{'min-width': minWidth}">
<template v-for="ev in schedule.events" > <template v-for="ev in schedule.events" >
<div :key="ev.startTime.getTime()" class="schedule-event" :style="{ height: getHeight(ev) + 'px', top: getTop(ev) + 'px' }"> <div :key="ev.start_time" class="schedule-event" :style="{ height: getHeight(ev) + 'px', top: getTop(ev) + 'px' }">
<slot name="content" :data="ev"> <slot name="content" :data="ev">
<div class="schedule-ev-inner"> <div class="schedule-ev-inner">
<h5>{{ev.title}}</h5> <h5>{{ev.title}}</h5>
<p>{{ev.startTime | timeFormat}}-{{ev.endTime | timeFormat}}</p> <p>{{ev.start_time | timeFormat}}-{{ev.end_time | timeFormat}}</p>
</div> </div>
</slot> </slot>
<div class="shadow" @click.stop="detailsClick(ev, $event)"></div> <div class="shadow" @click.stop="detailsClick(ev, $event)"></div>
...@@ -81,14 +81,14 @@ export default { ...@@ -81,14 +81,14 @@ export default {
}, },
methods: { methods: {
getTop(ev) { getTop(ev) {
const timeRange = timeTrans(ev.startTime).getTime() - this.startDotTimestamp const timeRange = timeTrans(ev.start_time).getTime() - this.startDotTimestamp
const top = timeRange / ((60 * 1000 * this.options.step) / this.timeLineHeight) const top = timeRange / ((60 * 1000 * this.options.step) / this.timeLineHeight)
ev.top = top + 1 ev.top = top + 1
return top + 1 return top + 1
}, },
getHeight(ev) { getHeight(ev) {
const start = timeTrans(ev.startTime) const start = timeTrans(ev.start_time)
let end = timeTrans(ev.endTime) let end = timeTrans(ev.end_time)
if (!isSameDate(start, end)) { if (!isSameDate(start, end)) {
end = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 24, 0, 0) end = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 24, 0, 0)
} }
...@@ -102,25 +102,28 @@ export default { ...@@ -102,25 +102,28 @@ export default {
return { return {
'schedule-event': true, 'schedule-event': true,
'status-start': ev.status === 1, 'status-start': ev.status === 1,
'status-notstarted': ev.status === 3, 'status-notstarted': ev.status === 0,
small: h < 120 && h >= 40, small: h < 120 && h >= 40,
medium: h >= 120 && h < 200, medium: h >= 120 && h < 200,
large: h >= 200 large: h >= 200
} }
}, },
detailsClick(ev, e) { detailsClick(ev, e) {
const o = { if (!this.options.readonly) {
ev, const o = {
id: this.schedule.id, ev,
x: e.clientX - e.offsetX + 'px', id: this.schedule.id,
y: e.clientY - e.offsetY + 'px', x: e.clientX - e.offsetX + 'px',
width: e.target.clientWidth + 'px', y: e.clientY - e.offsetY + 'px',
height: e.target.clientHeight + 'px' width: e.target.clientWidth + 'px',
height: e.target.clientHeight + 'px'
}
this.$emit('details', o)
} }
this.$emit('details', o)
}, },
newSchedule(dot, e) { newSchedule(dot, e) {
if (!this.options.disabledNew) { if (!this.options.readonly) {
dot.accountId = this.schedule.userid || ''
dot.x = e.clientX - e.offsetX + 'px' dot.x = e.clientX - e.offsetX + 'px'
dot.y = e.clientY - e.offsetY + 'px' dot.y = e.clientY - e.offsetY + 'px'
dot.width = e.target.clientWidth + 'px' dot.width = e.target.clientWidth + 'px'
......
<template> <template>
<div class="schedule"> <div class="schedule">
<div class="multi-schedule-header" ref="scheduleHeader"> <div class="multi-schedule-header" ref="scheduleHeader">
<div v-for="(schedule, idx) in scheduleList" :key="idx" :style="{'min-width': minWidth}">{{schedule.title}}</div> <div v-for="(schedule, idx) in scheduleList" :key="idx" :style="{'min-width': minWidth}">{{schedule.name}}</div>
</div> </div>
<el-scrollbar ref="scheduleScroll" style="height: calc(100% - 50px)"> <el-scrollbar ref="scheduleScroll" style="height: calc(100% - 50px)">
<div class="schedule-container"> <div class="schedule-container">
......
<template>
<el-form label-width="140px">
<el-form-item label="会议主题:">
{{details.subject}}
</el-form-item>
<el-form-item label="会议时间:">
{{details.start_time | dateFormat}} - {{details.end_time | dateFormat('{h}:{i}')}}GMT+08:00)
</el-form-item>
<el-form-item label="会议链接:">
{{details.join_url}}
</el-form-item>
<el-form-item label="会议号:">
{{details.meeting_code}}
</el-form-item>
<el-form-item label="会议直播:" v-if="details.enable_live === 1">
{{details.live_config.live_addr}}
</el-form-item>
<el-form-item label="手机拨号入会:" v-if="false">
<p>+8675536550000,,526430840#(中国大陆)</p>
<p>+85230018898,,526430840#(中国香港)</p>
</el-form-item>
<el-form-item label="根据您的位置拨号:" v-if="false">
<p>+8675536550000(中国大陆)</p>
<p>++85230018898(中国香港)</p>
</el-form-item>
</el-form>
</template>
<script>
import { dateFormat } from '@/utils/dateAlgs'
export default {
props: {
rowData: {},
details: {}
},
computed: {
hasLive() {
return this.rowData.hasLive || false
}
},
filters: {
dateFormat(value, fmt) {
return dateFormat(value, fmt || '{y}年{m}月{d}日 {h}:{i}')
}
}
}
</script>
<style scoped>
::v-deep.el-form-item{
margin:0;
}
</style>
\ No newline at end of file
<template>
<el-form label-width="140px">
<el-form-item label="会议主题:">
{{details.subject}}
</el-form-item>
<el-form-item label="会议时间:">
{{details.start_time | dateFormat}} - {{details.end_time | dateFormat('{h}:{i}')}}GMT+08:00)
</el-form-item>
<el-form-item label="会议号:">
{{details.meeting_code}}
</el-form-item>
<el-form-item label="会议创建者:">
{{rowData.sso_user.nickname}}
</el-form-item>
<el-form-item label="会议主持人:">
<span v-for="(it, index) in details.hosts" :key="it.userid">{{it.username}}{{index > 0 ? '、' : ''}}</span>
</el-form-item>
<el-form-item label="会议管理员:">
<span v-for="(it, index) in details.managers" :key="it.userid">{{it.nickname}}{{index > 0 ? '、' : ''}}</span>
</el-form-item>
<el-form-item label="会议直播主题:" v-if="details.enable_live === 1">
{{details.live_config.live_subject}}
</el-form-item>
<el-form-item label="会议直播简介:" v-if="details.enable_live === 1">
<p style="line-height:26px;padding:7px 10px 7px 0">{{details.live_config.live_summary}}</p>
</el-form-item>
<el-form-item label="参会成员:" v-if="rowData.status === 2">
<el-button type="text" @click="handleExport">导出excel</el-button>
</el-form-item>
<el-form-item label="回放:" v-if="rowData.status === 2">
<el-button type="text" v-if="hasRecord" @click="handleDownload">下载</el-button>
<el-button type="text" v-else disabled>暂无回放</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { dateFormat } from '@/utils/dateAlgs'
import { exportParticipants, getMeetingRecordAddr } from '@api/common'
export default {
props: {
details: {},
rowData: {},
dialogType: {}
},
computed: {
hasRecord() {
if (this.rowData.record_file_ids && Array.isArray(this.rowData.record_file_ids) && this.rowData.record_file_ids.length > 0) {
return true
} else {
return false
}
},
nowFormat() {
const now = Date.now()
const _format = dateFormat(now, '{y}{m}{d}{h}{i}{s}')
const nowStr = now.toString()
return _format + nowStr.substr(10, 12)
}
},
filters: {
dateFormat(value, fmt) {
return dateFormat(value, fmt || '{y}年{m}月{d}日 {h}:{i}')
}
},
methods: {
handleExport() {
const row = this.rowData
const params = {
meeting_id: row.meeting_id
}
if (row.meeting_type === 1) {
params.sub_meeting_id = row.sub_meeting_id
}
exportParticipants(params).then((res) => {
if (res && res.type === 'text/xlsx') {
const url = URL.createObjectURL(res)
// const elink = document.createElement('a')// 创建一个a标签
// elink.download = `参会人员表_${this.nowFormat}.xlsx`;// 设置a标签的下载属性
// elink.style.display = 'none';// 将a标签设置为隐藏
// elink.href = URL.createObjectURL(blob);// 把之前处理好的地址赋给a标签的href
// document.body.appendChild(elink);// 将a标签添加到body中
// elink.click();// 执行a标签的点击方法
// URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
// document.body.removeChild(elink)// 移除a标签
this.funDownload(url, `参会人员表_${this.nowFormat}.xlsx`)
}
})
},
async handleDownload() {
const list = await this.fetchMeetingRecordAddr()
if (list && Array.isArray(list)) {
list.forEach(it => {
if (it.download_address) {
// window.open(it.download_address, '_blank')
this.funDownload(it.download_address, it.download_address)
}
})
}
},
funDownload(fileUrl, fileName) {
const elink = document.createElement('a')// 创建一个a标签
elink.download = fileName;// 设置a标签的下载属性
elink.style.display = 'none';// 将a标签设置为隐藏
elink.href = fileUrl;// 把之前处理好的地址赋给a标签的href
document.body.appendChild(elink);// 将a标签添加到body中
elink.click();// 执行a标签的点击方法
URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
document.body.removeChild(elink)// 移除a标签
},
fetchMeetingRecordAddr() {
const params = {
meeting_id: this.rowData.meeting_id,
record_file_ids: this.rowData.record_file_ids
}
return new Promise((resolve, reject) => {
getMeetingRecordAddr(params).then(res => {
if (res.code === 0 && res.data.files) {
resolve(res.data.files)
} else {
reject(res)
}
}).catch((err) => reject(err))
})
}
}
}
</script>
<style scoped>
::v-deep.el-form-item{
margin:0;
}
</style>
\ No newline at end of file
<template>
<div class="btns">
<template v-if="status === 1">
<el-button type="text" size="small" v-if="operatable" @click="handleJoin">进入会议</el-button>
<el-button type="text" size="small" v-if="operatable && hasLive" @click="handleLive">观看直播</el-button>
<el-button type="text" size="small" v-if="operatable" @click="handleCopy">复制邀请</el-button>
<el-button type="text" size="small" v-if="operatable" @click="handleStop">终止</el-button>
<el-button type="text" size="small" v-if="!operatable" @click="handleDetails">查看</el-button>
</template>
<template v-if="status === 0">
<el-button type="text" size="small" v-if="operatable" @click="handleJoin">进入会议</el-button>
<el-button type="text" size="small" v-if="operatable" @click="handleCopy">复制邀请</el-button>
<el-button type="text" size="small" v-if="operatable" @click="handleUpdate">修改</el-button>
<!-- <el-dropdown v-if="operatable && isCycle">
<span class="dropdown-link">
修改<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click="handleUpdate">修改本次会议</el-dropdown-item>
<el-dropdown-item @click="handleUpdate">修改周期会议</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown> -->
<el-button type="text" size="small" v-if="operatable" @click="handleCancel">取消</el-button>
<el-button type="text" size="small" v-if="!operatable" @click="handleDetails">查看</el-button>
</template>
<template v-if="status === 2">
<el-button type="text" size="small" v-if="operatable" @click="handleRecord">看回放</el-button>
<el-button type="text" size="small" @click="handleDetails">查看</el-button>
<el-button type="text" size="small" v-if="operatable" @click="handleDelete">删除</el-button>
</template>
<el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="520px" center>
<div slot="title" class="dialog-header">
<p class="meeting-status" v-show="dialogType === 'details'">会议{{rowData.status | statusFilter}}</p>
<p class="title">{{domicTitle}}</p>
</div>
<dialog-details :rowData="rowData" :details="details" v-show="dialogType === 'details'" />
<dialog-copy-invite :rowData="rowData" :details="details" v-show="dialogType === 'copy'"/>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" v-show="dialogType === 'copy'" @click="copyLink">复制</el-button>
<el-button @click="dialogVisible = false" size="mini">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import DialogDetails from './DialogDetails.vue'
import DialogCopyInvite from './DialogCopyInvite'
import { mapGetters } from 'vuex'
import { getMeetingDetails, stopMeeting, cancelMeeting, getMeetingRecordAddr } from '@api/common'
export default {
props: {
rowData: {}
},
data() {
return {
userId: '1234',
roleName: '', // general_admin
dialogVisible: false,
dialogType: 'copy',
details: ''
}
},
computed: {
...mapGetters(['isSuperAdmin', 'user']),
domicTitle() {
let title = ''
switch (this.dialogType) {
case 'copy':
title = '复制邀请'
break
case 'details':
title = '会议详情'
break
}
return title
},
status() {
return this.rowData.status
},
isCycle() {
return this.rowData.meeting_type === 1
},
isMyself() {
return this.rowData.sso_id === this.user.id
},
isGeneralAdmin() {
const admins = this.rowData.manage_ids
let flag = false
for (let i = 0; i < admins.length; i++) {
if (admins[i] === this.user.id) {
flag = true
break
}
}
return flag
},
hasLive() {
return this.rowData.enable_live || false
},
operatable() {
return this.isMyself || this.isSuperAdmin || this.isGeneralAdmin
}
},
filters: {
statusFilter(val) {
let result = ''
switch (val) {
case 0:
result = '未开始'
break
case 1:
result = '进行中'
break
case 2:
result = '已结束'
break
}
return result
}
},
components: { DialogDetails, DialogCopyInvite },
created() {
},
methods: {
handleCopy() {
this.fetchMeetingDetails()
this.dialogVisible = true
this.dialogType = 'copy'
},
handleDetails() {
this.dialogVisible = true
this.dialogType = 'details'
this.fetchMeetingDetails()
},
handleLive() {
window.open(this.live_config.live_addr, '_blank');
},
handleUpdate() {
this.$router.push({ path: '/meeting', query: { type: '2', meeting_id: this.rowData.meeting_id, sub_meeting_id: this.rowData.sub_meeting_id } })
},
handleCancel() {
this.$confirm('此操作将取消这场会议, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.fetchCancelMeeting('cancel')
}).catch(() => {})
},
handleStop() {
this.$confirm('此操作将终止正在进行中的会议, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.fetchStopMeeting()
}).catch(() => {})
},
handleDelete() {
this.$confirm('此操作将删除这场会议, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.fetchCancelMeeting('delete')
}).catch(() => {})
},
handleJoin() {
window.open(this.rowData.join_url, '_blank');
},
copyLink() {
const dom = document.createElement('input')
document.body.appendChild(dom)
dom.value = this.rowData.join_url
dom.select(); // 选择对象
document.execCommand('Copy');
this.$message({
message: '复制成功!',
type: 'success'
})
document.body.removeChild(dom)
},
async handleRecord() {
if (this.rowData.record_file_ids.length === 0) {
this.$message.error('该会议没有回放')
} else {
const list = await this.fetchMeetingRecordAddr()
if (list && Array.isArray(list)) {
if (list.length === 1) {
window.open(list[0].view_address, '_blank')
}
}
}
},
fetchStopMeeting() {
const params = {
meeting_id: this.rowData.meeting_id
}
stopMeeting(params).then(res => {
if (res.code === 0 && res.data.status) {
this.$message.success('会议终止成功')
this.$emit('refresh')
} else {
this.$message.error(res.msg || '会议终止失败')
}
})
},
fetchCancelMeeting(type) {
const params = {
meeting_id: this.rowData.meeting_id
}
const msg = type === 'cancel' ? '会议取消' : '会议删除'
cancelMeeting(params).then(res => {
if (res.code === 0 && res.data.status) {
this.$message.success(msg + '成功')
this.$emit('refresh')
} else {
this.$message.error(res.msg || msg + '失败')
}
})
},
fetchMeetingDetails() {
const row = this.rowData
const params = {
meeting_id: row.meeting_id
}
if (row.meeting_type === 1) {
params.sub_meeting_id = row.sub_meeting_id
}
getMeetingDetails(params).then(res => {
if (res.code === 0 && res.data.id) {
this.details = res.data
}
})
},
fetchMeetingRecordAddr() {
const params = {
meeting_id: this.rowData.meeting_id,
record_file_ids: this.rowData.record_file_ids
}
return new Promise((resolve, reject) => {
getMeetingRecordAddr(params).then(res => {
if (res.code === 0 && res.data.files) {
resolve(res.data.files)
} else {
reject(res)
}
}).catch((err) => reject(err))
})
}
}
}
</script>
<style scoped>
.dropdown-link{
cursor: pointer;
color: #409EFF;
font-size:12px;
}
::v-deep.el-icon-arrow-down {
font-size: 12px;
}
.btns ::v-deep.el-dialog__header{
padding-top:14px;
}
.btns ::v-deep.el-dialog__headerbtn{
top:12px;
right:12px;
}
.btns ::v-deep.el-dialog__body{
padding:10px 0;
margin:0 20px;
border: 1px solid #DBDBDB;
}
.btns ::v-deep.el-dialog__footer{
padding-bottom:16px;
}
.dialog-header .meeting-status{
text-align:left;
}
.dialog-header .title{
font-size:16px;
}
</style>
\ No newline at end of file
...@@ -13,8 +13,11 @@ ...@@ -13,8 +13,11 @@
<i class="el-icon-caret-bottom" /> <i class="el-icon-caret-bottom" />
</div> </div>
<el-dropdown-menu slot="dropdown" class="user-dropdown"> <el-dropdown-menu slot="dropdown" class="user-dropdown">
<el-dropdown-item>
<span>{{user.nickname || ''}}, 你好</span>
</el-dropdown-item>
<el-dropdown-item divided @click.native="logout"> <el-dropdown-item divided @click.native="logout">
<span style="display: block">Log Out</span> <span style="display: block">退出登录</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
...@@ -34,10 +37,7 @@ export default { ...@@ -34,10 +37,7 @@ export default {
} }
}, },
computed: { computed: {
...mapGetters(['sidebar']), ...mapGetters(['sidebar', 'user']),
user() {
return this.$store.state.user
},
avatar() { avatar() {
return this.user.avatar || defaultAvatar return this.user.avatar || defaultAvatar
} }
...@@ -51,8 +51,8 @@ export default { ...@@ -51,8 +51,8 @@ export default {
this.$router.push('/meeting') this.$router.push('/meeting')
}, },
async logout() { async logout() {
await this.$store.dispatch('user/logout') await this.$store.dispatch('logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`) this.$router.push(`/${this.$route.fullPath}`)
} }
} }
} }
......
...@@ -19,7 +19,7 @@ export default { ...@@ -19,7 +19,7 @@ export default {
<style scoped> <style scoped>
.app-main { .app-main {
height: calc(100vh - 62px); height: calc(100vh - 52px);
width: 100%; width: 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
......
...@@ -3,16 +3,16 @@ ...@@ -3,16 +3,16 @@
<h5>会议详情</h5> <h5>会议详情</h5>
<p> <p>
<i class="el-icon-tickets"></i> <i class="el-icon-tickets"></i>
<span>{{ev.title}}</span> <span>{{ev.subject}}</span>
</p> </p>
<p> <p>
<i class="el-icon-time"></i> <i class="el-icon-time"></i>
<span v-if="ev.startTime.getDate() === ev.endTime.getDate()">{{ev.startTime | timeFormat('{m}月{d}日')}} {{ev.startTime | timeFormat('周{a}')}} {{ev.startTime | timeFormat}}-{{ev.endTime | timeFormat}}</span> <span v-if="isSameDate">{{ev.start_time | timeFormat('{m}月{d}日')}} {{ev.end_time | timeFormat('周{a}')}} {{ev.start_time | timeFormat}}-{{ev.end_time | timeFormat}}</span>
<span v-else>{{ev.title}}</span> <span v-else>{{ev.start_time | timeFormat('{m}月{d}日 {h}:{i}')}} - {{ev.start_time | timeFormat('{m}月{d}日 {h}:{i}')}}</span>
</p> </p>
<p> <p>
<i class="el-icon-s-custom"></i> <i class="el-icon-s-custom"></i>
<span>{{ev.creator}}</span> <span>{{ev.sso_user.nickname}}</span>
</p> </p>
</div> </div>
</template> </template>
...@@ -35,6 +35,9 @@ export default { ...@@ -35,6 +35,9 @@ export default {
computed: { computed: {
ev() { ev() {
return this.data.ev return this.data.ev
},
isSameDate() {
return dateFormat(this.ev.start_time, '{m}-{d}') === dateFormat(this.ev.end_time, '{m}-{d}')
} }
}, },
created() { created() {
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="new"> <div class="new">
<h5>新建会议</h5> <h5>新建会议</h5>
<el-form ref="ruleForm" :model="form" :rules="rules" label-width="84px"> <el-form ref="ruleForm" :model="form" :rules="rules" label-width="84px">
<el-form-item label="会议主题" prop="theme"> <el-form-item label="会议主题" prop="subject">
<el-input v-model="form.theme" size="small" /> <el-input v-model="form.subject" size="small" />
</el-form-item> </el-form-item>
<el-form-item label="开始时间" required> <el-form-item label="开始时间" required>
<el-col :span="11"> <el-col :span="11">
...@@ -32,12 +32,12 @@ ...@@ -32,12 +32,12 @@
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item label="会议直播" style="margin-bottom:12px;"> <el-form-item label="会议直播" style="margin-bottom:12px;">
<el-checkbox v-model="form.isLive" @change="updatePopper">开启会议直播(用于分享给观看直播的用户)</el-checkbox> <el-checkbox v-model="form.enable_live" @change="updatePopper">开启会议直播(用于分享给观看直播的用户)</el-checkbox>
</el-form-item> </el-form-item>
<el-form-item v-if="form.isLive" label="直播主题" :required="form.isLive" prop="liveTheme"> <el-form-item v-if="form.enable_live" label="直播主题" :required="form.enable_live" prop="liveTheme">
<el-input v-model="form.liveTheme" size="small" /> <el-input v-model="form.liveTheme" size="small" />
</el-form-item> </el-form-item>
<el-form-item v-if="form.isLive" label="直播简介" :required="form.isLive" prop="liveDesc"> <el-form-item v-if="form.enable_live" label="直播简介" :required="form.enable_live" prop="liveDesc">
<el-input type="textarea" v-model="form.liveDesc"></el-input> <el-input type="textarea" v-model="form.liveDesc"></el-input>
</el-form-item> </el-form-item>
<el-form-item style="text-align:center;"> <el-form-item style="text-align:center;">
...@@ -45,10 +45,14 @@ ...@@ -45,10 +45,14 @@
<el-button type="primary" @click="submitForm('ruleForm')" size="mini">立即创建</el-button> <el-button type="primary" @click="submitForm('ruleForm')" size="mini">立即创建</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<meeting-success-dialog :dialogVisible.sync="dialogVisible" :details="details"/>
</div> </div>
</template> </template>
<script> <script>
import MeetingSuccessDialog from '@/components/MeetingSuccessDialog/index'
import { timeTrans, dateFormat, getTimestampYMD, getCurHalfHour } from '@/utils/dateAlgs' import { timeTrans, dateFormat, getTimestampYMD, getCurHalfHour } from '@/utils/dateAlgs'
import { createMeeting, operateLog, getMeetingDetails } from '@api/common'
import { mapGetters } from 'vuex'
const DAY_TIMESTAMP = 8.64e7 const DAY_TIMESTAMP = 8.64e7
export default { export default {
props: { props: {
...@@ -67,6 +71,8 @@ export default { ...@@ -67,6 +71,8 @@ export default {
const timestamp = Date.parse(value); const timestamp = Date.parse(value);
if (timestamp < Date.now() - DAY_TIMESTAMP) { if (timestamp < Date.now() - DAY_TIMESTAMP) {
callback(new Error('开始时间必须大于当前时间')); callback(new Error('开始时间必须大于当前时间'));
} else {
callback();
} }
} }
} }
...@@ -76,6 +82,8 @@ export default { ...@@ -76,6 +82,8 @@ export default {
callback(new Error('结束时间必须大于开始时间')); callback(new Error('结束时间必须大于开始时间'));
} else if (this.endTimestamp > this.startTimestamp + DAY_TIMESTAMP) { } else if (this.endTimestamp > this.startTimestamp + DAY_TIMESTAMP) {
callback(new Error('会议时间不能超过24小时')); callback(new Error('会议时间不能超过24小时'));
} else {
callback();
} }
} }
} }
...@@ -91,31 +99,17 @@ export default { ...@@ -91,31 +99,17 @@ export default {
return { return {
timerClear: true, timerClear: true,
form: { form: {
theme: '', subject: '',
startDate: this.date, startDate: this.date,
startTime: getCurHalfHour('start'), startTime: getCurHalfHour('start'),
endDate: this.date, endDate: this.date,
endTime: getCurHalfHour('end'), endTime: getCurHalfHour('end'),
timezone: 'beijing', enable_live: false,
periodic: false, live_subject: '',
repeatRate: 'everyday', live_summary: ''
endType: 'endOneday',
periodicEndDate: '',
periodicTimes: 7,
isSecret: false,
secret: '',
openWaitingRoom: false,
joinAdvance: false,
mute: false,
recordVideo: false,
isLive: false,
liveTheme: '',
liveDesc: '',
isLiveSecret: false,
permitComment: false
}, },
rules: { rules: {
theme: [{ required: true, message: '请填写会议主题', trigger: 'blur' }], subject: [{ required: true, message: '请填写会议主题', trigger: 'blur' }],
startDate: [ startDate: [
{ type: 'date', required: true, message: '请选择开始日期', trigger: 'change' }, { type: 'date', required: true, message: '请选择开始日期', trigger: 'change' },
{ type: 'date', validator: startDateChecked, trigger: 'change' } { type: 'date', validator: startDateChecked, trigger: 'change' }
...@@ -126,8 +120,8 @@ export default { ...@@ -126,8 +120,8 @@ export default {
{ required: true, message: '请选择结束时间', trigger: 'change' }, { required: true, message: '请选择结束时间', trigger: 'change' },
{ validator: endDateChecked, trigger: 'change' } { validator: endDateChecked, trigger: 'change' }
], ],
liveTheme: [{ validator: validateErrMsg }], live_subject: [{ validator: validateErrMsg }],
liveDesc: [{ validator: validateErrMsg }] live_summary: [{ validator: validateErrMsg }]
}, },
startDateOptions: { startDateOptions: {
disabledDate(time) { disabledDate(time) {
...@@ -143,10 +137,13 @@ export default { ...@@ -143,10 +137,13 @@ export default {
start: getCurHalfHour('end'), start: getCurHalfHour('end'),
step: '00:30', step: '00:30',
end: '23:30' end: '23:30'
} },
details: {},
dialogVisible: false
} }
}, },
computed: { computed: {
...mapGetters(['user']),
startTimestamp() { startTimestamp() {
return this.getFullDateTime(this.form.startDate, this.form.startTime).getTime() return this.getFullDateTime(this.form.startDate, this.form.startTime).getTime()
}, },
...@@ -166,6 +163,8 @@ export default { ...@@ -166,6 +163,8 @@ export default {
data: { data: {
handler: function(nv) { handler: function(nv) {
if (nv) { if (nv) {
// console.log(nv)
this.form.subject = ''
this.form.startDate = nv.date this.form.startDate = nv.date
this.startDateChange(nv.date) this.startDateChange(nv.date)
this.form.startTime = nv.time this.form.startTime = nv.time
...@@ -176,6 +175,7 @@ export default { ...@@ -176,6 +175,7 @@ export default {
deep: true deep: true
} }
}, },
components: { MeetingSuccessDialog },
methods: { methods: {
updatePopper() { updatePopper() {
this.$emit('refreshPopover', Date.now()) this.$emit('refreshPopover', Date.now())
...@@ -219,7 +219,6 @@ export default { ...@@ -219,7 +219,6 @@ export default {
} }
}, },
endDateChange() { endDateChange() {
console.log(12344)
this.startTimeChange(this.form.startTime) this.startTimeChange(this.form.startTime)
}, },
getFullDateTime(date, timeStr) { getFullDateTime(date, timeStr) {
...@@ -252,12 +251,66 @@ export default { ...@@ -252,12 +251,66 @@ export default {
submitForm(formName) { submitForm(formName) {
this.$refs[formName].validate((valid) => { this.$refs[formName].validate((valid) => {
if (valid) { if (valid) {
console.log(valid); this.fetchCreateMeeting()
} }
}); });
}, },
more() { more() {
this.$router.push({ path: '/meeting', query: { type: '1' } }) this.$router.push({ path: '/meeting', query: { type: '1', account: this.data.accountId, start: this.startTimestamp, end: this.endTimestamp } })
},
fetchCreateMeeting() {
const form = this.form
const params = {
instanceid: 1,
userid: this.data.accountId,
subject: form.subject,
start_time: dateFormat(this.startTimestamp),
end_time: dateFormat(this.endTimestamp),
meeting_type: 0,
enable_live: form.enable_live,
live_config: {
live_subject: form.live_subject,
live_summary: form.live_summary
},
managers: [this.user.id]
}
const loading = this.$loading({
lock: true,
text: '创建腾讯会议中,请稍后...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
createMeeting(params).then(res => {
loading.close()
if (res.code === 0 && res.data.id) {
operateLog({ type: `创建会议,被创建会议meeting_code:${res.data.meeting_code}`, user: this.user })
this.$message.success('创建腾讯会议成功')
this.fetchMeetingDetails({ meeting_type: form.meeting_type, meeting_id: res.data.meeting_id })
this.$emit('refreshData')
}
})
},
fetchMeetingDetails(obj) {
if (obj.type === 1) {
console.log(111)
} else {
const params = {
meeting_id: obj.meeting_id
}
const loading = this.$loading({
lock: true,
text: '获取腾讯会议详情,请稍后...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
getMeetingDetails(params).then(res => {
loading.close()
if (res.code === 0 && res.data.id) {
this.details = res.data
this.dialogVisible = true
}
})
}
} }
} }
} }
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
<div :class="getClass(ev)"> <div :class="getClass(ev)">
<div class="status"> <div class="status">
{{ev.status | statusFilter}} {{ev.status | statusFilter}}
<span class="time-range">{{ev.startTime | timeFormat}}-{{ev.endTime | timeFormat}}</span> <span class="time-range">{{ev.start_time | timeFormat}}-{{ev.end_time | timeFormat}}</span>
</div> </div>
<div class="event-cont"> <div class="event-cont">
<div class="title"> <div class="title">
<span>{{ev.title}}</span> <span>{{ev.subject}}</span>
</div> </div>
<div class="creator"> <div class="creator">
<span><i class="el-icon-s-custom"></i>:{{ev.creator}}</span> <span><i class="el-icon-s-custom"></i>:{{ev.sso_user.nickname}}</span>
</div> </div>
</div> </div>
</div> </div>
...@@ -35,7 +35,7 @@ export default { ...@@ -35,7 +35,7 @@ export default {
case 2: case 2:
result = '已完成' result = '已完成'
break break
case 3: case 0:
result = '未开始' result = '未开始'
break break
} }
...@@ -54,7 +54,7 @@ export default { ...@@ -54,7 +54,7 @@ export default {
return { return {
'schedule-ev-inner test': true, 'schedule-ev-inner test': true,
'status-start': ev.status === 1, 'status-start': ev.status === 1,
'status-notstarted': ev.status === 3, 'status-notstarted': ev.status === 0,
small: h < 120 && h >= 40, small: h < 120 && h >= 40,
medium: h >= 120 && h < 200, medium: h >= 120 && h < 200,
large: h >= 200 large: h >= 200
......
<template> <template>
<div class="day"> <div class="day">
<schedule :options="options" :data="scheduleList" :date="defaultDate" @eventClick="edit" @addEvent="add"> <schedule :options="options" :data="scheduleData" :date="defaultDate">
<template slot="content" slot-scope="scope"> <template slot="content" slot-scope="scope">
<schedule-content :ev="scope.data"></schedule-content> <schedule-content :ev="scope.data"></schedule-content>
</template> </template>
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<details-popover :data="scope.data"/> <details-popover :data="scope.data"/>
</template> </template>
<template slot="new-schedule" slot-scope="scope"> <template slot="new-schedule" slot-scope="scope">
<new-popover :data="scope.data" :date="defaultDate" @refreshPopover="refreshPop"/> <new-popover :data="scope.data" :date="defaultDate" @refreshPopover="refreshPop" @refreshData="getScheduleData"/>
</template> </template>
</schedule> </schedule>
</div> </div>
...@@ -18,6 +18,9 @@ import Schedule from '@/components/Schedule' ...@@ -18,6 +18,9 @@ import Schedule from '@/components/Schedule'
import ScheduleContent from './components/ScheduleContent' import ScheduleContent from './components/ScheduleContent'
import DetailsPopover from './components/DetailsPopover' import DetailsPopover from './components/DetailsPopover'
import NewPopover from './components/NewPopover' import NewPopover from './components/NewPopover'
import { getAllAccountList, getNonpagedMeetingList } from '@api/common'
import { dateFormat } from '@/utils/dateAlgs'
import { mapGetters } from 'vuex'
export default { export default {
props: { props: {
defaultDate: { defaultDate: {
...@@ -25,6 +28,9 @@ export default { ...@@ -25,6 +28,9 @@ export default {
validator: (value) => { validator: (value) => {
return typeof value === 'object' && (value === null || value instanceof Date) return typeof value === 'object' && (value === null || value instanceof Date)
} }
},
filter: {
type: Object
} }
}, },
data() { data() {
...@@ -45,142 +51,112 @@ export default { ...@@ -45,142 +51,112 @@ export default {
events: [ events: [
{ {
status: 2, status: 2,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会', title: '开个周会',
startTime: new Date(2021, 3, 13, 8, 30, 0), startTime: new Date(2021, 3, 13, 8, 30, 0),
endTime: new Date(2021, 3, 13, 9, 0, 0), endTime: new Date(2021, 3, 13, 9, 0, 0),
creator: '张三丰' creator: '张三丰'
},
{
status: 1,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 11, 0, 0),
endTime: new Date(2021, 3, 13, 13, 0, 0),
creator: '张三丰'
},
{
status: 3,
title: '开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 14, 30, 0),
endTime: new Date(2021, 3, 13, 15, 30, 0),
creator: '张三丰'
} }
] ]
}, },
scheduleList: [ scheduleData: []
{
id: 'live-1',
title: '会议室1',
events: [
{
status: 2,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 8, 30, 0),
endTime: new Date(2021, 3, 13, 9, 0, 0),
creator: '张三丰'
},
{
status: 1,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 11, 0, 0),
endTime: new Date(2021, 3, 13, 13, 0, 0),
creator: '张三丰'
},
{
status: 3,
title: '开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 20, 30, 0),
endTime: new Date(2021, 3, 14, 1, 30, 0),
creator: '张三丰'
}
]
},
{
id: 'live-2',
title: '会议室2',
events: [
{
status: 2,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 9, 30, 0),
endTime: new Date(2021, 3, 13, 10, 0, 0),
creator: '张三丰'
}
]
},
{
id: 'live-3',
title: '会议室3',
events: [
{
status: 3,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 16, 30, 0),
endTime: new Date(2021, 3, 13, 18, 0, 0),
creator: '张三丰'
}
]
},
{
id: 'live-4',
title: '会议室4',
events: [
{
status: 3,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 13, 19, 30, 0),
endTime: new Date(2021, 3, 13, 20, 30, 0),
creator: '张三丰'
}
]
},
{
id: 'live-5',
title: '会议室5',
events: [
{
status: 3,
title: '开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会开个周会',
startTime: new Date(2021, 3, 8, 21, 0, 0),
endTime: new Date(2021, 3, 8, 22, 0, 0),
creator: '张三丰'
}
]
}
],
list: [
{
id: 'live-1',
title: '会议室1',
events: []
},
{
id: 'live-2',
title: '会议室2',
events: []
}
]
} }
}, },
computed: {
...mapGetters(['user'])
},
components: { Schedule, ScheduleContent, DetailsPopover, NewPopover }, components: { Schedule, ScheduleContent, DetailsPopover, NewPopover },
watch: { watch: {
defaultDate: { defaultDate: {
handler: function(nv, ov) { handler: function(nv, ov) {
if (nv) { if (nv) {
// console.log(nv) console.log(nv)
this.getScheduleData()
} }
}, },
immediate: true immediate: true
},
'filter.status': {
handler: function(nv, ov) {
if (nv !== ov) {
this.getScheduleData()
}
},
deep: true
},
'filter.isMine': {
handler: function(nv, ov) {
if (nv !== ov) {
this.getScheduleData()
}
},
deep: true
} }
}, },
methods: { methods: {
refreshPop(val) { refreshPop(val) {
this.options.refreshPopoverState = val this.options.refreshPopoverState = val
}, },
edit(val) { pickMeeingData(aList, mList) {
console.log(val) const data = []
for (let i = 0; i < aList.length; i++) {
const _accont = aList[i]
if (_accont.userid) {
const account = {
userid: _accont.userid,
name: _accont.username,
events: []
}
for (let j = 0; j < mList.length; j++) {
const meeting = mList[j]
if (meeting.userid === _accont.userid) {
account.events.push(meeting)
}
}
data.push(account)
}
}
return data
}, },
add(val) { getScheduleData() {
console.log(val) //
Promise.all([this.fetchAccountList(), this.fetchMeetingList()]).then(res => {
// 组装数据
const scheduleData = this.pickMeeingData(res[0], res[1])
this.scheduleData = scheduleData
}).catch(err => {
console.log(err)
})
},
fetchMeetingList() {
const date = this.defaultDate
const start = dateFormat(date)
const end = dateFormat(new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1))
const params = {
sso_id: this.filter.isMine ? this.user.id : undefined,
status: this.filter.status > 2 ? undefined : this.filter.status,
start_time: start,
end_time: end
}
return new Promise((resolve, reject) => {
getNonpagedMeetingList(params).then((res) => {
if (res.code === 0 && res.data && res.data.list) {
resolve(res.data.list)
} else {
reject(res)
}
}).catch((err) => reject(err))
})
},
fetchAccountList() {
return new Promise((resolve, reject) => {
getAllAccountList().then((res) => {
if (res.code === 0 && res.data.list) {
resolve(res.data.list)
} else {
reject(res)
}
}).catch((err) => reject(err))
})
} }
} }
} }
......
...@@ -9,20 +9,22 @@ ...@@ -9,20 +9,22 @@
<calendar :type="dateType" style="margin-left:-10px;" :defaultDate="defaultDate" @change="calendarChange" /> <calendar :type="dateType" style="margin-left:-10px;" :defaultDate="defaultDate" @change="calendarChange" />
<div class="bottom"> <div class="bottom">
<div class="title"> <div class="title">
直播日历 <el-checkbox style="margin-left:20px;" v-model="mineFilter">我的</el-checkbox> 直播日历 <el-checkbox style="margin-left:20px;" v-model="filter.isMine">我的</el-checkbox>
</div> </div>
<div class="status-filter"> <div class="status-filter">
<el-radio-group v-model="statusFilter"> <el-radio-group v-model="filter.status">
<el-radio :label="3">进行中</el-radio> <el-radio :label="9999">全部</el-radio>
<el-radio :label="6">未开始</el-radio> <el-radio :label="1">进行中</el-radio>
<el-radio :label="9">已完成</el-radio> <el-radio :label="0">未开始</el-radio>
<el-radio :label="2">已完成</el-radio>
</el-radio-group> </el-radio-group>
</div> </div>
</div> </div>
</div> </div>
<div class="right-container"> <div class="right-container">
<div class="top"> <div class="top">
<div class="title">2021年04月</div> <div class="title" v-if="tabActive === 'list'">{{defaultDate[0] | dateFormat}} - {{defaultDate[1] | dateFormat}}</div>
<div class="title" v-if="tabActive === 'day'">{{defaultDate | dateFormat}} {{defaultDate | dateFormat('星期{a}')}} </div>
<el-radio-group v-model="tabActive" size="mini"> <el-radio-group v-model="tabActive" size="mini">
<el-radio-button label="list">列表</el-radio-button> <el-radio-button label="list">列表</el-radio-button>
<el-radio-button label="day"></el-radio-button> <el-radio-button label="day"></el-radio-button>
...@@ -30,8 +32,8 @@ ...@@ -30,8 +32,8 @@
<el-radio-button label="month"></el-radio-button> --> <el-radio-button label="month"></el-radio-button> -->
</el-radio-group> </el-radio-group>
</div> </div>
<list v-if="tabActive === 'list'" /> <list v-if="tabActive === 'list'" :defaultDate="defaultDate" :filter="filter"/>
<day v-if="tabActive === 'day'" :defaultDate="defaultDate"/> <day v-if="tabActive === 'day'" :defaultDate="defaultDate" :filter="filter"/>
</div> </div>
</div> </div>
</div> </div>
...@@ -44,8 +46,10 @@ import { dateFormat } from '@/utils/dateAlgs' ...@@ -44,8 +46,10 @@ import { dateFormat } from '@/utils/dateAlgs'
export default { export default {
data () { data () {
return { return {
mineFilter: false, filter: {
statusFilter: '', isMine: false,
status: 9999
},
tabActive: 'list', tabActive: 'list',
defaultDate: null, defaultDate: null,
dateType: 'date' dateType: 'date'
...@@ -60,22 +64,7 @@ export default { ...@@ -60,22 +64,7 @@ export default {
}, },
filters: { filters: {
dateFormat (value, fmt) { dateFormat (value, fmt) {
return dateFormat(value, fmt) return dateFormat(value, fmt || '{y}年{m}月{d}日')
},
statusFilter(val) {
let result = ''
switch (val) {
case 1:
result = '进行中'
break
case 2:
result = '已完成'
break
case 3:
result = '未开始'
break
}
return result
} }
}, },
watch: { watch: {
...@@ -85,7 +74,7 @@ export default { ...@@ -85,7 +74,7 @@ export default {
this.defaultDate = this.now this.defaultDate = this.now
this.dateType = 'date' this.dateType = 'date'
} else { } else {
this.defaultDate = null this.defaultDate = [this.now, this.now]
this.dateType = 'daterange' this.dateType = 'daterange'
} }
}, },
...@@ -97,17 +86,7 @@ export default { ...@@ -97,17 +86,7 @@ export default {
this.$router.push('/search') this.$router.push('/search')
}, },
calendarChange(val) { calendarChange(val) {
if (this.dateType === 'date') { this.defaultDate = val
this.defaultDate = val
} else {
console.log(val)
}
},
joinMeeting(data) {
console.log(data)
},
pageChange(val) {
console.log(val)
} }
} }
} }
...@@ -144,23 +123,30 @@ h5{ ...@@ -144,23 +123,30 @@ h5{
margin-bottom:10px; margin-bottom:10px;
} }
.status-filter ::v-deep.el-radio:first-child .el-radio__input.is-checked .el-radio__inner{ .status-filter ::v-deep.el-radio:first-child .el-radio__input.is-checked .el-radio__inner{
border-color:#636363;
background:#636363;
}
.status-filter ::v-deep.el-radio:nth-child(2) .el-radio__input.is-checked .el-radio__inner{
border-color:#409eff; border-color:#409eff;
background:#409eff; background:#409eff;
} }
.status-filter ::v-deep.el-radio:last-child .el-radio__input.is-checked .el-radio__inner{ .status-filter ::v-deep.el-radio:nth-child(3) .el-radio__input.is-checked .el-radio__inner{
border-color:#BFBFBF;
background:#BFBFBF;
}
.status-filter ::v-deep.el-radio__input.is-checked .el-radio__inner{
border-color:#52B837; border-color:#52B837;
background:#52B837; background:#52B837;
} }
.status-filter ::v-deep.el-radio__input + .el-radio__label{ .status-filter ::v-deep.el-radio:last-child .el-radio__input.is-checked .el-radio__inner{
color:#52B837; border-color:#BFBFBF;
background:#BFBFBF;
} }
.status-filter ::v-deep.el-radio:first-child .el-radio__input + .el-radio__label{ .status-filter ::v-deep.el-radio:first-child .el-radio__input + .el-radio__label{
color:#636363;
}
.status-filter ::v-deep.el-radio:nth-child(2) .el-radio__input + .el-radio__label{
color:#409eff; color:#409eff;
} }
.status-filter ::v-deep.el-radio:nth-child(3) .el-radio__input + .el-radio__label{
color:#52B837;
}
.status-filter ::v-deep.el-radio:last-child .el-radio__input + .el-radio__label{ .status-filter ::v-deep.el-radio:last-child .el-radio__input + .el-radio__label{
color:#BFBFBF; color:#BFBFBF;
} }
......
<template> <template>
<el-form label-width="140px"> <el-form label-width="140px">
<el-form-item label="会议主题:"> <el-form-item label="会议主题:">
某某某会议主题 {{details.subject}}
</el-form-item> </el-form-item>
<el-form-item label="会议时间:"> <el-form-item label="会议时间:">
2021年11月06日 10:00-11:00(GMT+08:00) {{details.start_time | dateFormat}} - {{details.end_time | dateFormat('{h}:{i}')}}GMT+08:00)
</el-form-item> </el-form-item>
<el-form-item label="会议链接:"> <el-form-item label="会议链接:">
http://meeting.tencent.com/sS42KPDILN {{details.join_url}}
</el-form-item> </el-form-item>
<el-form-item label="会议号:"> <el-form-item label="会议号:">
526 430 840 {{details.meeting_code}}
</el-form-item> </el-form-item>
<el-form-item label="会议直播:" v-if="hasLive"> <el-form-item label="会议直播:" v-if="details.enable_live === 1">
http://meeting.tencent.com/sS42KPDILN {{details.live_config.live_addr}}
</el-form-item> </el-form-item>
<el-form-item label="手机拨号入会:"> <el-form-item label="手机拨号入会:" v-if="false">
<p>+8675536550000,,526430840#(中国大陆)</p> <p>+8675536550000,,526430840#(中国大陆)</p>
<p>+85230018898,,526430840#(中国香港)</p> <p>+85230018898,,526430840#(中国香港)</p>
</el-form-item> </el-form-item>
<el-form-item label="根据您的位置拨号:"> <el-form-item label="根据您的位置拨号:" v-if="false">
<p>+8675536550000(中国大陆)</p> <p>+8675536550000(中国大陆)</p>
<p>++85230018898(中国香港)</p> <p>++85230018898(中国香港)</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script>
import { dateFormat } from '@/utils/dateAlgs'
export default { export default {
props: { props: {
rowData: {} rowData: {},
details: {}
}, },
computed: { computed: {
hasLive() { hasLive() {
return this.rowData.hasLive || false return this.rowData.hasLive || false
} }
},
filters: {
dateFormat(value, fmt) {
return dateFormat(value, fmt || '{y}年{m}月{d}日 {h}:{i}')
}
} }
} }
</script> </script>
......
<template> <template>
<el-form label-width="140px"> <el-form label-width="140px">
<el-form-item label="会议主题:"> <el-form-item label="会议主题:">
某某某会议主题 {{details.subject}}
</el-form-item> </el-form-item>
<el-form-item label="会议时间:"> <el-form-item label="会议时间:">
2021年11月06日 10:00-11:00(GMT+08:00) {{details.start_time | dateFormat}} - {{details.end_time | dateFormat('{h}:{i}')}}GMT+08:00)
</el-form-item> </el-form-item>
<el-form-item label="会议号:"> <el-form-item label="会议号:">
526 430 840 {{details.meeting_code}}
</el-form-item> </el-form-item>
<el-form-item label="会议创建者:"> <el-form-item label="会议创建者:">
张三 {{rowData.sso_user.nickname}}
</el-form-item> </el-form-item>
<el-form-item label="会议主持人:"> <el-form-item label="会议主持人:">
李四 <span v-for="(it, index) in details.hosts" :key="it.userid">{{it.username}}{{index > 0 ? '、' : ''}}</span>
</el-form-item> </el-form-item>
<el-form-item label="会议主持人:"> <el-form-item label="会议管理员:">
王五、赵⑥ <span v-for="(it, index) in details.managers" :key="it.userid">{{it.nickname}}{{index > 0 ? '、' : ''}}</span>
</el-form-item> </el-form-item>
<el-form-item label="会议直播主题:"> <el-form-item label="会议直播主题:" v-if="details.enable_live === 1">
随便写点啥 {{details.live_config.live_subject}}
</el-form-item> </el-form-item>
<el-form-item label="会议直播简介:"> <el-form-item label="会议直播简介:" v-if="details.enable_live === 1">
<p style="line-height:26px;padding:7px 10px 7px 0">随便写点啥随便写点啥随便写点啥随便写点啥随便写点啥随便写点啥随便写点啥随便写点啥随便写点啥随便写点啥</p> <p style="line-height:26px;padding:7px 10px 7px 0">{{details.live_config.live_summary}}</p>
</el-form-item> </el-form-item>
<el-form-item label="参会成员:"> <el-form-item label="参会成员:" v-if="rowData.status === 2">
<el-button type="text">导出excel</el-button> <el-button type="text" @click="handleExport">导出excel</el-button>
</el-form-item> </el-form-item>
<el-form-item label="回放:"> <el-form-item label="回放:" v-if="rowData.status === 2">
<el-button type="text">下载</el-button> <el-button type="text" v-if="hasRecord" @click="handleDownload">下载</el-button>
<el-button type="text" v-else disabled>暂无回放</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script>
import { dateFormat } from '@/utils/dateAlgs'
import { exportParticipants, getMeetingRecordAddr } from '@api/common'
export default { export default {
props: { props: {
details: {},
rowData: {}, rowData: {},
dialogType: {} dialogType: {}
}, },
computed: { computed: {
hasLive() { hasRecord() {
return this.rowData.hasLive || false if (this.rowData.record_file_ids && Array.isArray(this.rowData.record_file_ids) && this.rowData.record_file_ids.length > 0) {
return true
} else {
return false
}
},
nowFormat() {
const now = Date.now()
const _format = dateFormat(now, '{y}{m}{d}{h}{i}{s}')
const nowStr = now.toString()
return _format + nowStr.substr(10, 12)
}
},
filters: {
dateFormat(value, fmt) {
return dateFormat(value, fmt || '{y}年{m}月{d}日 {h}:{i}')
}
},
methods: {
handleExport() {
const row = this.rowData
const params = {
meeting_id: row.meeting_id
}
if (row.meeting_type === 1) {
params.sub_meeting_id = row.sub_meeting_id
}
exportParticipants(params).then((res) => {
if (res && res.type === 'text/xlsx') {
const url = URL.createObjectURL(res)
// const elink = document.createElement('a')// 创建一个a标签
// elink.download = `参会人员表_${this.nowFormat}.xlsx`;// 设置a标签的下载属性
// elink.style.display = 'none';// 将a标签设置为隐藏
// elink.href = URL.createObjectURL(blob);// 把之前处理好的地址赋给a标签的href
// document.body.appendChild(elink);// 将a标签添加到body中
// elink.click();// 执行a标签的点击方法
// URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
// document.body.removeChild(elink)// 移除a标签
this.funDownload(url, `参会人员表_${this.nowFormat}.xlsx`)
}
})
},
async handleDownload() {
const list = await this.fetchMeetingRecordAddr()
if (list && Array.isArray(list)) {
list.forEach(it => {
if (it.download_address) {
// window.open(it.download_address, '_blank')
this.funDownload(it.download_address, it.download_address)
}
})
}
},
funDownload(fileUrl, fileName) {
const elink = document.createElement('a')// 创建一个a标签
elink.download = fileName;// 设置a标签的下载属性
elink.style.display = 'none';// 将a标签设置为隐藏
elink.href = fileUrl;// 把之前处理好的地址赋给a标签的href
document.body.appendChild(elink);// 将a标签添加到body中
elink.click();// 执行a标签的点击方法
URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
document.body.removeChild(elink)// 移除a标签
},
fetchMeetingRecordAddr() {
const params = {
meeting_id: this.rowData.meeting_id,
record_file_ids: this.rowData.record_file_ids
}
return new Promise((resolve, reject) => {
getMeetingRecordAddr(params).then(res => {
if (res.code === 0 && res.data.files) {
resolve(res.data.files)
} else {
reject(res)
}
}).catch((err) => reject(err))
})
} }
} }
} }
......
<template> <template>
<div class="btns"> <div class="btns">
<template v-if="status === 1"> <template v-if="status === 1">
<el-button type="text" size="small" v-if="operatable">进入会议</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleJoin">进入会议</el-button>
<el-button type="text" size="small" v-if="operatable && hasLive">观看直播</el-button> <el-button type="text" size="small" v-if="operatable && hasLive" @click="handleLive">观看直播</el-button>
<el-button type="text" size="small" v-if="operatable" @click="dialogVisible = 'copy'">复制邀请</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleCopy">复制邀请</el-button>
<el-button type="text" size="small" v-if="operatable">终止</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleStop">终止</el-button>
<el-button type="text" size="small" v-if="!operatable" @click="dialogVisible = 'details'">查看</el-button> <el-button type="text" size="small" v-if="!operatable" @click="handleDetails">查看</el-button>
</template> </template>
<template v-if="status === 2"> <template v-if="status === 0">
<el-button type="text" size="small" v-if="operatable">进入会议</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleJoin">进入会议</el-button>
<el-button type="text" size="small" v-if="operatable">复制邀请</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleCopy">复制邀请</el-button>
<el-button type="text" size="small" v-if="operatable && !isCycle">修改</el-button> <el-button type="text" size="small" v-if="operatable && !isCycle">修改</el-button>
<el-dropdown v-if="operatable && isCycle"> <el-dropdown v-if="operatable && isCycle">
<span class="dropdown-link"> <span class="dropdown-link">
...@@ -20,23 +20,23 @@ ...@@ -20,23 +20,23 @@
<el-dropdown-item>修改周期会议</el-dropdown-item> <el-dropdown-item>修改周期会议</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
<el-button type="text" size="small" v-if="operatable">取消</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleCancel">取消</el-button>
<el-button type="text" size="small" v-if="!operatable" @click="dialogVisible = 'details'">查看</el-button> <el-button type="text" size="small" v-if="!operatable" @click="handleDetails">查看</el-button>
</template> </template>
<template v-if="status === 3"> <template v-if="status === 2">
<el-button type="text" size="small" v-if="operatable">看回放</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleRecord">看回放</el-button>
<el-button type="text" size="small" @click="dialogVisible = 'details'">查看</el-button> <el-button type="text" size="small" @click="handleDetails">查看</el-button>
<el-button type="text" size="small" v-if="operatable">删除</el-button> <el-button type="text" size="small" v-if="operatable" @click="handleDelete">删除</el-button>
</template> </template>
<el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="520px" center> <el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="520px" center>
<div slot="title" class="dialog-header"> <div slot="title" class="dialog-header">
<p class="meeting-status" v-show="dialogVisible === 'details'">会议进行中</p> <p class="meeting-status" v-show="dialogType === 'details'">会议{{rowData.status | statusFilter}}</p>
<p class="title">{{domicTitle}}</p> <p class="title">{{domicTitle}}</p>
</div> </div>
<dialog-details :rowData="rowData" :dialogType="dialogVisible" v-show="dialogVisible === 'details'" /> <dialog-details :rowData="rowData" :details="details" v-show="dialogType === 'details'" />
<dialog-copy-invite :rowData="rowData" v-show="dialogVisible === 'copy'"/> <dialog-copy-invite :rowData="rowData" :details="details" v-show="dialogType === 'copy'"/>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" v-show="dialogVisible === 'copy'">复制</el-button> <el-button type="primary" size="mini" v-show="dialogType === 'copy'" @click="copyLink">复制</el-button>
<el-button @click="dialogVisible = false" size="mini">取 消</el-button> <el-button @click="dialogVisible = false" size="mini">取 消</el-button>
</div> </div>
</el-dialog> </el-dialog>
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
<script> <script>
import DialogDetails from './DialogDetails.vue' import DialogDetails from './DialogDetails.vue'
import DialogCopyInvite from './DialogCopyInvite' import DialogCopyInvite from './DialogCopyInvite'
import { mapGetters } from 'vuex'
import { getMeetingDetails, stopMeeting, cancelMeeting, getMeetingRecordAddr } from '@api/common'
export default { export default {
props: { props: {
rowData: {} rowData: {}
...@@ -53,13 +55,16 @@ export default { ...@@ -53,13 +55,16 @@ export default {
return { return {
userId: '1234', userId: '1234',
roleName: '', // general_admin roleName: '', // general_admin
dialogVisible: false dialogVisible: false,
dialogType: 'copy',
details: ''
} }
}, },
computed: { computed: {
...mapGetters(['isSuperAdmin', 'user']),
domicTitle() { domicTitle() {
let title = '' let title = ''
switch (this.dialogVisible) { switch (this.dialogType) {
case 'copy': case 'copy':
title = '复制邀请' title = '复制邀请'
break break
...@@ -73,19 +78,16 @@ export default { ...@@ -73,19 +78,16 @@ export default {
return this.rowData.status return this.rowData.status
}, },
isCycle() { isCycle() {
return this.rowData.isCycle return this.rowData.meeting_type === 1
}, },
isMyself() { isMyself() {
return this.rowData.creatorId === this.userId return this.rowData.sso_id === this.user.id
},
isSuperAdmin() {
return this.roleName === 'administrator'
}, },
isGeneralAdmin() { isGeneralAdmin() {
const admins = this.rowData.general_admin const admins = this.rowData.manage_ids
let flag = false let flag = false
for (let i = 0; i < admins.length; i++) { for (let i = 0; i < admins.length; i++) {
if (admins[i].userId === this.userId) { if (admins[i] === this.user.id) {
flag = true flag = true
break break
} }
...@@ -93,14 +95,153 @@ export default { ...@@ -93,14 +95,153 @@ export default {
return flag return flag
}, },
hasLive() { hasLive() {
return this.rowData.hasLive || false return this.rowData.enable_live || false
}, },
operatable() { operatable() {
return this.isMyself || this.isSuperAdmin || this.isGeneralAdmin return this.isMyself || this.isSuperAdmin || this.isGeneralAdmin
} }
}, },
filters: {
statusFilter(val) {
let result = ''
switch (val) {
case 0:
result = '未开始'
break
case 1:
result = '进行中'
break
case 2:
result = '已结束'
break
}
return result
}
},
components: { DialogDetails, DialogCopyInvite }, components: { DialogDetails, DialogCopyInvite },
created() { created() {
},
methods: {
handleCopy() {
this.fetchMeetingDetails()
this.dialogVisible = true
this.dialogType = 'copy'
},
handleDetails() {
this.dialogVisible = true
this.dialogType = 'details'
this.fetchMeetingDetails()
},
handleLive() {
window.open(this.live_config.live_addr, '_blank');
},
handleCancel() {
this.$confirm('此操作将取消这场会议, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.fetchCancelMeeting('cancel')
}).catch(() => {})
},
handleStop() {
this.$confirm('此操作将终止正在进行中的会议, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.fetchStopMeeting()
}).catch(() => {})
},
handleDelete() {
this.$confirm('此操作将删除这场会议, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.fetchCancelMeeting('delete')
}).catch(() => {})
},
handleJoin() {
window.open(this.rowData.join_url, '_blank');
},
copyLink() {
const dom = document.createElement('input')
document.body.appendChild(dom)
dom.value = this.rowData.join_url
dom.select(); // 选择对象
document.execCommand('Copy');
this.$message({
message: '复制成功!',
type: 'success'
})
document.body.removeChild(dom)
},
async handleRecord() {
if (this.rowData.record_file_ids.length === 0) {
this.$message.error('该会议没有回放')
} else {
const list = await this.fetchMeetingRecordAddr()
if (list && Array.isArray(list)) {
if (list.length === 1) {
window.open(list[0].view_address, '_blank')
}
}
}
},
fetchStopMeeting() {
const params = {
meeting_id: this.rowData.meeting_id
}
stopMeeting(params).then(res => {
if (res.code === 0 && res.data.status) {
this.$message.success('会议终止成功')
this.$emit('refresh')
} else {
this.$message.error(res.msg || '会议终止失败')
}
})
},
fetchCancelMeeting(type) {
const params = {
meeting_id: this.rowData.meeting_id
}
const msg = type === 'cancel' ? '会议取消' : '会议删除'
cancelMeeting(params).then(res => {
if (res.code === 0 && res.data.status) {
this.$message.success(msg + '成功')
this.$emit('refresh')
} else {
this.$message.error(res.msg || msg + '失败')
}
})
},
fetchMeetingDetails() {
const row = this.rowData
const params = {
meeting_id: row.meeting_id
}
if (row.meeting_type === 1) {
params.sub_meeting_id = row.sub_meeting_id
}
getMeetingDetails(params).then(res => {
if (res.code === 0 && res.data.id) {
this.details = res.data
}
})
},
fetchMeetingRecordAddr() {
const params = {
meeting_id: this.rowData.meeting_id,
record_file_ids: this.rowData.record_file_ids
}
return new Promise((resolve, reject) => {
getMeetingRecordAddr(params).then(res => {
if (res.code === 0 && res.data.files) {
resolve(res.data.files)
} else {
reject(res)
}
}).catch((err) => reject(err))
})
}
} }
} }
</script> </script>
......
<template>
<div class="create-meeting">
<el-radio-group v-model="tabActive" size="mini" style="margin:14px 0 10px 40px;">
<el-radio-button label="tx">腾讯</el-radio-button>
<el-radio-button label="cc">cc</el-radio-button>
<!-- <el-radio-button label="week"></el-radio-button>
<el-radio-button label="month"></el-radio-button> -->
</el-radio-group>
<tencent-meeting-test />
</div>
</template>
<script>
import TencentMeetingTest from './tencent-meeting-test/index.vue'
export default {
data() {
return {
tabActive: 'tx'
}
},
components: { TencentMeetingTest }
}
</script>
<style scope>
.create-meeting{
height:100%;
}
</style>
\ No newline at end of file
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</div> </div>
</template> </template>
<script> <script>
import TencentMeeting from './components/tencentMeeting.vue' import TencentMeeting from './tencent-meeting/index.vue'
export default { export default {
data() { data() {
return { return {
......
<template>
<component v-bind:is="currentPage"></component>
</template>
<script>
import PageCreate from './page-create'
import PageAccountCreate from './page-account-create'
import PageUpdate from './page-update'
export default {
data () {
return {
currentPage: 'PageCreate'
}
},
components: { PageCreate, PageAccountCreate, PageUpdate },
watch: {
$route: {
handler: function (nv, ov) {
const query = this.$route.query
console.log(query)
if (query.type === '1') {
this.currentPage = 'PageAccountCreate'
} else if (query.type === '2') {
console.log('edit')
this.currentPage = 'PageUpdate'
} else {
this.currentPage = 'PageCreate'
}
},
immediate: true
}
}
}
</script>
\ No newline at end of file
<template>
<div>同一账号下创建</div>
</template>
<script>
export default ({
data () {
return {}
}
})
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div class="create">
<div class="inner">
<meeting-form></meeting-form>
</div>
</div>
</template>
<script>
import MeetingForm from './components/MeetingForm'
export default ({
data () {
return {}
},
components: { MeetingForm }
})
</script>
<style scoped>
.create{
overflow-y: auto;
height: calc(100% - 52px);
}
.inner {
background: #fff;
margin: 0 15px;
border-radius: 4px;
padding-bottom:10px;
}
</style>
<template>
<div>修改</div>
</template>
<script>
export default {
data() {
return {
obj: {
timestamp: 1618998029,
nonce: 'rgHMrr7Bg',
signature: 'UG7wBenexQhiuD2wpCwuxkU0jqcj006d',
instanceid: 1,
userid: '6653195831513972736',
subject: 'sewe',
start_time: '2021-04-21 17:30:00',
end_time: '2021-04-21 18:00:00',
password: '',
meeting_type: 1,
recurring_rule: {
recurring_type: 0,
until_type: 1,
until_count: 2
},
settings: {
mute_enable_join: false,
auto_in_waiting_room: false,
allow_in_before_host: true,
auto_record_type: 'none'
},
enable_live: 0,
live_config: {
live_subject: '',
live_summary: '',
enable_live_password: false,
enable_live_im: false
},
managers: ['6775725014348988416'],
meeting_id: '8343776720283269132'
}
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
差异被折叠。
<template> <template>
<div class="account"> <div class="account">
<h5>角色管理</h5> <h5>
角色管理
<el-button style="float: right; margin: 12px 30px 0 0" size="mini" type="primary" plain @click="handleAdd"
>添加角色</el-button
>
</h5>
<div class="inner"> <div class="inner">
<el-table :data="listData" style="width: 100%" height="calc(100% - 32px)">
<el-table-column prop="name" label="角色" min-width="140" v-if="!isSuperAdmin"></el-table-column>
<el-table-column prop="display_name" label="角色名称" min-width="120"></el-table-column>
<el-table-column prop="description" label="角色描述" min-width="120"></el-table-column>
<el-table-column prop="updated_at" label="创建时间" min-width="120"></el-table-column>
<el-table-column label="操作" min-width="140">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleUsers(scope.row)">分配用户</el-button>
<el-button type="text" size="small" @click="handlePermission(scope.row)">设置权限</el-button>
<el-button type="text" size="small" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" size="small" @click="handleDelete(scope.row.userid)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination :current-page.sync="curPage" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="pageChange" style="float:right;"></el-pagination>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getRoles } from '@api/system'
import { mapGetters } from 'vuex'
export default { export default {
data () { data() {
return {} return {
listData: [
{
id: 2,
name: 'general_admin',
display_name: '普通管理员',
description: '拥有超级管理员下的最高权限',
created_at: '2021-04-01 09:38:25',
updated_at: '2021-04-01 09:38:25'
},
{
id: 1,
name: 'administrator',
display_name: '超级管理员',
description: '拥有所有的权限',
created_at: '2021-04-01 09:29:41',
updated_at: '2021-04-01 09:29:41'
}
],
curPage: 1,
pageSize: 20,
total: 0
}
},
computed: {
...mapGetters(['isSuperAdmin'])
},
created() {
this.fetchRoleList()
},
methods: {
handleUsers(val) {
this.$router.push({ path: '/system/roleToUser', query: { id: val.id } })
},
handlePermission(val) {
console.log(val)
},
handleEdit(val) {
console.log(val)
},
handleDelete(val) {
console.log(val)
},
pageChange() {
this.fetchRoleList()
},
fetchRoleList() {
const params = {
page: this.curPage,
limit: this.pageSize
}
getRoles(params).then((res) => {
if (res.code === 0 && res.data.data) {
this.listData = res.data.data
this.total = res.data.total
}
})
}
} }
} }
</script> </script>
<style scoped> <style scoped>
.account{ .account {
height:100%; height: 100%;
} }
h5{ h5 {
font-size: 16px; font-size: 16px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
color:#333; color: #333;
font-weight: 400; font-weight: 400;
line-height:50px; line-height: 50px;
text-indent:40px; text-indent: 40px;
} }
.inner{ .inner {
height: calc(100% - 50px - 10px); height: calc(100% - 50px - 10px);
display:flex; background: #ffffff;
background: #FFFFFF;
border-radius: 10px; border-radius: 10px;
margin:0 16px; margin: 0 16px;
box-sizing:border-box; box-sizing: border-box;
padding:14px 14px 6px; padding: 14px 14px 6px;
} }
</style> </style>
\ No newline at end of file
<template>
<div class="account">
<h5>
角色管理 / 分配用户
<el-button style="float: right; margin: 12px 30px 0 0" size="mini" type="primary" plain @click="handleAdd"
>角色下增加用户</el-button
>
</h5>
<div class="inner">
<el-table :data="listData" style="width: 100%" height="calc(100% - 32px)">
<!-- <el-table-column prop="name" label="角色" min-width="140"></el-table-column> -->
<el-table-column prop="user_info.nickname" label="用户昵称" min-width="120"></el-table-column>
<el-table-column prop="user_info.id" label="用户ID" min-width="120"></el-table-column>
<el-table-column prop="user_info.mobile" label="手机号" min-width="120"></el-table-column>
<el-table-column prop="user_info.email" label="邮箱" min-width="120"></el-table-column>
<el-table-column label="操作" min-width="140">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleDelete(scope.row.userid)">从角色下删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
listData: [
{
created_at: '2021-04-01 10:45:38',
updated_at: '2021-04-01 10:45:38',
user_info: {
id: '6653195831513972736',
username: 'ZJ6653195831513972736',
email: 'wangyizheng@ezijing.com',
mobile: '18435134258',
wechat_unionid: 'oJ6hPszybKN83GkWbvaY33q4oeIo',
nickname: 'sdagads',
country_code: '86',
id_number: null,
user_id: '6653195831513972736',
gender: '0',
province: null,
city: null,
county: null,
company_name: null,
position: null,
personal_signature: null,
phone: null,
qq: null,
wechat: null,
weibo: null,
tencent_weibo: null,
org: null,
real_name: 'sdagads',
highest_degree: null,
major: null,
birthday: null,
channel_code: null,
created_time: '2020-04-07 15:44:57',
updated_time: '2020-08-26 17:12:10',
status: '0',
avatar: null,
realname: 'sdagads'
}
}
]
}
},
methods: {
handleAdd() {},
handleUsers(val) {
console.log(val)
},
handlePermission(val) {
console.log(val)
},
handleEdit(val) {
console.log(val)
},
handleDelete(val) {
console.log(val)
}
}
}
</script>
<style scoped>
.account {
height: 100%;
}
h5 {
font-size: 16px;
font-family: PingFangSC-Regular, PingFang SC;
color: #333;
font-weight: 400;
line-height: 50px;
text-indent: 40px;
}
.inner {
height: calc(100% - 50px - 10px);
display: flex;
background: #ffffff;
border-radius: 10px;
margin: 0 16px;
box-sizing: border-box;
padding: 14px 14px 6px;
}
</style>
\ No newline at end of file
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论