Commit d8a328be8fec8d082e36e3793a198213d1dc013d

Authored by fengwotao
1 parent e2b70c09

pref:调整公共接口管理

... ... @@ -34,6 +34,8 @@ enum Api {
34 34 getTenantProfile = '/tenant_profiles',
35 35 deleteTenantProfile = '/tenantProfile',
36 36 setTenantProfile = '/tenantProfile',
  37 + getTenantPageList = '/admin/all/tenants',
  38 + getTenantAllPageList = '/admin/',
37 39 }
38 40
39 41 export async function deleteTenantProfileApi(ids: string) {
... ... @@ -155,3 +157,15 @@ export function getTenantRoles(tenantCode: string) {
155 157 url: Api.getTenantRoles,
156 158 });
157 159 }
  160 +
  161 +export function getTenantPageList() {
  162 + return defHttp.get({
  163 + url: Api.getTenantPageList,
  164 + });
  165 +}
  166 +
  167 +export function getTenantAllPageLists(tenantId) {
  168 + return defHttp.get({
  169 + url: `${Api.getTenantAllPageList}${tenantId}/all/tenant_admin`,
  170 + });
  171 +}
... ...
... ... @@ -39,6 +39,7 @@ export interface TenantPageRequestParams extends BaseQueryParams {
39 39 }
40 40
41 41 export interface TenantAdminPageRequestParams extends BaseQueryParams {
  42 + [x: string]: any;
42 43 realName?: string;
43 44 tenantId?: string;
44 45 items?: string[];
... ...
... ... @@ -42,8 +42,6 @@
42 42
43 43 const role: string = userInfo?.roles[0];
44 44
45   - console.log({ role });
46   -
47 45 const loading = ref(true);
48 46
49 47 setTimeout(() => {
... ...
... ... @@ -22,6 +22,7 @@
22 22 v-show="getRequestBody.content.requestParamsBodyType === 'x-www-form-urlencoded'"
23 23 />
24 24 <JsonEditor
  25 + style="width: 35vw; height: 30vh"
25 26 v-show="getRequestBody.content.requestParamsBodyType === 'json'"
26 27 ref="jsonEditorRef"
27 28 />
... ...
... ... @@ -20,7 +20,7 @@
20 20 mode: 'code',
21 21 mainMenuBar: false,
22 22 statusBar: false,
23   - };
  23 + } as object;
24 24 let editor = new jsoneditor(jsoneditorRef.value, options);
25 25 editor.set(jsonValue.value);
26 26 jsonInstance.value = editor;
... ...
... ... @@ -2,15 +2,45 @@
2 2 <div>
3 3 <div class="mt-8">
4 4 <div class="flex">
5   - <Button @click="handleTest" type="primary"> 打开测试接口 </Button>
6   - <Button class="ml-2" @click="onCloseTest" type="primary"> 关闭测试接口 </Button>
  5 + <div class="flex" v-if="isAdmin(role)">
  6 + <Select
  7 + v-model:value="selectTenant"
  8 + allowClear
  9 + @change="onSelect"
  10 + style="width: 150px"
  11 + :getPopupContainer="
  12 + (triggerNode) => {
  13 + return triggerNode.parentNode;
  14 + }
  15 + "
  16 + placeholder="请选择租户"
  17 + :options="selectOptions"
  18 + />
  19 + <Select
  20 + v-model:value="selectSysTenant"
  21 + allowClear
  22 + @change="onSelctTenant"
  23 + style="width: 150px; margin-left: 10px"
  24 + v-if="selectTenantOptions.length > 0"
  25 + :getPopupContainer="
  26 + (triggerNode) => {
  27 + return triggerNode.parentNode;
  28 + }
  29 + "
  30 + placeholder="请选择租户"
  31 + :options="selectTenantOptions"
  32 + />
  33 + </div>
  34 + <Button class="ml-2" @click="handleTest(isSingleClickText)" type="primary"
  35 + >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
  36 + </Button>
7 37 </div>
8 38 <div v-if="showTestEditCell" class="mt-8">
9 39 <a-row type="flex" justify="center">
10 40 <a-col :span="3"> 参数设置 </a-col>
11 41 <a-col :span="21">
12 42 <div v-if="data?.type === 'x-www-form-urlencoded' || data?.type === 'form-data'">
13   - <TestBodyCellTable ref="testEditCellTableRef" />
  43 + <TestBodyCellTable :token="getToken" ref="testEditCellTableRef" />
14 44 </div>
15 45 <div style="width: 30vw" v-else-if="data?.type === 'json'">
16 46 <JsonEditor ref="jsonEditorRef" />
... ... @@ -26,13 +56,24 @@
26 56 </div>
27 57 </template>
28 58 <script lang="ts" setup name="testRequest">
29   - import { ref, nextTick } from 'vue';
  59 + import { ref, nextTick, onMounted } from 'vue';
30 60 import { Button } from 'ant-design-vue';
31 61 import TestBodyCellTable from './testEditBodyCellTable.vue';
32 62 import moment from 'moment';
33 63 import { useUtils } from '../../../hooks/useUtils';
34 64 import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
35 65 import { useMessage } from '/@/hooks/web/useMessage';
  66 + import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
  67 + import { selectType } from '../../../types';
  68 + import { Select } from 'ant-design-vue';
  69 + import { getUserToken } from '/@/api/sys/user';
  70 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  71 + import { getAuthCache } from '/@/utils/auth';
  72 + import { isAdmin } from '/@/enums/roleEnum';
  73 +
  74 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  75 +
  76 + const role: string = userInfo?.roles[0];
36 77
37 78 const emits = defineEmits(['testBodyInterface', 'closeTest']);
38 79
... ... @@ -42,12 +83,31 @@
42 83 },
43 84 });
44 85
  86 + onMounted(async () => {
  87 + if (isAdmin(role)) {
  88 + const res = await getTenantPageList();
  89 + selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
  90 + } else {
  91 + //租户
  92 + const { token } = await getUserToken(userInfo?.userId);
  93 + getToken.value = token;
  94 + }
  95 + });
  96 +
  97 + const selectOptions = ref<selectType[]>([]);
  98 +
  99 + const selectTenantOptions = ref<selectType[]>([]);
  100 +
