Merge branch 'ts' into dev
# Conflicts:
# package.json
# src/layout/components/TagsView/index.vue
| | |
| | | "unplugin-auto-import": "0.13.0", |
| | | "unplugin-icons": "0.15.1", |
| | | "unplugin-vue-components": "0.23.0", |
| | | "vite": "4.3.1", |
| | | "vite-plugin-compression": "0.5.1", |
| | | "vite-plugin-svg-icons": "2.0.1", |
| | | "vite-plugin-vue-setup-extend": "^0.4.0", |
| | | "vitest": "^0.29.7", |
| | | "vite": "4.3.1", |
| | | "vue-eslint-parser": "9.1.0", |
| | | "vue-tsc": "0.35.0" |
| | | } |
| | |
| | | // 查询OSS对象存储列表 |
| | | export function listOss(query: OssQuery): AxiosPromise<OssVO[]> { |
| | | return request({ |
| | | url: '/system/oss/list', |
| | | url: '/resource/oss/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | // 查询OSS对象基于id串 |
| | | export function listByIds(ossId: string | number): AxiosPromise<OssVO[]> { |
| | | return request({ |
| | | url: '/system/oss/listByIds/' + ossId, |
| | | url: '/resource/oss/listByIds/' + ossId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | |
| | | // 删除OSS对象存储 |
| | | export function delOss(ossId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/oss/' + ossId, |
| | | url: '/resource/oss/' + ossId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | // 查询对象存储配置列表 |
| | | export function listOssConfig(query: OssConfigQuery): AxiosPromise<OssConfigVO[]> { |
| | | return request({ |
| | | url: '/system/oss/config/list', |
| | | url: '/resource/oss/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | // 查询对象存储配置详细 |
| | | export function getOssConfig(ossConfigId: string | number): AxiosPromise<OssConfigVO> { |
| | | return request({ |
| | | url: '/system/oss/config/' + ossConfigId, |
| | | url: '/resource/oss/config/' + ossConfigId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | |
| | | // 新增对象存储配置 |
| | | export function addOssConfig(data: OssConfigForm) { |
| | | return request({ |
| | | url: '/system/oss/config', |
| | | url: '/resource/oss/config', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | |
| | | // 修改对象存储配置 |
| | | export function updateOssConfig(data: OssConfigForm) { |
| | | return request({ |
| | | url: '/system/oss/config', |
| | | url: '/resource/oss/config', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | |
| | | // 删除对象存储配置 |
| | | export function delOssConfig(ossConfigId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/oss/config/' + ossConfigId, |
| | | url: '/resource/oss/config/' + ossConfigId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | configKey |
| | | }; |
| | | return request({ |
| | | url: '/system/oss/config/changeStatus', |
| | | url: '/resource/oss/config/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | |
| | | #app { |
| | | .main-container { |
| | | min-height: 100%; |
| | | height: 100%; |
| | | transition: margin-left 0.28s; |
| | | margin-left: $base-sidebar-width; |
| | | position: relative; |
| | |
| | | <div> |
| | | <template v-for="(item, index) in options"> |
| | | <template v-if="values.includes(item.value)"> |
| | | <span |
| | | v-if="item.elTagType == 'default' || item.elTagType == ''" |
| | | :key="item.value" |
| | | :index="index" |
| | | :class="item.elTagClass" |
| | | >{{ item.label }}</span |
| | | > |
| | | <span v-if="item.elTagType == 'default' || item.elTagType == ''" :key="item.value" :index="index" :class="item.elTagClass"> |
| | | {{ item.label + " " }} |
| | | </span> |
| | | <el-tag |
| | | v-else |
| | | :disable-transitions="true" |
| | |
| | | :index="index" |
| | | :type="item.elTagType === 'primary' ? '' : item.elTagType" |
| | | :class="item.elTagClass" |
| | | >{{ item.label }}</el-tag |
| | | > |
| | | {{ item.label + " " }} |
| | | </el-tag> |
| | | </template> |
| | | </template> |
| | | <template v-if="unmatch && showValue"> |
| | | {{ unmatchArray }} |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { PropType } from 'vue'; |
| | | |
| | | |
| | | const props = defineProps({ |
| | | // 数据 |
| | |
| | | default: null, |
| | | }, |
| | | // 当前的值 |
| | | value: [Number, String, Array], |
| | | }) |
| | | value: [Number, String, Array] as PropType<number | string | Array<number | string>>, |
| | | // 当未找到匹配的数据时,显示value |
| | | showValue: { |
| | | type: Boolean as PropType<boolean>, |
| | | default: true, |
| | | }, |
| | | }); |
| | | |
| | | const values = computed(() => { |
| | | if (props.value !== null && typeof props.value !== 'undefined') { |
| | | if (props.value !== null && typeof props.value !== "undefined") { |
| | | return Array.isArray(props.value) ? props.value : [String(props.value)]; |
| | | } else { |
| | | return []; |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | const unmatch = computed(() => { |
| | | if (props.value !== null && typeof props.value !== "undefined") { |
| | | // 传入值为非数组 |
| | | if (!Array.isArray(props.value)) { |
| | | if (props.options.some((v) => v.value == props.value)) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | return true; |
| | | } |
| | | // 没有value不显示 |
| | | return false; |
| | | }); |
| | | |
| | | const unmatchArray = computed(() => { |
| | | // 记录未匹配的项 |
| | | const itemUnmatchArray: Array<string | number> = []; |
| | | if (props.value !== null && typeof props.value !== "undefined") { |
| | | // 传入值为非数组 |
| | | if (!Array.isArray(props.value)) { |
| | | itemUnmatchArray.push(props.value); |
| | | } else { |
| | | // 传入值为Array |
| | | props.value.forEach((item) => { |
| | | if (!props.options.some((v) => v.value == item)) { |
| | | itemUnmatchArray.push(item); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | // 没有value不显示 |
| | | return handleArray(itemUnmatchArray); |
| | | }); |
| | | |
| | | const handleArray = (array: Array<string | number>) => { |
| | | if (array.length === 0) return ""; |
| | | return array.reduce((pre, cur) => { |
| | | return pre + " " + cur; |
| | | }); |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | |
| | | const upload = reactive<UploadOption>({ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | url: import.meta.env.VITE_APP_BASE_API + '/system/oss/upload' |
| | | url: import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload' |
| | | }) |
| | | const myQuillEditor = ref(); |
| | | |
| | |
| | | const uploadList = ref<any[]>([]); |
| | | |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API; |
| | | const uploadFileUrl = ref(baseUrl + "/system/oss/upload"); // 上传文件服务器地址 |
| | | const uploadFileUrl = ref(baseUrl + "/resource/oss/upload"); // 上传文件服务器地址 |
| | | const headers = ref({ Authorization: "Bearer " + getToken() }); |
| | | |
| | | const fileList = ref<any[]>([]); |
| | |
| | | <div class="relative" :style="{ width: width }"> |
| | | <el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="点击选择图标"> |
| | | <template #prepend> |
| | | <svg-icon :icon-class="modelValue as string"></svg-icon> |
| | | <svg-icon :icon-class="modelValue as string" /> |
| | | </template> |
| | | </el-input> |
| | | |
| | |
| | | <el-scrollbar height="w-[200px]"> |
| | | <ul class="icon-list"> |
| | | <el-tooltip v-for="(iconName, index) in iconNames" :key="index" :content="iconName" placement="bottom" effect="light"> |
| | | <li class="icon-item" @click="selectedIcon(iconName)"> |
| | | <li :class="['icon-item', {active: modelValue == iconName}]" @click="selectedIcon(iconName)"> |
| | | <svg-icon color="var(--el-text-color-regular)" :icon-class="iconName" /> |
| | | </li> |
| | | </el-tooltip> |
| | |
| | | iconNames.value = icons; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 选择图标 |
| | | * @param iconName 选择的图标名称 |
| | |
| | | transform: scaleX(1.1); |
| | | } |
| | | } |
| | | .active { |
| | | border-color: var(--el-color-primary); |
| | | color: var(--el-color-primary); |
| | | } |
| | | } |
| | | </style> |
| | |
| | | const dialogVisible = ref(false); |
| | | |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API; |
| | | const uploadImgUrl = ref(baseUrl + "/system/oss/upload"); // 上传的图片服务器地址 |
| | | const uploadImgUrl = ref(baseUrl + "/resource/oss/upload"); // 上传的图片服务器地址 |
| | | const headers = ref({ Authorization: "Bearer " + getToken() }); |
| | | |
| | | const fileList = ref<any[]>([]); |
| | |
| | | visibleNumber.value = parseInt(String(width / 85)); |
| | | } |
| | | |
| | | const handleSelect = (key: string, keyPath: string[]) => { |
| | | const handleSelect = (key: string) => { |
| | | currentIndex.value = key; |
| | | const route = routers.value.find(item => item.path === key); |
| | | if (isHttp(key)) { |
| | |
| | | window.open(key, "_blank"); |
| | | } else if (!route || !route.children) { |
| | | // 没有子路由路径内部打开 |
| | | router.push({ path: key, fullPath: '' }); |
| | | const routeMenu = childrenMenus.value.find(item => item.path === key); |
| | | if (routeMenu && routeMenu.query) { |
| | | let query = JSON.parse(routeMenu.query); |
| | | router.push({ path: key, query: query }); |
| | | } else { |
| | | router.push({ path: key }); |
| | | } |
| | | appStore.toggleSideBarHide(true); |
| | | } else { |
| | | // 显示左侧联动菜单 |
| | |
| | | } |
| | | } |
| | | </style> |
| | | <style lang="scss"> |
| | | // fix css style bug in open el-dialog |
| | | .el-popup-parent--hidden { |
| | | .fixed-header { |
| | | padding-right: 6px; |
| | | } |
| | | } |
| | | |
| | | ::-webkit-scrollbar { |
| | | width: 6px; |
| | | height: 6px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-track { |
| | | background-color: #f1f1f1; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb { |
| | | background-color: #c0c0c0; |
| | | border-radius: 3px; |
| | | } |
| | | </style> |
| | |
| | | bottom: 0px; |
| | | } |
| | | :deep(.el-scrollbar__wrap) { |
| | | height: 49px; |
| | | height: 39px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | position: relative; |
| | | cursor: pointer; |
| | | height: 26px; |
| | | line-height: 26px; |
| | | line-height: 23px; |
| | | background-color: var(--el-bg-color); |
| | | border: 1px solid var(--el-border-color-light); |
| | | color: #495060; |
| | | padding: 0 8px; |
| | | font-size: 12px; |
| | | margin-left: 5px; |
| | |
| | | <template> |
| | | <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> |
| | | <el-scrollbar> |
| | | <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> |
| | | <side-bar v-if="!sidebar.hide" class="sidebar-container" /> |
| | | <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> |
| | | <!-- <el-scrollbar> |
| | | <div :class="{ 'fixed-header': fixedHeader }"> |
| | | <navbar ref="navbarRef" @setLayout="setLayout" /> |
| | | <tags-view v-if="needTagsView" /> |
| | | </div> |
| | | <app-main /> |
| | | <settings ref="settingRef" /> |
| | | </el-scrollbar> --> |
| | | <div :class="{ 'fixed-header': fixedHeader }"> |
| | | <navbar ref="navbarRef" @setLayout="setLayout" /> |
| | | <tags-view v-if="needTagsView" /> |
| | |
| | | <app-main /> |
| | | <settings ref="settingRef" /> |
| | | </div> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | position: relative; |
| | | height: 100%; |
| | | width: 100%; |
| | | |
| | | .el-scrollbar { |
| | | height: 100%; |
| | | } |
| | | |
| | | :deep(.el-scrollbar__bar).is-vertical { |
| | | z-index: 10; |
| | | } |
| | | |
| | | :deep(.el-scrollbar__wrap) { |
| | | overflow-x: hidden; |
| | | } |
| | | |
| | | &.mobile.openSidebar { |
| | | position: fixed; |
| | |
| | | let downloadLoadingInstance: LoadingInstance; |
| | | export default { |
| | | async oss(ossId: string | number) { |
| | | const url = baseURL + '/system/oss/download/' + ossId; |
| | | const url = baseURL + '/resource/oss/download/' + ossId; |
| | | downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }); |
| | | try { |
| | | const res = await axios({ |
| | |
| | | path: '/system/oss-config', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['monitor:job:list'], |
| | | permissions: ['system:oss:list'], |
| | | children: [ |
| | | { |
| | | path: 'index', |
| | |
| | | title: string; |
| | | icon: string; |
| | | }; |
| | | query?: string; |
| | | } & RouteRecordRaw; |
| | | |
| | | interface _RouteLocationBase { |
| | |
| | | nextTick(() => { |
| | | reset(); |
| | | if (row && row.deptId) { |
| | | form.value.parentId = row?.parentId; |
| | | form.value.parentId = row?.deptId; |
| | | } |
| | | }) |
| | | } |
| | |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="handleQuery" |
| | | @pagination="getList" |
| | | /> |
| | | <select-user ref="selectRef" :roleId="queryParams.roleId" @ok="handleQuery" /> |
| | | </el-card> |
| | |
| | | v-model:total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="handleQuery" |
| | | @pagination="getList" |
| | | /> |
| | | </el-card> |
| | | |
| | |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="handleQuery" |
| | | @pagination="getList" |
| | | /> |
| | | </el-card> |
| | | </el-col> |
| | |
| | | if (tableId) { |
| | | // 获取表详细信息 |
| | | const res = await getGenTable(tableId); |
| | | res.data.info.parentMenuId = Number(res.data.info.parentMenuId); |
| | | columns.value = res.data.rows; |
| | | info.value = res.data.info; |
| | | tables.value = res.data.tables; |
| | |
| | | import { ComponentInternalInstance, PropType } from 'vue'; |
| | | |
| | | interface MenuOptionsType { |
| | | menuId: number; |
| | | menuId: number | string; |
| | | menuName: string; |
| | | children: MenuOptionsType[] | undefined; |
| | | } |
| | |
| | | /** 查询菜单下拉树结构 */ |
| | | const getMenuTreeselect = async () => { |
| | | const res = await listMenu(); |
| | | res.data.forEach(m => m.menuId = m.menuId.toString()); |
| | | const data = proxy?.handleTree<MenuOptionsType>(res.data, "menuId"); |
| | | if (data) { |
| | | menuOptions.value = data |