diff --git a/package.json b/package.json index eac52df..493bb7d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@vueuse/core": "^10.1.2", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.10", + "@wangeditor/plugin-upload-attachment": "^1.1.0", "@zxcvbn-ts/core": "^3.0.1", "animate.css": "^4.1.1", "axios": "^1.4.0", diff --git a/src/api/okr/meeting.js b/src/api/okr/meeting.js new file mode 100644 index 0000000..6cdaad4 --- /dev/null +++ b/src/api/okr/meeting.js @@ -0,0 +1,45 @@ +import request from '@/config/axios' + +export const createMeeting = (data) => { + return request.post({ + url: '/admin-api/okr/meeting/add', + data, + isSubmitForm: true + // headers: { 'instance-id': 1016 } + }) +} + +// 修改 +export const updateMeeting = (data) => { + return request.put({ + url: '/admin-api/okr/meeting/update', + data + // headers: { 'instance-id': 1016 } + }) +} +// 查询详情 +export const getMeetingDetail = (params) => { + return request.get({ + url: '/admin-api/okr/meeting/get', + params + // headers: { 'instance-id': 1016 } + }) +} + +// 取消会议 +export const cancelMeeting = (data) => { + return request.put({ + url: '/admin-api/okr/meeting/cancel', + data + // headers: { 'instance-id': 1016 } + }) +} + +// 分页查询 +export const getMeetingPage = (params) => { + return request.get({ + url: '/admin-api/okr/meeting/page', + params + // headers: { 'instance-id': 1016 } + }) +} diff --git a/src/api/okr/okr.js b/src/api/okr/okr.js index 09edcd4..46b2619 100644 --- a/src/api/okr/okr.js +++ b/src/api/okr/okr.js @@ -143,3 +143,12 @@ export const getChannelOptions = () => { // headers: { 'instance-id': 1016 } }) } + +// 获取统计表中的合计信息 +export const getOkrStatisticsTotal = (params) => { + return request.get({ + url: '/admin-api/okr/node/data/count', + params + // headers: { 'instance-id': 1016 } + }) +} diff --git a/src/components/Editor/src/Editor.vue b/src/components/Editor/src/Editor.vue index 33affc4..22df80b 100644 --- a/src/components/Editor/src/Editor.vue +++ b/src/components/Editor/src/Editor.vue @@ -42,7 +42,11 @@ const props = defineProps({ 'undo', // 撤销 'redo', // 重做 'fullScreen' - ] + ], + insertKeys: { + index: 20, // 自定义插入的位置 + keys: ['uploadAttachment'] // “上传附件”菜单 + } }) } }) @@ -104,6 +108,12 @@ const editorConfig = computed((): IEditorConfig => { }, autoFocus: false, scroll: true, + // 在编辑器中,点击选中“附件”节点时,要弹出的菜单 + hoverbarKeys: { + attachment: { + menuKeys: ['downloadAttachment'] // “下载附件”菜单 + } + }, MENU_CONF: { ['uploadImage']: { server: import.meta.env.VITE_UPLOAD_URL, @@ -218,6 +228,52 @@ const editorConfig = computed((): IEditorConfig => { customInsert(res: any, insertFn: InsertFnType) { insertFn(res.data, 'video', res.data) } + }, + uploadAttachment: { + server: import.meta.env.VITE_UPLOAD_URL, + timeout: 20 * 1000, // 2s + + fieldName: 'file', + // meta: { token: 'xxx', a: 100 }, // 请求时附加的数据 + // metaWithUrl: true, // meta 拼接到 url 上 + // headers: { Accept: 'text/x-json' }, + // 自定义增加 http header + headers: { + Accept: '*', + Authorization: 'Bearer ' + getAccessToken(), + 'tenant-id': getTenantId(), + 'instance-id': getAppId() + }, + + maxFileSize: 20 * 1024 * 1024, // 20M + + onBeforeUpload(file: File) { + console.log('onBeforeUpload', file) + return file // 上传 file 文件 + // return false // 会阻止上传 + }, + onProgress(progress: number) { + console.log('onProgress', progress) + }, + onSuccess(file: File, res: any) { + console.log('onSuccess', file, res) + }, + onFailed(file: File, res: any) { + alert(res.message) + console.log('onFailed', file, res) + }, + onError(file: File, err: Error, res: any) { + alert(err.message) + console.error('onError', file, err, res) + }, + // 上传成功后,用户自定义插入文件 + customInsert(res: any, file: File, insertFn: Function) { + console.log('customInsert', res) + + // 插入附件到编辑器 + insertFn(file.name, res.data) + // insertFn(res.data, `customInsert-${file.name}`, res.data) + } } }, uploadImgShowBase64: true diff --git a/src/main.js b/src/main.js index bb6458c..438270f 100644 --- a/src/main.js +++ b/src/main.js @@ -41,9 +41,14 @@ import '@/plugins/tongji' // 百度统计 import Logger from '@/utils/Logger' import VueDOMPurifyHTML from 'vue-dompurify-html' +import { Boot } from '@wangeditor/editor' +import attachmentModule from '@wangeditor/plugin-upload-attachment' // 创建实例 const setupAll = async () => { + // 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。 + Boot.registerModule(attachmentModule) + const app = createApp(App) await setupI18n(app) diff --git a/src/permission.js b/src/permission.js index 2eac4ef..5ded0f7 100644 --- a/src/permission.js +++ b/src/permission.js @@ -64,7 +64,9 @@ router.beforeEach(async (to, from, next) => { if (tenantId && appId) { next(`/login?tenantId=${tenantId}&appId=${appId}&redirect=${to.fullPath}`) // 否则全部重定向到登录页 } else { - next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + // next(`/login?redirect=${to.fullPath}`) + // 否则全部重定向到平台登陆页 + window.location.href = 'https://cloud.ahduima.com/ss/login' } } } diff --git a/src/router/modules/static.ts b/src/router/modules/static.ts index e33943f..4e897c7 100644 --- a/src/router/modules/static.ts +++ b/src/router/modules/static.ts @@ -35,6 +35,46 @@ const staticRouter: AppCustomRouteRecordRaw[] = [ visible: true, alwaysShow: true, redirect: '' + }, + { + icon: 'ep:data-line', + path: 'okr-analysis', + name: 'OKR统计', + componentName: 'OkrAnalysis', + component: 'OKR/Analysis/index', + meta: { + title: 'OKR统计' + }, + visible: true, + alwaysShow: true, + redirect: '' + }, + { + icon: 'ep:data-board', + path: 'okr-meeting', + name: '会议管理', + componentName: 'OkrMeeting', + component: 'OKR/Meeting/index', + meta: { + title: '会议管理' + }, + visible: true, + alwaysShow: true, + redirect: '' + }, + { + icon: 'ep:data-board', + path: 'okr-meeting-info/:id', + name: '会议详情', + componentName: 'MeetingInfo', + component: 'OKR/Meeting/MeetingInfo', + meta: { + title: '会议详情' + }, + visible: false, + alwaysShow: true, + redirect: '', + keepAlive: true } ], meta: { diff --git a/src/styles/index.scss b/src/styles/index.scss index f4e9f17..318e27f 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -97,4 +97,13 @@ /* 去除 Firefox 中的指示器 */ .el-input__inner[type='number'] { -moz-appearance: textfield; +} +.el-drawer__header { + padding: 16px 16px 8px 16px !important; + margin: 0 !important; + line-height: 24px !important; + font-size: 18px !important; + color: #303133 !important; + box-sizing: border-box !important; + // border-bottom: 1px solid #e8e8e8 !important; } \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts index 9b02f25..9636493 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -220,3 +220,30 @@ export const removeNullField = (obj: Object) => { } return obj } + +import * as XLSX from 'xlsx' +import * as FileSaver from 'file-saver' +export const exportTableWithVue = (domId: any, fileName: String) => { + // const XLSX = require('xlsx') + // 使用 this.$nextTick 是在dom元素都渲染完成之后再执行 + // this.$nextTick(function () { + // 设置导出的内容是否只做解析,不进行格式转换 false:要解析, true:不解析 + const xlsxParam = { raw: true } + const wb = XLSX.utils.table_to_book(document.querySelector(domId), xlsxParam) + + const wbout = XLSX.write(wb, { + bookType: 'xlsx', + bookSST: true, + type: 'array' + }) + try { + // 下载保存文件 + FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${fileName}.xlsx`) + } catch (e) { + if (typeof console !== 'undefined') { + console.log(e, wbout) + } + } + return wbout + // }); +} diff --git a/src/utils/tableObjectSpanMethod.js b/src/utils/tableObjectSpanMethod.js deleted file mode 100644 index 2dabd28..0000000 --- a/src/utils/tableObjectSpanMethod.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @Author: River_qiu - * @Date: 2021/11/18 - */ -// 表格单元格合并多列 -let [spanObj, pos] = [{}, {}] -//spanObj 存储每个key 对应的合并值 -//pos 存储的是 key合并值得索引 大概吧 -export const dataMethod = (data, isH, allColumns = []) => { - //循环数据(行) - for (let i in data) { - let dataI = data[i] - //循环数据内对象,查看有多少key - if (allColumns.length > 0) { - let preProp = undefined - // dataI.historyValue = - // 循环列数据 - for (let index = 0; index < allColumns.length; index++) { - let j = allColumns[index] - if (i == 0) { - // 第一行,每列至少展示1行 - spanObj[j] = [1] - pos[j] = 0 - } else { - if (index == 0) { - data[i].historyValue = '' - data[i - 1].historyValue = '' - } else { - data[i].historyValue += data[i][preProp] - data[i - 1].historyValue += data[i - 1][preProp] - } - // e: 当前行数据,k:上一行数据 - let [e, k] = [dataI, data[i - 1]] - // 判断上一行数据是否存在 - // 空数据不合并 - // 前一列值相同并且不为空或者为第一列 - // 存在当前的列的值与上一行是否一样 - // 判断是否有数组规定只允许那几列需要合并单元格的 - if ( - k && - e[j] && - (!preProp || (e.historyValue && e.historyValue == k.historyValue)) && - e[j] == k[j] && - (!isH || isH.length == 0 || isH.includes(j)) - ) { - //如果上一级和当前一级相当,数组就加1 数组后面就添加一个0 - spanObj[j][pos[j]] += 1 - spanObj[j].push(0) - } else { - spanObj[j].push(1) - pos[j] = i - } - preProp = j - } - } - } else { - for (let j in dataI) { - //如果只有一条数据时默认为1即可,无需合并 - if (i == 0) { - spanObj[j] = [1] - pos[j] = 0 - } else { - let [e, k] = [dataI, data[i - 1]] - //判断上一级别是否存在 , - //存在当前的key是否和上级别的key是否一样 - //判断是否有数组规定只允许那几列需要合并单元格的 - if (k && e[j] && k[j] && e[j] == k[j] && (!isH || isH.length == 0 || isH.includes(j))) { - //如果上一级和当前一级相当,数组就加1 数组后面就添加一个0 - spanObj[j][pos[j]] += 1 - spanObj[j].push(0) - } else { - spanObj[j].push(1) - pos[j] = i - } - } - } - } - } - return spanObj -} diff --git a/src/views/Home/Index.vue b/src/views/Home/Index.vue index 7beecf8..65b9205 100644 --- a/src/views/Home/Index.vue +++ b/src/views/Home/Index.vue @@ -1,7 +1,96 @@ + +const { t } = useI18n() +const userStore = useUserStore() +const router = useRouter() // 路由对象 +const loading = ref(false) +const avatar = userStore.getUser.avatar ? userStore.getUser.avatar : avatarImg +const username = userStore.getUser.nickname - +function getWaitTargetCount() { + getWaitCount({}).then((res) => { + waitCount.value = res + }) +} + +const waitCount = ref({ + dayEndAgentWorkNum: 0, + myAgentWorkNum: 0, + urgeAgentWorkNum: 0, + notifyNum: 0 +}) + +const getAllApi = async () => { + await getWaitTargetCount() + loading.value = false +} + +onMounted(() => { + getAllApi() +}) + + + diff --git a/src/views/OKR/Analysis/index.vue b/src/views/OKR/Analysis/index.vue index 3b8d285..037e300 100644 --- a/src/views/OKR/Analysis/index.vue +++ b/src/views/OKR/Analysis/index.vue @@ -1,6 +1,6 @@ - + diff --git a/src/views/OKR/Management/Components/DialogOkr.vue b/src/views/OKR/Management/Components/DialogOkr.vue index cabb65c..05a9d0a 100644 --- a/src/views/OKR/Management/Components/DialogOkr.vue +++ b/src/views/OKR/Management/Components/DialogOkr.vue @@ -143,7 +143,7 @@ - +
@@ -178,7 +178,7 @@
- 新增评论 + 新增笔谈