45 101 const { createMessage } = useMessage();
46 102
47 103 const showTestEditCell = ref(false);
48 104
49 105 const excuteData = ref({});
50 106
  107 + const selectTenant = ref(undefined);
  108 +
  109 + const selectSysTenant = ref(undefined);
  110 +
51 111 const xmlContent = ref('');
52 112
53 113 const testEditCellTableRef = ref<InstanceType<typeof TestBodyCellTable>>();
... ... @@ -58,10 +118,37 @@
58 118
59 119 const { getMultipleKeys } = useUtils();
60 120
61   - const handleTest = () => {
62   - showTestEditCell.value = true;
63   - emits('testBodyInterface');
64   - getValue();
  121 + const getToken = ref('');
  122 +
  123 + const onSelect = async (e) => {
  124 + selectSysTenant.value = undefined;
  125 + const rest = (await getTenantAllPageLists(e)) as any;
  126 + selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
  127 + };
  128 +
  129 + const onSelctTenant = async (e) => {
  130 + const { token } = await getUserToken(e);
  131 + getToken.value = token;
  132 + };
  133 +
  134 + const isSingleClickText = ref('open');
  135 +
  136 + const handleTest = (o) => {
  137 + if (isAdmin(role)) {
  138 + if (!selectTenant.value || !selectSysTenant.value) {
  139 + createMessage.error('请选择租户或者租户管理员');
  140 + throw Error('请选择租户或者租户管理员');
  141 + }
  142 + }
  143 + if (o === 'open') {
  144 + showTestEditCell.value = true;
  145 + emits('testBodyInterface');
  146 + getValue();
  147 + isSingleClickText.value = 'close';
  148 + } else {
  149 + isSingleClickText.value = 'open';
  150 + onCloseTest();
  151 + }
65 152 };
66 153
67 154 const getValue = async () => {
... ... @@ -141,6 +228,7 @@
141 228 }
142 229 excuteData.value = {
143 230 params,
  231 + token: getToken.value,
144 232 };
145 233 return excuteData.value;
146 234 };
... ... @@ -149,6 +237,9 @@
149 237 const setValue = () => {
150 238 showTestEditCell.value = false;
151 239 testResult.value = '';
  240 + selectTenant.value = undefined;
  241 + selectSysTenant.value = undefined;
  242 + selectTenantOptions.value = [];
152 243 };
153 244
154 245 const onCloseTest = () => {
... ...
... ... @@ -130,9 +130,8 @@
130 130 import { reactive, ref, onMounted } from 'vue';
131 131 import { Select } from 'ant-design-vue';
132 132 import { findDictItemByCode } from '/@/api/system/dict';
133   - import { getAllDeviceByOrg } from '/@/api/dataBoard';
134   - import { getDeviceAttributes } from '/@/api/dataBoard';
135 133 import { useApi } from '../../../hooks/useApi';
  134 + import { useUtils } from '../../../hooks/useUtils';
136 135 import { cloneDeep } from 'lodash-es';
137 136 import { tableItems, selectType } from '../../../types';
138 137 import { editTestCellTableTHeadConfig } from '../../../config';
... ... @@ -142,6 +141,9 @@
142 141 method: {
143 142 type: String,
144 143 },
  144 + token: {
  145 + type: String,
  146 + },
145 147 });
146 148
147 149 onMounted(async () => {
... ... @@ -155,6 +157,8 @@
155 157 selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
156 158 });
157 159
  160 + const { isOtherHttp } = useUtils();
  161 +
158 162 const selectOptions = ref<selectType[]>([]);
159 163
160 164 const valueOptions = ref<selectType[]>([]);
... ... @@ -199,10 +203,10 @@
199 203 const getApi = (list) => {
200 204 list?.forEach(async (it) => {
201 205 if (it.key === 'deviceProfileId') {
202   - const { options } = await useApi(it.key);
  206 + const { options } = await useApi(it.key, props.token);
203 207 valueOptions.value = options;
204 208 } else if (it.key === 'organizationId') {
205   - const { options } = await useApi(it.key);
  209 + const { options } = await useApi(it.key, props.token);
206 210 treeData.value = options as any;
207 211 }
208 212 });
... ... @@ -220,7 +224,10 @@
220 224 };
221 225
222 226 const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
223   - const res = await getAllDeviceByOrg(organizationId, deviceProfileId);
  227 + const res = await isOtherHttp('api/yt/device/list', props.token, {
  228 + organizationId,
  229 + deviceProfileId,
  230 + });
