diff --git a/src/api/device/instance.ts b/src/api/device/instance.ts index 5148bca8..d9290b4b 100644 --- a/src/api/device/instance.ts +++ b/src/api/device/instance.ts @@ -482,4 +482,19 @@ export const getPropertiesInfo = (deviceId: string, data: Record) => server.post(`/device-instance/${deviceId}/property/${property}/_query`, data) \ No newline at end of file +export const getPropertiesList = (deviceId: string, property: string, data: Record) => server.post(`/device-instance/${deviceId}/property/${property}/_query`, data) + +/** + * 查询设备日志 + * @param deviceId + * @param data + * @returns + */ +export const queryLog = (deviceId: string, data: Record) => server.post(`/device-instance/${deviceId}/logs`, data) + +/** + * 查询设备日志类型 + * @returns + */ +export const queryLogsType = () => server.get(`/dictionary/device-log-type/items`) + diff --git a/src/api/device/product.ts b/src/api/device/product.ts index dca448a4..f6a31e9d 100644 --- a/src/api/device/product.ts +++ b/src/api/device/product.ts @@ -184,4 +184,13 @@ export const getOperator = () => server.get('/property-calculate-r /** * 获取聚合函数列表 */ -export const getStreamingAggType = () => server.get[]>('/dictionary/streaming-agg-type/items') \ No newline at end of file +export const getStreamingAggType = () => server.get[]>('/dictionary/streaming-agg-type/items') + +export const getMetadataConfig = (params: { + deviceId: string; + metadata: { + type: MetadataType | 'property'; + id: string; + dataType: string; + }; +}) => server.get[]>(`/device/product/${params.deviceId}/config-metadata/${params.metadata.type}/${params.metadata.id}/${params.metadata.dataType}`) \ No newline at end of file diff --git a/src/api/media/cascade.ts b/src/api/media/cascade.ts new file mode 100644 index 00000000..c0b71ded --- /dev/null +++ b/src/api/media/cascade.ts @@ -0,0 +1,29 @@ +import server from '@/utils/request' +import type { CascadeItem } from '@/views/media/Cascade/typings' + +export default { + // 列表 + list: (data: any) => server.post(`/media/gb28181-cascade/_query`, data), + // 列表字段通道数量, 来自下面接口的total + queryCount: (id: string) => server.post(`/media/gb28181-cascade/${id}/bindings/_query`), + // 详情 + detail: (id: string): any => server.get(`/media/gb28181-cascade/${id}`), + // 新增 + save: (data: any) => server.post(`/media/gb28181-cascade`, data), + // 修改 + // update: (id: string, data: any) => server.put(`/media/gb28181-cascade/${id}`, data), + update: (data: any) => server.patch(`/media/gb28181-cascade`, data), + // 删除 + del: (id: string) => server.remove(`media/gb28181-cascade/${id}`), + // 禁用 + disabled: (id: string) => server.post(`/media/gb28181-cascade/${id}/_disabled`), + // 启用 + enabled: (id: string) => server.post(`/media/gb28181-cascade/${id}/_enabled`), + + // 新增/编辑 + // 获取集群节点 + clusters: () => server.get(`/network/resources/clusters`), + // SIP本地地址 + all: () => server.get(`/network/resources/alive/_all`), + +} \ No newline at end of file diff --git a/src/api/media/channel.ts b/src/api/media/channel.ts new file mode 100644 index 00000000..da64173a --- /dev/null +++ b/src/api/media/channel.ts @@ -0,0 +1,16 @@ +import server from '@/utils/request' + +export default { + // 列表 + list: (data: any, id: string) => server.post(`/media/device/${id}/channel/_query`, data), + // 详情 + detail: (id: string): any => server.get(`/media/channel/${id}`), + // 验证通道ID是否存在 + validateField: (params: any): any => server.get(`/media/channel/channelId/_validate`, params), + // 新增 + save: (data: any) => server.post(`/media/channel`, data), + // 修改 + update: (id: string, data: any) => server.put(`/media/channel/${id}`, data), + // 删除 + del: (id: string) => server.remove(`media/channel/${id}`), +} \ No newline at end of file diff --git a/src/api/rule-engine/log.ts b/src/api/rule-engine/log.ts new file mode 100644 index 00000000..05eddf37 --- /dev/null +++ b/src/api/rule-engine/log.ts @@ -0,0 +1,21 @@ +import server from '@/utils/request'; + +/** + * 获取产品列表 + */ +export const getProductList = (parmas?:any) => server.get('/device/product/_query/no-paging?paging=false',parmas); + +/** + * 获取设备列表 + */ +export const getDeviceList = (parmas?:any) => server.get('/device-instance/_query/no-paging?paging=false',parmas); + +/** + * 获取组织列表 + */ +export const getOrgList = (parmas?:any) => server.get('/organization/_query/no-paging?paging=false',parmas); + +/** + * 搜索 + */ +export const query = (data:any) => server.post('/alarm/record/_query/',data); \ No newline at end of file diff --git a/src/api/system/apply.ts b/src/api/system/apply.ts index 9bf97443..b3b4c218 100644 --- a/src/api/system/apply.ts +++ b/src/api/system/apply.ts @@ -4,17 +4,30 @@ import server from '@/utils/request'; // 获取应用管理列表 export const getApplyList_api = (data: any) => server.post(`/application/_query/`, data) // 修改应用状态 -export const changeApplyStatus_api = (id:string,data: any) => server.put(`/application/${id}`, data) +export const changeApplyStatus_api = (id: string, data: any) => server.put(`/application/${id}`, data) // 删除应用 -export const delApply_api = (id:string) => server.remove(`/application/${id}`) +export const delApply_api = (id: string) => server.remove(`/application/${id}`) // 获取组织列表 export const getDepartmentList_api = () => server.get(`/organization/_all/tree`); // 获取组织列表 -export const getAppInfo_api = (id:string) => server.get(`/application/${id}`); +export const getAppInfo_api = (id: string) => server.get(`/application/${id}`); // 新增应用 -export const addApp_api = (data:object) => server.post(`/application`, data); +export const addApp_api = (data: object) => server.post(`/application`, data); // 更新应用 -export const updateApp_api = (id:string, data:object) => server.put(`/application/${id}`, data); \ No newline at end of file +export const updateApp_api = (id: string, data: object) => server.put(`/application/${id}`, data); + + +// ---------集成菜单----------- + +// 获取所属系统 +export const getOwner_api = (data: object) => server.post(`/menu/owner`, data); +export const getOwnerStandalone_api = (appId: string, data: object) => server.post(`/application/${appId}/_/api/menu/owner`, data); + +// 获取对应系统菜单树 +export const getOwnerTree_api = (owner: string) => server.post(`/menu/owner/tree/${owner}`, {}); +export const getOwnerTreeStandalone_api = (appId: string, owner: string) => server.post(`/application/${appId}/_/api/menu/owner/tree/${owner}`, {}); +// 保存集成菜单 +export const saveOwnerMenu_api = (owner: string, appId: string, data: object) => server.patch(`/menu/owner/${owner}/${appId}/_all`, data); diff --git a/src/components/AIcon/index.tsx b/src/components/AIcon/index.tsx index 2c589ac5..6e1682a0 100644 --- a/src/components/AIcon/index.tsx +++ b/src/components/AIcon/index.tsx @@ -48,7 +48,7 @@ const iconKeys = [ 'ClockCircleOutlined', 'PartitionOutlined', 'ShareAltOutlined', - 'playCircleOutlined', + 'PlayCircleOutlined', 'RightOutlined', 'FileTextOutlined', 'UploadOutlined', @@ -58,6 +58,8 @@ const iconKeys = [ 'PauseOutlined', 'ControlOutlined', 'RedoOutlined', + 'VideoCameraOutlined', + 'HistoryOutlined', ] const Icon = (props: {type: string}) => { diff --git a/src/components/AMapComponent/PathSimplifier.vue b/src/components/AMapComponent/PathSimplifier.vue new file mode 100644 index 00000000..a34d05d1 --- /dev/null +++ b/src/components/AMapComponent/PathSimplifier.vue @@ -0,0 +1,106 @@ + + + \ No newline at end of file diff --git a/src/components/AMapComponent/index.vue b/src/components/AMapComponent/index.vue new file mode 100644 index 00000000..03e9befd --- /dev/null +++ b/src/components/AMapComponent/index.vue @@ -0,0 +1,71 @@ + + + + + \ No newline at end of file diff --git a/src/components/AMapComponent/types.d.ts b/src/components/AMapComponent/types.d.ts new file mode 100644 index 00000000..db4f66b6 --- /dev/null +++ b/src/components/AMapComponent/types.d.ts @@ -0,0 +1,130 @@ +export type PathDataType = number[][]; + +export type PathSimplifierOptions = { + map?: any; + zIndex?: number; + data?: number[][]; + getPath?: (pathData: {}, pathIndex: number) => PathDataType; + getZIndex?: (pathData: any, pathIndex: number) => number; + getHoverTitle?: (pathData: any, pathIndex: number, pointIndex: number) => string; + autoSetFitView?: boolean; + clickToSelectPath?: boolean; + onTopWhenSelected?: boolean; + renderConstructor?: Function; + renderOptions?: {}; +}; + +export type PathDataItemType = { + name?: string; + path: PathDataType; +}; + +export interface PathSimplifier { + new (options: PathSimplifierOptions); + + readonly supportCanvas: boolean; + + getZIndexOfPath: (pathIndex: number) => number; + + setZIndexOfPath: (pathIndex: number, zIndex: number) => void; + + /** + * 是否置顶显示pathIndex对应的轨迹 + * @param pathIndex + * @param isTop isTop为真,设置 zIndex 为 现存最大zIndex+1; isTop为假,设置 zIndex 为 构造参数中 getZIndex 的返回值 + */ + toggleTopOfPath: (pathIndex: number, isTop: boolean) => void; + + getPathData: (pathIndex: number) => any; + + createPathNavigator: (pathIndex: number, options: {}) => PathNavigator; + + getPathNavigators: () => any[]; + + clearPathNavigators: () => void; + + getSelectedPathData: () => any; + + getSelectedPathIndex: () => number; + + isSelectedPathIndex: (pathIndex: number) => boolean; + + setSelectedPathIndex: (pathIndex: number) => void; + + render: () => void; + + renderLater: (delay: number[]) => void; + + setData: (data: any[]) => void; + + setFitView: (pathIndex: number) => void; + + on: (eventName: string, handler: Function) => void; + + off: (eventName: string, handler: Function) => void; + + hide: () => void; + + show: () => void; + + isHidden: () => boolean; + + getRender: () => boolean; + + getRenderOptions: () => any; +} + +export interface PathNavigatorOptions { + loop?: boolean; + speed?: number; + pathNavigatorStyle?: {}; + animInterval?: number; + dirToPosInMillsecs?: number; + range?: [number, number]; +} + +export interface PathNavigator { + new (options: PathNavigatorOptions); + + start: (pointIndex?: number) => void; + + pause: () => void; + + resume: () => void; + + stop: () => void; + + destroy: () => void; + + getCursor: () => any; + + getNaviStatus: () => string; + + getPathIndex: () => number; + + getPosition: () => [number, number]; + + getSpeed: () => number; + + getMovedDistance: () => number; + + getPathStartIdx: () => number; + + getPathEndIdx: () => number; + + moveByDistance: (distance: number) => void; + + moveToPoint: (idx: number, tail: number) => void; + + isCursorAtPathEnd: () => boolean; + + isCursorAtPathStart: () => boolean; + + setSpeed: (speed: number) => void; + + setRange: (startIndex: number, endIndex: number) => void; + + on: (eventName: string, handler: Function) => void; + + off: (eventName: string, handler: Function) => void; +} diff --git a/src/components/AMapComponent/utils.ts b/src/components/AMapComponent/utils.ts new file mode 100644 index 00000000..dd7f91ec --- /dev/null +++ b/src/components/AMapComponent/utils.ts @@ -0,0 +1,26 @@ +const protocol = window.location.protocol; + +const buildScriptTag = (src: string): HTMLScriptElement => { + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.async = true; + script.defer = true; + script.src = src; + return script; +}; + +export const getAMapUiPromise = (version: string = '1.0'): Promise => { + if ((window as any).AMapUI) { + return Promise.resolve(); + } + const script = buildScriptTag(`${protocol}//webapi.amap.com/ui/${version}/main-async.js`); + const pro = new Promise((resolve) => { + script.onload = () => { + (window as any).initAMapUI(); + resolve(true); + }; + }); + + document.body.append(script); + return pro; +}; \ No newline at end of file diff --git a/src/components/CardBox/index.vue b/src/components/CardBox/index.vue index dee607c8..bfe32ab1 100644 --- a/src/components/CardBox/index.vue +++ b/src/components/CardBox/index.vue @@ -40,11 +40,19 @@ +
+
+ +
+
-
+
- - - - - - - diff --git a/src/views/device/Instance/Detail/Running/Property/Detail/PropertyAMap.vue b/src/views/device/Instance/Detail/Running/Property/Detail/PropertyAMap.vue index b7860f91..e6380a17 100644 --- a/src/views/device/Instance/Detail/Running/Property/Detail/PropertyAMap.vue +++ b/src/views/device/Instance/Detail/Running/Property/Detail/PropertyAMap.vue @@ -3,12 +3,14 @@
- 开始动画 - 停止动画 + 开始动画 + 停止动画
- + + + @@ -16,7 +18,6 @@ import { getPropertyData } from '@/api/device/instance'; import { useInstanceStore } from '@/store/instance'; import encodeQuery from '@/utils/encodeQuery'; -import AMap from './AMap.vue'; const instanceStore = useInstanceStore(); @@ -33,6 +34,15 @@ const prop = defineProps({ const geoList = ref([]); const loading = ref(false); +const amapPath = ref() + +const onStart = () => { + amapPath.value.start() +} + +const onStop = () => { + amapPath.value.stop() +} const query = async () => { loading.value = true; @@ -53,7 +63,10 @@ const query = async () => { ((resp.result as any)?.data || []).forEach((item: any) => { list.push([item.value.lon, item.value.lat]); }); - geoList.value = list + geoList.value = [{ + name: prop?.data?.name, + path: list + }] } }; diff --git a/src/views/device/Instance/Detail/Running/Property/Detail/index.vue b/src/views/device/Instance/Detail/Running/Property/Detail/index.vue index 6bdb9c4b..39d3d376 100644 --- a/src/views/device/Instance/Detail/Running/Property/Detail/index.vue +++ b/src/views/device/Instance/Detail/Running/Property/Detail/index.vue @@ -2,7 +2,7 @@
- + diff --git a/src/views/device/Instance/Detail/index.vue b/src/views/device/Instance/Detail/index.vue index f775e847..e42f0687 100644 --- a/src/views/device/Instance/Detail/index.vue +++ b/src/views/device/Instance/Detail/index.vue @@ -116,6 +116,7 @@ import Function from './Function/index.vue'; import Modbus from './Modbus/index.vue'; import OPCUA from './OPCUA/index.vue'; import EdgeMap from './EdgeMap/index.vue'; +import Log from './Log/index.vue' import { _deploy, _disconnect } from '@/api/device/instance'; import { message } from 'ant-design-vue'; import { getImage } from '@/utils/comm'; @@ -147,6 +148,10 @@ const list = ref([ key: 'Metadata', tab: '物模型', }, + { + key: 'Log', + tab: '日志管理', + }, { key: 'Function', tab: '设备功能', @@ -167,6 +172,7 @@ const tabs = { Modbus, OPCUA, EdgeMap, + Log }; const getStatus = (id: string) => { diff --git a/src/views/device/Instance/index.vue b/src/views/device/Instance/index.vue index bf1e1393..cfa46224 100644 --- a/src/views/device/Instance/index.vue +++ b/src/views/device/Instance/index.vue @@ -694,7 +694,6 @@ const saveBtn = () => { }; const handleSearch = (_params: any) => { - console.log(_params); params.value = _params; }; diff --git a/src/views/device/Product/index.vue b/src/views/device/Product/index.vue index 456eedbe..6f5076fd 100644 --- a/src/views/device/Product/index.vue +++ b/src/views/device/Product/index.vue @@ -35,7 +35,6 @@ - \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue b/src/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue index 2efa7b2a..5911b0f5 100644 --- a/src/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue +++ b/src/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue @@ -1,28 +1,25 @@ \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/index.vue b/src/views/device/components/Metadata/Base/index.vue index 196cb6b7..c7cae06d 100644 --- a/src/views/device/components/Metadata/Base/index.vue +++ b/src/views/device/components/Metadata/Base/index.vue @@ -9,11 +9,11 @@ title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增', }"> 新增 - + @@ -60,7 +62,6 @@ import { useInstanceStore } from '@/store/instance' import { useProductStore } from '@/store/product' import { useMetadataStore } from '@/store/metadata' import PermissionButton from '@/components/PermissionButton/index.vue' -import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons-vue' import { message } from 'ant-design-vue/es' import { SystemConst } from '@/utils/consts' import { Store } from 'jetlinks-store' @@ -122,7 +123,8 @@ onMounted(() => { }) -watch([route.params.id, type], () => { +const refreshMetadata = () => { + loading.value = true // const res = target === 'product' // ? await productDetail(route.params.id as string) // : await detail(route.params.id as string); @@ -130,7 +132,8 @@ watch([route.params.id, type], () => { const item = JSON.parse(result || '{}') as MetadataItem[] data.value = item[type]?.sort((a: any, b: any) => b?.sortsIndex - a?.sortsIndex) loading.value = false -}, { immediate: true }) +} +watch([route.params.id, type], refreshMetadata, { immediate: true }) const metadataStore = useMetadataStore() const handleAddClick = () => { diff --git a/src/views/device/components/Metadata/Cat/index.vue b/src/views/device/components/Metadata/Cat/index.vue index bde3f7fd..a9bafd58 100644 --- a/src/views/device/components/Metadata/Cat/index.vue +++ b/src/views/device/components/Metadata/Cat/index.vue @@ -122,7 +122,7 @@ watch( ) watch( - [props.visible, props.type], + () => [props.visible, props.type], () => { if (props.visible) { loading.value = true @@ -136,7 +136,7 @@ watch( } else { productDetail(id as string).then((resp) => { loading.value = false - // productStore.setCurrent(resp.result) + productStore.setCurrent(resp.result) value.value = resp.result.metadata }); } diff --git a/src/views/device/components/Metadata/Import/index.vue b/src/views/device/components/Metadata/Import/index.vue index eb5de412..7d8867b1 100644 --- a/src/views/device/components/Metadata/Import/index.vue +++ b/src/views/device/components/Metadata/Import/index.vue @@ -3,7 +3,7 @@ @ok="handleImport" :confirm-loading="loading">

- + 导入的物模型会覆盖原来的属性、功能、事件、标签,请谨慎操作。

@@ -37,8 +37,7 @@ - - + @@ -62,9 +61,8 @@ import { Store } from 'jetlinks-store'; import { SystemConst } from '@/utils/consts'; import { useInstanceStore } from '@/store/instance' import { useProductStore } from '@/store/product'; -import { UploadOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue'; import { FILE_UPLOAD } from '@/api/comm'; -import { LocalStore, getToken } from '@/utils/comm'; +import { getToken } from '@/utils/comm'; import MonacoEditor from '@/components/MonacoEditor/index.vue' const route = useRoute() @@ -258,13 +256,15 @@ const handleImport = async () => { if (resp.status === 200) { if (props?.type === 'device') { const metadata: DeviceMetadata = JSON.parse(paramsDevice || '{}') + // TODO导入 // MetadataAction.insert(metadata); - instanceStore.setCurrent(metadata) + // instanceStore.setCurrent(metadata) message.success('导入成功') } else { const metadata: ProductItem = JSON.parse(params?.metadata || '{}') + // TODO导入 // MetadataAction.insert(metadata); - productStore.setCurrent(metadata) + // productStore.setCurrent(metadata) message.success('导入成功') } } diff --git a/src/views/device/components/Metadata/index.vue b/src/views/device/components/Metadata/index.vue index 42f3d46d..36ea3747 100644 --- a/src/views/device/components/Metadata/index.vue +++ b/src/views/device/components/Metadata/index.vue @@ -6,7 +6,7 @@ ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响' : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'">
- + {{ instanceStore.detail?.independentMetadata && type === 'device' ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响' @@ -47,7 +47,6 @@ + + diff --git a/src/views/media/Cascade/index.vue b/src/views/media/Cascade/index.vue new file mode 100644 index 00000000..21ac2e94 --- /dev/null +++ b/src/views/media/Cascade/index.vue @@ -0,0 +1,430 @@ + + + diff --git a/src/views/media/Cascade/typings.d.ts b/src/views/media/Cascade/typings.d.ts new file mode 100644 index 00000000..7d2f6fb8 --- /dev/null +++ b/src/views/media/Cascade/typings.d.ts @@ -0,0 +1,41 @@ +type BaseItem = { + id: string; + name: string; +}; + +type State = { + value: string; + text: string; +}; + +type SipConfig = { + catalogEach: number; + charset: string; + clusterNodeId: string; + domain: string; + firmware: string; + hostAndPort: string; + keepaliveInterval: number; + keepaliveTimeoutTimes: number; + localAddress: string; + localSipId: string; + manufacturer: string; + model: string; + name: string; + password: string; + port: number; + publicAddress: string; + publicPort: number; + sipId: string; + stackName: string; + transport: string; + user: string; +}; +export type CascadeItem = { + mediaServerId: string; + onlineStatus: State; + proxyStream: boolean; + sipConfigs: Partial[]; + status: State; + count?: number; +} & BaseItem; diff --git a/src/views/media/Device/Channel/Save.vue b/src/views/media/Device/Channel/Save.vue new file mode 100644 index 00000000..3a6de43c --- /dev/null +++ b/src/views/media/Device/Channel/Save.vue @@ -0,0 +1,267 @@ + + + + diff --git a/src/views/media/Device/Channel/index.vue b/src/views/media/Device/Channel/index.vue index 4ef66e6d..a01bb5ae 100644 --- a/src/views/media/Device/Channel/index.vue +++ b/src/views/media/Device/Channel/index.vue @@ -1,3 +1,4 @@ +
说明
-
{{ slotProps.description }}
+ + {{ slotProps.description }} + diff --git a/src/views/rule-engine/Alarm/Log/TabComponent/indev.vue b/src/views/rule-engine/Alarm/Log/TabComponent/indev.vue new file mode 100644 index 00000000..fede21b6 --- /dev/null +++ b/src/views/rule-engine/Alarm/Log/TabComponent/indev.vue @@ -0,0 +1,316 @@ + + + + diff --git a/src/views/rule-engine/Alarm/Log/index.vue b/src/views/rule-engine/Alarm/Log/index.vue index d9e0a826..da7e6983 100644 --- a/src/views/rule-engine/Alarm/Log/index.vue +++ b/src/views/rule-engine/Alarm/Log/index.vue @@ -1,9 +1,70 @@ \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/Device/InvokeFunction.vue b/src/views/rule-engine/Scene/Save/Device/InvokeFunction.vue new file mode 100644 index 00000000..2c71b4a1 --- /dev/null +++ b/src/views/rule-engine/Scene/Save/Device/InvokeFunction.vue @@ -0,0 +1,106 @@ + + + + + \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/Device/ReadProperties.vue b/src/views/rule-engine/Scene/Save/Device/ReadProperties.vue new file mode 100644 index 00000000..c5b191a4 --- /dev/null +++ b/src/views/rule-engine/Scene/Save/Device/ReadProperties.vue @@ -0,0 +1,81 @@ + + + + + \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/Device/Type.vue b/src/views/rule-engine/Scene/Save/Device/Type.vue index 7d1e0c23..8df13881 100644 --- a/src/views/rule-engine/Scene/Save/Device/Type.vue +++ b/src/views/rule-engine/Scene/Save/Device/Type.vue @@ -7,23 +7,46 @@ >
- + + + + + + + +
\ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/components/FunctionCall/FunctionCall.vue b/src/views/rule-engine/Scene/Save/components/FunctionCall/FunctionCall.vue new file mode 100644 index 00000000..2244b82d --- /dev/null +++ b/src/views/rule-engine/Scene/Save/components/FunctionCall/FunctionCall.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/components/FunctionCall/index.ts b/src/views/rule-engine/Scene/Save/components/FunctionCall/index.ts new file mode 100644 index 00000000..d2ab9e1e --- /dev/null +++ b/src/views/rule-engine/Scene/Save/components/FunctionCall/index.ts @@ -0,0 +1 @@ +export { default as FunctionCall } from './FunctionCall.vue' \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/components/Timer/WhenOption.vue b/src/views/rule-engine/Scene/Save/components/Timer/WhenOption.vue new file mode 100644 index 00000000..345f3fb1 --- /dev/null +++ b/src/views/rule-engine/Scene/Save/components/Timer/WhenOption.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/components/Timer/index.ts b/src/views/rule-engine/Scene/Save/components/Timer/index.ts new file mode 100644 index 00000000..79dacbf1 --- /dev/null +++ b/src/views/rule-engine/Scene/Save/components/Timer/index.ts @@ -0,0 +1,3 @@ +import Timer from './index.vue' + +export default Timer \ No newline at end of file diff --git a/src/views/rule-engine/Scene/Save/components/Timer.vue b/src/views/rule-engine/Scene/Save/components/Timer/index.vue similarity index 68% rename from src/views/rule-engine/Scene/Save/components/Timer.vue rename to src/views/rule-engine/Scene/Save/components/Timer/index.vue index 5f4977f6..03054f3e 100644 --- a/src/views/rule-engine/Scene/Save/components/Timer.vue +++ b/src/views/rule-engine/Scene/Save/components/Timer/index.vue @@ -17,12 +17,26 @@ button-style='solid' /> - - + + @@ -1389,7 +1394,7 @@ import { } from '@/api/system/apply'; import FormLabel from './FormLabel.vue'; import RequestTable from './RequestTable.vue'; -import MenuDialog from './MenuDialog.vue'; +import MenuDialog from '../../componenets/MenuDialog.vue'; import { getImage } from '@/utils/comm'; import type { formType, dictType, optionsType } from '../typing'; import { getRoleList_api } from '@/api/system/user'; @@ -1400,32 +1405,34 @@ import { UploadFile, } from 'ant-design-vue'; import { randomString } from '@/utils/utils'; -import { cloneDeep } from 'lodash'; +import { cloneDeep, difference } from 'lodash'; +import { useMenuStore } from '@/store/menu'; const emit = defineEmits(['changeApplyType']); const routeQuery = useRoute().query; +const menuStory = useMenuStore(); const deptPermission = 'system/Department'; const rolePermission = 'system/Role'; const dialogRef = ref(); +// 初始化表单 const initForm: formType = { name: '', provider: 'internal-standalone', integrationModes: [], - config: '', description: '', page: { // 页面集成 baseUrl: '', routeType: 'hash', - parameters: [{ label: '', value: '' }], + parameters: [], }, apiClient: { // API客户端 baseUrl: '', - headers: [{ label: '', value: '' }], // 请求头 - parameters: [{ label: '', value: '' }], // 请求参数 + headers: [], // 请求头 + parameters: [], // 请求参数 authConfig: { // API客户端 type: 'oauth2', // 类型, 可选值:none, bearer, oauth2, basic, other @@ -1447,13 +1454,12 @@ const initForm: formType = { }, apiServer: { // API服务 - appId: '', + appId: randomString(16), secureKey: randomString(), // 密钥 redirectUri: '', // 重定向URL roleIdList: [], // 角色列表 orgIdList: [], // 部门列表 ipWhiteList: '', // IP白名单 - signature: '', // 签名方式, 可选值:MD5,SHA256 enableOAuth2: false, // 是否启用OAuth2 }, sso: { @@ -1497,9 +1503,9 @@ const initForm: formType = { const formRef = ref(); const form = reactive({ data: { ...initForm }, - integrationModesISO: [] as string[], - roleIdList: [] as optionsType, - orgIdList: [] as dictType, + integrationModesISO: [] as string[], // 接入方式镜像 折叠面板使用 + roleIdList: [] as optionsType, // 角色列表 + orgIdList: [] as dictType, // 组织列表 errorNumInfo: { page: new Set(), @@ -1509,7 +1515,6 @@ const form = reactive({ }, fileList: [] as any[], - fileUrlList: [] as string[], uploadLoading: false, }); // 接入方式的选项 @@ -1591,6 +1596,7 @@ function init() { () => form.data.provider, (n) => { emit('changeApplyType', n); + if (routeQuery.id) return; if (n === 'wechat-webapp' || n === 'dingtalk-ent-app') { form.data.integrationModes = ['ssoClient']; form.integrationModesISO = ['ssoClient']; @@ -1616,6 +1622,7 @@ function getInfo(id: string) { (item: any) => item.value, ), } as formType; + form.data.apiServer && (form.data.apiServer.appId = id); }); } // 获取角色列表 @@ -1651,6 +1658,23 @@ function clickAddItem(data: string[], target: string) { function clickSave() { formRef.value?.validate().then(() => { const params = cloneDeep(form.data); + // 删除多余的参数 + const list = ['page', 'apiClient', 'apiServer', 'ssoClient']; + difference(list, params.integrationModes).forEach((item) => { + if (item === 'ssoClient') { + // @ts-ignore + delete params['sso']; + } + delete params[item]; + }); + clearNullProp(params); + if ( + params.provider === 'internal-standalone' && + params.integrationModes.includes('page') + ) { + // @ts-ignore + delete params.page.parameters; + } if ( params.provider === 'internal-standalone' && @@ -1674,15 +1698,19 @@ function clickSave() { const request = routeQuery.id ? updateApp_api(routeQuery.id as string, params) : addApp_api(params); - request.then((resp) => { + request.then((resp: any) => { if (resp.status === 200) { const isPage = params.integrationModes.includes('page'); if (isPage) { form.data = params; - dialogRef.value && dialogRef.value.openDialog(); + dialogRef.value && + dialogRef.value.openDialog( + routeQuery.id || resp.result.id, + form.data.provider, + ); } else { message.success('保存成功'); - jumpPage('system/Apply'); + menuStory.jumpPage('system/Apply'); } } }); @@ -1722,9 +1750,15 @@ function changeBackUpload(info: UploadChangeParam>) { function test(...args: any[]) { console.log('test:', args); } - -function jumpPage(arg0: string) { - throw new Error('Function not implemented.'); +function clearNullProp(obj: object) { + if (typeof obj !== 'object') return; + for (const prop in obj) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { + const val = obj[prop]; + if (val === '') delete obj[prop]; + else if (typeof val === 'object') clearNullProp(obj[prop]); + } + } } @@ -1743,6 +1777,16 @@ function jumpPage(arg0: string) { :deep(.ant-form-item-control) { .ant-form-item-control-input-content { display: flex; + .ant-upload-select-picture-card { + width: auto; + height: auto; + max-width: 150px; + max-height: 150px; + + >.ant-upload { + height: 150px; + } + } } } } diff --git a/src/views/system/Apply/Save/components/MenuDialog.vue b/src/views/system/Apply/Save/components/MenuDialog.vue deleted file mode 100644 index b706bf1e..00000000 --- a/src/views/system/Apply/Save/components/MenuDialog.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/system/Apply/Save/components/RequestTable.vue b/src/views/system/Apply/Save/components/RequestTable.vue index 888d5e76..4c8ff9ee 100644 --- a/src/views/system/Apply/Save/components/RequestTable.vue +++ b/src/views/system/Apply/Save/components/RequestTable.vue @@ -88,6 +88,7 @@ const tableData = computed(() => { return props.value.slice((current.value - 1) * 10, current.value * 10); }); +if(props.value.length < 1) addRow() watch( () => props.value, (n, o) => { diff --git a/src/views/system/Apply/Save/typing.d.ts b/src/views/system/Apply/Save/typing.d.ts index af68633c..2bc07a2f 100644 --- a/src/views/system/Apply/Save/typing.d.ts +++ b/src/views/system/Apply/Save/typing.d.ts @@ -19,7 +19,7 @@ export type formType = { name: string; provider: applyType; integrationModes: string[]; - config: string; + config?: string; description: string; page: { // 页面集成 baseUrl: string, @@ -54,7 +54,7 @@ export type formType = { roleIdList: string[], // 角色列表 orgIdList: string[], // 部门列表 ipWhiteList: string, // IP白名单 - signature: 'MD5' | 'SHA256' | '', // 签名方式, 可选值:MD5,SHA256 + signature?: 'MD5' | 'SHA256' | '', // 签名方式, 可选值:MD5,SHA256 enableOAuth2: boolean, // 是否启用OAuth2 }, sso: { // 统一单点登陆集成 diff --git a/src/views/system/Apply/View/index.vue b/src/views/system/Apply/View/index.vue new file mode 100644 index 00000000..8e67c7ce --- /dev/null +++ b/src/views/system/Apply/View/index.vue @@ -0,0 +1,14 @@ + + + + + diff --git a/src/views/system/Apply/componenets/MenuDialog.vue b/src/views/system/Apply/componenets/MenuDialog.vue new file mode 100644 index 00000000..bc4a5d7a --- /dev/null +++ b/src/views/system/Apply/componenets/MenuDialog.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/src/views/system/Apply/index.vue b/src/views/system/Apply/index.vue index aa8d8021..967e61de 100644 --- a/src/views/system/Apply/index.vue +++ b/src/views/system/Apply/index.vue @@ -1,5 +1,5 @@ @@ -151,11 +160,15 @@ +
+ +
+ + diff --git a/src/views/system/Platforms/Api/components/LeftTree.vue b/src/views/system/Platforms/Api/components/LeftTree.vue index 63d31d99..7420a355 100644 --- a/src/views/system/Platforms/Api/components/LeftTree.vue +++ b/src/views/system/Platforms/Api/components/LeftTree.vue @@ -2,6 +2,7 @@ @@ -14,16 +15,23 @@