Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # components.d.ts
This commit is contained in:
commit
3cfee37765
|
@ -11,7 +11,6 @@ node_modules
|
|||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
yarn.lock
|
||||
components.d.ts
|
||||
|
||||
# Editor directories and files
|
||||
|
|
|
@ -7,22 +7,27 @@ export {}
|
|||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
||||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
AEmpty: typeof import('ant-design-vue/es')['Empty']
|
||||
AForm: typeof import('ant-design-vue/es')['Form']
|
||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||
AInput: typeof import('ant-design-vue/es')['Input']
|
||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||
ATable: typeof import('ant-design-vue/es')['Table']
|
||||
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
|
||||
|
@ -35,6 +40,7 @@ declare module '@vue/runtime-core' {
|
|||
PermissionButton: typeof import('./src/components/PermissionButton/index.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
Table: typeof import('./src/components/Table/index.vue')['default']
|
||||
TitleComponent: typeof import('./src/components/TitleComponent/index.vue')['default']
|
||||
ValueItem: typeof import('./src/components/ValueItem/index.vue')['default']
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 469 B |
|
@ -0,0 +1,3 @@
|
|||
import server from '@/utils/request'
|
||||
|
||||
export const deleteMetadata = (deviceId: string) => server.remove(`/device-instance/${deviceId}/metadata`)
|
|
@ -0,0 +1,8 @@
|
|||
import server from '@/utils/request';
|
||||
|
||||
// 设备数量
|
||||
export const getDeviceCount_api = () => server.get(`/device/instance/_count`);
|
||||
// 产品数量
|
||||
export const getProductCount_api = (data) => server.post(`/device-product/_count`, data);
|
||||
// 查询产品列表
|
||||
export const getProductList_api = (data) => server.get(`/device/product/_query/no-paging?paging=false`, data);
|
|
@ -0,0 +1,3 @@
|
|||
import server from '@/utils/request'
|
||||
|
||||
export const save = (data) => server.post(`/network/certificate`, data)
|
|
@ -0,0 +1,6 @@
|
|||
import server from '@/utils/request';
|
||||
|
||||
// 获取tree数据-第一层
|
||||
export const getTreeOne_api = () => server.get(`/v3/api-docs/swagger-config`);
|
||||
// 获取tree数据-第二层
|
||||
export const getTreeTwo_api = (name:string) => server.get(`/v3/api-docs/${name}`);
|
|
@ -60,7 +60,7 @@
|
|||
</div>
|
||||
|
||||
<!-- 按钮 -->
|
||||
<slot name="botton-tool">
|
||||
<slot name="bottom-tool">
|
||||
<div v-if="showTool" class="card-tools">
|
||||
<div
|
||||
v-for="item in actions"
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<div class="jtable-body">
|
||||
<div class="jtable-body-header">
|
||||
<div class="jtable-body-header-left">
|
||||
<slot name="headerTitle"></slot>
|
||||
</div>
|
||||
<div class="jtable-body-header-right" v-if="!model">
|
||||
<div class="jtable-setting-item" :class="[ModelEnum.CARD === _model ? 'active' : '']" @click="modelChange(ModelEnum.CARD)">
|
||||
<AppstoreOutlined />
|
||||
</div>
|
||||
<div class="jtable-setting-item" :class="[ModelEnum.TABLE === _model ? 'active' : '']" @click="modelChange(ModelEnum.TABLE)">
|
||||
<UnorderedListOutlined />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jtable-content">
|
||||
<!-- <div class="jtable-alert">
|
||||
<a-alert message="Info Text" type="info" />
|
||||
</div> -->
|
||||
<div v-if="_model === ModelEnum.CARD" class="jtable-card">
|
||||
<div
|
||||
v-if="_dataSource.length"
|
||||
class="jtable-card-items"
|
||||
:style="{gridTemplateColumns: `repeat(${column}, 1fr)`}"
|
||||
>
|
||||
<div
|
||||
class="jtable-card-item"
|
||||
v-for="(item, index) in _dataSource"
|
||||
:key="index"
|
||||
>
|
||||
<CardBox :actions="actions" v-bind="cardProps">
|
||||
<template #img>
|
||||
<slot name="img">
|
||||
<img :src="getImage('/device-product.png')" />
|
||||
</slot>
|
||||
</template>
|
||||
<template #content>
|
||||
<slot name="cardContent" :item="item" :index="index"></slot>
|
||||
</template>
|
||||
</CardBox>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-empty :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-table :rowSelection="rowSelection" :columns="[..._columns]" :dataSource="_dataSource" :pagination="false" :scroll="{ x: 1366 }">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-tooltip v-for="i in actions" :key="i.key" v-bind="i.tooltip">
|
||||
<a-popconfirm v-if="i.popConfirm" v-bind="i.popConfirm">
|
||||
<a>
|
||||
{{i.text}}
|
||||
</a>
|
||||
</a-popconfirm>
|
||||
<a v-else @click="i.onClick && i.onClick(record)">
|
||||
{{i.text}}
|
||||
</a>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
<template v-else-if="column.scopedSlots">
|
||||
<slot :name="column.key" :row="record"></slot>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jtable-pagination" v-if="_dataSource.length && !noPagination">
|
||||
<a-pagination
|
||||
size="small"
|
||||
:total="total"
|
||||
:showQuickJumper="false"
|
||||
:showSizeChanger="true"
|
||||
v-model:current="pageIndex"
|
||||
v-model:page-size="pageSize"
|
||||
:show-total="(total, range) => `第 ${range[0]} - ${range[1]} 条/总共 ${total} 条`"
|
||||
@change="pageChange"
|
||||
:page-size-options="[12, 24, 48, 60, 100]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UnorderedListOutlined, AppstoreOutlined } from '@ant-design/icons-vue'
|
||||
import type { TableProps } from 'ant-design-vue/es/table'
|
||||
import type { TooltipProps } from 'ant-design-vue/es/tooltip'
|
||||
import type { PopconfirmProps } from 'ant-design-vue/es/popconfirm'
|
||||
import { Empty } from 'ant-design-vue'
|
||||
import { CSSProperties } from 'vue';
|
||||
import { getImage } from '@/utils/comm';
|
||||
|
||||
enum ModelEnum {
|
||||
TABLE = 'TABLE',
|
||||
CARD = 'CARD',
|
||||
}
|
||||
|
||||
type RequestData = {
|
||||
code: string;
|
||||
result: {
|
||||
data: Record<string, any>[] | undefined;
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
};
|
||||
status: number;
|
||||
} & Record<string, any>;
|
||||
|
||||
export interface ActionsType {
|
||||
key: string;
|
||||
text?: string;
|
||||
disabled?: boolean;
|
||||
permission?: boolean;
|
||||
onClick?: (data: any) => void;
|
||||
style?: CSSProperties;
|
||||
tooltip?: TooltipProps;
|
||||
popConfirm?: PopconfirmProps;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
interface JTableProps extends TableProps{
|
||||
request?: (params: Record<string, any> & {
|
||||
pageSize: number;
|
||||
pageIndex: number;
|
||||
}) => Promise<Partial<RequestData>>;
|
||||
cardBodyClass?: string;
|
||||
columns: Record<string, any>[];
|
||||
params?: Record<string, any> & {
|
||||
pageSize: number;
|
||||
pageIndex: number;
|
||||
};
|
||||
model?: keyof typeof ModelEnum | undefined; // 显示table还是card
|
||||
actions?: ActionsType[];
|
||||
noPagination?: boolean;
|
||||
rowSelection?: TableProps['rowSelection'];
|
||||
cardProps?: Record<string, any>;
|
||||
dataSource?: Record<string, any>[];
|
||||
}
|
||||
// props
|
||||
const props = withDefaults(defineProps<JTableProps>(), {
|
||||
cardBodyClass: '',
|
||||
request: undefined,
|
||||
})
|
||||
|
||||
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
|
||||
|
||||
const _model = ref<keyof typeof ModelEnum>(props.model ? props.model : ModelEnum.CARD); // 模式切换
|
||||
const column = ref<number>(4);
|
||||
const _dataSource = ref<Record<string, any>[]>([])
|
||||
const pageIndex = ref<number>(0)
|
||||
const pageSize = ref<number>(6)
|
||||
const total = ref<number>(0)
|
||||
const _columns = ref<Record<string, any>[]>([])
|
||||
const loading = ref<boolean>(true)
|
||||
//
|
||||
// const slotColumns = computed(() => props.columns.filter((item) => item.scopedSlots))
|
||||
// 方法
|
||||
// 切换卡片和表格
|
||||
const modelChange = (type: keyof typeof ModelEnum) => {
|
||||
_model.value = type
|
||||
}
|
||||
// 请求数据
|
||||
const handleSearch = async (_params?: Record<string, any>) => {
|
||||
loading.value = true
|
||||
if(props.request) {
|
||||
const resp = await props.request({
|
||||
pageSize: 12,
|
||||
pageIndex: 1,
|
||||
..._params
|
||||
})
|
||||
if(resp.status === 200){
|
||||
// 判断如果是最后一页且最后一页为空,就跳转到前一页
|
||||
if(resp.result?.data?.length === 0 && resp.result.total && resp.result.pageSize && resp.result.pageIndex) {
|
||||
handleSearch({
|
||||
..._params,
|
||||
pageSize: pageSize.value,
|
||||
pageIndex: pageIndex.value - 1,
|
||||
})
|
||||
} else {
|
||||
_dataSource.value = resp.result?.data || []
|
||||
pageIndex.value = resp.result?.pageIndex || 0
|
||||
pageSize.value = resp.result?.pageSize || 6
|
||||
total.value = resp.result?.total || 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_dataSource.value = props?.dataSource || []
|
||||
}
|
||||
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const pageChange = (page: number, size: number) => {
|
||||
handleSearch({
|
||||
...props.params,
|
||||
pageSize: size,
|
||||
pageIndex: pageSize.value === size ? page : 1,
|
||||
})
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if(Array.isArray(props.actions) && props.actions.length) {
|
||||
_columns.value = [...props.columns,
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 250
|
||||
}
|
||||
]
|
||||
} else {
|
||||
_columns.value = [...props.columns]
|
||||
}
|
||||
handleSearch(props.params)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.jtable-body {
|
||||
width: 100%;
|
||||
padding: 0 24px 24px;
|
||||
background-color: white;
|
||||
.jtable-body-header {
|
||||
padding: 16px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.jtable-body-header-right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
.jtable-setting-item {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color-hover;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: @primary-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.jtable-content {
|
||||
.jtable-card {
|
||||
.jtable-card-items {
|
||||
display: grid;
|
||||
grid-gap: 26px;
|
||||
// grid-template-columns: repeat(4, 1fr);
|
||||
.jtable-card-item {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.jtable-pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
/deep/ .ant-pagination-item {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,8 @@
|
|||
import { UnorderedListOutlined, AppstoreOutlined } from '@ant-design/icons-vue'
|
||||
import styles from './index.module.less'
|
||||
import { Space, Pagination, Table, Empty } from 'ant-design-vue'
|
||||
import { Pagination, Table, Empty } from 'ant-design-vue'
|
||||
import type { TableProps } from 'ant-design-vue/es/table'
|
||||
|
||||
enum ModelEnum {
|
||||
TABLE = 'TABLE',
|
||||
CARD = 'CARD',
|
||||
|
@ -17,18 +18,15 @@ export declare type RequestData = {
|
|||
};
|
||||
status: number;
|
||||
} & Record<string, any>;
|
||||
// interface ColumnType extends
|
||||
|
||||
interface JTableProps extends TableProps{
|
||||
// columns?: ColumnsType<RecordType>;
|
||||
request: (params: Record<string, any> & {
|
||||
pageSize?: number;
|
||||
pageIndex?: number;
|
||||
pageSize: number;
|
||||
pageIndex: number;
|
||||
}) => Promise<Partial<RequestData>>;
|
||||
cardBodyClass?: string;
|
||||
cardBodyClass: string;
|
||||
}
|
||||
|
||||
|
||||
const JTable = defineComponent<JTableProps>({
|
||||
name: 'JTable',
|
||||
slots: [
|
||||
|
@ -38,10 +36,15 @@ const JTable = defineComponent<JTableProps>({
|
|||
emits: [
|
||||
'modelChange', // 切换卡片和表格
|
||||
],
|
||||
setup(props: JTableProps, { slots, emit }){
|
||||
props: {
|
||||
cardBodyClass: '',
|
||||
request: undefined,
|
||||
columns: []
|
||||
} as any,
|
||||
setup(props ,{ slots, emit }){
|
||||
const model = ref<keyof typeof ModelEnum>(ModelEnum.CARD); // 模式切换
|
||||
const column = ref<number>(3);
|
||||
console.log(props)
|
||||
console.log(props.columns, props.request)
|
||||
const dataSource = ref<any[]>([
|
||||
{
|
||||
key: '1',
|
||||
|
@ -81,6 +84,8 @@ const JTable = defineComponent<JTableProps>({
|
|||
},
|
||||
])
|
||||
|
||||
// 请求数据
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
|
@ -1,9 +1,10 @@
|
|||
import type { App } from 'vue'
|
||||
import AIcon from './AIcon'
|
||||
import PermissionButton from './PermissionButton/index.vue'
|
||||
import JTable from './Table/index'
|
||||
import JTable from './Table/index.vue'
|
||||
import TitleComponent from "./TitleComponent/index.vue";
|
||||
import Form from './Form'
|
||||
import Form from './Form';
|
||||
import CardBox from './CardBox/index.vue';
|
||||
|
||||
export default {
|
||||
install(app: App) {
|
||||
|
@ -12,5 +13,6 @@ export default {
|
|||
.component('JTable', JTable)
|
||||
.component('TitleComponent', TitleComponent)
|
||||
.component('Form', Form)
|
||||
.component('CardBox', CardBox)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ const router = createRouter({
|
|||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const token = LocalStore.get(TOKEN_KEY)
|
||||
next() // 测试用, 可删除
|
||||
if (token) {
|
||||
next()
|
||||
} else {
|
||||
|
|
|
@ -29,16 +29,16 @@ export default [
|
|||
component: () => import('@/views/demo/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/bind',
|
||||
path: '/account/center/bind',
|
||||
component: () => import('@/views/account/Center/bind/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/iot/home',
|
||||
component: () => import('@/views/iot/home/index.vue')
|
||||
component: () => import('@/views/home/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/table',
|
||||
component: () => import('@/views/table/index.vue')
|
||||
component: () => import('@/views/demo/table/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/form',
|
||||
|
|
|
@ -1,240 +0,0 @@
|
|||
/** 路由Code */
|
||||
export enum MENUS_CODE {
|
||||
'home' = 'home',
|
||||
'Analysis/CPU' = 'Analysis/CPU',
|
||||
'Analysis/DeviceChart' = 'Analysis/DeviceChart',
|
||||
'Analysis/DeviceMessage' = 'Analysis/DeviceMessage',
|
||||
'Analysis/Jvm' = 'Analysis/Jvm',
|
||||
'Analysis/MessageChart' = 'Analysis/MessageChart',
|
||||
'Analysis' = 'Analysis',
|
||||
'cloud/Aliyun' = 'cloud/Aliyun',
|
||||
'cloud/Ctwing' = 'cloud/Ctwing',
|
||||
'cloud/DuerOS' = 'cloud/DuerOS',
|
||||
'cloud/Onenet' = 'cloud/Onenet',
|
||||
'device/Alarm' = 'device/Alarm',
|
||||
'device/Category/Save' = 'device/Category/Save',
|
||||
'device/Category' = 'device/Category',
|
||||
'device/Command' = 'device/Command',
|
||||
'device/DataSource' = 'device/DataSource',
|
||||
'device/Instance' = 'device/Instance',
|
||||
'device/Location' = 'device/Location',
|
||||
'device/Product/Save' = 'device/Product/Save',
|
||||
'device/Product' = 'device/Product',
|
||||
'device/DashBoard' = 'device/DashBoard',
|
||||
'device/components/Alarm/Edit' = 'device/components/Alarm/Edit',
|
||||
'device/components/Alarm/Record' = 'device/components/Alarm/Record',
|
||||
'device/components/Alarm/Setting' = 'device/components/Alarm/Setting',
|
||||
'device/components/Alarm' = 'device/components/Alarm',
|
||||
'device/components/Metadata/Base/Edit' = 'device/components/Metadata/Base/Edit',
|
||||
'device/components/Metadata/Base' = 'device/components/Metadata/Base',
|
||||
'device/components/Metadata/Cat' = 'device/components/Metadata/Cat',
|
||||
'device/components/Metadata/Import' = 'device/components/Metadata/Import',
|
||||
'device/components/Metadata' = 'device/components/Metadata',
|
||||
'link/Certificate' = 'link/Certificate',
|
||||
'link/Certificate/Detail' = 'link/Certificate/Detail',
|
||||
'link/Gateway' = 'link/Gateway',
|
||||
'link/Protocol/Debug' = 'link/Protocol/Debug',
|
||||
'link/Protocol' = 'link/Protocol',
|
||||
'link/Type' = 'link/Type',
|
||||
'link/AccessConfig' = 'link/AccessConfig',
|
||||
'link/DataCollect/Dashboard' = 'link/DataCollect/Dashboard',
|
||||
'link/DataCollect/DataGathering' = 'link/DataCollect/DataGathering',
|
||||
'link/DataCollect/IntegratedQuery' = 'link/DataCollect/IntegratedQuery',
|
||||
'edge/Device' = 'edge/Device',
|
||||
'edge/Resource' = 'edge/Resource',
|
||||
'Log' = 'Log',
|
||||
'media/Cascade' = 'media/Cascade',
|
||||
'media/Cascade/Save' = 'media/Cascade/Save',
|
||||
'media/Cascade/Channel' = 'media/Cascade/Channel',
|
||||
'media/Config' = 'media/Config',
|
||||
'media/Device' = 'media/Device',
|
||||
'media/Device/Save' = 'media/Device/Save',
|
||||
'media/Device/Channel' = 'media/Device/Channel',
|
||||
'media/Device/Playback' = 'media/Device/Playback',
|
||||
'media/Reveal' = 'media/Reveal',
|
||||
'media/Stream' = 'media/Stream',
|
||||
'media/Stream/Detail' = 'media/Stream/Detail',
|
||||
'media/DashBoard' = 'media/DashBoard',
|
||||
'notice/Type' = 'notice/Type',
|
||||
'notice/Config' = 'notice/Config',
|
||||
'media/SplitScreen' = 'media/SplitScreen',
|
||||
'notice/Type/Config' = 'notice/Config',
|
||||
'notice/Config/Detail' = 'notice/Config/Detail',
|
||||
'notice/Template' = 'notice/Template',
|
||||
'notice/Template/Detail' = 'notice/Template/Detail',
|
||||
'rule-engine/DashBoard' = 'rule-engine/DashBoard',
|
||||
'rule-engine/Instance' = 'rule-engine/Instance',
|
||||
'rule-engine/SQLRule' = 'rule-engine/SQLRule',
|
||||
'rule-engine/Scene' = 'rule-engine/Scene',
|
||||
'rule-engine/Alarm/Log' = 'rule-engine/Alarm/Log',
|
||||
'rule-engine/Alarm/Log/Detail' = 'rule-engine/Alarm/Log/Detail',
|
||||
'rule-engine/Alarm/Config' = 'rule-engine/Alarm/Config',
|
||||
'rule-engine/Scene/Save' = 'rule-engine/Scene/Save',
|
||||
'rule-engine/Scene/Save2' = 'rule-engine/Scene/Save2',
|
||||
'rule-engine/Alarm/Configuration' = 'rule-engine/Alarm/Configuration',
|
||||
'rule-engine/Alarm/Configuration/Save' = 'rule-engine/Alarm/Configuration/Save',
|
||||
'simulator/Device' = 'simulator/Device',
|
||||
'system/DataSource' = 'system/DataSource',
|
||||
'system/DataSource/Management' = 'system/DataSource/Management',
|
||||
'system/Department/Assets' = 'system/Department/Assets',
|
||||
'system/Department/Member' = 'system/Department/Member',
|
||||
'system/Department' = 'system/Department',
|
||||
'system/Menu' = 'system/Menu',
|
||||
'system/Menu/Setting' = 'system/Menu/Setting',
|
||||
'system/OpenAPI' = 'system/OpenAPI',
|
||||
'system/Permission' = 'system/Permission',
|
||||
'system/Role/Detail' = 'system/Role/Detail',
|
||||
'system/Role' = 'system/Role',
|
||||
'system/Tenant/Detail/Assets' = 'system/Tenant/Detail/Assets',
|
||||
'system/Tenant/Detail/Info' = 'system/Tenant/Detail/Info',
|
||||
'system/Tenant/Detail/Member' = 'system/Tenant/Detail/Member',
|
||||
'system/Tenant/Detail/Permission' = 'system/Tenant/Detail/Permission',
|
||||
'system/Tenant/Detail' = 'system/Tenant/Detail',
|
||||
'system/Tenant' = 'system/Tenant',
|
||||
'system/User' = 'system/User',
|
||||
'system/Relationship' = 'system/Relationship',
|
||||
'system/Basis' = 'system/Basis',
|
||||
'user/Login' = 'user/Login',
|
||||
'visualization/Category' = 'visualization/Category',
|
||||
'visualization/Configuration' = 'visualization/Configuration',
|
||||
'visualization/Screen' = 'visualization/Screen',
|
||||
'device/Firmware' = 'device/Firmware',
|
||||
'device/Firmware/Task' = 'device/Firmware/Task',
|
||||
'device/Firmware/Task/Detail' = 'device/Firmware/Task/Detail',
|
||||
'device/Instance/Detail/Config/Tags' = 'device/Instance/Detail/Config/Tags',
|
||||
'device/Instance/Detail/Config' = 'device/Instance/Detail/Config',
|
||||
'device/Instance/Detail/Functions' = 'device/Instance/Detail/Functions',
|
||||
'device/Instance/Detail/Info' = 'device/Instance/Detail/Info',
|
||||
'device/Instance/Detail/Log' = 'device/Instance/Detail/Log',
|
||||
'device/Instance/Detail/MetadataLog/Event' = 'device/Instance/Detail/MetadataLog/Event',
|
||||
'device/Instance/Detail/MetadataLog/Property' = 'device/Instance/Detail/MetadataLog/Property',
|
||||
'device/Instance/Detail/Running' = 'device/Instance/Detail/Running',
|
||||
'device/Instance/Detail' = 'device/Instance/Detail',
|
||||
'device/Product/Detail/BaseInfo' = 'device/Product/Detail/BaseInfo',
|
||||
'device/Product/Detail' = 'device/Product/Detail',
|
||||
'link/AccessConfig/Detail' = 'link/AccessConfig/Detail',
|
||||
'link/DashBoard' = 'link/DashBoard',
|
||||
'system/Menu/Detail' = 'system/Menu/Detail',
|
||||
'system/Department/Detail' = 'system/Department/Detail',
|
||||
'link/Type/Detail' = 'link/Type/Detail',
|
||||
'account/Center' = 'account/Center',
|
||||
'account/NotificationSubscription' = 'account/NotificationSubscription',
|
||||
'account/NotificationRecord' = 'account/NotificationRecord',
|
||||
'account/Center/bind' = 'account/Center/bind',
|
||||
'Northbound/DuerOS' = 'Northbound/DuerOS',
|
||||
'Northbound/DuerOS/Detail' = 'Northbound/DuerOS/Detail',
|
||||
'Northbound/AliCloud' = 'Northbound/AliCloud',
|
||||
'Northbound/AliCloud/Detail' = 'Northbound/AliCloud/Detail',
|
||||
'system/Platforms' = 'system/Platforms',
|
||||
'system/Platforms/Api' = 'system/Platforms/Api',
|
||||
'system/Platforms/View' = 'system/Platforms/View',
|
||||
'system/Platforms/Setting' = 'system/Platforms/Setting',
|
||||
'system/Apply' = 'system/Apply',
|
||||
'system/Apply/Api' = 'system/Apply/Api',
|
||||
'system/Apply/View' = 'system/Apply/View',
|
||||
'system/License' = 'system/License',
|
||||
'iot-card/Home' = 'iot-card/Home',
|
||||
'iot-card/Platform' = 'iot-card/Platform',
|
||||
'iot-card/Platform/Detail' = 'iot-card/Platform/Detail',
|
||||
'iot-card/Recharge' = 'iot-card/Recharge',
|
||||
'iot-card/Dashboard' = 'iot-card/Dashboard',
|
||||
'iot-card/CardManagement' = 'iot-card/CardManagement',
|
||||
'iot-card/Record' = 'iot-card/Record',
|
||||
}
|
||||
|
||||
export type MENUS_CODE_TYPE = keyof typeof MENUS_CODE | string;
|
||||
|
||||
export enum BUTTON_PERMISSION_ENUM {
|
||||
'add' = 'add',
|
||||
'delete' = 'delete',
|
||||
'import' = 'import',
|
||||
'view' = 'view',
|
||||
'export' = 'export',
|
||||
'update' = 'update',
|
||||
'action' = 'action',
|
||||
'push' = 'push',
|
||||
'assert' = 'assert',
|
||||
'bind-user' = 'bind-user',
|
||||
'active' = 'active',
|
||||
'sync' = 'sync',
|
||||
'channel' = 'channel',
|
||||
'debug' = 'debug',
|
||||
'log' = 'log',
|
||||
'tigger' = 'tigger',
|
||||
'empowerment' = 'empowerment',
|
||||
'bind' = 'bind',
|
||||
'edit' = 'edit', //资产权限编辑
|
||||
'setting' = 'setting', //菜单配置
|
||||
'password' = 'password', //重置密码
|
||||
'api' = 'api', //查看api
|
||||
'manage' = 'manage', //数据源-管理
|
||||
'stop' = 'stop',
|
||||
'restart' = 'restart',
|
||||
'pay' = 'pay', //充值
|
||||
}
|
||||
|
||||
// 调试按钮、通知记录、批量导出、批量导入、选择通道、推送、分配资产、绑定用户对应的ID是啥
|
||||
export type CUSTOM_BUTTON = 'debug' | 'log' | 'channel' | 'assert' | 'bind-user';
|
||||
|
||||
export type BUTTON_PERMISSION = keyof typeof BUTTON_PERMISSION_ENUM | string | CUSTOM_BUTTON;
|
||||
|
||||
export const getDetailNameByCode = {
|
||||
'system/Menu/Detail': '菜单详情',
|
||||
'device/Product/Detail': '产品详情',
|
||||
'device/Instance/Detail': '设备详情',
|
||||
'device/Firmware/Task/Detail': '详情',
|
||||
'system/Department/Detail': '组织详情',
|
||||
'system/Role/Detail': '权限配置',
|
||||
'link/Type/Detail': '网络组件详情',
|
||||
'link/AccessConfig/Detail': '配置详情',
|
||||
'media/Stream/Detail': '流媒体详情',
|
||||
'rule-engine/Alarm/Log/Detail': '告警日志',
|
||||
'Northbound/AliCloud/Detail': '阿里云详情',
|
||||
'link/Certificate/Detail': '证书详情',
|
||||
'iot-card/Platform/Detail': '平台对接详情',
|
||||
};
|
||||
|
||||
// 开源版路由
|
||||
export const CommunityCodeList = [
|
||||
'account/Center',
|
||||
'account/NotificationSubscription',
|
||||
'account/NotificationRecord',
|
||||
'system/Basis',
|
||||
'system/User',
|
||||
'system/Department',
|
||||
'system/Department/Detail',
|
||||
'system/Role',
|
||||
'system/Role/Detail',
|
||||
'system/Menu',
|
||||
'system/Menu/Detail',
|
||||
'system/Menu/Setting',
|
||||
'system/Permission',
|
||||
'system/Relationship',
|
||||
'home',
|
||||
'rule-engine/DashBoard',
|
||||
'rule-engine/Alarm/Configuration',
|
||||
'rule-engine/Alarm/Configuration/Save',
|
||||
'rule-engine/Alarm/Log',
|
||||
'rule-engine/Alarm/Log/Detail',
|
||||
'device/DashBoard',
|
||||
'device/Category',
|
||||
'device/Instance',
|
||||
'device/Instance/Detail',
|
||||
'device/Product',
|
||||
'device/Product/Detail',
|
||||
'link/AccessConfig',
|
||||
'link/AccessConfig/Detail',
|
||||
'link/Protocol',
|
||||
'link/DashBoard',
|
||||
'Log',
|
||||
'link/Type',
|
||||
'link/Type/Detail',
|
||||
'link/Certificate',
|
||||
'link/Certificate/Detail',
|
||||
'rule-engine/Scene',
|
||||
'rule-engine/Scene/Save',
|
||||
'notice/Config',
|
||||
'notice/Config/Detail',
|
||||
'notice/Template',
|
||||
'notice/Template/Detail',
|
||||
];
|
|
@ -1,10 +1,9 @@
|
|||
import { defineStore } from "pinia";
|
||||
import type { MENUS_CODE_TYPE, BUTTON_PERMISSION } from '@/router/router'
|
||||
|
||||
export const usePermissionStore = defineStore({
|
||||
id: 'permission',
|
||||
state: () => ({
|
||||
permissions: {} as {[key: MENUS_CODE_TYPE]: BUTTON_PERMISSION},
|
||||
permissions: {} as {[key: string]: string},
|
||||
}),
|
||||
getters: {
|
||||
check(state) {
|
||||
|
|
|
@ -2,4 +2,6 @@ export const BASE_API_PATH = import.meta.env.VITE_APP_BASE_API
|
|||
|
||||
export const TOKEN_KEY = 'X-Access-Token'
|
||||
|
||||
export const Version_Code = 'version_code'
|
||||
export const Version_Code = 'version_code'
|
||||
|
||||
export const NETWORK_CERTIFICATE_UPLOAD = '/network/certificate/upload'
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<JTable
|
||||
:columns="[
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
scopedSlots: true
|
||||
},
|
||||
{
|
||||
title: '分类',
|
||||
dataIndex: 'classifiedName',
|
||||
key: 'classifiedName',
|
||||
},
|
||||
]"
|
||||
:actions="actions"
|
||||
:request="request"
|
||||
:rowSelection="rowSelection"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<a-button type="primary">新增</a-button>
|
||||
</template>
|
||||
<template #cardContent="slotProps">
|
||||
<h3>{{slotProps.item.name}}</h3>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
设备类型
|
||||
</div>
|
||||
<div>直连设备</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
产品名称
|
||||
</div>
|
||||
<div>测试固定地址</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<template #id="slotProps">
|
||||
<a>{{slotProps.row.id}}</a>
|
||||
</template>
|
||||
</JTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import server from "@/utils/request";
|
||||
import type { ActionsType } from '@/components/Table/index.vue'
|
||||
import { getImage } from '@/utils/comm';
|
||||
import type { TableProps, TableColumnType } from 'ant-design-vue';
|
||||
|
||||
const request = (data: any) => server.post(`/device-product/_query`, data)
|
||||
const actions: ActionsType[] = [
|
||||
{
|
||||
key: 'edit',
|
||||
// disabled: true,
|
||||
text: "编辑",
|
||||
tooltip: {
|
||||
title: '编辑'
|
||||
},
|
||||
// component: <UnorderedListOutlined />
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
disabled: true,
|
||||
text: "删除",
|
||||
tooltip: {
|
||||
title: '删除'
|
||||
},
|
||||
popConfirm: {
|
||||
title: '确认删除?'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const rowSelection: TableProps['rowSelection'] = {
|
||||
onChange: (selectedRowKeys: string[], selectedRows: any[]) => {
|
||||
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||
},
|
||||
getCheckboxProps: (record: any) => ({
|
||||
disabled: record.name === 'Disabled User',
|
||||
name: record.name,
|
||||
}),
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
.box {
|
||||
padding: 20px;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -42,6 +42,10 @@ import Pie from './Pie.vue';
|
|||
const cpu = ref('20%');
|
||||
const jvm = ref('31%');
|
||||
|
||||
const getData = ()=>{
|
||||
|
||||
}
|
||||
|
||||
const jumpPage = () => {};
|
||||
</script>
|
||||
|
|
@ -186,5 +186,5 @@ const opsStepDetails = [
|
|||
linkUrl: '/a',
|
||||
auth: false,
|
||||
},
|
||||
];
|
||||
] as recommendList[];
|
||||
</script>
|
|
@ -27,6 +27,7 @@ import BasicCountCard from '../BasicCountCard.vue';
|
|||
import PlatformPicCard from '../PlatformPicCard.vue';
|
||||
import StepCard from '../StepCard.vue';
|
||||
|
||||
import {recommendList} from '../../index'
|
||||
// import {getImage} from '@/utils/comm'
|
||||
|
||||
// 运维引导-数据
|
||||
|
@ -93,7 +94,7 @@ const stepDetails = [
|
|||
linkUrl: '/a',
|
||||
auth: false,
|
||||
},
|
||||
];
|
||||
] as recommendList[];
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
|
@ -25,9 +25,22 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getDeviceCount_api, getProductCount_api } from '@/api/home';
|
||||
const projectNum = ref(0);
|
||||
const deviceNum = ref(0);
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
|
||||
const getData = () => {
|
||||
getDeviceCount_api().then((resp) => {
|
||||
deviceNum.value = resp.result;
|
||||
});
|
||||
getProductCount_api().then((resp) => {
|
||||
projectNum.value = resp.result;
|
||||
});
|
||||
};
|
||||
const jumpPage = () => {};
|
||||
</script>
|
||||
|
|
@ -26,6 +26,9 @@ import BootCard from '../BootCard.vue';
|
|||
import DeviceCountCard from '../DeviceCountCard.vue';
|
||||
import PlatformPicCard from '../PlatformPicCard.vue';
|
||||
import StepCard from '../StepCard.vue';
|
||||
|
||||
import {recommendList} from '../../index'
|
||||
|
||||
// import {getImage} from '@/utils/comm'
|
||||
|
||||
// 物联网引导-数据
|
||||
|
@ -90,7 +93,7 @@ const stepDetails = [
|
|||
linkUrl: '/a',
|
||||
auth: false,
|
||||
},
|
||||
];
|
||||
] as recommendList[];
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import * as echarts from 'echarts';
|
||||
import { ComponentInternalInstance } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const props = defineProps({
|
||||
chartRef: String,
|
||||
|
@ -50,7 +51,7 @@ watch(options, () => {
|
|||
});
|
||||
const initChart = () => {
|
||||
nextTick(() => {
|
||||
const myChart = echarts.init(proxy.$refs[props.chartRef]);
|
||||
const myChart = echarts.init(proxy?.$refs[props.chartRef as string] as HTMLElement);
|
||||
|
||||
myChart.clear();
|
||||
myChart.setOption(options.value);
|
|
@ -11,12 +11,8 @@
|
|||
</h5>
|
||||
|
||||
<div class="box-list">
|
||||
<div
|
||||
class="list-item"
|
||||
v-for="item in dataList"
|
||||
@click="jumpPage(item)"
|
||||
>
|
||||
<div class="box-top">
|
||||
<div class="list-item" v-for="item in dataList">
|
||||
<div class="box-top" @click="jumpPage(item)">
|
||||
<span class="top-title">{{ item.title }}</span>
|
||||
<img :src="item.iconUrl" alt="" />
|
||||
</div>
|
||||
|
@ -25,7 +21,10 @@
|
|||
</div>
|
||||
|
||||
<div class="dialogs">
|
||||
<AccessMethodDialog :open-number="openAccess" />
|
||||
<AccessMethodDialog
|
||||
:open-number="openAccess"
|
||||
@confirm="againJumpPage"
|
||||
/>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
|
@ -39,6 +38,11 @@ import AccessMethodDialog from './dialogs/AccessMethodDialog.vue';
|
|||
|
||||
import { recommendList } from '../index';
|
||||
|
||||
type rowType = {
|
||||
params: object;
|
||||
linkUrl: string;
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
cardTitle: String,
|
||||
tooltip: String,
|
||||
|
@ -49,15 +53,25 @@ const router = useRouter();
|
|||
const { cardTitle, tooltip, dataList } = toRefs(props);
|
||||
const openAccess = ref<number>(0);
|
||||
const openFunc = ref<number>(0);
|
||||
|
||||
let selectRow: recommendList | rowType = {
|
||||
params: {},
|
||||
linkUrl: '',
|
||||
};
|
||||
// 跳转页面
|
||||
const jumpPage = (row: recommendList) => {
|
||||
if (!row.auth) return message.warning('暂无权限,请联系管理员');
|
||||
else if (row.dialogTag == 'accessMethod') return (openAccess.value += 1);
|
||||
selectRow = row; // 二次跳转需要使用
|
||||
if (row.dialogTag == 'accessMethod') return (openAccess.value += 1);
|
||||
else if (row.dialogTag === 'funcTest') return (openFunc.value += 1);
|
||||
else if (row.linkUrl) {
|
||||
router.push(`${row.linkUrl}${objToParams(row.params || {})}`);
|
||||
}
|
||||
};
|
||||
// 弹窗返回后的二次跳转
|
||||
const againJumpPage = (paramsSource: object) => {
|
||||
const params = { ...(selectRow.params || {}), ...paramsSource };
|
||||
router.push(`${selectRow.linkUrl}${objToParams(params || {})}`);
|
||||
};
|
||||
|
||||
const objToParams = (source: object): string => {
|
||||
if (Object.prototype.toString.call(source) === '[object Object]') {
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<div ref="modal" class="access-method-dialog-container"></div>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="选择产品"
|
||||
style="width: 700px"
|
||||
@ok="handleOk"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
:getContainer="getContainer"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<a-form :model="form" name="basic" autocomplete="off" layout="vertical">
|
||||
<a-form-item
|
||||
label="产品"
|
||||
name="productId"
|
||||
:rules="[{ required: true, message: '该字段是必填字段' }]"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="form.productId"
|
||||
style="width: 100%"
|
||||
:options="productList"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<template #footer>
|
||||
<a-button key="back" @click="visible = false">取消</a-button>
|
||||
<a-button key="submit" type="primary" @click="handleOk"
|
||||
>确认</a-button
|
||||
>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ComponentInternalInstance } from 'vue';
|
||||
|
||||
import { getProductList_api } from '@/api/home';
|
||||
import { productItem } from '../../index';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const props = defineProps({
|
||||
openNumber: Number,
|
||||
});
|
||||
const emits = defineEmits(['confirm']);
|
||||
const visible = ref<boolean>(false);
|
||||
const form = ref({
|
||||
productId: '',
|
||||
});
|
||||
|
||||
const productList = ref<[productItem] | []>([]);
|
||||
|
||||
const getContainer = () => proxy?.$refs.modal as HTMLElement;
|
||||
const getOptions = () => {
|
||||
getProductList_api().then((resp) => {
|
||||
productList.value = resp.result
|
||||
.filter((i: any) => !i?.accessId)
|
||||
.map((item: { name: any; id: any }) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
})) as [productItem];
|
||||
});
|
||||
};
|
||||
const handleOk = () => {
|
||||
emits('confirm', form.value);
|
||||
visible.value = false;
|
||||
};
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
watch(
|
||||
() => props.openNumber,
|
||||
() => {
|
||||
visible.value = true;
|
||||
form.value.productId = '';
|
||||
getOptions();
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.access-method-dialog-container {
|
||||
:deep(.ant-modal-body) {
|
||||
.ant-form {
|
||||
.ant-form-item-label {
|
||||
color: green;
|
||||
.ant-form-item-required {
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,135 @@
|
|||
<template>
|
||||
<div ref="modal" class="func-test-dialog-container"></div>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="选择产品"
|
||||
style="width: 700px"
|
||||
@ok="handleOk"
|
||||
:getContainer="getContainer"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div class="search">
|
||||
<a-select
|
||||
v-model:value="form.key"
|
||||
style="width: 100%"
|
||||
:options="productList"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="form.relation"
|
||||
style="width: 100%"
|
||||
:options="productList"
|
||||
/>
|
||||
<a-input v-model:value="form.keyValue" allow-clear />
|
||||
|
||||
<a-button type="primary" @click="clickSearch">
|
||||
<template #icon><SearchOutlined /></template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button type="primary" @click="clickReset">
|
||||
<template #icon><reload-outlined /></template>
|
||||
重置
|
||||
</a-button>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="tableData"
|
||||
:row-selection="{
|
||||
onChange: (selectedRowKeys, selectedRows) =>
|
||||
(selectItem = selectedRows),
|
||||
type: 'radio',
|
||||
}"
|
||||
>
|
||||
</a-table>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<a-button key="back" @click="visible = false">取消</a-button>
|
||||
<a-button key="submit" type="primary" @click="handleOk"
|
||||
>确认</a-button
|
||||
>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ComponentInternalInstance } from 'vue';
|
||||
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
import { productItem, deviceInfo } from '../../index';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const emits = defineEmits(['confirm']);
|
||||
const props = defineProps({
|
||||
openNumber: Number,
|
||||
});
|
||||
|
||||
// 弹窗控制
|
||||
const visible = ref<boolean>(false);
|
||||
const getContainer = () => proxy?.$refs.modal as HTMLElement;
|
||||
const handleOk = () => {
|
||||
emits('confirm', form.value);
|
||||
visible.value = false;
|
||||
};
|
||||
watch(
|
||||
() => props.openNumber,
|
||||
() => {
|
||||
clickReset();
|
||||
getOptions();
|
||||
clickSearch();
|
||||
visible.value = true;
|
||||
},
|
||||
);
|
||||
|
||||
// 搜索部分
|
||||
const form = ref({
|
||||
key: '',
|
||||
relation: '',
|
||||
keyValue: '',
|
||||
});
|
||||
const productList = ref<[productItem] | []>([]);
|
||||
const getOptions = () => {
|
||||
productList.value = [];
|
||||
};
|
||||
const clickSearch = ()=>{
|
||||
|
||||
}
|
||||
const clickReset = () => {
|
||||
Object.entries(form.value).forEach(([prop]) => {
|
||||
form.value[prop] = '';
|
||||
});
|
||||
};
|
||||
|
||||
// 表格部分
|
||||
const columns = [
|
||||
{
|
||||
name: 'deviceId',
|
||||
dataIndex: 'deviceId',
|
||||
key: 'deviceId',
|
||||
},
|
||||
{
|
||||
name: 'deviceName',
|
||||
dataIndex: 'deviceName',
|
||||
key: 'deviceName',
|
||||
},
|
||||
{
|
||||
name: 'productName',
|
||||
dataIndex: 'productName',
|
||||
key: 'productName',
|
||||
},
|
||||
{
|
||||
name: 'createTime',
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
},
|
||||
];
|
||||
const tableData = ref<deviceInfo[]>([]);
|
||||
const selectItem: deviceInfo | {} = {};
|
||||
const getList = () => {};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -12,4 +12,12 @@ export interface recommendList {
|
|||
export interface productItem {
|
||||
label: string;
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface deviceInfo {
|
||||
deviceId: string,
|
||||
deviceName: string,
|
||||
productName: string,
|
||||
createTime: string,
|
||||
status: boolean
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
<!-- <InitHome /> -->
|
||||
<!-- <DeviceHome /> -->
|
||||
<!-- <DevOpsHome /> -->
|
||||
<ComprehensiveHome />
|
||||
<!-- <ComprehensiveHome /> -->
|
||||
<ApiPage />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -16,6 +17,7 @@ import InitHome from './components/InitHome/index.vue';
|
|||
import DeviceHome from './components/DeviceHome/index.vue';
|
||||
import DevOpsHome from './components/DevOpsHome/index.vue';
|
||||
import ComprehensiveHome from './components/ComprehensiveHome/index.vue';
|
||||
import ApiPage from '@/views/system/apiPage/index.vue'
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,845 @@
|
|||
/**
|
||||
* 内置角色数据
|
||||
*/
|
||||
export enum ROLEKEYS {
|
||||
'device' = 'device',
|
||||
'link' = 'link',
|
||||
'complex' = 'complex',
|
||||
}
|
||||
|
||||
export type roleKeysType = keyof typeof ROLEKEYS;
|
||||
|
||||
export const RoleData = {
|
||||
[ROLEKEYS.device]: {
|
||||
name: '设备接入岗',
|
||||
description: '该角色负责设备接入模块的维护管理',
|
||||
state: { text: '正常', value: 'enabled' },
|
||||
},
|
||||
[ROLEKEYS.link]: {
|
||||
name: '运维管理岗',
|
||||
description: '该角色负责系统运维模块的维护管理',
|
||||
state: { text: '正常', value: 'enabled' },
|
||||
},
|
||||
[ROLEKEYS.complex]: {
|
||||
name: '综合管理岗',
|
||||
description: '该角色负责系统运维和设备接入模块的维护管理',
|
||||
state: { text: '正常', value: 'enabled' },
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
[ROLEKEYS.device]: [
|
||||
{
|
||||
id: '1-3-2',
|
||||
parentId: '1-3',
|
||||
path: 'T4zX-b4q8-o7Jy',
|
||||
sortIndex: 2,
|
||||
level: 1,
|
||||
name: '产品',
|
||||
code: 'device/Product',
|
||||
icon: 'icon-chanpin',
|
||||
url: '/iot/device/Product',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'action', name: '启/禁用', enabled: true, granted: true },
|
||||
{
|
||||
id: 'export',
|
||||
name: '导出',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'import', name: '导入', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
accessSupport: { text: '支持', value: 'support' },
|
||||
assetType: 'product',
|
||||
assetAccesses: [
|
||||
{
|
||||
supportId: 'ignore',
|
||||
name: '全部数据',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
|
||||
{
|
||||
supportId: 'org',
|
||||
name: '所在组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{
|
||||
supportId: 'org-include-children',
|
||||
name: '所在组织及下级组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
],
|
||||
options: { switch: true },
|
||||
createTime: 1659344075524,
|
||||
accessDescription: '此菜单支持数据权限控制',
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-3-3',
|
||||
parentId: '1-3',
|
||||
path: 'T4zX-b4q8-xYd0',
|
||||
sortIndex: 3,
|
||||
level: 1,
|
||||
name: '设备',
|
||||
code: 'device/Instance',
|
||||
icon: 'icon-shebei',
|
||||
url: '/iot/device/Instance',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'export',
|
||||
name: '导出',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'import', name: '导入', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'action', name: '启/禁用', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
accessSupport: { text: '支持', value: 'support' },
|
||||
assetType: 'device',
|
||||
assetAccesses: [
|
||||
{
|
||||
supportId: 'ignore',
|
||||
name: '全部数据',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
|
||||
{
|
||||
supportId: 'org',
|
||||
name: '所在组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{
|
||||
supportId: 'org-include-children',
|
||||
name: '所在组织及下级组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
],
|
||||
options: { switch: true },
|
||||
createTime: 1659344075524,
|
||||
accessDescription: '此菜单支持数据权限控制',
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-3-4',
|
||||
parentId: '1-3',
|
||||
path: 'T4zX-b4q8-8ZFx',
|
||||
sortIndex: 4,
|
||||
level: 3,
|
||||
name: '产品分类',
|
||||
code: 'device/Category',
|
||||
icon: 'icon-chanpinfenlei1',
|
||||
url: '/iot/device/Category',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: { switch: true },
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
[ROLEKEYS.link]: [
|
||||
{
|
||||
id: '1-4-2',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-UlSD',
|
||||
sortIndex: 2,
|
||||
level: 3,
|
||||
name: '设备接入网关',
|
||||
code: 'link/AccessConfig',
|
||||
icon: 'icon-wangguanzishebei',
|
||||
url: '/iot/link/accessConfig',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'action', name: '启/禁用', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-3',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-ctFm',
|
||||
sortIndex: 3,
|
||||
level: 3,
|
||||
name: '协议管理',
|
||||
code: 'link/Protocol',
|
||||
icon: 'icon-tongzhiguanli',
|
||||
url: '/iot/link/protocol',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-5',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-fDic',
|
||||
sortIndex: 5,
|
||||
level: 3,
|
||||
name: '网络组件',
|
||||
code: 'link/Type',
|
||||
icon: 'icon-wangluozujian',
|
||||
url: '/iot/link/type',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-6',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-bBs5',
|
||||
sortIndex: 6,
|
||||
level: 3,
|
||||
name: '证书管理',
|
||||
code: 'link/Certificate',
|
||||
icon: 'icon-rizhifuwu',
|
||||
url: '/iot/link/Certificate',
|
||||
buttons: [
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-7',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-VilV',
|
||||
sortIndex: 7,
|
||||
level: 3,
|
||||
name: '流媒体服务',
|
||||
code: 'media/Stream',
|
||||
icon: 'icon-xuanzetongdao1',
|
||||
url: '/iot/link/Stream',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-8-1',
|
||||
parentId: '1-4-8',
|
||||
path: 'T4zX-A0TC-GIE8-3Op3',
|
||||
sortIndex: 1,
|
||||
level: 4,
|
||||
name: 'OPC UA',
|
||||
code: 'link/Channel/Opcua',
|
||||
icon: 'icon-zhilianshebei',
|
||||
url: '/iot/link/Channel/Opcua',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-8-2',
|
||||
parentId: '1-4-8',
|
||||
path: 'T4zX-A0TC-GIE8-79SB',
|
||||
sortIndex: 2,
|
||||
level: 4,
|
||||
name: 'Modbus',
|
||||
code: 'link/Channel/Modbus',
|
||||
icon: 'icon-changjingliandong',
|
||||
url: '/iot/link/Channel/Modbus',
|
||||
buttons: [
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-9',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-BFum',
|
||||
sortIndex: 9999,
|
||||
level: 1,
|
||||
name: '远程升级',
|
||||
code: 'device/Firmware',
|
||||
icon: 'icon-wangluozujian',
|
||||
url: '/iot/link/firmware',
|
||||
buttons: [
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
accessSupport: { text: '不支持', value: 'unsupported' },
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
accessDescription: '此菜单不支持数据权限控制',
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
[ROLEKEYS.complex]: [
|
||||
{
|
||||
id: '1-3-2',
|
||||
parentId: '1-3',
|
||||
path: 'T4zX-b4q8-o7Jy',
|
||||
sortIndex: 2,
|
||||
level: 1,
|
||||
name: '产品',
|
||||
code: 'device/Product',
|
||||
icon: 'icon-chanpin',
|
||||
url: '/iot/device/Product',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'action', name: '启/禁用', enabled: true, granted: true },
|
||||
{
|
||||
id: 'export',
|
||||
name: '导出',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'import', name: '导入', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
accessSupport: { text: '支持', value: 'support' },
|
||||
assetType: 'product',
|
||||
assetAccesses: [
|
||||
{
|
||||
supportId: 'ignore',
|
||||
name: '全部数据',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
|
||||
{
|
||||
supportId: 'org',
|
||||
name: '所在组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{
|
||||
supportId: 'org-include-children',
|
||||
name: '所在组织及下级组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
],
|
||||
options: { switch: true },
|
||||
createTime: 1659344075524,
|
||||
accessDescription: '此菜单支持数据权限控制',
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-3-3',
|
||||
parentId: '1-3',
|
||||
path: 'T4zX-b4q8-xYd0',
|
||||
sortIndex: 3,
|
||||
level: 1,
|
||||
name: '设备',
|
||||
code: 'device/Instance',
|
||||
icon: 'icon-shebei',
|
||||
url: '/iot/device/Instance',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'export',
|
||||
name: '导出',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'import', name: '导入', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'action', name: '启/禁用', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
accessSupport: { text: '支持', value: 'support' },
|
||||
assetType: 'device',
|
||||
assetAccesses: [
|
||||
{
|
||||
supportId: 'ignore',
|
||||
name: '全部数据',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
|
||||
{
|
||||
supportId: 'org',
|
||||
name: '所在组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
{
|
||||
supportId: 'org-include-children',
|
||||
name: '所在组织及下级组织',
|
||||
enabled: false,
|
||||
granted: false,
|
||||
},
|
||||
],
|
||||
options: { switch: true },
|
||||
createTime: 1659344075524,
|
||||
accessDescription: '此菜单支持数据权限控制',
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-3-4',
|
||||
parentId: '1-3',
|
||||
path: 'T4zX-b4q8-8ZFx',
|
||||
sortIndex: 4,
|
||||
level: 3,
|
||||
name: '产品分类',
|
||||
code: 'device/Category',
|
||||
icon: 'icon-chanpinfenlei1',
|
||||
url: '/iot/device/Category',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: { switch: true },
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-2',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-UlSD',
|
||||
sortIndex: 2,
|
||||
level: 3,
|
||||
name: '设备接入网关',
|
||||
code: 'link/AccessConfig',
|
||||
icon: 'icon-wangguanzishebei',
|
||||
url: '/iot/link/accessConfig',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'action', name: '启/禁用', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-3',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-ctFm',
|
||||
sortIndex: 3,
|
||||
level: 3,
|
||||
name: '协议管理',
|
||||
code: 'link/Protocol',
|
||||
icon: 'icon-tongzhiguanli',
|
||||
url: '/iot/link/protocol',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-5',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-fDic',
|
||||
sortIndex: 5,
|
||||
level: 3,
|
||||
name: '网络组件',
|
||||
code: 'link/Type',
|
||||
icon: 'icon-wangluozujian',
|
||||
url: '/iot/link/type',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-6',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-bBs5',
|
||||
sortIndex: 6,
|
||||
level: 3,
|
||||
name: '证书管理',
|
||||
code: 'link/Certificate',
|
||||
icon: 'icon-rizhifuwu',
|
||||
url: '/iot/link/Certificate',
|
||||
buttons: [
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'update',
|
||||
name: '编辑',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-7',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-VilV',
|
||||
sortIndex: 7,
|
||||
level: 3,
|
||||
name: '流媒体服务',
|
||||
code: 'media/Stream',
|
||||
icon: 'icon-xuanzetongdao1',
|
||||
url: '/iot/link/Stream',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-8-1',
|
||||
parentId: '1-4-8',
|
||||
path: 'T4zX-A0TC-GIE8-3Op3',
|
||||
sortIndex: 1,
|
||||
level: 4,
|
||||
name: 'OPC UA',
|
||||
code: 'link/Channel/Opcua',
|
||||
icon: 'icon-zhilianshebei',
|
||||
url: '/iot/link/Channel/Opcua',
|
||||
buttons: [
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-8-2',
|
||||
parentId: '1-4-8',
|
||||
path: 'T4zX-A0TC-GIE8-79SB',
|
||||
sortIndex: 2,
|
||||
level: 4,
|
||||
name: 'Modbus',
|
||||
code: 'link/Channel/Modbus',
|
||||
icon: 'icon-changjingliandong',
|
||||
url: '/iot/link/Channel/Modbus',
|
||||
buttons: [
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'view', name: '查看', enabled: true, granted: true },
|
||||
{
|
||||
id: 'delete',
|
||||
name: '删除',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'add', name: '新增', enabled: true, granted: true },
|
||||
],
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
granted: true,
|
||||
},
|
||||
{
|
||||
id: '1-4-9',
|
||||
parentId: '1-4',
|
||||
path: 'T4zX-A0TC-BFum',
|
||||
sortIndex: 9999,
|
||||
level: 1,
|
||||
name: '远程升级',
|
||||
code: 'device/Firmware',
|
||||
icon: 'icon-wangluozujian',
|
||||
url: '/iot/link/firmware',
|
||||
buttons: [
|
||||
{ id: 'update', name: '编辑', enabled: true, granted: true },
|
||||
{
|
||||
id: 'action',
|
||||
name: '启/禁用',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
{ id: 'delete', name: '删除', enabled: true, granted: true },
|
||||
{
|
||||
id: 'add',
|
||||
name: '新增',
|
||||
enabled: true,
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
accessSupport: { text: '不支持', value: 'unsupported' },
|
||||
assetAccesses: [],
|
||||
options: {},
|
||||
createTime: 1659344075524,
|
||||
accessDescription: '此菜单不支持数据权限控制',
|
||||
granted: true,
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/** 初始化数据提交表单 */
|
||||
export interface modalState {
|
||||
host: string; // 本地地址
|
||||
port: string; // 本地端口
|
||||
publicHost: string; // 公网地址
|
||||
publicPort: number | null; // 公网端口
|
||||
rules: Record<string, Rule[]>;
|
||||
}
|
||||
|
||||
/**基本信息表单 */
|
||||
export interface formState {
|
||||
title: string; // 系统名称
|
||||
headerTheme: string; // 主题色
|
||||
apikey: string; // 高德 API key
|
||||
basePath: string; // 系统后台访问的URL
|
||||
logo: string; // 系统logo
|
||||
icon: string; // 浏览器页签
|
||||
rulesFrom: Record<string, Rule[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* logo上传表当
|
||||
*/
|
||||
export interface logoState {
|
||||
logoValue: string;
|
||||
logoLoading: boolean;
|
||||
inLogo: boolean;
|
||||
inIcon: boolean;
|
||||
inBackground: boolean;
|
||||
iconValue: string;
|
||||
backValue: string;
|
||||
handleChangeLogo:(url: string) => void
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,55 +0,0 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="选择产品"
|
||||
style="width: 500px"
|
||||
@ok="handleOk"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="productId"
|
||||
style="width: 100%"
|
||||
:options="productList"
|
||||
>
|
||||
</a-select>
|
||||
<template #footer>
|
||||
<a-button key="back" @click="visible = false">取消</a-button>
|
||||
<a-button key="submit" type="primary" @click="handleOk"
|
||||
>确认</a-button
|
||||
>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { productItem } from '../../index';
|
||||
|
||||
const props = defineProps({
|
||||
openNumber: Number,
|
||||
});
|
||||
const emits = defineEmits(['confirm']);
|
||||
const { openNumber } = toRefs(props);
|
||||
const visible = ref<boolean>(false);
|
||||
|
||||
const productId = ref<string>('');
|
||||
const productList = ref<[productItem] | []>([]);
|
||||
|
||||
const getOptions = () => {
|
||||
productList.value = [];
|
||||
};
|
||||
const handleOk = () => {
|
||||
emits('confirm', productId.value);
|
||||
visible.value = false;
|
||||
};
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
watch(openNumber, () => {
|
||||
visible.value = true;
|
||||
productId.value = '';
|
||||
getOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -1,88 +1,91 @@
|
|||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<div>
|
||||
<a-textarea
|
||||
:rows="4"
|
||||
@change="textChange"
|
||||
v-model="keystoreBase64"
|
||||
:placeholder=placeholder
|
||||
/>
|
||||
<a-upload
|
||||
accept=".pem"
|
||||
listType="text"
|
||||
:action="action"
|
||||
:headers="headers"
|
||||
:showUploadList="false"
|
||||
@change="handleChange"
|
||||
>
|
||||
<a-button style="margin-top: 10px">
|
||||
<upload-outlined></upload-outlined>
|
||||
|
||||
上传文件</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
</a-spin>
|
||||
<a-spin :spinning="loading">
|
||||
<div>
|
||||
<a-textarea
|
||||
:rows="4"
|
||||
@change="textChange"
|
||||
v-model:value="keystoreBase64"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
<a-upload
|
||||
accept=".pem"
|
||||
listType="text"
|
||||
:action="`${BASE_API_PATH}${NETWORK_CERTIFICATE_UPLOAD}`"
|
||||
:headers="{
|
||||
[TOKEN_KEY]: LocalStore.get(TOKEN_KEY),
|
||||
}"
|
||||
:showUploadList="false"
|
||||
@change="handleChange"
|
||||
>
|
||||
<a-button style="margin-top: 10px">
|
||||
<upload-outlined />
|
||||
上传文件</a-button
|
||||
>
|
||||
</a-upload>
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import storage from 'store'
|
||||
// import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
// import { ACCESS_TOKEN_KEY } from '@/utils/consts'
|
||||
<script setup lang="ts" name="CertificateFile">
|
||||
import { UploadOutlined } from '@ant-design/icons-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import type { UploadChangeParam } from 'ant-design-vue';
|
||||
import { LocalStore } from '@/utils/comm';
|
||||
import {
|
||||
BASE_API_PATH,
|
||||
TOKEN_KEY,
|
||||
NETWORK_CERTIFICATE_UPLOAD,
|
||||
} from '@/utils/variable';
|
||||
import type { UploadProps } from 'ant-design-vue';
|
||||
|
||||
export default {
|
||||
name: 'CertificateFile',
|
||||
data () {
|
||||
return {
|
||||
keystoreBase64: '',
|
||||
loading: false,
|
||||
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
|
||||
headers:{
|
||||
authorization: 'authorization-text',
|
||||
}
|
||||
// action: process.env.VUE_APP_BASE_API + `/network/certificate/upload`,
|
||||
// headers: {
|
||||
// [ACCESS_TOKEN_KEY]: storage.get(ACCESS_TOKEN)
|
||||
// }
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
const emit = defineEmits(['update:modelValue', 'change']);
|
||||
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler (v) {
|
||||
this.keystoreBase64 = v
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange (info) {
|
||||
this.loading = true
|
||||
if (info.file.status === 'done') {
|
||||
this.$message.success('上传成功!')
|
||||
const result = info.file.response?.result
|
||||
this.loading = false
|
||||
this.$emit('change', result)
|
||||
}
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
textChange (val) {
|
||||
this.$emit('change', val)
|
||||
});
|
||||
|
||||
const keystoreBase64 = ref(props.modelValue);
|
||||
const loading = ref(false);
|
||||
|
||||
const handleChange = (info: UploadChangeParam) => {
|
||||
loading.value = true;
|
||||
if (info.file.status === 'done') {
|
||||
message.success('上传成功!');
|
||||
const result = info.file.response?.result;
|
||||
keystoreBase64.value = result;
|
||||
console.log(1114, result);
|
||||
loading.value = false;
|
||||
emit('change', result);
|
||||
emit('update:modelValue', result);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const textChange = (val: any) => {
|
||||
val.name = props.name;
|
||||
emit('change', val);
|
||||
// emit('update:modelValue', val);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
keystoreBase64.value = v;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -11,18 +11,9 @@
|
|||
:wrapper-col="{ span: 16 }"
|
||||
autocomplete="off"
|
||||
@finish="onFinish"
|
||||
@finishFailed="onFinishFailed"
|
||||
:rules="formRules"
|
||||
>
|
||||
<a-form-item
|
||||
label="证书标准"
|
||||
name="type"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择证书标准',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-form-item label="证书标准" name="type">
|
||||
<a-radio-group v-model:value="formData.type">
|
||||
<a-radio-button
|
||||
class="form-radio-button"
|
||||
|
@ -33,46 +24,25 @@
|
|||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="证书名称"
|
||||
name="name"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入证书名称',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-form-item label="证书名称" name="name">
|
||||
<a-input
|
||||
placeholder="请输入证书名称"
|
||||
v-model:value="formData.name"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="证书文件"
|
||||
name="cert"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '上传证书文件',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-form-item label="证书文件" name="cert">
|
||||
<CertificateFile
|
||||
name="cert"
|
||||
v-model:modelValue="formData.cert"
|
||||
@change="changeFileValue"
|
||||
placeholder='证书格式以"-----BEGIN CERTIFICATE-----"开头,以"-----END CERTIFICATE-----"结尾"'
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="证书私钥"
|
||||
name="key"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请上传证书私钥',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-form-item label="证书私钥" name="key">
|
||||
<CertificateFile
|
||||
name="key"
|
||||
v-model:modelValue="formData.key"
|
||||
@change="changeFileValue"
|
||||
placeholder='证书私钥格式以"-----BEGIN (RSA|EC) PRIVATE KEY-----"开头,以"-----END(RSA|EC) PRIVATE KEY-----"结尾。'
|
||||
/>
|
||||
</a-form-item>
|
||||
|
@ -117,46 +87,73 @@
|
|||
</a-row>
|
||||
</a-card>
|
||||
</template>
|
||||
<!-- export const ACCESS_TOKEN_KEY = 'X-Access-Token' -->
|
||||
<!-- export const ACCESS_TOKEN = 'device_token' -->
|
||||
|
||||
<script lang="ts" setup name="CertificateDetail">
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getImage } from '@/utils/comm';
|
||||
import CertificateFile from './CertificateFile.vue';
|
||||
import type { UploadChangeParam } from 'ant-design-vue';
|
||||
import { LocalStore } from '@/utils/comm';
|
||||
import {
|
||||
BASE_API_PATH,
|
||||
TOKEN_KEY,
|
||||
NETWORK_CERTIFICATE_UPLOAD,
|
||||
} from '@/utils/variable';
|
||||
import { save } from '@/api/link/certificate';
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
type: 'common',
|
||||
name: '',
|
||||
configs: {
|
||||
cert: '',
|
||||
key: '',
|
||||
},
|
||||
cert: '',
|
||||
key: '',
|
||||
// configs: {
|
||||
// cert: '',
|
||||
// key: '',
|
||||
// },
|
||||
description: '',
|
||||
});
|
||||
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
const formRules = {
|
||||
type: [{ required: true, message: '请选择证书标准', trigger: 'blur' }],
|
||||
name: [
|
||||
{ required: true, message: '请输入证书名称', trigger: 'blur' },
|
||||
{ max: 64, message: '最多可输入64个字符' },
|
||||
],
|
||||
cert: [{ required: true, message: '请输入或上传文件', trigger: 'blur' }],
|
||||
key: [{ required: true, message: '请输入或上传文件', trigger: 'blur' }],
|
||||
description: [{ max: 200, message: '最多可输入200个字符' }],
|
||||
};
|
||||
|
||||
const headers = {
|
||||
authorization: 'authorization-text',
|
||||
const onFinish = async (values: any) => {
|
||||
values.configs = {
|
||||
cert: formData.cert,
|
||||
key: formData.key,
|
||||
};
|
||||
delete values.cert;
|
||||
delete values.key;
|
||||
|
||||
const response = await save(values)
|
||||
if (response.status === 200) {
|
||||
message.success('操作成功')
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const handleChange = (info: any) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
const changeFileValue = (v: any) => {
|
||||
formData[v.name] = v.data;
|
||||
};
|
||||
|
||||
const handleChange = (info: UploadChangeParam) => {
|
||||
loading.value = true;
|
||||
if (info.file.status === 'done') {
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
message.success('上传成功!');
|
||||
const result = info.file.response?.result;
|
||||
formData.cert = result;
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
const fileList = ref([]);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<template>
|
||||
<a-tree
|
||||
:tree-data="treeData"
|
||||
@select="clickSelectItem"
|
||||
showLine
|
||||
class="left-tree-container"
|
||||
>
|
||||
<template #title="{ name }">
|
||||
{{ name }}
|
||||
</template>
|
||||
</a-tree>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TreeProps } from 'ant-design-vue';
|
||||
|
||||
import { getTreeOne_api, getTreeTwo_api } from '@/api/system/apiPage';
|
||||
|
||||
type treeNodeTpye = {
|
||||
name: string;
|
||||
url: string;
|
||||
children?: treeNodeTpye[];
|
||||
};
|
||||
const emits = defineEmits(['select']);
|
||||
|
||||
const treeData: TreeProps['treeData'] = ref([]);
|
||||
|
||||
const getTreeData = () => {
|
||||
let tree: treeNodeTpye[] = [];
|
||||
getTreeOne_api().then((resp) => {
|
||||
tree = resp.urls.map((item) => ({
|
||||
...item,
|
||||
key: item.url,
|
||||
}));
|
||||
const allPromise = tree.map((item) => getTreeTwo_api(item.name));
|
||||
Promise.all(allPromise).then((values) => {
|
||||
values.forEach((item, i) => {
|
||||
tree[i].children = combData(item.paths);
|
||||
});
|
||||
console.log(tree);
|
||||
treeData.value = tree
|
||||
});
|
||||
});
|
||||
};
|
||||
const clickSelectItem = (key, { node }) => {
|
||||
emits('select', node);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getTreeData();
|
||||
});
|
||||
|
||||
const combData = (dataSource: object): object[] => {
|
||||
const apiList: object[] = [];
|
||||
const keys = Object.keys(dataSource);
|
||||
|
||||
keys.forEach((key) => {
|
||||
const method = Object.keys(dataSource[key] || {})[0];
|
||||
const name = dataSource[key][method].tags[0];
|
||||
let apiObj = apiList.find((item) => item.name === name);
|
||||
if (!apiObj) {
|
||||
apiObj = { name, link: key, methods: dataSource[key], key };
|
||||
apiList.push(apiObj);
|
||||
}
|
||||
});
|
||||
|
||||
return apiList;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<a-card class="api-page-container" >
|
||||
<LeftTree />
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import LeftTree from './components/LeftTree.vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.api-page-container {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -1,44 +0,0 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<JTable
|
||||
:columns="[
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
},
|
||||
{
|
||||
title: '住址',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
}
|
||||
]"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<a-button type="primary">新增</a-button>
|
||||
</template>
|
||||
<template #cardRender="slotProps">
|
||||
{{slotProps.name}}
|
||||
</template>
|
||||
</JTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { post } from "@/utils/request";
|
||||
// :request="post('/device-product/_query', {})"
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
.box {
|
||||
padding: 20px;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -18,8 +18,9 @@
|
|||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"types": ["ant-design-vue/typings/global"]
|
||||
"types": ["ant-design-vue/typings/global"],
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
"references": [{ "path": "./tsconfig.node.json" }],
|
||||
}
|
||||
|
|
74
yarn.lock
74
yarn.lock
|
@ -34,6 +34,14 @@
|
|||
"@jridgewell/gen-mapping" "^0.1.0"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@ampproject/remapping@^2.1.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
|
||||
integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==
|
||||
dependencies:
|
||||
"@jridgewell/gen-mapping" "^0.1.0"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@ant-design/colors@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz"
|
||||
|
@ -287,6 +295,29 @@
|
|||
"@babel/helper-plugin-utils" "^7.20.2"
|
||||
"@babel/plugin-syntax-typescript" "^7.20.0"
|
||||
|
||||
"@babel/plugin-syntax-jsx@^7.0.0":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0"
|
||||
integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.18.6"
|
||||
|
||||
"@babel/plugin-syntax-typescript@^7.20.0":
|
||||
version "7.20.0"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7"
|
||||
integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.19.0"
|
||||
|
||||
"@babel/plugin-transform-typescript@^7.20.2":
|
||||
version "7.20.7"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz#673f49499cd810ae32a1ea5f3f8fab370987e055"
|
||||
integrity sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw==
|
||||
dependencies:
|
||||
"@babel/helper-create-class-features-plugin" "^7.20.7"
|
||||
"@babel/helper-plugin-utils" "^7.20.2"
|
||||
"@babel/plugin-syntax-typescript" "^7.20.0"
|
||||
|
||||
"@babel/runtime@^7.10.5":
|
||||
version "7.20.7"
|
||||
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.20.7.tgz"
|
||||
|
@ -496,6 +527,40 @@
|
|||
dependencies:
|
||||
"@jridgewell/trace-mapping" "0.3.9"
|
||||
|
||||
"@babel/template@^7.0.0", "@babel/template@^7.18.10", "@babel/template@^7.20.7":
|
||||
version "7.20.7"
|
||||
resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
|
||||
integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.18.6"
|
||||
"@babel/parser" "^7.20.7"
|
||||
"@babel/types" "^7.20.7"
|
||||
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.7":
|
||||
version "7.20.12"
|
||||
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5"
|
||||
integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.18.6"
|
||||
"@babel/generator" "^7.20.7"
|
||||
"@babel/helper-environment-visitor" "^7.18.9"
|
||||
"@babel/helper-function-name" "^7.19.0"
|
||||
"@babel/helper-hoist-variables" "^7.18.6"
|
||||
"@babel/helper-split-export-declaration" "^7.18.6"
|
||||
"@babel/parser" "^7.20.7"
|
||||
"@babel/types" "^7.20.7"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7":
|
||||
version "7.20.7"
|
||||
resolved "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f"
|
||||
integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.19.4"
|
||||
"@babel/helper-validator-identifier" "^7.19.1"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@ctrl/tinycolor@^3.4.0":
|
||||
version "3.5.0"
|
||||
resolved "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.5.0.tgz"
|
||||
|
@ -815,6 +880,15 @@
|
|||
"@babel/plugin-transform-typescript" "^7.20.2"
|
||||
"@vue/babel-plugin-jsx" "^1.1.1"
|
||||
|
||||
"@vitejs/plugin-vue-jsx@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.0.0.tgz#42e89d6d9eb89604d109ff9a615d77c3c080dd25"
|
||||
integrity sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==
|
||||
dependencies:
|
||||
"@babel/core" "^7.20.5"
|
||||
"@babel/plugin-transform-typescript" "^7.20.2"
|
||||
"@vue/babel-plugin-jsx" "^1.1.1"
|
||||
|
||||
"@vitejs/plugin-vue@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz"
|
||||
|
|
Loading…
Reference in New Issue