224 231 entityOptions.value = res.map((item) => ({
225 232 label: item.name,
226 233 value: item.tbDeviceId,
... ... @@ -228,7 +235,10 @@
228 235 };
229 236
230 237 const getAttributeOptions = async (params) => {
231   - const res = await getDeviceAttributes(params);
  238 + const { deviceProfileId, dataType } = params;
  239 + const res = await isOtherHttp(`api/yt/device/attributes/${deviceProfileId}`, props.token, {
  240 + dataType,
  241 + });
232 242 if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);
233 243 attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
234 244 };
... ...
... ... @@ -5,25 +5,14 @@
5 5 </div>
6 6 <div class="mt-8">
7 7 <a-row type="flex" justify="center">
8   - <a-col :span="24">
9   - <a-textarea
10   - disabled
  8 + <a-col :span="2"> 测试结果 </a-col>
  9 + <a-col :span="22">
  10 + <JsonEditor
11 11 v-if="isWebSocketType === '2'"
12   - allow-clear
13   - show-count
14   - v-model:value="testResult"
15   - placeholder="测试结果为:"
16   - :rows="8"
17   - />
18   - <a-textarea
19   - disabled
20   - v-else
21   - allow-clear
22   - show-count
23   - v-model:value="httpResult"
24   - placeholder="测试结果为:"
25   - :rows="8"
  12 + style="width: 35vw; height: 40vh"
  13 + ref="jsonWebsocketEditorRef"
26 14 />
  15 + <JsonEditor v-else style="width: 35vw; height: 40vh" ref="jsonEditorRef" />
27 16 </a-col>
28 17 </a-row>
29 18 </div>
... ... @@ -34,9 +23,8 @@
34 23 import { Button } from 'ant-design-vue';
35 24 import { otherHttp } from '/@/utils/http/axios';
36 25 import { useWebSocket } from '@vueuse/core';
37   - import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
38   - import { getAuthCache } from '/@/utils/auth';
39 26 import { useUtils } from '../../../hooks/useUtils';
  27 + import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
40 28
41 29 const emits = defineEmits(['emitExcute']);
42 30
... ... @@ -48,7 +36,9 @@
48 36
49 37 const showTestFlag = ref(false);
50 38
51   - const token = getAuthCache(JWT_TOKEN_KEY);
  39 + const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
  40 +
  41 + const jsonWebsocketEditorRef = ref<InstanceType<typeof JsonEditor>>();
52 42
53 43 const socketUrls = ref('');
54 44
... ... @@ -79,11 +69,11 @@
79 69 return formatString(this, replacements);
80 70 };
81 71
82   - const testResult = ref('');
  72 + const isWebSocketType = ref('');
83 73
84   - const httpResult = ref('');
  74 + const isToken = ref('');
85 75
86   - const isWebSocketType = ref('');
  76 + const isPostToken = ref('');
87 77
88 78 //执行测试接口
89 79 const handleExcute = () => {
... ... @@ -100,11 +90,13 @@
100 90 const url = Objects?.apiGetUrl;
101 91 const headers = Objects?.Header?.params;
102 92 const params = Objects?.Params?.params;
  93 + isToken.value = Objects?.Params?.token;
103 94 const body = Objects?.Body?.params;
  95 + isPostToken.value = Objects?.Body?.token;
104 96 const apiUrl = url?.restfulFormat(params);
105 97 if (isWebSocketType.value === '2') {
106 98 socketUrls.value = url;
107   - socketMessage.server = `${socketUrls.value}?token=${token}`;
  99 + socketMessage.server = `${socketUrls.value}?token=${isToken.value}`;
108 100 const list = Object.values(params);
109 101 const isEmpty = list.some((it) => it === '' || null || undefined);
110 102 if (!isEmpty) {
... ... @@ -113,20 +105,38 @@
113 105 resetValue(false);
114 106 }
115 107 } else {
116   - const resp = await otherHttpRequest(apiType, apiUrl?.split('{?')[0], headers, params, body);
  108 + const resp = await otherHttpRequest(
  109 + apiType,
  110 + apiUrl?.split('{?')[0],
  111 + headers,
  112 + params,
  113 + body,
  114 + isToken.value,
  115 + isPostToken.value
  116 + );
117 117 if (!resp) return;
118   - httpResult.value = JSON.stringify(resp);
  118 + if (Object.prototype.toString.call(resp) === '[object Object]') {
  119 + jsonEditorRef.value?.setJsonValue(resp);
  120 + } else if (typeof resp === 'string') {
  121 + jsonEditorRef.value?.setJsonValue(resp);
  122 + } else if (Array.isArray(resp)) {
  123 + jsonEditorRef.value?.setJsonValue(JSON.stringify(resp));
  124 + } else {
  125 + jsonEditorRef.value?.setJsonValue(JSON.stringify(resp));
  126 + }
119 127 }
120 128 };
121 129
122 130 //websocket请求
123 131 const websocketRequest = (params, destroy = false) => {
124 132 //websocket请求
125   - Reflect.deleteProperty(params, 'deviceProfileId');
126   - Reflect.deleteProperty(params, 'organizationId');
127   - Reflect.set(params, 'cmdId', 1);
128   - Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
129   - Reflect.set(params, 'entityType', 'DEVICE');
  133 + if (Object.prototype.toString.call(params) === '[object Object]') {
  134 + Reflect.deleteProperty(params, 'deviceProfileId');
  135 + Reflect.deleteProperty(params, 'organizationId');
  136 + Reflect.set(params, 'cmdId', 1);
  137 + Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
  138 + Reflect.set(params, 'entityType', 'DEVICE');
  139 + }
130 140 socketMessage.sendValue.tsSubCmds.push(params);
131 141 const { send, close } = useWebSocket(socketMessage.server, {
132 142 onConnected() {
... ... @@ -135,7 +145,15 @@
135 145 },
136 146 onMessage(_, e) {
137 147 const { data } = JSON.parse(e.data);
138   - testResult.value = JSON.stringify(data);
  148 + if (Object.prototype.toString.call(data) === '[object Object]') {
  149 + jsonWebsocketEditorRef.value?.setJsonValue(data);
  150 + } else if (typeof data === 'string') {
  151 + jsonWebsocketEditorRef.value?.setJsonValue(data);
  152 + } else if (Array.isArray(data)) {
  153 + jsonWebsocketEditorRef.value?.setJsonValue(JSON.stringify(data));
  154 + } else {
  155 + jsonEditorRef.value?.setJsonValue(JSON.stringify(data));
  156 + }
139 157 },
140 158 onDisconnected() {
141 159 console.log('断开连接了');
... ... @@ -159,32 +177,40 @@
159 177 headers = {},
160 178 params = {},
161 179 body,
  180 + token,
  181 + postToken,
162 182 joinPrefix = false
163 183 ) => {
  184 + const { convertObj } = useUtils();
164 185 switch (apiType) {
165 186 case 'GET':
  187 + const objGet = Object.assign({}, headers, { 'X-Authorization': `Bearer ${token}` });
166 188 return await otherHttp.get(
167   - { url: apiUrl, params, headers },
  189 + { url: apiUrl, params, headers: objGet },
168 190 {
169 191 apiUrl: '',
170 192 joinPrefix,
  193 + withToken: false,
171 194 }
172 195 );
173 196 case 'POST':
174   - const { convertObj } = useUtils();
  197 + const objPost = Object.assign({}, headers, { 'X-Authorization': `Bearer ${postToken}` });
175 198 return await otherHttp.post(
176   - { url: `${apiUrl}?${convertObj(params)}`, data: body, headers },
  199 + { url: `${apiUrl}?${convertObj(params)}`, data: body, headers: objPost },
177 200 {
178 201 apiUrl: '',
179 202 joinPrefix,
  203 + withToken: false,
180 204 }
181 205 );
182 206 case 'PUT':
  207 + const objPut = Object.assign({}, headers, { 'X-Authorization': `Bearer ${postToken}` });
183 208 return await otherHttp.put(
184   - { url: apiUrl, data: body, headers, params },
  209 + { url: `${apiUrl}?${convertObj(params)}`, data: body, headers: objPut, params },
185 210 {
186 211 apiUrl: '',
187 212 joinPrefix,
  213 + withToken: false,
188 214 }
189 215 );
190 216 }
... ... @@ -194,8 +220,8 @@
194 220 if (flag) {
195 221 showTestFlag.value = false;
196 222 }
197   - httpResult.value = '测试结果为:';
198   - testResult.value = '测试结果为:';
  223 + jsonEditorRef.value?.setJsonValue({});
  224 + jsonWebsocketEditorRef.value?.setJsonValue({});
199 225 isWebSocketType.value = '0';
200 226 };
201 227
... ...
... ... @@ -2,8 +2,38 @@
2 2 <div>
3 3 <div class="mt-8">
4 4 <div class="flex">
5   - <Button @click="handleTest" type="primary"> 打开测试接口 </Button>
6   - <Button class="ml-2" @click="onCloseTest" type="primary"> 关闭测试接口 </Button>
  5 + <div class="flex" v-if="isAdmin(role)">
  6 + <Select
  7 + allowClear
  8 + v-model:value="selectTenant"
  9 + @change="onSelect"
  10 + style="width: 150px"
  11 + :getPopupContainer="
  12 + (triggerNode) => {
  13 + return triggerNode.parentNode;
  14 + }
  15 + "
  16 + placeholder="请选择租户"
  17 + :options="selectOptions"
  18 + />
  19 + <Select
  20 + v-model:value="selectSysTenant"
  21 + allowClear
  22 + @change="onSelctTenant"
  23 + style="width: 150px; margin-left: 10px"
  24 + v-if="selectTenantOptions.length > 0"
  25 + :getPopupContainer="
  26 + (triggerNode) => {
  27 + return triggerNode.parentNode;
  28 + }
  29 + "
  30 + placeholder="请选择租户"
  31 + :options="selectTenantOptions"
  32 + />
  33 + </div>
  34 + <Button class="ml-2" @click="handleTest(isSingleClickText)" type="primary"
  35 + >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
  36 + </Button>
7 37 </div>
8 38 <div v-if="showTestEditCell" class="mt-8">
9 39 <a-row type="flex" justify="center">
... ... @@ -18,33 +48,90 @@
18 48 </div>
19 49 </template>
20 50 <script lang="ts" setup name="testRequest">
21   - import { ref, nextTick } from 'vue';
  51 + import { ref, nextTick, onMounted } from 'vue';
22 52 import { Button } from 'ant-design-vue';
23 53 import TestHeaderEditCellTable from './testEditHeaderCellTable.vue';
24 54 import { useMessage } from '/@/hooks/web/useMessage';
  55 + import { selectType } from '../../../types';
  56 + import { Select } from 'ant-design-vue';
  57 + import { getUserToken } from '/@/api/sys/user';
  58 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  59 + import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
  60 + import { getAuthCache } from '/@/utils/auth';
  61 + import { isAdmin } from '/@/enums/roleEnum';
25 62
26 63 const emits = defineEmits(['testHeaderInterface', 'closeTest']);
27 64
  65 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  66 +
  67 + const role: string = userInfo?.roles[0];
  68 +
28 69 const props = defineProps({
29 70 data: {
30 71 type: Object,
31 72 },
32 73 });
33 74
  75 + onMounted(async () => {
  76 + if (isAdmin(role)) {
  77 + const res = await getTenantPageList();
  78 + selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
  79 + } else {
  80 + //租户
  81 + const { token } = await getUserToken(userInfo?.userId);
  82 + getToken.value = token;
  83 + }
  84 + });
  85 +
  86 + const selectOptions = ref<selectType[]>([]);
  87 +
  88 + const selectTenantOptions = ref<selectType[]>([]);
  89 +
34 90 const { createMessage } = useMessage();
35 91
36 92 const showTestEditCell = ref(false);
37 93
38 94 const excuteData = ref({});
39 95
  96 + const selectTenant = ref(undefined);
  97 +
  98 + const selectSysTenant = ref(undefined);
  99 +
40 100 const testEditCellTableRef = ref<InstanceType<typeof TestHeaderEditCellTable>>();
41 101
42 102 const testResult = ref('');
43 103
44   - const handleTest = () => {
45   - showTestEditCell.value = true;
46   - emits('testHeaderInterface');
47   - getValue();
  104 + const getToken = ref('');
  105 +
  106 + const onSelect = async (e) => {
  107 + selectSysTenant.value = undefined;
  108 + const rest = (await getTenantAllPageLists(e)) as any;
  109 + selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
  110 + };
  111 +
  112 + const onSelctTenant = async (e) => {
  113 + const { token } = await getUserToken(e);
  114 + getToken.value = token;
  115 + };
  116 +
  117 + const isSingleClickText = ref('open');
  118 +
  119 + const handleTest = (o) => {
  120 + if (isAdmin(role)) {
  121 + if (!selectTenant.value || !selectSysTenant.value) {
  122 + createMessage.error('请选择租户或者租户管理员');
  123 + throw Error('请选择租户或者租户管理员');
  124 + }
  125 + }
  126 + if (o === 'open') {
  127 + showTestEditCell.value = true;
  128 + emits('testHeaderInterface');
  129 + getValue();
  130 + isSingleClickText.value = 'close';
  131 + } else {
  132 + isSingleClickText.value = 'open';
  133 + onCloseTest();
  134 + }
48 135 };
49 136
50 137 const getValue = async () => {
... ... @@ -72,6 +159,7 @@
72 159 getTable?.map((it: any) => (params[it.key!] = it.value!));
73 160 excuteData.value = {
74 161 params,
  162 + token: getToken.value,
75 163 };
76 164 return excuteData.value;
77 165 };
... ... @@ -80,6 +168,9 @@
80 168 const setValue = () => {
81 169 showTestEditCell.value = false;
82 170 testResult.value = '';
  171 + selectTenant.value = undefined;
  172 + selectSysTenant.value = undefined;
  173 + selectTenantOptions.value = [];
83 174 };
84 175
85 176 const onCloseTest = () => {
... ...
... ... @@ -2,14 +2,34 @@
2 2 <div>
3 3 <div class="mt-8">
4 4 <div class="flex">
5   - <Button @click="handleTest" type="primary"> 打开测试接口 </Button>
6   - <Button class="ml-2" @click="onCloseTest" type="primary"> 关闭测试接口 </Button>
  5 + <div class="flex" v-if="isAdmin(role)">
  6 + <Select
  7 + allowClear
  8 + v-model:value="selectTenant"
  9 + @change="onSelect"
  10 + style="width: 150px"
  11 + placeholder="请选择租户"
  12 + :options="selectOptions"
  13 + />
  14 + <Select
  15 + v-model:value="selectSysTenant"
  16 + allowClear
  17 + @change="onSelctTenant"
  18 + style="width: 150px; margin-left: 10px"
  19 + v-if="selectTenantOptions.length > 0"
  20 + placeholder="请选择租户"
  21 + :options="selectTenantOptions"
  22 + />
  23 + </div>
  24 + <Button class="ml-2" @click="handleTest(isSingleClickText)" type="primary"
  25 + >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
  26 + </Button>
7 27 </div>
8 28 <div v-if="showTestEditCell" class="mt-8">
9 29 <a-row type="flex" justify="center">
10 30 <a-col :span="3"> 参数设置 </a-col>
11 31 <a-col :span="21">
12   - <TestParamsCellTable ref="testEditCellTableRef" />
  32 + <TestParamsCellTable :token="getToken" ref="testEditCellTableRef" />
13 33 </a-col>
14 34 </a-row>
15 35 </div>
... ... @@ -18,12 +38,23 @@
18 38 </div>
19 39 </template>
20 40 <script lang="ts" setup name="testRequest">
21   - import { ref, nextTick } from 'vue';
  41 + import { ref, nextTick, onMounted } from 'vue';
22 42 import { Button } from 'ant-design-vue';
23 43 import TestParamsCellTable from './testEditParamsCellTable.vue';
24 44 import moment from 'moment';
25 45 import { useUtils } from '../../../hooks/useUtils';
26 46 import { useMessage } from '/@/hooks/web/useMessage';
  47 + import { getTenantAllPageLists, getTenantPageList } from '/@/api/tenant/tenantApi';
  48 + import { selectType } from '../../../types';
  49 + import { Select } from 'ant-design-vue';
  50 + import { getUserToken } from '/@/api/sys/user';
  51 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  52 + import { getAuthCache } from '/@/utils/auth';
  53 + import { isAdmin } from '/@/enums/roleEnum';
  54 +
  55 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  56 +
  57 + const role: string = userInfo?.roles[0];
27 58
28 59 const emits = defineEmits(['testParamsInterface', 'closeTest']);
29 60
... ... @@ -33,22 +64,67 @@
33 64 },
34 65 });
35 66
  67 + onMounted(async () => {
  68 + if (isAdmin(role)) {
  69 + const res = await getTenantPageList();
  70 + selectOptions.value = res.map((m) => ({ label: m.name, value: m.tenantId }));
  71 + } else {
  72 + //租户
  73 + const { token } = await getUserToken(userInfo?.userId);
  74 + getToken.value = token;
  75 + }
  76 + });
  77 +
  78 + const selectOptions = ref<selectType[]>([]);
  79 +
  80 + const selectTenantOptions = ref<selectType[]>([]);
  81 +
36 82 const { createMessage } = useMessage();
37 83
38 84 const showTestEditCell = ref(false);
39 85
40 86 const excuteData = ref({});
41 87
  88 + const selectTenant = ref(undefined);
  89 +
  90 + const selectSysTenant = ref(undefined);
  91 +
42 92 const testEditCellTableRef = ref<InstanceType<typeof TestParamsCellTable>>();
43 93
44 94 const testResult = ref('');
45 95
46 96 const { getMultipleKeys } = useUtils();
47 97
48   - const handleTest = () => {
49   - showTestEditCell.value = true;
50   - emits('testParamsInterface');
51   - getValue();
  98 + const getToken = ref('');
  99 +
  100 + const onSelect = async (e) => {
  101 + selectSysTenant.value = undefined;
  102 + const rest = (await getTenantAllPageLists(e)) as any;
  103 + selectTenantOptions.value = rest?.map((m) => ({ label: m.realName, value: m.id }));
  104 + };
  105 +
  106 + const onSelctTenant = async (e) => {
  107 + const { token } = await getUserToken(e);
  108 + getToken.value = token;
  109 + };
  110 + const isSingleClickText = ref('open');
  111 +
  112 + const handleTest = (o) => {
  113 + if (isAdmin(role)) {
  114 + if (!selectTenant.value || !selectSysTenant.value) {
  115 + createMessage.error('请选择租户或者租户管理员');
  116 + throw Error('请选择租户或者租户管理员');
  117 + }
  118 + }
  119 + if (o === 'open') {
  120 + showTestEditCell.value = true;
  121 + emits('testParamsInterface');
  122 + getValue();
  123 + isSingleClickText.value = 'close';
  124 + } else {
  125 + isSingleClickText.value = 'open';
  126 + onCloseTest();
  127 + }
52 128 };
53 129
54 130 const getValue = async () => {
... ... @@ -116,6 +192,7 @@
116 192 }
117 193 excuteData.value = {
118 194 params,
  195 + token: getToken.value,
119 196 };
120 197 return excuteData.value;
121 198 };
... ... @@ -124,6 +201,9 @@
124 201 const setValue = () => {
125 202 showTestEditCell.value = false;
126 203 testResult.value = '';
  204 + selectTenant.value = undefined;
  205 + selectSysTenant.value = undefined;
  206 + selectTenantOptions.value = [];
127 207 };
128 208
129 209 const onCloseTest = () => {
... ...
... ... @@ -130,9 +130,8 @@
130 130 import { reactive, ref, onMounted } from 'vue';
131 131 import { Select } from 'ant-design-vue';
132 132 import { findDictItemByCode } from '/@/api/system/dict';
133   - import { getAllDeviceByOrg } from '/@/api/dataBoard';
134   - import { getDeviceAttributes } from '/@/api/dataBoard';
135 133 import { useApi } from '../../../hooks/useApi';
  134 + import { useUtils } from '../../../hooks/useUtils';
136 135 import { cloneDeep } from 'lodash-es';
137 136 import { tableItems, selectType } from '../../../types';
138 137 import { editTestCellTableTHeadConfig } from '../../../config';
... ... @@ -142,6 +141,9 @@
142 141 method: {
143 142 type: String,
144 143 },
  144 + token: {
  145 + type: String,
  146 + },
145 147 });
146 148
147 149 onMounted(async () => {
... ... @@ -155,6 +157,8 @@
155 157 selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
156 158 });
157 159
  160 + const { isOtherHttp } = useUtils();
  161 +
158 162 const selectOptions = ref<selectType[]>([]);
159 163
160 164 const valueOptions = ref<selectType[]>([]);
... ... @@ -191,10 +195,10 @@
191 195 const getApi = (list) => {
192 196 list?.forEach(async (it) => {
193 197 if (it.key === 'deviceProfileId') {
194   - const { options } = await useApi(it.key);
  198 + const { options } = await useApi(it.key, props.token);
195 199 valueOptions.value = options;
196 200 } else if (it.key === 'organizationId') {
197   - const { options } = await useApi(it.key);
  201 + const { options } = await useApi(it.key, props.token);
198 202 treeData.value = options as any;
199 203 }
200 204 });
... ... @@ -212,7 +216,10 @@
212 216 };
213 217
214 218 const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
215   - const res = await getAllDeviceByOrg(organizationId, deviceProfileId);
  219 + const res = await isOtherHttp('api/yt/device/list', props.token, {
  220 + organizationId,
  221 + deviceProfileId,
  222 + });
216 223 entityOptions.value = res.map((item) => ({
217 224 label: item.name,
218 225 value: item.tbDeviceId,
... ... @@ -220,7 +227,10 @@
220 227 };
221 228
222 229 const getAttributeOptions = async (params) => {
223   - const res = await getDeviceAttributes(params);
  230 + const { deviceProfileId, dataType } = params;
  231 + const res = await isOtherHttp(`api/yt/device/attributes/${deviceProfileId}`, props.token, {
  232 + dataType,
  233 + });
224 234 if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);
225 235 attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
226 236 };
... ...
... ... @@ -102,6 +102,7 @@ export const schemas: FormSchema[] = [
102 102 getPopupContainer: () => document.body,
103 103 async onChange(e) {
104 104 setFieldsValue({
  105 + requestOriginUrl: '',
105 106 requestHttpTypeAndUrl: {
106 107 requestHttpType: undefined,
107 108 requestUrl: '',
... ... @@ -113,6 +114,14 @@ export const schemas: FormSchema[] = [
113 114 type: e,
114 115 },
115 116 });
  117 + updateSchema({
  118 + field: 'requestOriginUrl',
  119 + componentProps: {
  120 + placeholder: `${
  121 + e === '0' ? '示例:http://127.0.0.1' : e === '2' ? '示例:ws://127.0.0.1' : ''
  122 + }`,
  123 + },
  124 + });
116 125 },
117 126 };
118 127 },
... ... @@ -124,14 +133,24 @@ export const schemas: FormSchema[] = [
124 133 required: true,
125 134 colProps: { span: 24 },
126 135 defaultValue: 'server_url',
127   - componentProps: {
128   - placeholder: '请选择地址类型',
129   - api: findDictItemByCode,
130   - params: {
131   - dictCode: 'dataview_select_origin_type',
132   - },
133   - labelField: 'itemText',
134   - valueField: 'itemValue',
  136 + componentProps: ({ formActionType }) => {
  137 + const { setFieldsValue } = formActionType;
  138 + return {
  139 + placeholder: '请选择地址类型',
  140 + api: findDictItemByCode,
  141 + params: {
  142 + dictCode: 'dataview_select_origin_type',
  143 + },
  144 + labelField: 'itemText',
  145 + valueField: 'itemValue',
  146 + onChange: (e) => {
  147 + if (e) {
  148 + setFieldsValue({
  149 + requestOriginUrl: '',
  150 + });
  151 + }
  152 + },
  153 + };
135 154 },
136 155 },
137 156 {
... ... @@ -140,9 +159,14 @@ export const schemas: FormSchema[] = [
140 159 colProps: { span: 24 },
141 160 required: true,
142 161 component: 'Input',
143   - componentProps: {
144   - maxLength: 255,
145   - placeholder: '请输入地址',
  162 + componentProps: ({ formActionType }) => {
  163 + const { getFieldsValue } = formActionType;
  164 + const type = getFieldsValue()?.requestContentType;
  165 + return {
  166 + placeholder: `${
  167 + type === '0' ? '示例:http://127.0.0.1' : type === '2' ? '示例:ws://127.0.0.1' : ''
  168 + }`,
  169 + };
146 170 },
147 171 ifShow: ({ values }) => values['originUrlType'] === 'custom_url',
148 172 },
... ... @@ -160,6 +184,13 @@ export const schemas: FormSchema[] = [
160 184 },
161 185 },
162 186 {
  187 + field: 'fillAddress',
  188 + label: '完整地址',
  189 + component: 'Input',
  190 + slot: 'slotFillAddress',
  191 + colProps: { span: 24 },
  192 + },
  193 + {
163 194 field: 'requestSQLKey',
164 195 label: '键名',
165 196 colProps: { span: 6 },
... ...
1 1 <template>
2 2 <div>
3 3 <BasicDrawer
  4 + destroyOnClose
4 5 showFooter
5 6 v-bind="$attrs"
6 7 @register="registerDrawer"
... ... @@ -27,6 +28,24 @@
27 28 />
28 29 </div>
29 30 </template>
  31 + <template #slotFillAddress="{ model }">
  32 + <div>
  33 + <Tag style="height: 3.3vh; line-height: 3.3vh">
  34 + {{
  35 + ` ${
  36 + model['originUrlType'] !== 'server_url'
  37 + ? !model['requestOriginUrl']
  38 + ? ''
  39 + : model['requestOriginUrl'] + model['requestHttpTypeAndUrl']?.requestUrl
  40 + : `${templateFillAddress(model['requestContentType'], model['originUrlType'])}${
  41 + model['requestHttpTypeAndUrl']?.requestUrl
  42 + }`
  43 + }
  44 + `
  45 + }}
  46 + </Tag>
  47 + </div>
  48 + </template>
30 49 </BasicForm>
31 50 </BasicDrawer>
32 51 </div>
... ... @@ -45,8 +64,9 @@
45 64
46 65 import { useMessage } from '/@/hooks/web/useMessage';
47 66 import { useUtils } from './hooks/useUtils';
  67 + import { Tag } from 'ant-design-vue';
48 68
49   - const { resetReqHttpType } = useUtils();
  69 + const { resetReqHttpType, isServerUrl } = useUtils();
50 70
51 71 const emits = defineEmits(['success', 'register']);
52 72
... ... @@ -60,6 +80,10 @@
60 80
61 81 const testSqlRef = ref<InstanceType<typeof TestSql>>();
62 82
  83 + const templateFillAddress = (method, type) => {
  84 + return isServerUrl(method, type);
  85 + };
  86 +
63 87 const [registerForm, { resetFields, validate, setFieldsValue, updateSchema }] = useForm({
64 88 labelWidth: 120,
65 89 schemas,
... ... @@ -110,12 +134,19 @@
110 134 const values = await validate();
111 135 if (!values) return;
112 136 const isRequestHttpTypeAndUrlEmpty = values?.requestHttpTypeAndUrl;
113   - if (
114   - !Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestHttpType') ||
115   - !Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestUrl')
116   - ) {
117   - createMessage.error('请填写请求类型&地址');
118   - throw Error('请填写请求类型&地址');
  137 + if (values.requestContentType === '0') {
  138 + if (
  139 + !Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestHttpType') ||
  140 + !Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestUrl')
  141 + ) {
  142 + createMessage.error('请填写请求类型&地址');
  143 + throw Error('请填写请求类型&地址');
  144 + }
  145 + } else if (values.requestContentType === '2') {
  146 + if (!Reflect.get(isRequestHttpTypeAndUrlEmpty, 'requestUrl')) {
  147 + createMessage.error('请填写请求类型&地址');
  148 + throw Error('请填写请求类型&地址');
  149 + }
119 150 }
120 151 const Objects = simpleRequestRef.value?.getValue(true);
121 152 const requestOriginUrl =
... ...
1 1 import { ref } from 'vue';
2   -import { deviceProfile } from '/@/api/device/deviceManager';
3   -import { getOrganizationList } from '/@/api/system/system';
4   -// import { copyTransFun } from '/@/utils/fnUtils';
5   -// import { getAllDeviceByOrg } from '/@/api/dataBoard';
6   -// import { getDeviceAttributes } from '/@/api/dataBoard';
7 2 import { copyTransFun } from '/@/utils/fnUtils';
  3 +import { useUtils } from './useUtils';
8 4
9   -export const useApi = async (key) => {
  5 +export const useApi = async (key, token) => {
  6 + const { isOtherHttp } = useUtils();
10 7 const options = ref<{ label: string; value: string; disabled?: boolean }[]>([]);
11 8 switch (key) {
12 9 case 'deviceProfileId':
13   - const res = await deviceProfile();
  10 + const res = (await isOtherHttp('/api/yt/device_profile/me/list', token, {})) as any;
14 11 options.value = res?.map((m) => ({ label: m.name, value: m.id }));
15 12 break;
16 13 case 'organizationId':
17   - const data = await getOrganizationList();
  14 + const data = await isOtherHttp('/api/yt/organization/me/list', token, {});
18 15 copyTransFun(data as never as any);
19 16 options.value = data as any;
20 17 }
... ...
  1 +import { otherHttp } from '/@/utils/http/axios';
  2 +
1 3 export const useUtils = () => {
2 4 //获取多个key
3 5 const getMultipleKeys = (list) => {
... ... @@ -51,5 +53,44 @@ export const useUtils = () => {
51 53 }
52 54 return _result.join('&');
53 55 };
54   - return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema, convertObj };
  56 + //判断服务器地址是否为http/https ws/wss
  57 + const isServerUrl = (method, type) => {
  58 + const pathUrl = window.location.host;
  59 + const protocol = window.location.protocol;
  60 + let url = '';
  61 + if (method === '2') {
  62 + if (type === 'server_url') {
  63 + url = `${protocol === 'http' ? 'ws:' : protocol === 'https' ? 'wss:' : 'ws:'}//${pathUrl}`;
  64 + }
  65 + } else if (method === '0') {
  66 + if (type === 'server_url') {
  67 + url = `${protocol}//${pathUrl}`;
  68 + }
  69 + }
  70 + return url;
  71 + };
  72 + //TODO:待优化自定义请求
  73 + const isOtherHttp = async (url, token, params) => {
  74 + return await otherHttp.get(
  75 + {
  76 + url,
  77 + headers: { 'X-Authorization': `Bearer ${token}` },
  78 + params,
  79 + },
  80 + {
  81 + apiUrl: '',
  82 + withToken: false,
  83 + joinPrefix: false,
  84 + }
  85 + );
  86 + };
  87 + return {
  88 + getMultipleKeys,
  89 + pushObj,
  90 + resetReqHttpType,
  91 + resetUpdateSchema,
  92 + isServerUrl,
  93 + convertObj,
  94 + isOtherHttp,
  95 + };
55 96 };
... ...