Commit c9cd2fada671ecefe40f91d61ddbede9eefb1fbb

Authored by xp.Huang
2 parents 98be9762 f17f2ee0

Merge branch 'main_dev'

# Conflicts:
#	src/views/dataview/publicApi/components/SimpleRequest/components/bodyTable.vue
#	src/views/dataview/publicApi/components/SimpleRequest/components/paramsTable.vue
#	src/views/dataview/publicApi/components/TestInterface/bodyTest/index.vue
#	src/views/dataview/publicApi/components/TestInterface/bodyTest/testEditBodyCellTable.vue
#	src/views/dataview/publicApi/components/TestInterface/components/excuteTest.vue
#	src/views/dataview/publicApi/components/TestInterface/headerTest/index.vue
#	src/views/dataview/publicApi/components/TestInterface/paramsTest/index.vue
#	src/views/dataview/publicApi/components/TestInterface/paramsTest/testEditParamsCellTable.vue
#	src/views/dataview/publicApi/form.vue
#	src/views/dataview/publicApi/hooks/useUtils.ts
#	src/views/dataview/publicApi/list.vue
#	src/views/device/profiles/CardMode.vue
1 -<template>  
2 - <div class="table-content">  
3 - <!-- 采用的原生表格 -->  
4 - <table align="center">  
5 - <thead>  
6 - <tr>  
7 - <th v-for="item in editCellTableTHeadConfig" :key="item">{{ item }}</th>  
8 - </tr>  
9 - </thead>  
10 - <tbody>  
11 - <tr v-for="(item, index) in tableArray.content" :key="index">  
12 - <td>  
13 - {{ index + 1 }}  
14 - </td>  
15 - <td style="width: 12vw">  
16 - <Select  
17 - v-model:value="item.key"  
18 - placeholder="请选择"  
19 - :options="selectOptions"  
20 - @change="handleChange"  
21 - @dropdownVisibleChange="hanldeDropdownVisibleChange"  
22 - allowClear  
23 - />  
24 - </td>  
25 - <td style="width: 12vw">  
26 - <div v-if="item.key === 'date_range'">  
27 - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />  
28 - <span>~</span>  
29 - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />  
30 - </div>  
31 - <div v-else>  
32 - <a-input  
33 - :disabled="item.editDisabled"  
34 - placeholder="请输入"  
35 - v-model:value="item.value"  
36 - />  
37 - </div>  
38 - </td>  
39 - <td style="width: 4vw">  
40 - <a-switch v-model:checked="item.required" />  
41 - </td>  
42 - <td style="width: 4vw">  
43 - <div>  
44 - <Button type="dashed" @click="add(item, index)">  
45 - <template #icon><PlusOutlined /></template  
46 - ></Button>  
47 - <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">  
48 - <template #icon> <MinusOutlined /></template>  
49 - </Button>  
50 - </div>  
51 - </td>  
52 - </tr>  
53 - </tbody>  
54 - </table>  
55 - </div>  
56 -</template>  
57 -<script lang="ts" setup name="editCellTable">  
58 - import { reactive, ref, onMounted, nextTick } from 'vue';  
59 - import { Select, Button } from 'ant-design-vue';  
60 - import { findDictItemByCode } from '/@/api/system/dict';  
61 - import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';  
62 - import { editCellTableTHeadConfig } from '../../../config';  
63 - import { selectType, tableItems } from '../../../types';  
64 -  
65 - defineProps({  
66 - method: {  
67 - type: String,  
68 - },  
69 - });  
70 -  
71 - const selectOptions = ref<selectType[]>([]);  
72 -  
73 - onMounted(() => {  
74 - getSelectOptions();  
75 - });  
76 -  
77 - const getSelectOptions = async () => {  
78 - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });  
79 - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));  
80 - selectOptions.value.push({  
81 - label: '自定义',  
82 - value: 'scope',  
83 - });  
84 - };  
85 -  
86 - const tableArray = reactive<{  
87 - content: tableItems[];  
88 - }>({  
89 - content: [  
90 - {  
91 - key: undefined,  
92 - value: '',  
93 - editDisabled: false,  
94 - required: false,  
95 - date1: '',  
96 - date2: '',  
97 - },  
98 - ],  
99 - });  
100 -  
101 - // 新增  
102 - const add = (_, index: number) => {  
103 - tableArray.content.splice(index + 1, 0, {  
104 - key: undefined,  
105 - value: '',  
106 - editDisabled: false,  
107 - required: false,  
108 - date1: '',  
109 - date2: '',  
110 - });  
111 - };  
112 -  
113 - // 减少  
114 - const remove = (item, index: number) => {  
115 - if (tableArray.content.length > 1) {  
116 - selectOptions.value.forEach((ele) => {  
117 - if (ele.value == item.key) {  
118 - ele.disabled = false;  
119 - }  
120 - });  
121 - tableArray.content.splice(index, 1);  
122 - } else {  
123 - resetValue();  
124 - }  
125 - };  
126 -  
127 - const hanldeDropdownVisibleChange = () => handleChange();  
128 -  
129 - //Select互斥  
130 - const handleChange = () => {  
131 - selectOptions.value.forEach((ele) => {  
132 - ele.disabled = false;  
133 - tableArray.content.forEach((element) => {  
134 - if (element.key === 'scope' || element.key === 'fixed_date') {  
135 - element.editDisabled = false;  
136 - } else {  
137 - element.value = '';  
138 - element.editDisabled = true;  
139 - }  
140 - if (element.key === ele.value && element.key !== 'scope') {  
141 - ele.disabled = true;  
142 - }  
143 - });  
144 - });  
145 - };  
146 -  
147 - //获取数据  
148 - const getValue = () => {  
149 - const assemblyData = tableArray.content.map((it) => {  
150 - return {  
151 - key: it.key,  
152 - value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,  
153 - editDisabled: it.editDisabled,  
154 - required: it.required,  
155 - };  
156 - });  
157 - return assemblyData;  
158 - };  
159 -  
160 - //设置数据  
161 - const setValue = async (data) => {  
162 - await nextTick();  
163 - const assemblyData = data.map((it) => {  
164 - return {  
165 - key: it.key,  
166 - value: it.value,  
167 - editDisabled: it.editDisabled,  
168 - required: it.required,  
169 - date1: it.key === 'date_range' ? it.value?.split(',')?.at(-2) : '',  
170 - date2: it.key === 'date_range' ? it.value?.split(',')?.at(-1) : '',  
171 - };  
172 - });  
173 - tableArray.content = assemblyData;  
174 - tableArray.content.forEach(() => {  
175 - handleChange();  
176 - });  
177 - };  
178 -  
179 - //重置数据  
180 - const resetValue = () => {  
181 - tableArray.content = [];  
182 - tableArray.content.push({  
183 - key: undefined,  
184 - value: '',  
185 - editDisabled: false,  
186 - required: false,  
187 - date1: '',  
188 - date2: '',  
189 - });  
190 - nextTick(() => {  
191 - tableArray.content.forEach(() => {  
192 - handleChange();  
193 - });  
194 - });  
195 - };  
196 - defineExpose({  
197 - getValue,  
198 - setValue,  
199 - resetValue,  
200 - });  
201 -</script>  
202 -  
203 -<style scoped lang="less">  
204 - @table-color: #e5e7eb;  
205 -  
206 - .table-border-color {  
207 - border: 1px solid #e5e7eb;  
208 - text-align: center;  
209 - }  
210 -  
211 - .table-content {  
212 - overflow-x: auto;  
213 -  
214 - table {  
215 - border-collapse: collapse;  
216 - width: 35vw;  
217 - &:extend(.table-border-color);  
218 - }  
219 -  
220 - table thead {  
221 - white-space: nowrap;  
222 - }  
223 -  
224 - table td {  
225 - padding: 5px;  
226 - white-space: nowrap;  
227 - &:extend(.table-border-color);  
228 - }  
229 -  
230 - table th {  
231 - padding: 5px;  
232 - &:extend(.table-border-color);  
233 - }  
234 - }  
235 -</style> 1 +<template>
  2 + <div class="table-content">
  3 + <!-- 采用的原生表格 -->
  4 + <table align="center">
  5 + <thead>
  6 + <tr>
  7 + <th v-for="item in editCellTableTHeadConfig" :key="item">{{ item }}</th>
  8 + </tr>
  9 + </thead>
  10 + <tbody>
  11 + <tr v-for="(item, index) in tableArray.content" :key="index">
  12 + <td>
  13 + {{ index + 1 }}
  14 + </td>
  15 + <td style="width: 12vw">
  16 + <Select
  17 + v-model:value="item.key"
  18 + placeholder="请选择"
  19 + :options="selectOptions"
  20 + @change="handleChange"
  21 + allowClear
  22 + />
  23 + </td>
  24 + <td style="width: 12vw">
  25 + <div v-if="item.key === 'date_range'">
  26 + <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />
  27 + <span>~</span>
  28 + <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />
  29 + </div>
  30 + <div v-else>
  31 + <a-input
  32 + :disabled="item.editDisabled"
  33 + placeholder="请输入"
  34 + v-model:value="item.value"
  35 + />
  36 + </div>
  37 + </td>
  38 + <td style="width: 4vw">
  39 + <a-switch v-model:checked="item.required" />
  40 + </td>
  41 + <td style="width: 4vw">
  42 + <div>
  43 + <Button type="dashed" @click="add(item, index)">
  44 + <template #icon><PlusOutlined /></template
  45 + ></Button>
  46 + <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">
  47 + <template #icon> <MinusOutlined /></template>
  48 + </Button>
  49 + </div>
  50 + </td>
  51 + </tr>
  52 + </tbody>
  53 + </table>
  54 + </div>
  55 +</template>
  56 +<script lang="ts" setup name="editCellTable">
  57 + import { reactive, ref, onMounted, nextTick } from 'vue';
  58 + import { Select, Button } from 'ant-design-vue';
  59 + import { findDictItemByCode } from '/@/api/system/dict';
  60 + import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
  61 + import { editCellTableTHeadConfig } from '../../../config';
  62 + import { selectType, tableItems } from '../../../types';
  63 +
  64 + defineProps({
  65 + method: {
  66 + type: String,
  67 + },
  68 + });
  69 +
  70 + const selectOptions = ref<selectType[]>([]);
  71 +
  72 + onMounted(() => {
  73 + getSelectOptions();
  74 + });
  75 +
  76 + const getSelectOptions = async () => {
  77 + const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
  78 + selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
  79 + selectOptions.value.push({
  80 + label: '自定义',
  81 + value: 'scope',
  82 + });
  83 + };
  84 +
  85 + const tableArray = reactive<{
  86 + content: tableItems[];
  87 + }>({
  88 + content: [
  89 + {
  90 + key: undefined,
  91 + value: '',
  92 + editDisabled: false,
  93 + required: false,
  94 + date1: '',
  95 + date2: '',
  96 + },
  97 + ],
  98 + });
  99 +
  100 + // 新增
  101 + const add = (_, index: number) => {
  102 + tableArray.content.splice(index + 1, 0, {
  103 + key: undefined,
  104 + value: '',
  105 + editDisabled: false,
  106 + required: false,
  107 + date1: '',
  108 + date2: '',
  109 + });
  110 + };
  111 +
  112 + // 减少
  113 + const remove = (item, index: number) => {
  114 + if (tableArray.content.length !== 1) {
  115 + selectOptions.value.forEach((ele) => {
  116 + if (ele.value == item.key) {
  117 + ele.disabled = false;
  118 + }
  119 + });
  120 + tableArray.content.splice(index, 1);
  121 + }
  122 + };
  123 +
  124 + //Select互斥
  125 + const handleChange = () => {
  126 + selectOptions.value.forEach((ele) => {
  127 + ele.disabled = false;
  128 + tableArray.content.forEach((element) => {
  129 + if (element.key === 'scope' || element.key === 'fixed_date') {
  130 + element.editDisabled = false;
  131 + } else {
  132 + element.value = '';
  133 + element.editDisabled = true;
  134 + }
  135 + if (element.key === ele.value && element.key !== 'scope' && element.key !== 'fixed_date') {
  136 + ele.disabled = true;
  137 + }
  138 + });
  139 + });
  140 + };
  141 +
  142 + //获取数据
  143 + const getValue = () => {
  144 + const assemblyData = tableArray.content.map((it) => {
  145 + return {
  146 + key: it.key,
  147 + value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,
  148 + editDisabled: it.editDisabled,
  149 + required: it.required,
  150 + };
  151 + });
  152 + return assemblyData;
  153 + };
  154 +
  155 + //设置数据
  156 + const setValue = async (data) => {
  157 + await nextTick();
  158 + const assemblyData = data.map((it) => {
  159 + return {
  160 + key: it.key,
  161 + value: it.value,
  162 + editDisabled: it.editDisabled,
  163 + required: it.required,
  164 + date1: it.key === 'date_range' ? it.value?.split(',')?.at(-2) : '',
  165 + date2: it.key === 'date_range' ? it.value?.split(',')?.at(-1) : '',
  166 + };
  167 + });
  168 + tableArray.content = assemblyData;
  169 + tableArray.content.forEach(() => {
  170 + handleChange();
  171 + });
  172 + };
  173 +
  174 + //重置数据
  175 + const resetValue = () => {
  176 + tableArray.content = [];
  177 + tableArray.content.push({
  178 + key: undefined,
  179 + value: '',
  180 + editDisabled: false,
  181 + required: false,
  182 + date1: '',
  183 + date2: '',
  184 + });
  185 + nextTick(() => {
  186 + tableArray.content.forEach(() => {
  187 + handleChange();
  188 + });
  189 + });
  190 + };
  191 + defineExpose({
  192 + getValue,
  193 + setValue,
  194 + resetValue,
  195 + });
  196 +</script>
  197 +
  198 +<style scoped lang="less">
  199 + @table-color: #e5e7eb;
  200 +
  201 + .table-border-color {
  202 + border: 1px solid #e5e7eb;
  203 + text-align: center;
  204 + }
  205 +
  206 + .table-content {
  207 + overflow-x: auto;
  208 +
  209 + table {
  210 + border-collapse: collapse;
  211 + width: 35vw;
  212 + &:extend(.table-border-color);
  213 + }
  214 +
  215 + table thead {
  216 + white-space: nowrap;
  217 + }
  218 +
  219 + table td {
  220 + padding: 5px;
  221 + white-space: nowrap;
  222 + &:extend(.table-border-color);
  223 + }
  224 +
  225 + table th {
  226 + padding: 5px;
  227 + &:extend(.table-border-color);
  228 + }
  229 + }
  230 +</style>
1 -<template>  
2 - <div class="table-content">  
3 - <!-- 采用的原生表格 -->  
4 - <table align="center">  
5 - <thead>  
6 - <tr>  
7 - <th v-for="item in editCellTableTHeadConfig" :key="item">{{ item }}</th>  
8 - </tr>  
9 - </thead>  
10 - <tbody>  
11 - <tr v-for="(item, index) in tableArray.content" :key="index">  
12 - <td>  
13 - {{ index + 1 }}  
14 - </td>  
15 - <td style="width: 12vw">  
16 - <Select  
17 - v-model:value="item.key"  
18 - placeholder="请选择"  
19 - :options="selectOptions"  
20 - @change="handleChange"  
21 - @dropdownVisibleChange="hanldeDropdownVisibleChange"  
22 - allowClear  
23 - />  
24 - </td>  
25 - <td style="width: 12vw">  
26 - <div v-if="item.key === 'date_range'">  
27 - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />  
28 - <span>~</span>  
29 - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />  
30 - </div>  
31 - <div v-else>  
32 - <a-input  
33 - :disabled="item.editDisabled"  
34 - placeholder="请输入"  
35 - v-model:value="item.value"  
36 - />  
37 - </div>  
38 - </td>  
39 - <td style="width: 4vw">  
40 - <a-switch v-model:checked="item.required" />  
41 - </td>  
42 - <td style="width: 4vw">  
43 - <div>  
44 - <Button type="dashed" @click="add(item, index)">  
45 - <template #icon><PlusOutlined /></template  
46 - ></Button>  
47 - <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">  
48 - <template #icon> <MinusOutlined /></template>  
49 - </Button>  
50 - </div>  
51 - </td>  
52 - </tr>  
53 - </tbody>  
54 - </table>  
55 - </div>  
56 -</template>  
57 -<script lang="ts" setup name="editCellTable">  
58 - import { reactive, ref, onMounted, nextTick } from 'vue';  
59 - import { Select, Button } from 'ant-design-vue';  
60 - import { findDictItemByCode } from '/@/api/system/dict';  
61 - import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';  
62 - import { editCellTableTHeadConfig } from '../../../config';  
63 - import { selectType, tableItems } from '../../../types';  
64 -  
65 - defineProps({  
66 - method: {  
67 - type: String,  
68 - },  
69 - });  
70 -  
71 - const selectOptions = ref<selectType[]>([]);  
72 -  
73 - onMounted(() => {  
74 - getSelectOptions();  
75 - });  
76 -  
77 - const getSelectOptions = async () => {  
78 - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });  
79 - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));  
80 - selectOptions.value.push({  
81 - label: '自定义',  
82 - value: 'scope',  
83 - });  
84 - };  
85 -  
86 - const tableArray = reactive<{  
87 - content: tableItems[];  
88 - }>({  
89 - content: [  
90 - {  
91 - key: undefined,  
92 - value: '',  
93 - editDisabled: false,  
94 - required: false,  
95 - date1: '',  
96 - date2: '',  
97 - },  
98 - ],  
99 - });  
100 -  
101 - // 新增  
102 - const add = (_, index: number) => {  
103 - tableArray.content.splice(index + 1, 0, {  
104 - key: undefined,  
105 - value: '',  
106 - editDisabled: false,  
107 - required: false,  
108 - date1: '',  
109 - date2: '',  
110 - });  
111 - };  
112 -  
113 - // 减少  
114 - const remove = (item, index: number) => {  
115 - if (tableArray.content.length > 1) {  
116 - selectOptions.value.forEach((ele) => {  
117 - if (ele.value == item.key) {  
118 - ele.disabled = false;  
119 - }  
120 - });  
121 - tableArray.content.splice(index, 1);  
122 - } else {  
123 - resetValue();  
124 - }  
125 - };  
126 -  
127 - //Select互斥  
128 - const handleChange = () => {  
129 - selectOptions.value.forEach((ele) => {  
130 - ele.disabled = false;  
131 - tableArray.content.forEach((element) => {  
132 - if (element.key === 'scope' || element.key === 'fixed_date') {  
133 - element.editDisabled = false;  
134 - } else {  
135 - element.value = '';  
136 - element.editDisabled = true;  
137 - }  
138 - if (element.key === ele.value && element.key !== 'scope') {  
139 - ele.disabled = true;  
140 - }  
141 - });  
142 - });  
143 - };  
144 -  
145 - const hanldeDropdownVisibleChange = () => handleChange();  
146 -  
147 - //获取数据  
148 - const getValue = () => {  
149 - const assemblyData = tableArray.content.map((it) => {  
150 - return {  
151 - key: it.key,  
152 - value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,  
153 - editDisabled: it.editDisabled,  
154 - required: it.required,  
155 - };  
156 - });  
157 - return assemblyData;  
158 - };  
159 -  
160 - //设置数据  
161 - const setValue = async (data) => {  
162 - await nextTick();  
163 - const assemblyData = data.map((it) => {  
164 - return {  
165 - key: it.key,  
166 - value: it.value,  
167 - editDisabled: it.editDisabled,  
168 - required: it.required,  
169 - date1: it.key === 'date_range' ? it.value?.split(',')?.at(-2) : '',  
170 - date2: it.key === 'date_range' ? it.value?.split(',')?.at(-1) : '',  
171 - };  
172 - });  
173 - tableArray.content = assemblyData;  
174 - tableArray.content.forEach(() => {  
175 - handleChange();  
176 - });  
177 - };  
178 -  
179 - //重置数据  
180 - const resetValue = () => {  
181 - tableArray.content = [];  
182 - tableArray.content.push({  
183 - key: undefined,  
184 - value: '',  
185 - editDisabled: false,  
186 - required: false,  
187 - date1: '',  
188 - date2: '',  
189 - });  
190 - nextTick(() => {  
191 - tableArray.content.forEach(() => {  
192 - handleChange();  
193 - });  
194 - });  
195 - };  
196 - defineExpose({  
197 - getValue,  
198 - setValue,  
199 - resetValue,  
200 - });  
201 -</script>  
202 -  
203 -<style scoped lang="less">  
204 - @table-color: #e5e7eb;  
205 -  
206 - .table-border-color {  
207 - border: 1px solid #e5e7eb;  
208 - text-align: center;  
209 - }  
210 -  
211 - .table-content {  
212 - overflow-x: auto;  
213 -  
214 - table {  
215 - border-collapse: collapse;  
216 - width: 35vw;  
217 - &:extend(.table-border-color);  
218 - }  
219 -  
220 - table thead {  
221 - white-space: nowrap;  
222 - }  
223 -  
224 - table td {  
225 - padding: 5px;  
226 - white-space: nowrap;  
227 - &:extend(.table-border-color);  
228 - }  
229 -  
230 - table th {  
231 - padding: 5px;  
232 - &:extend(.table-border-color);  
233 - }  
234 - }  
235 -</style> 1 +<template>
  2 + <div class="table-content">
  3 + <!-- 采用的原生表格 -->
  4 + <table align="center">
  5 + <thead>
  6 + <tr>
  7 + <th v-for="item in editCellTableTHeadConfig" :key="item">{{ item }}</th>
  8 + </tr>
  9 + </thead>
  10 + <tbody>
  11 + <tr v-for="(item, index) in tableArray.content" :key="index">
  12 + <td>
  13 + {{ index + 1 }}
  14 + </td>
  15 + <td style="width: 12vw">
  16 + <Select
  17 + v-model:value="item.key"
  18 + placeholder="请选择"
  19 + :options="selectOptions"
  20 + @change="handleChange"
  21 + allowClear
  22 + />
  23 + </td>
  24 + <td style="width: 12vw">
  25 + <div v-if="item.key === 'date_range'">
  26 + <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />
  27 + <span>~</span>
  28 + <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />
  29 + </div>
  30 + <div v-else>
  31 + <a-input
  32 + :disabled="item.editDisabled"
  33 + placeholder="请输入"
  34 + v-model:value="item.value"
  35 + />
  36 + </div>
  37 + </td>
  38 + <td style="width: 4vw">
  39 + <a-switch v-model:checked="item.required" />
  40 + </td>
  41 + <td style="width: 4vw">
  42 + <div>
  43 + <Button type="dashed" @click="add(item, index)">
  44 + <template #icon><PlusOutlined /></template
  45 + ></Button>
  46 + <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">
  47 + <template #icon> <MinusOutlined /></template>
  48 + </Button>
  49 + </div>
  50 + </td>
  51 + </tr>
  52 + </tbody>
  53 + </table>
  54 + </div>
  55 +</template>
  56 +<script lang="ts" setup name="editCellTable">
  57 + import { reactive, ref, onMounted, nextTick } from 'vue';
  58 + import { Select, Button } from 'ant-design-vue';
  59 + import { findDictItemByCode } from '/@/api/system/dict';
  60 + import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
  61 + import { editCellTableTHeadConfig } from '../../../config';
  62 + import { selectType, tableItems } from '../../../types';
  63 +
  64 + defineProps({
  65 + method: {
  66 + type: String,
  67 + },
  68 + });
  69 +
  70 + const selectOptions = ref<selectType[]>([]);
  71 +
  72 + onMounted(() => {
  73 + getSelectOptions();
  74 + });
  75 +
  76 + const getSelectOptions = async () => {
  77 + const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
  78 + selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
  79 + selectOptions.value.push({
  80 + label: '自定义',
  81 + value: 'scope',
  82 + });
  83 + };
  84 +
  85 + const tableArray = reactive<{
  86 + content: tableItems[];
  87 + }>({
  88 + content: [
  89 + {
  90 + key: undefined,
  91 + value: '',
  92 + editDisabled: false,
  93 + required: false,
  94 + date1: '',
  95 + date2: '',
  96 + },
  97 + ],
  98 + });
  99 +
  100 + // 新增
  101 + const add = (_, index: number) => {
  102 + tableArray.content.splice(index + 1, 0, {
  103 + key: undefined,
  104 + value: '',
  105 + editDisabled: false,
  106 + required: false,
  107 + date1: '',
  108 + date2: '',
  109 + });
  110 + };
  111 +
  112 + // 减少
  113 + const remove = (item, index: number) => {
  114 + if (tableArray.content.length !== 1) {
  115 + selectOptions.value.forEach((ele) => {
  116 + if (ele.value == item.key) {
  117 + ele.disabled = false;
  118 + }
  119 + });
  120 + tableArray.content.splice(index, 1);
  121 + }
  122 + };
  123 +
  124 + //Select互斥
  125 + const handleChange = () => {
  126 + selectOptions.value.forEach((ele) => {
  127 + ele.disabled = false;
  128 + tableArray.content.forEach((element) => {
  129 + if (element.key === 'scope' || element.key === 'fixed_date') {
  130 + element.editDisabled = false;
  131 + } else {
  132 + element.value = '';
  133 + element.editDisabled = true;
  134 + }
  135 + if (element.key === ele.value && element.key !== 'scope' && element.key !== 'fixed_date') {
  136 + ele.disabled = true;
  137 + }
  138 + });
  139 + });
  140 + };
  141 +
  142 + //获取数据
  143 + const getValue = () => {
  144 + const assemblyData = tableArray.content.map((it) => {
  145 + return {
  146 + key: it.key,
  147 + value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,
  148 + editDisabled: it.editDisabled,
  149 + required: it.required,
  150 + };
  151 + });
  152 + return assemblyData;
  153 + };
  154 +
  155 + //设置数据
  156 + const setValue = async (data) => {
  157 + await nextTick();
  158 + const assemblyData = data.map((it) => {
  159 + return {
  160 + key: it.key,
  161 + value: it.value,
  162 + editDisabled: it.editDisabled,
  163 + required: it.required,
  164 + date1: it.key === 'date_range' ? it.value?.split(',')?.at(-2) : '',
  165 + date2: it.key === 'date_range' ? it.value?.split(',')?.at(-1) : '',
  166 + };
  167 + });
  168 + tableArray.content = assemblyData;
  169 + tableArray.content.forEach(() => {
  170 + handleChange();
  171 + });
  172 + };
  173 +
  174 + //重置数据
  175 + const resetValue = () => {
  176 + tableArray.content = [];
  177 + tableArray.content.push({
  178 + key: undefined,
  179 + value: '',
  180 + editDisabled: false,
  181 + required: false,
  182 + date1: '',
  183 + date2: '',
  184 + });
  185 + nextTick(() => {
  186 + tableArray.content.forEach(() => {
  187 + handleChange();
  188 + });
  189 + });
  190 + };
  191 + defineExpose({
  192 + getValue,
  193 + setValue,
  194 + resetValue,
  195 + });
  196 +</script>
  197 +
  198 +<style scoped lang="less">
  199 + @table-color: #e5e7eb;
  200 +
  201 + .table-border-color {
  202 + border: 1px solid #e5e7eb;
  203 + text-align: center;
  204 + }
  205 +
  206 + .table-content {
  207 + overflow-x: auto;
  208 +
  209 + table {
  210 + border-collapse: collapse;
  211 + width: 35vw;
  212 + &:extend(.table-border-color);
  213 + }
  214 +
  215 + table thead {
  216 + white-space: nowrap;
  217 + }
  218 +
  219 + table td {
  220 + padding: 5px;
  221 + white-space: nowrap;
  222 + &:extend(.table-border-color);
  223 + }
  224 +
  225 + table th {
  226 + padding: 5px;
  227 + &:extend(.table-border-color);
  228 + }
  229 + }
  230 +</style>
1 -<template>  
2 - <div>  
3 - <div class="mt-8">  
4 - <div>  
5 - <Button @click="handleTest" type="primary"> 测试接口 </Button>  
6 - </div>  
7 - <div v-if="showTestEditCell" class="mt-8">  
8 - <a-row type="flex" justify="center">  
9 - <a-col :span="3"> 参数设置 </a-col>  
10 - <a-col :span="21">  
11 - <div v-if="data?.type === 'x-www-form-urlencoded' || data?.type === 'form-data'">  
12 - <TestBodyCellTable ref="testEditCellTableRef" />  
13 - </div>  
14 - <div style="width: 30vw" v-else-if="data?.type === 'json'">  
15 - <JsonEditor ref="jsonEditorRef" />  
16 - </div>  
17 - <div style="width: 30vw" v-else-if="data?.type === 'xml'">  
18 - <a-textarea v-model:value="xmlContent" placeholder="请输入xml" :rows="6" />  
19 - </div>  
20 - </a-col>  
21 - </a-row>  
22 - </div>  
23 - </div>  
24 - <div class="mt-8"> </div>  
25 - </div>  
26 -</template>  
27 -<script lang="ts" setup name="testRequest">  
28 - import { ref, nextTick } from 'vue';  
29 - import { Button } from 'ant-design-vue';  
30 - import TestBodyCellTable from './testEditBodyCellTable.vue';  
31 - import moment from 'moment';  
32 - import { useUtils } from '../../../hooks/useUtils';  
33 - import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';  
34 - import { useMessage } from '/@/hooks/web/useMessage';  
35 -  
36 - const emits = defineEmits(['testBodyInterface']);  
37 -  
38 - const props = defineProps({  
39 - data: {  
40 - type: Object,  
41 - },  
42 - });  
43 -  
44 - const { createMessage } = useMessage();  
45 -  
46 - const showTestEditCell = ref(false);  
47 -  
48 - const excuteData = ref({});  
49 -  
50 - const xmlContent = ref('');  
51 -  
52 - const testEditCellTableRef = ref<InstanceType<typeof TestBodyCellTable>>();  
53 -  
54 - const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();  
55 -  
56 - const testResult = ref('');  
57 -  
58 - const { getMultipleKeys } = useUtils();  
59 -  
60 - const handleTest = () => {  
61 - showTestEditCell.value = true;  
62 - emits('testBodyInterface');  
63 - getValue();  
64 - };  
65 -  
66 - const getValue = async () => {  
67 - await nextTick();  
68 - await nextTick(() => {  
69 - if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {  
70 - const getSingleKey = props.data?.list;  
71 - const getMuteKey = props.data?.list?.filter((it: any) => it.key?.split(',').length > 1);  
72 - const getMuteKeys = getMultipleKeys(getMuteKey);  
73 - const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter(  
74 - (it: any) => it.key?.split(',').length === 1  
75 - );  
76 - testEditCellTableRef.value?.setTableArray(mergeKeys);  
77 - } else if (props.data?.type === 'json') {  
78 - jsonEditorRef.value?.setJsonValue(props.data?.list);  
79 - } else if (props.data?.type === 'xml') {  
80 - xmlContent.value = props.data?.list;  
81 - }  
82 - });  
83 - };  
84 -  
85 - //测试表格里的数据转化为 key value 数组对象形式  
86 - //TODO:待优化这里的TS类型  
87 - const getTestTableKeyValue = () => {  
88 - //把日期拆分成多个  
89 - const keyValueList: any = [];  
90 - testEditCellTableRef.value?.getValue()?.forEach((item: any) => {  
91 - const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];  
92 - const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];  
93 - for (let i in splitDateKey) {  
94 - const obj = {  
95 - key: splitDateKey[i],  
96 - value: moment(splitDateValue[i]).valueOf(),  
97 - };  
98 - keyValueList.push(obj);  
99 - }  
100 - });  
101 - return testEditCellTableRef.value  
102 - ?.getValue()  
103 - .concat(keyValueList)  
104 - .filter((it) => it.key !== 'date_range')  
105 - .map((it: any) => {  
106 - const value =  
107 - it?.key === 'scope'  
108 - ? it?.keyValue  
109 - : it?.key === 'fixed_date'  
110 - ? moment(it?.fixed_date_value).valueOf()  
111 - : it?.value;  
112 - const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;  
113 - return {  
114 - key,  
115 - value,  
116 - required: it.required,  
117 - };  
118 - });  
119 - };  
120 -  
121 - //获取数据  
122 - const getTestValue = () => {  
123 - let params: any = {};  
124 - if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {  
125 - const getTable = getTestTableKeyValue();  
126 - const hasRequired = getTable?.some((it) => it.required === true && !it.value);  
127 - if (hasRequired) {  
128 - createMessage.error('参数不能为空');  
129 - throw new Error('参数不能为空');  
130 - }  
131 - getTable?.map((it) => (params[it.key!] = it.value!));  
132 - } else if (props.data?.type === 'json') {  
133 - params = jsonEditorRef.value?.getJsonValue();  
134 - } else if (props.data?.type === 'xml') {  
135 - params = xmlContent.value;  
136 - }  
137 - if (params['keys']) {  
138 - Reflect.set(params, 'keys', params['keys'].join(','));  
139 - }  
140 - excuteData.value = {  
141 - params,  
142 - };  
143 - return excuteData.value;  
144 - };  
145 -  
146 - //设置数据  
147 - const setValue = () => {  
148 - showTestEditCell.value = false;  
149 - testResult.value = '';  
150 - };  
151 -  
152 - defineExpose({  
153 - setValue,  
154 - handleTest,  
155 - getTestValue,  
156 - });  
157 -</script>  
158 -  
159 -<style scoped lang="less"></style> 1 +<template>
  2 + <div>
  3 + <div class="mt-8">
  4 + <div>
  5 + <Button @click="handleTest" type="primary"> 测试接口 </Button>
  6 + </div>
  7 + <div v-if="showTestEditCell" class="mt-8">
  8 + <a-row type="flex" justify="center">
  9 + <a-col :span="3"> 参数设置 </a-col>
  10 + <a-col :span="21">
  11 + <div v-if="data?.type === 'x-www-form-urlencoded' || data?.type === 'form-data'">
  12 + <TestBodyCellTable ref="testEditCellTableRef" />
  13 + </div>
  14 + <div style="width: 30vw" v-else-if="data?.type === 'json'">
  15 + <JsonEditor ref="jsonEditorRef" />
  16 + </div>
  17 + <div style="width: 30vw" v-else-if="data?.type === 'xml'">
  18 + <a-textarea v-model:value="xmlContent" placeholder="请输入xml" :rows="6" />
  19 + </div>
  20 + </a-col>
  21 + </a-row>
  22 + </div>
  23 + </div>
  24 + <div class="mt-8"> </div>
  25 + </div>
  26 +</template>
  27 +<script lang="ts" setup name="testRequest">
  28 + import { ref, nextTick } from 'vue';
  29 + import { Button } from 'ant-design-vue';
  30 + import TestBodyCellTable from './testEditBodyCellTable.vue';
  31 + import moment from 'moment';
  32 + import { useUtils } from '../../../hooks/useUtils';
  33 + import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
  34 +
  35 + const emits = defineEmits(['testBodyInterface']);
  36 +
  37 + const props = defineProps({
  38 + data: {
  39 + type: Object,
  40 + },
  41 + });
  42 +
  43 + const showTestEditCell = ref(false);
  44 +
  45 + const excuteData = ref({});
  46 +
  47 + const xmlContent = ref('');
  48 +
  49 + const testEditCellTableRef = ref<InstanceType<typeof TestBodyCellTable>>();
  50 +
  51 + const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
  52 +
  53 + const testResult = ref('');
  54 +
  55 + const { getMultipleKeys } = useUtils();
  56 +
  57 + const handleTest = () => {
  58 + showTestEditCell.value = true;
  59 + emits('testBodyInterface');
  60 + getValue();
  61 + };
  62 +
  63 + const getValue = async () => {
  64 + await nextTick();
  65 + await nextTick(() => {
  66 + console.log(props.data?.list);
  67 + if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {
  68 + const getSingleKey = props.data?.list;
  69 + const getMuteKey = props.data?.list?.filter((it: any) => it.key.split(',').length > 1);
  70 + const getMuteKeys = getMultipleKeys(getMuteKey);
  71 + const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter(
  72 + (it: any) => it.key.split(',').length === 1
  73 + );
  74 + testEditCellTableRef.value?.setTableArray(mergeKeys);
  75 + } else if (props.data?.type === 'json') {
  76 + jsonEditorRef.value?.setJsonValue(props.data?.list);
  77 + } else if (props.data?.type === 'xml') {
  78 + xmlContent.value = props.data?.list;
  79 + }
  80 + });
  81 + };
  82 +
  83 + //测试表格里的数据转化为 key value 数组对象形式
  84 + //TODO:待优化这里的TS类型
  85 + const getTestTableKeyValue = () => {
  86 + //把日期拆分成多个
  87 + const keyValueList: any = [];
  88 + testEditCellTableRef.value?.getValue()?.forEach((item: any) => {
  89 + const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];
  90 + const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];
  91 + for (let i in splitDateKey) {
  92 + const obj = {
  93 + key: splitDateKey[i],
  94 + value: moment(splitDateValue[i]).valueOf(),
  95 + };
  96 + keyValueList.push(obj);
  97 + }
  98 + });
  99 + return testEditCellTableRef.value
  100 + ?.getValue()
  101 + .concat(keyValueList)
  102 + .filter((it) => it.key !== 'date_range')
  103 + .map((it: any) => {
  104 + const value =
  105 + it?.key === 'scope'
  106 + ? it?.keyValue
  107 + : it?.key === 'fixed_date'
  108 + ? moment(it?.fixed_date_value).valueOf()
  109 + : it?.value;
  110 + const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;
  111 + return {
  112 + key,
  113 + value,
  114 + };
  115 + });
  116 + };
  117 +
  118 + //获取数据
  119 + const getTestValue = () => {
  120 + let params: any = {};
  121 + if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {
  122 + const getTable = getTestTableKeyValue();
  123 + getTable?.map((it) => (params[it.key!] = it.value!));
  124 + } else if (props.data?.type === 'json') {
  125 + params = jsonEditorRef.value?.getJsonValue();
  126 + } else if (props.data?.type === 'xml') {
  127 + params = xmlContent.value;
  128 + }
  129 + if (params['keys']) {
  130 + Reflect.set(params, 'keys', params['keys'].join(','));
  131 + }
  132 + excuteData.value = {
  133 + params,
  134 + };
  135 + return excuteData.value;
  136 + };
  137 +
  138 + //设置数据
  139 + const setValue = () => {
  140 + showTestEditCell.value = false;
  141 + testResult.value = '';
  142 + };
  143 +
  144 + defineExpose({
  145 + setValue,
  146 + handleTest,
  147 + getTestValue,
  148 + });
  149 +</script>
  150 +
  151 +<style scoped lang="less"></style>
1 -<!-- eslint-disable vue/valid-v-model -->  
2 -<template>  
3 - <div class="table-content">  
4 - <!-- TODO: 待优化测试表格 -->  
5 - <table align="center">  
6 - <thead>  
7 - <tr>  
8 - <th v-for="item in editTestCellTableTHeadConfig" :key="item">  
9 - <a-tooltip v-if="item === '参数值'">  
10 - <template #title>当自定义为entityType,应输入DEVICE</template>  
11 - <QuestionCircleOutlined :style="{ fontSize: '14px', marginLeft: '5px' }" />  
12 - </a-tooltip>  
13 - {{ item }}  
14 - </th>  
15 - </tr>  
16 - </thead>  
17 - <tbody>  
18 - <tr v-for="(item, index) in tableTestArray.content" :key="index">  
19 - <td style="width: 7.5vw">  
20 - <Select  
21 - :getPopupContainer="  
22 - (triggerNode) => {  
23 - return triggerNode.parentNode;  
24 - }  
25 - "  
26 - :disabled="true"  
27 - v-model:value="item.key"  
28 - placeholder="请选择"  
29 - :options="selectOptions"  
30 - />  
31 - </td>  
32 - <td style="width: 6.5vw">  
33 - <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />  
34 - <a-tree-select  
35 - :getPopupContainer="  
36 - (triggerNode) => {  
37 - return triggerNode.parentNode;  
38 - }  
39 - "  
40 - v-else-if="item.key === 'organizationId'"  
41 - v-model:value="item.value"  
42 - show-search  
43 - :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"  
44 - placeholder="请选择组织"  
45 - allow-clear  
46 - tree-default-expand-all  
47 - :tree-data="treeData"  
48 - @change="handleOrgnationChange(item)"  
49 - />  
50 - <Select  
51 - :getPopupContainer="  
52 - (triggerNode) => {  
53 - return triggerNode.parentNode;  
54 - }  
55 - "  
56 - v-else-if="item.key === 'entityId'"  
57 - v-model:value="item.value"  
58 - placeholder="请选择"  
59 - notFoundContent="请选择"  
60 - :options="entityOptions"  
61 - allowClear  
62 - />  
63 - <Select  
64 - :getPopupContainer="  
65 - (triggerNode) => {  
66 - return triggerNode.parentNode;  
67 - }  
68 - "  
69 - v-else-if="item.key === 'keys'"  
70 - v-model:value="item.value"  
71 - placeholder="请选择"  
72 - notFoundContent="请选择"  
73 - :options="attributeOptions"  
74 - mode="multiple"  
75 - allowClear  
76 - />  
77 - <div v-else-if="item.key === 'date_range'">  
78 - <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>  
79 - <span>~</span>  
80 - <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>  
81 - </div>  
82 - <div v-else-if="item.key === 'fixed_date'">  
83 - <a-button disabled type="primary">{{ item.value }}</a-button>  
84 - </div>  
85 - <Select  
86 - :getPopupContainer="  
87 - (triggerNode) => {  
88 - return triggerNode.parentNode;  
89 - }  
90 - "  
91 - v-else  
92 - v-model:value="item.value"  
93 - placeholder="请选择"  
94 - notFoundContent="请选择"  
95 - :options="valueOptions"  
96 - allowClear  
97 - @change="handleValueChange(item)"  
98 - />  
99 - </td>  
100 - <td style="width: 6.5vw">  
101 - <a-input  
102 - v-if="item.key === 'scope'"  
103 - placeholder="请输入"  
104 - v-model:value="item.keyValue"  
105 - />  
106 - <a-date-picker  
107 - v-else-if="item.key === 'fixed_date'"  
108 - style="width: 6.5vw"  
109 - v-model:value="item.keyValue"  
110 - :show-time="{ format: 'HH:mm' }"  
111 - format="YYYY-MM-DD HH:mm:ss"  
112 - placeholder="日期时间"  
113 - />  
114 - <a-range-picker  
115 - v-else-if="item.key == 'date_range'"  
116 - style="width: 6.5vw"  
117 - v-model:value="item.dateValue"  
118 - :show-time="{ format: 'HH:mm' }"  
119 - format="YYYY-MM-DD HH:mm"  
120 - :placeholder="['开始', '结束']"  
121 - />  
122 - <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" />  
123 - </td>  
124 - </tr>  
125 - </tbody>  
126 - </table>  
127 - </div>  
128 -</template>  
129 -<script lang="ts" setup name="editCellTable">  
130 - import { reactive, ref, onMounted } from 'vue';  
131 - import { Select } from 'ant-design-vue';  
132 - import { findDictItemByCode } from '/@/api/system/dict';  
133 - import { getAllDeviceByOrg } from '/@/api/dataBoard';  
134 - import { getDeviceAttributes } from '/@/api/dataBoard';  
135 - import { useApi } from '../../../hooks/useApi';  
136 - import { cloneDeep } from 'lodash-es';  
137 - import { tableItems, selectType } from '../../../types';  
138 - import { editTestCellTableTHeadConfig } from '../../../config';  
139 - import { QuestionCircleOutlined } from '@ant-design/icons-vue';  
140 -  
141 - const props = defineProps({  
142 - method: {  
143 - type: String,  
144 - },  
145 - });  
146 -  
147 - onMounted(async () => {  
148 - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });  
149 - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));  
150 - selectOptions.value.push({  
151 - label: '自定义',  
152 - value: 'scope',  
153 - });  
154 - if (props.method === '2')  
155 - selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');  
156 - });  
157 -  
158 - const selectOptions = ref<selectType[]>([]);  
159 -  
160 - const valueOptions = ref<selectType[]>([]);  
161 -  
162 - const entityOptions = ref<selectType[]>([]);  
163 -  
164 - const attributeOptions = ref<selectType[]>([]);  
165 -  
166 - const treeData = ref([]);  
167 -  
168 - const tableTestArray = reactive<{  
169 - content: tableItems[];  
170 - }>({  
171 - content: [  
172 - {  
173 - key: undefined,  
174 - value: undefined,  
175 - keyValue: null,  
176 - editDisabled: false,  
177 - dateValue: null,  
178 - },  
179 - ],  
180 - });  
181 -  
182 - //设置数据  
183 - const setTableArray = (data) => {  
184 - const list = cloneDeep(data);  
185 - list?.forEach((it) => {  
186 - if (it.key === 'keys') it.value = [];  
187 - });  
188 - if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);  
189 - if (list.hasOwnProperty('form-data') && Array.isArray(list['form-data']))  
190 - (tableTestArray.content = list['form-data']) && getApi(list['form-data']);  
191 - if (  
192 - list.hasOwnProperty('x-www-form-urlencoded') &&  
193 - Array.isArray(list['x-www-form-urlencoded'])  
194 - )  
195 - (tableTestArray.content = list['x-www-form-urlencoded']) &&  
196 - getApi(list['x-www-form-urlencoded']);  
197 - };  
198 -  
199 - const getApi = (list) => {  
200 - list?.forEach(async (it) => {  
201 - if (it.key === 'deviceProfileId') {  
202 - const { options } = await useApi(it.key);  
203 - valueOptions.value = options;  
204 - } else if (it.key === 'organizationId') {  
205 - const { options } = await useApi(it.key);  
206 - treeData.value = options as any;  
207 - }  
208 - });  
209 - };  
210 -  
211 - const handleOrgnationChange = async (e) => {  
212 - let deviceProfileId = '';  
213 - tableTestArray.content.forEach((f: any) => {  
214 - if (f.key === 'entityId') {  
215 - f.value = null;  
216 - }  
217 - if (f.key === 'deviceProfileId') deviceProfileId = f.value;  
218 - });  
219 - getEntityOptions(e.value, deviceProfileId);  
220 - };  
221 -  
222 - const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {  
223 - const res = await getAllDeviceByOrg(organizationId, deviceProfileId);  
224 - entityOptions.value = res.map((item) => ({  
225 - label: item.name,  
226 - value: item.tbDeviceId,  
227 - }));  
228 - };  
229 -  
230 - const getAttributeOptions = async (params) => {  
231 - console.log(params);  
232 - const res = await getDeviceAttributes(params);  
233 - if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);  
234 - attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));  
235 - };  
236 -  
237 - const handleValueChange = (e) => {  
238 - let organizationId = '';  
239 - if (e.key === 'deviceProfileId') {  
240 - tableTestArray.content.forEach((f: any) => {  
241 - if (f.key === 'keys') {  
242 - f.value = [];  
243 - }  
244 - if (f.key === 'organizationId') organizationId = f.value;  
245 - if (f.key === 'entityId') f.value = null;  
246 - });  
247 - if (e.value) {  
248 - getAttributeOptions({ deviceProfileId: e.value });  
249 - }  
250 - if (organizationId !== '') {  
251 - getEntityOptions(organizationId, e.value);  
252 - }  
253 - }  
254 - };  
255 -  
256 - //获取数据  
257 - const getValue = () => {  
258 - return tableTestArray.content;  
259 - };  
260 - defineExpose({  
261 - getValue,  
262 - setTableArray,  
263 - });  
264 -</script>  
265 -  
266 -<style scoped lang="less">  
267 - :deep(.ant-select-selector) {  
268 - max-width: 16vw;  
269 - }  
270 - @table-color: #e5e7eb;  
271 -  
272 - .table-border-color {  
273 - border: 1px solid #e5e7eb;  
274 - text-align: center;  
275 - }  
276 -  
277 - .table-content {  
278 - table {  
279 - width: 31vw;  
280 - &:extend(.table-border-color);  
281 - }  
282 -  
283 - table td {  
284 - padding: 5px;  
285 - white-space: nowrap;  
286 - &:extend(.table-border-color);  
287 - }  
288 -  
289 - table th {  
290 - padding: 5px;  
291 - &:extend(.table-border-color);  
292 - }  
293 - }  
294 -</style> 1 +<!-- eslint-disable vue/valid-v-model -->
  2 +<template>
  3 + <div class="table-content">
  4 + <!-- TODO: 待优化测试表格 -->
  5 + <table align="center">
  6 + <thead>
  7 + <tr>
  8 + <th v-for="item in editTestCellTableTHeadConfig" :key="item">
  9 + <a-tooltip v-if="item === '参数值'">
  10 + <template #title>当自定义为entityType,应输入DEVICE</template>
  11 + <QuestionCircleOutlined :style="{ fontSize: '14px', marginLeft: '5px' }" />
  12 + </a-tooltip>
  13 + {{ item }}
  14 + </th>
  15 + </tr>
  16 + </thead>
  17 + <tbody>
  18 + <tr v-for="(item, index) in tableTestArray.content" :key="index">
  19 + <td style="width: 7.5vw">
  20 + <Select
  21 + :getPopupContainer="
  22 + (triggerNode) => {
  23 + return triggerNode.parentNode;
  24 + }
  25 + "
  26 + :disabled="true"
  27 + v-model:value="item.key"
  28 + placeholder="请选择"
  29 + :options="selectOptions"
  30 + />
  31 + </td>
  32 + <td style="width: 6.5vw">
  33 + <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />
  34 + <a-tree-select
  35 + :getPopupContainer="
  36 + (triggerNode) => {
  37 + return triggerNode.parentNode;
  38 + }
  39 + "
  40 + v-else-if="item.key === 'organizationId'"
  41 + v-model:value="item.value"
  42 + show-search
  43 + :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
  44 + placeholder="请选择组织"
  45 + allow-clear
  46 + tree-default-expand-all
  47 + :tree-data="treeData"
  48 + @change="handleOrgnationChange(item)"
  49 + />
  50 + <Select
  51 + :getPopupContainer="
  52 + (triggerNode) => {
  53 + return triggerNode.parentNode;
  54 + }
  55 + "
  56 + v-else-if="item.key === 'entityId'"
  57 + v-model:value="item.value"
  58 + placeholder="请选择"
  59 + notFoundContent="请选择"
  60 + :options="entityOptions"
  61 + allowClear
  62 + />
  63 + <Select
  64 + :getPopupContainer="
  65 + (triggerNode) => {
  66 + return triggerNode.parentNode;
  67 + }
  68 + "
  69 + v-else-if="item.key === 'keys'"
  70 + v-model:value="item.value"
  71 + placeholder="请选择"
  72 + notFoundContent="请选择"
  73 + :options="attributeOptions"
  74 + mode="multiple"
  75 + allowClear
  76 + />
  77 + <div v-else-if="item.key === 'date_range'">
  78 + <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>
  79 + <span>~</span>
  80 + <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>
  81 + </div>
  82 + <div v-else-if="item.key === 'fixed_date'">
  83 + <a-button disabled type="primary">{{ item.value }}</a-button>
  84 + </div>
  85 + <Select
  86 + :getPopupContainer="
  87 + (triggerNode) => {
  88 + return triggerNode.parentNode;
  89 + }
  90 + "
  91 + v-else
  92 + v-model:value="item.value"
  93 + placeholder="请选择"
  94 + notFoundContent="请选择"
  95 + :options="valueOptions"
  96 + allowClear
  97 + @change="handleValueChange(item)"
  98 + />
  99 + </td>
  100 + <td style="width: 6.5vw">
  101 + <a-input
  102 + v-if="item.key === 'scope'"
  103 + placeholder="请输入"
  104 + v-model:value="item.keyValue"
  105 + />
  106 + <a-date-picker
  107 + v-else-if="item.key === 'fixed_date'"
  108 + style="width: 6.5vw"
  109 + v-model:value="item.keyValue"
  110 + :show-time="{ format: 'HH:mm' }"
  111 + format="YYYY-MM-DD HH:mm:ss"
  112 + placeholder="日期时间"
  113 + />
  114 + <a-range-picker
  115 + v-else-if="item.key == 'date_range'"
  116 + style="width: 6.5vw"
  117 + v-model:value="item.dateValue"
  118 + :show-time="{ format: 'HH:mm' }"
  119 + format="YYYY-MM-DD HH:mm"
  120 + :placeholder="['开始', '结束']"
  121 + />
  122 + <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" />
  123 + </td>
  124 + </tr>
  125 + </tbody>
  126 + </table>
  127 + </div>
  128 +</template>
  129 +<script lang="ts" setup name="editCellTable">
  130 + import { reactive, ref, onMounted } from 'vue';
  131 + import { Select } from 'ant-design-vue';
  132 + import { findDictItemByCode } from '/@/api/system/dict';
  133 + import { getAllDeviceByOrg } from '/@/api/dataBoard';
  134 + import { getDeviceAttributes } from '/@/api/dataBoard';
  135 + import { useApi } from '../../../hooks/useApi';
  136 + import { cloneDeep } from 'lodash-es';
  137 + import { tableItems, selectType } from '../../../types';
  138 + import { editTestCellTableTHeadConfig } from '../../../config';
  139 + import { QuestionCircleOutlined } from '@ant-design/icons-vue';
  140 +
  141 + const props = defineProps({
  142 + method: {
  143 + type: String,
  144 + },
  145 + });
  146 +
  147 + onMounted(async () => {
  148 + const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
  149 + selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
  150 + selectOptions.value.push({
  151 + label: '自定义',
  152 + value: 'scope',
  153 + });
  154 + if (props.method === '2')
  155 + selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
  156 + });
  157 +
  158 + const selectOptions = ref<selectType[]>([]);
  159 +
  160 + const valueOptions = ref<selectType[]>([]);
  161 +
  162 + const entityOptions = ref<selectType[]>([]);
  163 +
  164 + const attributeOptions = ref<selectType[]>([]);
  165 +
  166 + const treeData = ref([]);
  167 +
  168 + const tableTestArray = reactive<{
  169 + content: tableItems[];
  170 + }>({
  171 + content: [
  172 + {
  173 + key: undefined,
  174 + value: undefined,
  175 + keyValue: null,
  176 + editDisabled: false,
  177 + dateValue: null,
  178 + },
  179 + ],
  180 + });
  181 +
  182 + //设置数据
  183 + const setTableArray = (data) => {
  184 + const list = cloneDeep(data);
  185 + list?.forEach((it) => {
  186 + if (it.key === 'keys') it.value = [];
  187 + });
  188 + if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);
  189 + if (list.hasOwnProperty('form-data') && Array.isArray(list['form-data']))
  190 + (tableTestArray.content = list['form-data']) && getApi(list['form-data']);
  191 + if (
  192 + list.hasOwnProperty('x-www-form-urlencoded') &&
  193 + Array.isArray(list['x-www-form-urlencoded'])
  194 + )
  195 + (tableTestArray.content = list['x-www-form-urlencoded']) &&
  196 + getApi(list['x-www-form-urlencoded']);
  197 + };
  198 +
  199 + const getApi = (list) => {
  200 + list?.forEach(async (it) => {
  201 + if (it.key === 'deviceProfileId') {
  202 + const { options } = await useApi(it.key);
  203 + valueOptions.value = options;
  204 + } else if (it.key === 'organizationId') {
  205 + const { options } = await useApi(it.key);
  206 + treeData.value = options as any;
  207 + }
  208 + });
  209 + };
  210 +
  211 + const handleOrgnationChange = async (e) => {
  212 + let deviceProfileId = '';
  213 + tableTestArray.content.forEach((f: any) => {
  214 + if (f.key === 'entityId') {
  215 + f.value = null;
  216 + }
  217 + if (f.key === 'deviceProfileId') deviceProfileId = f.value;
  218 + });
  219 + getEntityOptions(e.value, deviceProfileId);
  220 + };
  221 +
  222 + const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
  223 + const res = await getAllDeviceByOrg(organizationId, deviceProfileId);
  224 + entityOptions.value = res.map((item) => ({
  225 + label: item.name,
  226 + value: item.tbDeviceId,
  227 + }));
  228 + };
  229 +
  230 + const getAttributeOptions = async (params) => {
  231 + const res = await getDeviceAttributes(params);
  232 + if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);
  233 + attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
  234 + };
  235 +
  236 + const handleValueChange = (e) => {
  237 + let organizationId = '';
  238 + if (e.key === 'deviceProfileId') {
  239 + tableTestArray.content.forEach((f: any) => {
  240 + if (f.key === 'keys') {
  241 + f.value = [];
  242 + }
  243 + if (f.key === 'organizationId') organizationId = f.value;
  244 + if (f.key === 'entityId') f.value = null;
  245 + });
  246 + getAttributeOptions({ deviceProfileId: e.value });
  247 + if (organizationId !== '') {
  248 + getEntityOptions(organizationId, e.value);
  249 + }
  250 + }
  251 + };
  252 +
  253 + //获取数据
  254 + const getValue = () => {
  255 + return tableTestArray.content;
  256 + };
  257 + defineExpose({
  258 + getValue,
  259 + setTableArray,
  260 + });
  261 +</script>
  262 +
  263 +<style scoped lang="less">
  264 + @table-color: #e5e7eb;
  265 +
  266 + .table-border-color {
  267 + border: 1px solid #e5e7eb;
  268 + text-align: center;
  269 + }
  270 +
  271 + .table-content {
  272 + table {
  273 + width: 31vw;
  274 + &:extend(.table-border-color);
  275 + }
  276 +
  277 + table td {
  278 + padding: 5px;
  279 + white-space: nowrap;
  280 + &:extend(.table-border-color);
  281 + }
  282 +
  283 + table th {
  284 + padding: 5px;
  285 + &:extend(.table-border-color);
  286 + }
  287 + }
  288 +</style>
1 -<template>  
2 - <div v-if="showTestFlag" class="mt-8">  
3 - <div>  
4 - <Button @click="handleExcute" type="primary"> 执行测试请求 </Button>  
5 - </div>  
6 - <div class="mt-8">  
7 - <a-row type="flex" justify="center">  
8 - <a-col :span="2"> 测试结果 </a-col>  
9 - <a-col :span="22">  
10 - <a-textarea  
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 - v-else  
20 - allow-clear  
21 - show-count  
22 - v-model:value="httpResult"  
23 - placeholder="测试结果为:"  
24 - :rows="8"  
25 - />  
26 - </a-col>  
27 - </a-row>  
28 - </div>  
29 - </div>  
30 -</template>  
31 -<script lang="ts" setup name="testRequest">  
32 - import { nextTick, ref, reactive, onUnmounted } from 'vue';  
33 - import { Button } from 'ant-design-vue';  
34 - import { otherHttp } from '/@/utils/http/axios';  
35 - import { useWebSocket } from '@vueuse/core';  
36 - import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';  
37 - import { getAuthCache } from '/@/utils/auth';  
38 - import { useUtils } from '../../../hooks/useUtils';  
39 -  
40 - const emits = defineEmits(['emitExcute']);  
41 -  
42 - const props = defineProps({  
43 - data: {  
44 - type: Object,  
45 - },  
46 - });  
47 -  
48 - const showTestFlag = ref(false);  
49 -  
50 - const token = getAuthCache(JWT_TOKEN_KEY);  
51 -  
52 - const socketUrls = ref('');  
53 -  
54 - const socketMessage: any = reactive({  
55 - server: ``,  
56 - sendValue: {  
57 - tsSubCmds: [],  
58 - },  
59 - });  
60 -  
61 - //格式化替换像"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式"  
62 - String.prototype.restfulFormat = function (replacements) {  
63 - var formatString = function (str, replacements) {  
64 - replacements =  
65 - typeof replacements === 'object' ? replacements : Array.prototype.slice.call(arguments, 1);  
66 - return str.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) {  
67 - if (m == '{{') {  
68 - return '{';  
69 - }  
70 - if (m == '}}') {  
71 - return '}';  
72 - }  
73 - return replacements[n];  
74 - });  
75 - };  
76 - replacements =  
77 - typeof replacements === 'object' ? replacements : Array.prototype.slice.call(arguments, 0);  
78 - return formatString(this, replacements);  
79 - };  
80 -  
81 - const testResult = ref('');  
82 -  
83 - const httpResult = ref('');  
84 -  
85 - const isWebSocketType = ref('');  
86 -  
87 - //执行测试接口  
88 - const handleExcute = () => {  
89 - emits('emitExcute');  
90 - getValue();  
91 - };  
92 -  
93 - const getValue = async () => {  
94 - await nextTick();  
95 - //获取Params和Header和Body  
96 - const Objects = props.data;  
97 - isWebSocketType.value = Objects?.method;  
98 - const apiType = Objects?.apiType;  
99 - const url = Objects?.apiGetUrl;  
100 - const headers = Objects?.Header?.params;  
101 - const params = Objects?.Params?.params;  
102 - const body = Objects?.Body?.params;  
103 - const apiUrl = url?.restfulFormat(params);  
104 - if (isWebSocketType.value === '2') {  
105 - socketUrls.value = url;  
106 - socketMessage.server = `${socketUrls.value}?token=${token}`;  
107 - const list = Object.values(params);  
108 - const isEmpty = list.some((it) => it === '' || null || undefined);  
109 - if (!isEmpty) {  
110 - websocketRequest(params);  
111 - } else {  
112 - resetValue(false);  
113 - }  
114 - } else {  
115 - const resp = await otherHttpRequest(apiType, apiUrl?.split('{?')[0], headers, params, body);  
116 - if (!resp) return;  
117 - httpResult.value = JSON.stringify(resp);  
118 - }  
119 - };  
120 -  
121 - //websocket请求  
122 - const websocketRequest = (params, destroy = false) => {  
123 - //websocket请求  
124 - if (Object.prototype.toString.call(params) === '[object Object]') {  
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');  
130 - }  
131 - socketMessage.sendValue.tsSubCmds.push(params);  
132 - const { send, close } = useWebSocket(socketMessage.server, {  
133 - onConnected() {  
134 - send(JSON.stringify(socketMessage.sendValue));  
135 - console.log('建立连接了');  
136 - },  
137 - onMessage(_, e) {  
138 - const { data } = JSON.parse(e.data);  
139 - testResult.value = JSON.stringify(data);  
140 - },  
141 - onDisconnected() {  
142 - console.log('断开连接了');  
143 - close();  
144 - },  
145 - onError() {},  
146 - });  
147 - if (destroy) close();  
148 - };  
149 -  
150 - onUnmounted(() => {  
151 - if (isWebSocketType.value === '2') {  
152 - websocketRequest(null, true);  
153 - }  
154 - });  
155 -  
156 - //TODO: 待优化 项目自带第三方请求  
157 - const otherHttpRequest = async (  
158 - apiType,  
159 - apiUrl,  
160 - headers = {},  
161 - params = {},  
162 - body = {},  
163 - joinPrefix = false  
164 - ) => {  
165 - switch (apiType) {  
166 - case 'GET':  
167 - return await otherHttp.get(  
168 - { url: apiUrl, params, headers },  
169 - {  
170 - apiUrl: '',  
171 - joinPrefix,  
172 - }  
173 - );  
174 - case 'POST':  
175 - const { convertObj } = useUtils();  
176 - return await otherHttp.post(  
177 - { url: `${apiUrl}?${convertObj(params)}`, data: body, headers },  
178 - {  
179 - apiUrl: '',  
180 - joinPrefix,  
181 - }  
182 - );  
183 - case 'PUT':  
184 - return await otherHttp.put(  
185 - { url: apiUrl, data: body, headers, params },  
186 - {  
187 - apiUrl: '',  
188 - joinPrefix,  
189 - }  
190 - );  
191 - }  
192 - };  
193 -  
194 - const resetValue = (flag) => {  
195 - if (flag) {  
196 - showTestFlag.value = false;  
197 - }  
198 - httpResult.value = '测试结果为:';  
199 - testResult.value = '测试结果为:';  
200 - isWebSocketType.value = '0';  
201 - };  
202 -  
203 - const showTest = () => (showTestFlag.value = true);  
204 -  
205 - defineExpose({  
206 - resetValue,  
207 - showTest,  
208 - });  
209 -</script>  
210 -  
211 -<style scoped lang="less">  
212 - :deep(.ant-input-textarea-show-count) {  
213 - width: 30vw;  
214 - }  
215 -</style> 1 +<template>
  2 + <div v-if="showTestFlag" class="mt-8">
  3 + <div>
  4 + <Button @click="handleExcute" type="primary"> 执行测试请求 </Button>
  5 + </div>
  6 + <div class="mt-8">
  7 + <a-row type="flex" justify="center">
  8 + <a-col :span="2"> 测试结果 </a-col>
  9 + <a-col :span="22">
  10 + <a-textarea
  11 + v-if="ifWebSocket === '2'"
  12 + allow-clear
  13 + show-count
  14 + v-model:value="testResult"
  15 + placeholder="测试结果为:"
  16 + :rows="8"
  17 + />
  18 + <a-textarea
  19 + v-else
  20 + allow-clear
  21 + show-count
  22 + v-model:value="httpResult"
  23 + placeholder="测试结果为:"
  24 + :rows="8"
  25 + />
  26 + </a-col>
  27 + </a-row>
  28 + </div>
  29 + </div>
  30 +</template>
  31 +<script lang="ts" setup name="testRequest">
  32 + import { nextTick, ref, reactive } from 'vue';
  33 + import { Button } from 'ant-design-vue';
  34 + import { otherHttp } from '/@/utils/http/axios';
  35 + import { useWebSocket } from '@vueuse/core';
  36 + import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
  37 + import { getAuthCache } from '/@/utils/auth';
  38 + import { useMessage } from '/@/hooks/web/useMessage';
  39 + // import { useGlobSetting } from '/@/hooks/setting';
  40 +
  41 + const emits = defineEmits(['emitExcute']);
  42 +
  43 + const props = defineProps({
  44 + data: {
  45 + type: Object,
  46 + },
  47 + });
  48 +
  49 + const showTestFlag = ref(false);
  50 +
  51 + const ifWebSocket = ref('');
  52 +
  53 + const { createMessage } = useMessage();
  54 +
  55 + const token = getAuthCache(JWT_TOKEN_KEY);
  56 +
  57 + const socketUrls = ref('');
  58 +
  59 + // const { socketUrl } = useGlobSetting();
  60 +
  61 + const socketMessage: any = reactive({
  62 + server: ``,
  63 + sendValue: {
  64 + tsSubCmds: [],
  65 + },
  66 + });
  67 +
  68 + //格式化替换像"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式"
  69 + String.prototype.restfulFormat = function (replacements) {
  70 + var formatString = function (str, replacements) {
  71 + replacements =
  72 + typeof replacements === 'object' ? replacements : Array.prototype.slice.call(arguments, 1);
  73 + return str.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) {
  74 + if (m == '{{') {
  75 + return '{';
  76 + }
  77 + if (m == '}}') {
  78 + return '}';
  79 + }
  80 + return replacements[n];
  81 + });
  82 + };
  83 + replacements =
  84 + typeof replacements === 'object' ? replacements : Array.prototype.slice.call(arguments, 0);
  85 + return formatString(this, replacements);
  86 + };
  87 +
  88 + const testResult = ref('');
  89 +
  90 + const httpResult = ref('');
  91 +
  92 + //执行测试接口
  93 + const handleExcute = () => {
  94 + emits('emitExcute');
  95 + getValue();
  96 + };
  97 +
  98 + const getValue = async () => {
  99 + await nextTick();
  100 + //获取Params和Header和Body
  101 + const Objects = props.data;
  102 + const isWebSocketType = Objects?.method;
  103 + const apiType = Objects?.apiType;
  104 + const url = Objects?.apiGetUrl;
  105 + const headers = Objects?.Header?.params;
  106 + const params = Objects?.Params?.params;
  107 + const body = Objects?.Body?.params;
  108 + const apiUrl = url?.restfulFormat(params);
  109 + ifWebSocket.value = isWebSocketType;
  110 + if (isWebSocketType === '2') {
  111 + socketUrls.value = url;
  112 + socketMessage.server = `${socketUrls.value}?token=${token}`;
  113 + websocketRequest(params);
  114 + } else {
  115 + const resp = await otherHttpRequest(apiType, apiUrl?.split('{?')[0], headers, params, body);
  116 + if (!resp) return;
  117 + httpResult.value = JSON.stringify(resp);
  118 + }
  119 + };
  120 +
  121 + //websocket请求
  122 + const websocketRequest = (params) => {
  123 + //websocket请求
  124 + Reflect.deleteProperty(params, 'deviceProfileId');
  125 + Reflect.deleteProperty(params, 'organizationId');
  126 + Reflect.set(params, 'cmdId', 1);
  127 + Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
  128 + Reflect.set(params, 'entityType', 'DEVICE');
  129 + socketMessage.sendValue.tsSubCmds.push(params);
  130 + const { send, close } = useWebSocket(socketMessage.server, {
  131 + onConnected() {
  132 + send(JSON.stringify(socketMessage.sendValue));
  133 + console.log('建立连接了');
  134 + },
  135 + onMessage(_, e) {
  136 + const { data } = JSON.parse(e.data);
  137 + testResult.value = JSON.stringify(data);
  138 + },
  139 + onDisconnected() {
  140 + console.log('断开连接了');
  141 + close();
  142 + },
  143 + onError() {
  144 + createMessage.error('webSocket连接超时,请联系管理员');
  145 + },
  146 + });
  147 + };
  148 +
  149 + //TODO: 待优化 项目自带第三方请求
  150 + const otherHttpRequest = async (
  151 + apiType,
  152 + apiUrl,
  153 + headers = {},
  154 + params = {},
  155 + body,
  156 + joinPrefix = false
  157 + ) => {
  158 + switch (apiType) {
  159 + case 'GET':
  160 + return await otherHttp.get(
  161 + { url: apiUrl, params, headers },
  162 + {
  163 + apiUrl: '',
  164 + joinPrefix,
  165 + }
  166 + );
  167 + case 'POST':
  168 + return await otherHttp.post(
  169 + { url: apiUrl, data: body, headers, params },
  170 + {
  171 + apiUrl: '',
  172 + joinPrefix,
  173 + }
  174 + );
  175 + case 'PUT':
  176 + return await otherHttp.put(
  177 + { url: apiUrl, data: body, headers, params },
  178 + {
  179 + apiUrl: '',
  180 + joinPrefix,
  181 + }
  182 + );
  183 + }
  184 + };
  185 +
  186 + const resetValue = (flag) => {
  187 + if (flag) {
  188 + showTestFlag.value = false;
  189 + }
  190 + httpResult.value = '测试结果为:';
  191 + testResult.value = '测试结果为:';
  192 + ifWebSocket.value = '0';
  193 + };
  194 +
  195 + const showTest = () => (showTestFlag.value = true);
  196 +
  197 + defineExpose({
  198 + resetValue,
  199 + showTest,
  200 + });
  201 +</script>
  202 +
  203 +<style scoped lang="less">
  204 + :deep(.ant-input-textarea-show-count) {
  205 + width: 30vw;
  206 + }
  207 +</style>
1 -<template>  
2 - <div>  
3 - <div class="mt-8">  
4 - <div>  
5 - <Button @click="handleTest" type="primary"> 测试接口 </Button>  
6 - </div>  
7 - <div v-if="showTestEditCell" class="mt-8">  
8 - <a-row type="flex" justify="center">  
9 - <a-col :span="3"> 参数设置 </a-col>  
10 - <a-col :span="21">  
11 - <TestHeaderEditCellTable ref="testEditCellTableRef" />  
12 - </a-col>  
13 - </a-row>  
14 - </div>  
15 - </div>  
16 - <div class="mt-8"> </div>  
17 - </div>  
18 -</template>  
19 -<script lang="ts" setup name="testRequest">  
20 - import { ref, nextTick } from 'vue';  
21 - import { Button } from 'ant-design-vue';  
22 - import TestHeaderEditCellTable from './testEditHeaderCellTable.vue';  
23 - import { useMessage } from '/@/hooks/web/useMessage';  
24 -  
25 - const emits = defineEmits(['testHeaderInterface']);  
26 -  
27 - const props = defineProps({  
28 - data: {  
29 - type: Object,  
30 - },  
31 - });  
32 -  
33 - const { createMessage } = useMessage();  
34 -  
35 - const showTestEditCell = ref(false);  
36 -  
37 - const excuteData = ref({});  
38 -  
39 - const testEditCellTableRef = ref<InstanceType<typeof TestHeaderEditCellTable>>();  
40 -  
41 - const testResult = ref('');  
42 -  
43 - const handleTest = () => {  
44 - showTestEditCell.value = true;  
45 - emits('testHeaderInterface');  
46 - getValue();  
47 - };  
48 -  
49 - const getValue = async () => {  
50 - await nextTick();  
51 - await nextTick(() => {  
52 - const getValue = props.data?.list;  
53 - testEditCellTableRef.value?.setTableArray(getValue);  
54 - });  
55 - };  
56 -  
57 - //测试表格里的数据转化为 key value 数组对象形式  
58 - const getTestTableKeyValue = () => {  
59 - return testEditCellTableRef.value?.getValue();  
60 - };  
61 -  
62 - //获取数据  
63 - const getTestValue = () => {  
64 - const getTable = getTestTableKeyValue();  
65 - const hasRequired = getTable?.some((it) => it.required === true && !it.value);  
66 - if (hasRequired) {  
67 - createMessage.error('参数不能为空');  
68 - throw new Error('参数不能为空');  
69 - }  
70 - const params: any = {};  
71 - getTable?.map((it: any) => (params[it.key!] = it.value!));  
72 - excuteData.value = {  
73 - params,  
74 - };  
75 - return excuteData.value;  
76 - };  
77 -  
78 - //设置数据  
79 - const setValue = () => {  
80 - showTestEditCell.value = false;  
81 - testResult.value = '';  
82 - };  
83 -  
84 - defineExpose({  
85 - setValue,  
86 - handleTest,  
87 - getTestValue,  
88 - });  
89 -</script>  
90 -  
91 -<style scoped lang="less"></style> 1 +<template>
  2 + <div>
  3 + <div class="mt-8">
  4 + <div>
  5 + <Button @click="handleTest" type="primary"> 测试接口 </Button>
  6 + </div>
  7 + <div v-if="showTestEditCell" class="mt-8">
  8 + <a-row type="flex" justify="center">
  9 + <a-col :span="3"> 参数设置 </a-col>
  10 + <a-col :span="21">
  11 + <TestHeaderEditCellTable ref="testEditCellTableRef" />
  12 + </a-col>
  13 + </a-row>
  14 + </div>
  15 + </div>
  16 + <div class="mt-8"> </div>
  17 + </div>
  18 +</template>
  19 +<script lang="ts" setup name="testRequest">
  20 + import { ref, nextTick } from 'vue';
  21 + import { Button } from 'ant-design-vue';
  22 + import TestHeaderEditCellTable from './testEditHeaderCellTable.vue';
  23 +
  24 + const emits = defineEmits(['testHeaderInterface']);
  25 +
  26 + const props = defineProps({
  27 + data: {
  28 + type: Object,
  29 + },
  30 + });
  31 +
  32 + const showTestEditCell = ref(false);
  33 +
  34 + const excuteData = ref({});
  35 +
  36 + const testEditCellTableRef = ref<InstanceType<typeof TestHeaderEditCellTable>>();
  37 +
  38 + const testResult = ref('');
  39 +
  40 + const handleTest = () => {
  41 + showTestEditCell.value = true;
  42 + emits('testHeaderInterface');
  43 + getValue();
  44 + };
  45 +
  46 + const getValue = async () => {
  47 + await nextTick();
  48 + await nextTick(() => {
  49 + const getValue = props.data?.list;
  50 + testEditCellTableRef.value?.setTableArray(getValue);
  51 + });
  52 + };
  53 +
  54 + //测试表格里的数据转化为 key value 数组对象形式
  55 + const getTestTableKeyValue = () => {
  56 + return testEditCellTableRef.value?.getValue();
  57 + };
  58 +
  59 + //获取数据
  60 + const getTestValue = () => {
  61 + const getTable = getTestTableKeyValue();
  62 + const params: any = {};
  63 + getTable?.map((it: any) => (params[it.key!] = it.value!));
  64 + excuteData.value = {
  65 + params,
  66 + };
  67 + return excuteData.value;
  68 + };
  69 +
  70 + //设置数据
  71 + const setValue = () => {
  72 + showTestEditCell.value = false;
  73 + testResult.value = '';
  74 + };
  75 +
  76 + defineExpose({
  77 + setValue,
  78 + handleTest,
  79 + getTestValue,
  80 + });
  81 +</script>
  82 +
  83 +<style scoped lang="less"></style>
1 -<template>  
2 - <div>  
3 - <div class="mt-8">  
4 - <div>  
5 - <Button @click="handleTest" type="primary"> 测试接口 </Button>  
6 - </div>  
7 - <div v-if="showTestEditCell" class="mt-8">  
8 - <a-row type="flex" justify="center">  
9 - <a-col :span="3"> 参数设置 </a-col>  
10 - <a-col :span="21">  
11 - <TestParamsCellTable ref="testEditCellTableRef" />  
12 - </a-col>  
13 - </a-row>  
14 - </div>  
15 - </div>  
16 - <div class="mt-8"> </div>  
17 - </div>  
18 -</template>  
19 -<script lang="ts" setup name="testRequest">  
20 - import { ref, nextTick } from 'vue';  
21 - import { Button } from 'ant-design-vue';  
22 - import TestParamsCellTable from './testEditParamsCellTable.vue';  
23 - import moment from 'moment';  
24 - import { useUtils } from '../../../hooks/useUtils';  
25 - import { useMessage } from '/@/hooks/web/useMessage';  
26 -  
27 - const emits = defineEmits(['testParamsInterface']);  
28 -  
29 - const props = defineProps({  
30 - data: {  
31 - type: Object,  
32 - },  
33 - });  
34 -  
35 - const { createMessage } = useMessage();  
36 -  
37 - const showTestEditCell = ref(false);  
38 -  
39 - const excuteData = ref({});  
40 -  
41 - const testEditCellTableRef = ref<InstanceType<typeof TestParamsCellTable>>();  
42 -  
43 - const testResult = ref('');  
44 -  
45 - const { getMultipleKeys } = useUtils();  
46 -  
47 - const handleTest = () => {  
48 - showTestEditCell.value = true;  
49 - emits('testParamsInterface');  
50 - getValue();  
51 - };  
52 -  
53 - const getValue = async () => {  
54 - await nextTick();  
55 - await nextTick(() => {  
56 - //拆分"xx,xx,xx"多个  
57 - const getSingleKey = props.data?.list;  
58 - const getMuteKey = props.data?.list?.filter((it: any) => it.key?.split(',').length > 1);  
59 - const getMuteKeys = getMultipleKeys(getMuteKey);  
60 - const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter(  
61 - (it: any) => it.key?.split(',').length === 1  
62 - );  
63 - testEditCellTableRef.value?.setTableArray(mergeKeys);  
64 - });  
65 - };  
66 -  
67 - //测试表格里的数据转化为 key value 数组对象形式  
68 - //TODO:待优化这里的TS类型  
69 - const getTestTableKeyValue = () => {  
70 - //把日期拆分成多个  
71 - const keyValueList: any = [];  
72 - testEditCellTableRef.value?.getValue()?.forEach((item: any) => {  
73 - const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];  
74 - const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];  
75 - for (let i in splitDateKey) {  
76 - const obj = {  
77 - key: splitDateKey[i],  
78 - value: moment(splitDateValue[i]).valueOf(),  
79 - };  
80 - keyValueList.push(obj);  
81 - }  
82 - });  
83 - return testEditCellTableRef.value  
84 - ?.getValue()  
85 - .concat(keyValueList)  
86 - .filter((it) => it.key !== 'date_range')  
87 - .map((it: any) => {  
88 - const value =  
89 - it?.key === 'scope'  
90 - ? it?.keyValue  
91 - : it?.key === 'fixed_date'  
92 - ? moment(it?.fixed_date_value).valueOf()  
93 - : it?.value;  
94 - const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;  
95 - return {  
96 - key,  
97 - value,  
98 - required: it.required,  
99 - };  
100 - });  
101 - };  
102 -  
103 - //获取数据  
104 - const getTestValue = () => {  
105 - const getTable = getTestTableKeyValue();  
106 - const hasRequired = getTable?.some((it) => it.required === true && !it.value);  
107 - if (hasRequired) {  
108 - createMessage.error('参数不能为空');  
109 - throw new Error('参数不能为空');  
110 - }  
111 - const params: any = {};  
112 - getTable?.map((it) => (params[it.key!] = it.value!));  
113 - if (params['keys']) {  
114 - Reflect.set(params, 'keys', params['keys'].join(','));  
115 - }  
116 - excuteData.value = {  
117 - params,  
118 - };  
119 - return excuteData.value;  
120 - };  
121 -  
122 - //设置数据  
123 - const setValue = () => {  
124 - showTestEditCell.value = false;  
125 - testResult.value = '';  
126 - };  
127 -  
128 - defineExpose({  
129 - setValue,  
130 - handleTest,  
131 - getTestValue,  
132 - });  
133 -</script>  
134 -  
135 -<style scoped lang="less"></style> 1 +<template>
  2 + <div>
  3 + <div class="mt-8">
  4 + <div>
  5 + <Button @click="handleTest" type="primary"> 测试接口 </Button>
  6 + </div>
  7 + <div v-if="showTestEditCell" class="mt-8">
  8 + <a-row type="flex" justify="center">
  9 + <a-col :span="3"> 参数设置 </a-col>
  10 + <a-col :span="21">
  11 + <TestParamsCellTable ref="testEditCellTableRef" />
  12 + </a-col>
  13 + </a-row>
  14 + </div>
  15 + </div>
  16 + <div class="mt-8"> </div>
  17 + </div>
  18 +</template>
  19 +<script lang="ts" setup name="testRequest">
  20 + import { ref, nextTick } from 'vue';
  21 + import { Button } from 'ant-design-vue';
  22 + import TestParamsCellTable from './testEditParamsCellTable.vue';
  23 + import moment from 'moment';
  24 + import { useUtils } from '../../../hooks/useUtils';
  25 +
  26 + const emits = defineEmits(['testParamsInterface']);
  27 +
  28 + const props = defineProps({
  29 + data: {
  30 + type: Object,
  31 + },
  32 + });
  33 +
  34 + const showTestEditCell = ref(false);
  35 +
  36 + const excuteData = ref({});
  37 +
  38 + const testEditCellTableRef = ref<InstanceType<typeof TestParamsCellTable>>();
  39 +
  40 + const testResult = ref('');
  41 +
  42 + const { getMultipleKeys } = useUtils();
  43 +
  44 + const handleTest = () => {
  45 + showTestEditCell.value = true;
  46 + emits('testParamsInterface');
  47 + getValue();
  48 + };
  49 +
  50 + const getValue = async () => {
  51 + await nextTick();
  52 + await nextTick(() => {
  53 + //拆分"xx,xx,xx"多个
  54 + const getSingleKey = props.data?.list;
  55 + const getMuteKey = props.data?.list?.filter((it: any) => it.key?.split(',').length > 1);
  56 + const getMuteKeys = getMultipleKeys(getMuteKey);
  57 + const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter(
  58 + (it: any) => it.key?.split(',').length === 1
  59 + );
  60 + testEditCellTableRef.value?.setTableArray(mergeKeys);
  61 + });
  62 + };
  63 +
  64 + //测试表格里的数据转化为 key value 数组对象形式
  65 + //TODO:待优化这里的TS类型
  66 + const getTestTableKeyValue = () => {
  67 + //把日期拆分成多个
  68 + const keyValueList: any = [];
  69 + testEditCellTableRef.value?.getValue()?.forEach((item: any) => {
  70 + const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];
  71 + const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];
  72 + for (let i in splitDateKey) {
  73 + const obj = {
  74 + key: splitDateKey[i],
  75 + value: moment(splitDateValue[i]).valueOf(),
  76 + };
  77 + keyValueList.push(obj);
  78 + }
  79 + });
  80 + return testEditCellTableRef.value
  81 + ?.getValue()
  82 + .concat(keyValueList)
  83 + .filter((it) => it.key !== 'date_range')
  84 + .map((it: any) => {
  85 + const value =
  86 + it?.key === 'scope'
  87 + ? it?.keyValue
  88 + : it?.key === 'fixed_date'
  89 + ? moment(it?.fixed_date_value).valueOf()
  90 + : it?.value;
  91 + const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;
  92 + return {
  93 + key,
  94 + value,
  95 + };
  96 + });
  97 + };
  98 +
  99 + //获取数据
  100 + const getTestValue = () => {
  101 + const getTable = getTestTableKeyValue();
  102 + const params: any = {};
  103 + getTable?.map((it) => (params[it.key!] = it.value!));
  104 + if (params['keys']) {
  105 + Reflect.set(params, 'keys', params['keys'].join(','));
  106 + }
  107 + excuteData.value = {
  108 + params,
  109 + };
  110 + return excuteData.value;
  111 + };
  112 +
  113 + //设置数据
  114 + const setValue = () => {
  115 + showTestEditCell.value = false;
  116 + testResult.value = '';
  117 + };
  118 +
  119 + defineExpose({
  120 + setValue,
  121 + handleTest,
  122 + getTestValue,
  123 + });
  124 +</script>
  125 +
  126 +<style scoped lang="less"></style>
1 -<!-- eslint-disable vue/valid-v-model -->  
2 -<template>  
3 - <div class="table-content">  
4 - <!-- TODO: 待优化测试表格 -->  
5 - <table align="center">  
6 - <thead>  
7 - <tr>  
8 - <th v-for="item in editTestCellTableTHeadConfig" :key="item">  
9 - <a-tooltip v-if="item === '参数值'">  
10 - <template #title>当自定义为entityType,应输入DEVICE</template>  
11 - <QuestionCircleOutlined :style="{ fontSize: '14px', marginLeft: '5px' }" />  
12 - </a-tooltip>  
13 - {{ item }}  
14 - </th>  
15 - </tr>  
16 - </thead>  
17 - <tbody>  
18 - <tr v-for="(item, index) in tableTestArray.content" :key="index">  
19 - <td style="width: 7.5vw">  
20 - <Select  
21 - :getPopupContainer="  
22 - (triggerNode) => {  
23 - return triggerNode.parentNode;  
24 - }  
25 - "  
26 - :disabled="true"  
27 - v-model:value="item.key"  
28 - placeholder="请选择"  
29 - :options="selectOptions"  
30 - />  
31 - </td>  
32 - <td style="width: 6.5vw">  
33 - <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />  
34 - <a-tree-select  
35 - :getPopupContainer="  
36 - (triggerNode) => {  
37 - return triggerNode.parentNode;  
38 - }  
39 - "  
40 - v-else-if="item.key === 'organizationId'"  
41 - v-model:value="item.value"  
42 - show-search  
43 - :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"  
44 - placeholder="请选择组织"  
45 - allow-clear  
46 - tree-default-expand-all  
47 - :tree-data="treeData"  
48 - @change="handleOrgnationChange(item)"  
49 - />  
50 - <Select  
51 - :getPopupContainer="  
52 - (triggerNode) => {  
53 - return triggerNode.parentNode;  
54 - }  
55 - "  
56 - v-else-if="item.key === 'entityId'"  
57 - v-model:value="item.value"  
58 - placeholder="请选择"  
59 - notFoundContent="请选择"  
60 - :options="entityOptions"  
61 - allowClear  
62 - />  
63 - <Select  
64 - :getPopupContainer="  
65 - (triggerNode) => {  
66 - return triggerNode.parentNode;  
67 - }  
68 - "  
69 - v-else-if="item.key === 'keys'"  
70 - v-model:value="item.value"  
71 - placeholder="请选择"  
72 - notFoundContent="请选择"  
73 - :options="attributeOptions"  
74 - mode="multiple"  
75 - allowClear  
76 - />  
77 - <div v-else-if="item.key === 'date_range'">  
78 - <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>  
79 - <span>~</span>  
80 - <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>  
81 - </div>  
82 - <div v-else-if="item.key === 'fixed_date'">  
83 - <a-button disabled type="primary">{{ item.value }}</a-button>  
84 - </div>  
85 - <Select  
86 - :getPopupContainer="  
87 - (triggerNode) => {  
88 - return triggerNode.parentNode;  
89 - }  
90 - "  
91 - v-else  
92 - v-model:value="item.value"  
93 - placeholder="请选择"  
94 - notFoundContent="请选择"  
95 - :options="valueOptions"  
96 - allowClear  
97 - @change="handleValueChange(item)"  
98 - />  
99 - </td>  
100 - <td style="width: 6.5vw">  
101 - <a-input  
102 - v-if="item.key === 'scope'"  
103 - placeholder="请输入"  
104 - v-model:value="item.keyValue"  
105 - />  
106 - <a-date-picker  
107 - v-else-if="item.key === 'fixed_date'"  
108 - style="width: 6.5vw"  
109 - v-model:value="item.fixed_date_value"  
110 - :show-time="{ format: 'HH:mm' }"  
111 - format="YYYY-MM-DD HH:mm:ss"  
112 - placeholder="日期时间"  
113 - />  
114 - <a-range-picker  
115 - v-else-if="item.key == 'date_range'"  
116 - style="width: 6.5vw"  
117 - v-model:value="item.dateValue"  
118 - :show-time="{ format: 'HH:mm' }"  
119 - format="YYYY-MM-DD HH:mm"  
120 - :placeholder="['开始', '结束']"  
121 - />  
122 - <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" />  
123 - </td>  
124 - </tr>  
125 - </tbody>  
126 - </table>  
127 - </div>  
128 -</template>  
129 -<script lang="ts" setup name="editCellTable">  
130 - import { reactive, ref, onMounted } from 'vue';  
131 - import { Select } from 'ant-design-vue';  
132 - import { findDictItemByCode } from '/@/api/system/dict';  
133 - import { getAllDeviceByOrg } from '/@/api/dataBoard';  
134 - import { getDeviceAttributes } from '/@/api/dataBoard';  
135 - import { useApi } from '../../../hooks/useApi';  
136 - import { cloneDeep } from 'lodash-es';  
137 - import { tableItems, selectType } from '../../../types';  
138 - import { editTestCellTableTHeadConfig } from '../../../config';  
139 - import { QuestionCircleOutlined } from '@ant-design/icons-vue';  
140 -  
141 - const props = defineProps({  
142 - method: {  
143 - type: String,  
144 - },  
145 - });  
146 -  
147 - onMounted(async () => {  
148 - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });  
149 - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));  
150 - selectOptions.value.push({  
151 - label: '自定义',  
152 - value: 'scope',  
153 - });  
154 - if (props.method === '2')  
155 - selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');  
156 - });  
157 -  
158 - const selectOptions = ref<selectType[]>([]);  
159 -  
160 - const valueOptions = ref<selectType[]>([]);  
161 -  
162 - const entityOptions = ref<selectType[]>([]);  
163 -  
164 - const attributeOptions = ref<selectType[]>([]);  
165 -  
166 - const treeData = ref([]);  
167 -  
168 - const tableTestArray = reactive<{  
169 - content: tableItems[];  
170 - }>({  
171 - content: [  
172 - {  
173 - key: undefined,  
174 - value: undefined,  
175 - keyValue: null,  
176 - editDisabled: false,  
177 - dateValue: null,  
178 - },  
179 - ],  
180 - });  
181 -  
182 - //设置数据  
183 - const setTableArray = (data) => {  
184 - const list = cloneDeep(data);  
185 - list?.forEach((it) => {  
186 - if (it.key === 'keys') it.value = [];  
187 - });  
188 - if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);  
189 - };  
190 -  
191 - const getApi = (list) => {  
192 - list?.forEach(async (it) => {  
193 - if (it.key === 'deviceProfileId') {  
194 - const { options } = await useApi(it.key);  
195 - valueOptions.value = options;  
196 - } else if (it.key === 'organizationId') {  
197 - const { options } = await useApi(it.key);  
198 - treeData.value = options as any;  
199 - }  
200 - });  
201 - };  
202 -  
203 - const handleOrgnationChange = async (e) => {  
204 - let deviceProfileId = '';  
205 - tableTestArray.content.forEach((f: any) => {  
206 - if (f.key === 'entityId') {  
207 - f.value = null;  
208 - }  
209 - if (f.key === 'deviceProfileId') deviceProfileId = f.value;  
210 - });  
211 - getEntityOptions(e.value, deviceProfileId);  
212 - };  
213 -  
214 - const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {  
215 - const res = await getAllDeviceByOrg(organizationId, deviceProfileId);  
216 - entityOptions.value = res.map((item) => ({  
217 - label: item.name,  
218 - value: item.tbDeviceId,  
219 - }));  
220 - };  
221 -  
222 - const getAttributeOptions = async (params) => {  
223 - const res = await getDeviceAttributes(params);  
224 - if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);  
225 - attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));  
226 - };  
227 -  
228 - const handleValueChange = (e) => {  
229 - let organizationId = '';  
230 - if (e.key === 'deviceProfileId') {  
231 - tableTestArray.content.forEach((f: any) => {  
232 - if (f.key === 'keys') {  
233 - f.value = [];  
234 - }  
235 - if (f.key === 'organizationId') organizationId = f.value;  
236 - if (f.key === 'entityId') f.value = null;  
237 - });  
238 - if (e.value) {  
239 - getAttributeOptions({ deviceProfileId: e.value });  
240 - }  
241 - if (organizationId !== '') {  
242 - getEntityOptions(organizationId, e.value);  
243 - }  
244 - }  
245 - };  
246 -  
247 - //获取数据  
248 - const getValue = () => {  
249 - return tableTestArray.content;  
250 - };  
251 - defineExpose({  
252 - getValue,  
253 - setTableArray,  
254 - });  
255 -</script>  
256 -  
257 -<style scoped lang="less">  
258 - @table-color: #e5e7eb;  
259 -  
260 - .table-border-color {  
261 - border: 1px solid #e5e7eb;  
262 - text-align: center;  
263 - }  
264 -  
265 - .table-content {  
266 - table {  
267 - width: 31vw;  
268 - &:extend(.table-border-color);  
269 - }  
270 -  
271 - table td {  
272 - padding: 5px;  
273 - white-space: nowrap;  
274 - &:extend(.table-border-color);  
275 - }  
276 -  
277 - table th {  
278 - padding: 5px;  
279 - &:extend(.table-border-color);  
280 - }  
281 - }  
282 -</style> 1 +<!-- eslint-disable vue/valid-v-model -->
  2 +<template>
  3 + <div class="table-content">
  4 + <!-- TODO: 待优化测试表格 -->
  5 + <table align="center">
  6 + <thead>
  7 + <tr>
  8 + <th v-for="item in editTestCellTableTHeadConfig" :key="item">
  9 + <a-tooltip v-if="item === '参数值'">
  10 + <template #title>当自定义为entityType,应输入DEVICE</template>
  11 + <QuestionCircleOutlined :style="{ fontSize: '14px', marginLeft: '5px' }" />
  12 + </a-tooltip>
  13 + {{ item }}
  14 + </th>
  15 + </tr>
  16 + </thead>
  17 + <tbody>
  18 + <tr v-for="(item, index) in tableTestArray.content" :key="index">
  19 + <td style="width: 7.5vw">
  20 + <Select
  21 + :getPopupContainer="
  22 + (triggerNode) => {
  23 + return triggerNode.parentNode;
  24 + }
  25 + "
  26 + :disabled="true"
  27 + v-model:value="item.key"
  28 + placeholder="请选择"
  29 + :options="selectOptions"
  30 + />
  31 + </td>
  32 + <td style="width: 6.5vw">
  33 + <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />
  34 + <a-tree-select
  35 + :getPopupContainer="
  36 + (triggerNode) => {
  37 + return triggerNode.parentNode;
  38 + }
  39 + "
  40 + v-else-if="item.key === 'organizationId'"
  41 + v-model:value="item.value"
  42 + show-search
  43 + :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
  44 + placeholder="请选择组织"
  45 + allow-clear
  46 + tree-default-expand-all
  47 + :tree-data="treeData"
  48 + @change="handleOrgnationChange(item)"
  49 + />
  50 + <Select
  51 + :getPopupContainer="
  52 + (triggerNode) => {
  53 + return triggerNode.parentNode;
  54 + }
  55 + "
  56 + v-else-if="item.key === 'entityId'"
  57 + v-model:value="item.value"
  58 + placeholder="请选择"
  59 + notFoundContent="请选择"
  60 + :options="entityOptions"
  61 + allowClear
  62 + />
  63 + <Select
  64 + :getPopupContainer="
  65 + (triggerNode) => {
  66 + return triggerNode.parentNode;
  67 + }
  68 + "
  69 + v-else-if="item.key === 'keys'"
  70 + v-model:value="item.value"
  71 + placeholder="请选择"
  72 + notFoundContent="请选择"
  73 + :options="attributeOptions"
  74 + mode="multiple"
  75 + allowClear
  76 + />
  77 + <div v-else-if="item.key === 'date_range'">
  78 + <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>
  79 + <span>~</span>
  80 + <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>
  81 + </div>
  82 + <div v-else-if="item.key === 'fixed_date'">
  83 + <a-button disabled type="primary">{{ item.value }}</a-button>
  84 + </div>
  85 + <Select
  86 + :getPopupContainer="
  87 + (triggerNode) => {
  88 + return triggerNode.parentNode;
  89 + }
  90 + "
  91 + v-else
  92 + v-model:value="item.value"
  93 + placeholder="请选择"
  94 + notFoundContent="请选择"
  95 + :options="valueOptions"
  96 + allowClear
  97 + @change="handleValueChange(item)"
  98 + />
  99 + </td>
  100 + <td style="width: 6.5vw">
  101 + <a-input
  102 + v-if="item.key === 'scope'"
  103 + placeholder="请输入"
  104 + v-model:value="item.keyValue"
  105 + />
  106 + <a-date-picker
  107 + v-else-if="item.key === 'fixed_date'"
  108 + style="width: 6.5vw"
  109 + v-model:value="item.fixed_date_value"
  110 + :show-time="{ format: 'HH:mm' }"
  111 + format="YYYY-MM-DD HH:mm:ss"
  112 + placeholder="日期时间"
  113 + />
  114 + <a-range-picker
  115 + v-else-if="item.key == 'date_range'"
  116 + style="width: 6.5vw"
  117 + v-model:value="item.dateValue"
  118 + :show-time="{ format: 'HH:mm' }"
  119 + format="YYYY-MM-DD HH:mm"
  120 + :placeholder="['开始', '结束']"
  121 + />
  122 + <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" />
  123 + </td>
  124 + </tr>
  125 + </tbody>
  126 + </table>
  127 + </div>
  128 +</template>
  129 +<script lang="ts" setup name="editCellTable">
  130 + import { reactive, ref, onMounted } from 'vue';
  131 + import { Select } from 'ant-design-vue';
  132 + import { findDictItemByCode } from '/@/api/system/dict';
  133 + import { getAllDeviceByOrg } from '/@/api/dataBoard';
  134 + import { getDeviceAttributes } from '/@/api/dataBoard';
  135 + import { useApi } from '../../../hooks/useApi';
  136 + import { cloneDeep } from 'lodash-es';
  137 + import { tableItems, selectType } from '../../../types';
  138 + import { editTestCellTableTHeadConfig } from '../../../config';
  139 + import { QuestionCircleOutlined } from '@ant-design/icons-vue';
  140 +
  141 + const props = defineProps({
  142 + method: {
  143 + type: String,
  144 + },
  145 + });
  146 +
  147 + onMounted(async () => {
  148 + const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
  149 + selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
  150 + selectOptions.value.push({
  151 + label: '自定义',
  152 + value: 'scope',
  153 + });
  154 + if (props.method === '2')
  155 + selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
  156 + });
  157 +
  158 + const selectOptions = ref<selectType[]>([]);
  159 +
  160 + const valueOptions = ref<selectType[]>([]);
  161 +
  162 + const entityOptions = ref<selectType[]>([]);
  163 +
  164 + const attributeOptions = ref<selectType[]>([]);
  165 +
  166 + const treeData = ref([]);
  167 +
  168 + const tableTestArray = reactive<{
  169 + content: tableItems[];
  170 + }>({
  171 + content: [
  172 + {
  173 + key: undefined,
  174 + value: undefined,
  175 + keyValue: null,
  176 + editDisabled: false,
  177 + dateValue: null,
  178 + },
  179 + ],
  180 + });
  181 +
  182 + //设置数据
  183 + const setTableArray = (data) => {
  184 + const list = cloneDeep(data);
  185 + list?.forEach((it) => {
  186 + if (it.key === 'keys') it.value = [];
  187 + });
  188 + if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);
  189 + };
  190 +
  191 + const getApi = (list) => {
  192 + list?.forEach(async (it) => {
  193 + if (it.key === 'deviceProfileId') {
  194 + const { options } = await useApi(it.key);
  195 + valueOptions.value = options;
  196 + } else if (it.key === 'organizationId') {
  197 + const { options } = await useApi(it.key);
  198 + treeData.value = options as any;
  199 + }
  200 + });
  201 + };
  202 +
  203 + const handleOrgnationChange = async (e) => {
  204 + let deviceProfileId = '';
  205 + tableTestArray.content.forEach((f: any) => {
  206 + if (f.key === 'entityId') {
  207 + f.value = null;
  208 + }
  209 + if (f.key === 'deviceProfileId') deviceProfileId = f.value;
  210 + });
  211 + getEntityOptions(e.value, deviceProfileId);
  212 + };
  213 +
  214 + const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
  215 + const res = await getAllDeviceByOrg(organizationId, deviceProfileId);
  216 + entityOptions.value = res.map((item) => ({
  217 + label: item.name,
  218 + value: item.tbDeviceId,
  219 + }));
  220 + };
  221 +
  222 + const getAttributeOptions = async (params) => {
  223 + const res = await getDeviceAttributes(params);
  224 + if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);
  225 + attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
  226 + };
  227 +
  228 + const handleValueChange = (e) => {
  229 + let organizationId = '';
  230 + if (e.key === 'deviceProfileId') {
  231 + tableTestArray.content.forEach((f: any) => {
  232 + if (f.key === 'keys') {
  233 + f.value = [];
  234 + }
  235 + if (f.key === 'organizationId') organizationId = f.value;
  236 + if (f.key === 'entityId') f.value = null;
  237 + });
  238 + getAttributeOptions({ deviceProfileId: e.value });
  239 + if (organizationId !== '') {
  240 + getEntityOptions(organizationId, e.value);
  241 + }
  242 + }
  243 + };
  244 +
  245 + //获取数据
  246 + const getValue = () => {
  247 + return tableTestArray.content;
  248 + };
  249 + defineExpose({
  250 + getValue,
  251 + setTableArray,
  252 + });
  253 +</script>
  254 +
  255 +<style scoped lang="less">
  256 + @table-color: #e5e7eb;
  257 +
  258 + .table-border-color {
  259 + border: 1px solid #e5e7eb;
  260 + text-align: center;
  261 + }
  262 +
  263 + .table-content {
  264 + table {
  265 + width: 31vw;
  266 + &:extend(.table-border-color);
  267 + }
  268 +
  269 + table td {
  270 + padding: 5px;
  271 + white-space: nowrap;
  272 + &:extend(.table-border-color);
  273 + }
  274 +
  275 + table th {
  276 + padding: 5px;
  277 + &:extend(.table-border-color);
  278 + }
  279 + }
  280 +</style>
1 -<template>  
2 - <div>  
3 - <BasicDrawer  
4 - destroyOnClose  
5 - showFooter  
6 - v-bind="$attrs"  
7 - @register="registerDrawer"  
8 - width="50%"  
9 - @ok="handleSubmit"  
10 - >  
11 - <BasicForm @register="registerForm">  
12 - <template #selectMethods="{ model }">  
13 - <SimpleRequest  
14 - ref="simpleRequestRef"  
15 - v-if="model['requestContentType'] === '0' || model['requestContentType'] === '2'"  
16 - :requestTypeAndUrl="model['requestHttpTypeAndUrl']"  
17 - :method="model['requestContentType']"  
18 - :requestOriginUrl="model['requestOriginUrl']"  
19 - :originUrlType="model['originUrlType']"  
20 - />  
21 - </template>  
22 - <template #testSql="{ model }">  
23 - <div style="margin: auto 7.5rem">  
24 - <TestSql  
25 - ref="testSqlRef"  
26 - v-if="model['requestContentType'] === '1'"  
27 - :method="model['requestContentType']"  
28 - />  
29 - </div>  
30 - </template>  
31 - </BasicForm>  
32 - </BasicDrawer>  
33 - </div>  
34 -</template>  
35 -<script lang="ts" setup name="publicApi">  
36 - import { ref, nextTick } from 'vue';  
37 - import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';  
38 - import { BasicForm, useForm } from '/@/components/Form';  
39 - import { schemas } from './config';  
40 - import SimpleRequest from './components/SimpleRequest/index.vue';  
41 - import { TestSql } from './components/TestSql/index';  
42 - import {  
43 - saveDataViewInterface,  
44 - updateDataViewInterface,  
45 - } from '/@/api/bigscreen/center/bigscreenCenter';  
46 -  
47 - import { useMessage } from '/@/hooks/web/useMessage';  
48 - import { useUtils } from './hooks/useUtils';  
49 -  
50 - const { resetReqHttpType } = useUtils();  
51 -  
52 - const emits = defineEmits(['success', 'register']);  
53 -  
54 - const { createMessage } = useMessage();  
55 -  
56 - const isUpdate = ref(false);  
57 -  
58 - const putId = ref('');  
59 -  
60 - const simpleRequestRef = ref<InstanceType<typeof SimpleRequest>>();  
61 -  
62 - const testSqlRef = ref<InstanceType<typeof TestSql>>();  
63 -  
64 - const [registerForm, { resetFields, validate, setFieldsValue, updateSchema }] = useForm({  
65 - labelWidth: 120,  
66 - schemas,  
67 - showActionButtonGroup: false,  
68 - });  
69 -  
70 - const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {  
71 - await resetFields();  
72 - await nextTick();  
73 - setFieldsValue(resetReqHttpType);  
74 - const title = `${!data.isUpdate ? '新增' : '修改'}公共接口`;  
75 - setDrawerProps({ title });  
76 - updateSchema({  
77 - field: 'requestHttpTypeAndUrl',  
78 - componentProps: {  
79 - type: '0',  
80 - },  
81 - });  
82 - isUpdate.value = data.isUpdate;  
83 - !isUpdate.value ? (putId.value = '') : (putId.value = data.record.id);  
84 - simpleRequestRef.value?.resetValue() && testSqlRef.value?.resetValue();  
85 - if (isUpdate.value) {  
86 - await setFieldsValue({  
87 - ...data.record,  
88 - requestContentType: String(data.record?.requestContentType),  
89 - requestSQLContent: JSON.parse(data.record?.requestParams)?.requestSQLContent?.sql,  
90 - originUrlType: data.record?.requestOriginUrl?.startsWith('localhost')  
91 - ? 'server_url'  
92 - : 'custom_url',  
93 - requestHttpTypeAndUrl: {  
94 - requestHttpType: data.record?.requestHttpType,  
95 - requestUrl: data.record?.requestUrl,  
96 - },  
97 - });  
98 - await nextTick(() => simpleRequestRef.value?.setValue(data.record));  
99 - updateSchema({  
100 - field: 'requestHttpTypeAndUrl',  
101 - componentProps: {  
102 - type: String(data.record?.requestContentType),  
103 - },  
104 - });  
105 - }  
106 - });  
107 -  
108 - const handleSubmit = async () => {  
109 - setDrawerProps({ loading: true });  
110 - try {  
111 - const values = await validate();  
112 - if (!values) return;  
113 - const Objects = simpleRequestRef.value?.getValue(true);  
114 - const requestOriginUrl =  
115 - values['originUrlType'] === 'server_url' ? 'localhost' : values['requestOriginUrl'];  
116 - const data = {  
117 - ...values,  
118 - id: !putId.value ? null : putId.value,  
119 - requestParams: JSON.stringify({  
120 - requestSQLContent: {  
121 - sql: values?.requestSQLContent,  
122 - },  
123 - ...Objects,  
124 - }),  
125 - requestOriginUrl,  
126 - requestHttpType: values['requestHttpTypeAndUrl']?.requestHttpType,  
127 - requestUrl: values['requestHttpTypeAndUrl']?.requestUrl,  
128 - };  
129 - Reflect.deleteProperty(data, 'requestHttpTypeAndUrl');  
130 - if (values['requestContentType'] === '2') Reflect.deleteProperty(data, 'requestHttpType');  
131 - !putId.value ? await saveDataViewInterface(data) : await updateDataViewInterface(data);  
132 - emits('success');  
133 - closeDrawer();  
134 - createMessage.success(`${!isUpdate.value ? '新增' : '修改'}公共接口成功`);  
135 - } finally {  
136 - setDrawerProps({ loading: false });  
137 - }  
138 - };  
139 -</script> 1 +<template>
  2 + <div>
  3 + <BasicDrawer
  4 + showFooter
  5 + v-bind="$attrs"
  6 + @register="registerDrawer"
  7 + width="50%"
  8 + @ok="handleSubmit"
  9 + >
  10 + <BasicForm @register="registerForm">
  11 + <template #selectMethods="{ model }">
  12 + <SimpleRequest
  13 + ref="simpleRequestRef"
  14 + v-if="model['requestContentType'] === '0' || model['requestContentType'] === '2'"
  15 + :requestTypeAndUrl="model['requestHttpTypeAndUrl']"
  16 + :method="model['requestContentType']"
  17 + :requestOriginUrl="model['requestOriginUrl']"
  18 + :originUrlType="model['originUrlType']"
  19 + />
  20 + </template>
  21 + <template #testSql="{ model }">
  22 + <div style="margin: auto 7.5rem">
  23 + <TestSql
  24 + ref="testSqlRef"
  25 + v-if="model['requestContentType'] === '1'"
  26 + :method="model['requestContentType']"
  27 + />
  28 + </div>
  29 + </template>
  30 + </BasicForm>
  31 + </BasicDrawer>
  32 + </div>
  33 +</template>
  34 +<script lang="ts" setup name="publicApi">
  35 + import { ref, nextTick } from 'vue';
  36 + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  37 + import { BasicForm, useForm } from '/@/components/Form';
  38 + import { schemas } from './config';
  39 + import SimpleRequest from './components/SimpleRequest/index.vue';
  40 + import { TestSql } from './components/TestSql/index';
  41 + import {
  42 + saveDataViewInterface,
  43 + updateDataViewInterface,
  44 + } from '/@/api/bigscreen/center/bigscreenCenter';
  45 +
  46 + import { useMessage } from '/@/hooks/web/useMessage';
  47 + import { useUtils } from './hooks/useUtils';
  48 +
  49 + const { resetReqHttpType, resetUpdateSchema } = useUtils();
  50 +
  51 + const emits = defineEmits(['success', 'register']);
  52 +
  53 + const { createMessage } = useMessage();
  54 +
  55 + const isUpdate = ref(false);
  56 +
  57 + const putId = ref('');
  58 +
  59 + const simpleRequestRef = ref<InstanceType<typeof SimpleRequest>>();
  60 +
  61 + const testSqlRef = ref<InstanceType<typeof TestSql>>();
  62 +
  63 + const [registerForm, { resetFields, validate, setFieldsValue, updateSchema }] = useForm({
  64 + labelWidth: 120,
  65 + schemas,
  66 + showActionButtonGroup: false,
  67 + });
  68 +
  69 + const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
  70 + await resetFields();
  71 + await nextTick();
  72 + updateSchema(resetUpdateSchema);
  73 + setFieldsValue(resetReqHttpType);
  74 + const title = `${!data.isUpdate ? '新增' : '修改'}公共接口`;
  75 + setDrawerProps({ title });
  76 + isUpdate.value = data.isUpdate;
  77 + !isUpdate.value ? (putId.value = '') : (putId.value = data.record.id);
  78 + simpleRequestRef.value?.resetValue() && testSqlRef.value?.resetValue();
  79 + if (isUpdate.value) {
  80 + await setFieldsValue({
  81 + ...data.record,
  82 + requestContentType: String(data.record?.requestContentType),
  83 + requestSQLContent: JSON.parse(data.record?.requestParams)?.requestSQLContent?.sql,
  84 + originUrlType: data.record?.requestOriginUrl?.startsWith('localhost')
  85 + ? 'server_url'
  86 + : 'custom_url',
  87 + requestHttpTypeAndUrl: {
  88 + requestHttpType: data.record?.requestHttpType,
  89 + requestUrl: data.record?.requestUrl,
  90 + },
  91 + });
  92 + await nextTick(() => simpleRequestRef.value?.setValue(data.record));
  93 + updateSchema({
  94 + field: 'requestHttpTypeAndUrl',
  95 + componentProps: {
  96 + type: String(data.record?.requestContentType),
  97 + },
  98 + });
  99 + }
  100 + });
  101 +
  102 + const handleSubmit = async () => {
  103 + setDrawerProps({ loading: true });
  104 + try {
  105 + const values = await validate();
  106 + if (!values) return;
  107 + const Objects = simpleRequestRef.value?.getValue(true);
  108 + const requestOriginUrl =
  109 + values['originUrlType'] === 'server_url' ? 'localhost' : values['requestOriginUrl'];
  110 + const data = {
  111 + ...values,
  112 + id: !putId.value ? null : putId.value,
  113 + requestParams: JSON.stringify({
  114 + requestSQLContent: {
  115 + sql: values?.requestSQLContent,
  116 + },
  117 + ...Objects,
  118 + }),
  119 + requestOriginUrl,
  120 + requestHttpType: values['requestHttpTypeAndUrl']?.requestHttpType,
  121 + requestUrl: values['requestHttpTypeAndUrl']?.requestUrl,
  122 + };
  123 + Reflect.deleteProperty(data, 'requestHttpTypeAndUrl');
  124 + if (values['requestContentType'] === '2') Reflect.deleteProperty(data, 'requestHttpType');
  125 + !putId.value ? await saveDataViewInterface(data) : await updateDataViewInterface(data);
  126 + emits('success');
  127 + closeDrawer();
  128 + createMessage.success(`${!isUpdate.value ? '新增' : '修改'}公共接口成功`);
  129 + } finally {
  130 + setDrawerProps({ loading: false });
  131 + }
  132 + };
  133 +</script>
1 -export const useUtils = () => {  
2 - //获取多个key  
3 - const getMultipleKeys = (list) => {  
4 - let temps = [];  
5 - list?.forEach((it) => {  
6 - const keys = it.key.split(',');  
7 - const temp = keys.map((item) => {  
8 - const obj: { key: string; value: string; required: boolean } = {  
9 - key: '',  
10 - value: '',  
11 - required: false,  
12 - };  
13 - obj.key = item;  
14 - obj.value = item === 'scope' ? it.value : '';  
15 - obj.required = it.required;  
16 - return obj;  
17 - });  
18 - temps = temp;  
19 - });  
20 - return temps;  
21 - };  
22 - //默认push一个  
23 - const pushObj = {  
24 - key: undefined,  
25 - value: '',  
26 - editDisabled: false,  
27 - required: false,  
28 - date1: '',  
29 - date2: '',  
30 - };  
31 - //新增时置空特定数据  
32 - const resetReqHttpType = {  
33 - requestHttpTypeAndUrl: {  
34 - requestHttpType: undefined,  
35 - requestUrl: '',  
36 - },  
37 - };  
38 - const resetUpdateSchema = {  
39 - field: 'requestHttpTypeAndUrl',  
40 - componentProps: {  
41 - type: '0',  
42 - },  
43 - };  
44 - //对象转get params参数  
45 - const convertObj = (data: object) => {  
46 - const _result: any = [];  
47 - for (const key in data) {  
48 - const value = data[key];  
49 - if (value.constructor == Array) {  
50 - value.forEach(function (_value) {  
51 - _result.push(key + '=' + _value);  
52 - });  
53 - } else {  
54 - _result.push(key + '=' + value);  
55 - }  
56 - }  
57 - return _result.join('&');  
58 - };  
59 - return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema, convertObj };  
60 -}; 1 +export const useUtils = () => {
  2 + //获取多个key
  3 + const getMultipleKeys = (list) => {
  4 + let temps = [];
  5 + list?.forEach((it) => {
  6 + const keys = it.key.split(',');
  7 + const temp = keys.map((item) => {
  8 + const obj: { key: string; value: string } = { key: '', value: '' };
  9 + obj.key = item;
  10 + obj.value = item === 'scope' ? it.value : '';
  11 + return obj;
  12 + });
  13 + temps = temp;
  14 + });
  15 + return temps;
  16 + };
  17 + //默认push一个
  18 + const pushObj = {
  19 + key: undefined,
  20 + value: '',
  21 + editDisabled: false,
  22 + required: false,
  23 + date1: '',
  24 + date2: '',
  25 + };
  26 + //新增时置空特定数据
  27 + const resetReqHttpType = {
  28 + requestHttpTypeAndUrl: {
  29 + requestHttpType: undefined,
  30 + requestUrl: '',
  31 + },
  32 + };
  33 + const resetUpdateSchema = {
  34 + field: 'requestHttpTypeAndUrl',
  35 + componentProps: {
  36 + type: '0',
  37 + },
  38 + };
  39 + return { getMultipleKeys, pushObj, resetReqHttpType, resetUpdateSchema };
  40 +};
1 -<template>  
2 - <div>  
3 - <BasicTable @register="registerTable" :row-selection="rowSelection">  
4 - <template #content="{ record }">  
5 - <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button>  
6 - </template>  
7 - <template #toolbar>  
8 - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增公共接口 </a-button>  
9 - <Popconfirm  
10 - title="您确定要批量删除数据"  
11 - ok-text="确定"  
12 - cancel-text="取消"  
13 - @confirm="handleDeleteOrBatchDelete(null)"  
14 - >  
15 - <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>  
16 - </Popconfirm>  
17 - <Popconfirm  
18 - title="您确定要批量发布"  
19 - ok-text="确定"  
20 - cancel-text="取消"  
21 - @confirm="handleBatchPublish('batchPublish')"  
22 - >  
23 - <a-button color="error" :disabled="hasBatchPublish"> 批量发布 </a-button>  
24 - </Popconfirm>  
25 - <!-- <Popconfirm  
26 - title="您确定要批量取消发布"  
27 - ok-text="确定"  
28 - cancel-text="取消"  
29 - @confirm="handleBatchPublish('cancelBatchPublish')"  
30 - >  
31 - <a-button color="error" :disabled="hasBatchPublish"> 批量取消发布 </a-button>  
32 - </Popconfirm> -->  
33 - </template>  
34 - <template #action="{ record }">  
35 - <TableAction  
36 - :actions="[  
37 - {  
38 - label: '发布',  
39 - icon: 'ant-design:node-expand-outlined',  
40 - onClick: handlePublish.bind(null, 'publish', record),  
41 - ifShow: () => {  
42 - return record.state === 0 && record.creator === userId;  
43 - },  
44 - },  
45 - {  
46 - label: '取消发布',  
47 - icon: 'ant-design:node-collapse-outlined',  
48 - onClick: handlePublish.bind(null, 'canelPublish', record),  
49 - ifShow: () => {  
50 - return record.state === 1 && record.creator === userId;  
51 - },  
52 - },  
53 - {  
54 - label: '修改',  
55 - icon: 'clarity:note-edit-line',  
56 - onClick: handleCreateOrEdit.bind(null, record),  
57 - ifShow: () => {  
58 - return record.state === 0 && record.creator === userId;  
59 - },  
60 - },  
61 - {  
62 - label: '删除',  
63 - icon: 'ant-design:delete-outlined',  
64 - color: 'error',  
65 - ifShow: () => {  
66 - return record.state === 0 && record.creator === userId;  
67 - },  
68 - popConfirm: {  
69 - title: '是否确认删除',  
70 - confirm: handleDeleteOrBatchDelete.bind(null, record),  
71 - },  
72 - },  
73 - ]"  
74 - />  
75 - </template>  
76 - </BasicTable>  
77 - </div>  
78 - <PublicApiForm @register="registerDrawer" @success="handleSuccess" />  
79 -</template>  
80 -<script lang="ts" setup name="list">  
81 - import { h, ref } from 'vue';  
82 - import { BasicTable, useTable, TableAction } from '/@/components/Table';  
83 - import { useDrawer } from '/@/components/Drawer';  
84 - import { columns, searchFormSchema } from './config';  
85 - import { PublicApiForm } from './index';  
86 - import {  
87 - getDataViewInterfacePage,  
88 - deleteBigViewInterface,  
89 - getPublish,  
90 - getCancelPublish,  
91 - putPublishOrCancelPublish,  
92 - } from '/@/api/bigscreen/center/bigscreenCenter';  
93 - import { Popconfirm, Modal } from 'ant-design-vue';  
94 - import { JsonPreview } from '/@/components/CodeEditor';  
95 - import { useMessage } from '/@/hooks/web/useMessage';  
96 - import { USER_INFO_KEY } from '/@/enums/cacheEnum';  
97 - import { getAuthCache } from '/@/utils/auth';  
98 -  
99 - const userInfo = getAuthCache(USER_INFO_KEY) as any;  
100 -  
101 - const userId = ref(userInfo?.userId);  
102 -  
103 - const [registerTable, { reload, clearSelectedRowKeys }] = useTable({  
104 - api: getDataViewInterfacePage,  
105 - columns,  
106 - showIndexColumn: false,  
107 - clickToRowSelect: false,  
108 - showTableSetting: true,  
109 - bordered: true,  
110 - formConfig: {  
111 - labelWidth: 120,  
112 - schemas: searchFormSchema,  
113 - },  
114 - useSearchForm: true,  
115 - actionColumn: {  
116 - width: 150,  
117 - title: '操作',  
118 - dataIndex: 'action',  
119 - slots: { customRender: 'action' },  
120 - fixed: 'right',  
121 - },  
122 - });  
123 -  
124 - const [registerDrawer, { openDrawer }] = useDrawer();  
125 -  
126 - const hasBatchPublish = ref(true);  
127 -  
128 - const hasBatchDelete = ref(true);  
129 -  
130 - const batchDeleteIds = ref([]);  
131 -  
132 - const { createMessage } = useMessage();  
133 -  
134 - const handleSuccess = () => {  
135 - reload();  
136 - setStatusIsTrue();  
137 - clearSelectedRowKeys();  
138 - };  
139 -  
140 - const setStatusIsFalse = () => {  
141 - (hasBatchDelete.value = false), (hasBatchPublish.value = false);  
142 - };  
143 -  
144 - const setStatusIsTrue = () => {  
145 - (hasBatchDelete.value = true), (hasBatchPublish.value = true);  
146 - };  
147 -  
148 - const rowSelection = {  
149 - onChange: (_, selectedRows: any[]) => {  
150 - batchDeleteIds.value = selectedRows.map((it) => it.id) as never as any;  
151 - if (batchDeleteIds.value.length > 0) setStatusIsFalse();  
152 - else setStatusIsTrue();  
153 - },  
154 - getCheckboxProps: (record) => ({  
155 - disabled: record.state === 1,  
156 - }),  
157 - };  
158 -  
159 - const handleCreateOrEdit = (record) => {  
160 - const isUpdate = record === null ? false : true;  
161 - const recordContent = record === null ? null : record;  
162 - openDrawer(true, {  
163 - isUpdate,  
164 - record: recordContent,  
165 - });  
166 - };  
167 -  
168 - const handleRecordContent = (record) => {  
169 - Modal.info({  
170 - title: '接口内容',  
171 - width: 600,  
172 - content: h(JsonPreview, { data: JSON.parse(record.requestParams) }),  
173 - });  
174 - };  
175 -  
176 - const handlePublish = async (type, record) => {  
177 - type === 'publish' ? await getPublish(record.id) : await getCancelPublish(record.id);  
178 - createMessage.success(`${type === 'publish' ? '发布' : '取消发布'}成功`);  
179 - handleSuccess();  
180 - };  
181 -  
182 - const handleBatchPublish = async (type) => {  
183 - await putPublishOrCancelPublish(type, batchDeleteIds.value);  
184 - createMessage.success(`${type === 'batchPublish' ? '批量发布' : '批量取消发布'}成功`);  
185 - handleSuccess();  
186 - };  
187 -  
188 - const handleDeleteOrBatchDelete = async (record) => {  
189 - const ids = record === null ? batchDeleteIds.value : [record.id];  
190 - await deleteBigViewInterface(ids);  
191 - createMessage.success(`${record === null ? '批量删除' : '删除'}成功`);  
192 - handleSuccess();  
193 - };  
194 -</script> 1 +<template>
  2 + <div>
  3 + <BasicTable @register="registerTable" :row-selection="rowSelection">
  4 + <template #content="{ record }">
  5 + <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button>
  6 + </template>
  7 + <template #toolbar>
  8 + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增公共接口 </a-button>
  9 + <Popconfirm
  10 + title="您确定要批量删除数据"
  11 + ok-text="确定"
  12 + cancel-text="取消"
  13 + @confirm="handleDeleteOrBatchDelete(null)"
  14 + >
  15 + <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
  16 + </Popconfirm>
  17 + <Popconfirm
  18 + title="您确定要批量发布"
  19 + ok-text="确定"
  20 + cancel-text="取消"
  21 + @confirm="handleBatchPublish('batchPublish')"
  22 + >
  23 + <a-button color="error" :disabled="hasBatchPublish"> 批量发布 </a-button>
  24 + </Popconfirm>
  25 + <!-- <Popconfirm
  26 + title="您确定要批量取消发布"
  27 + ok-text="确定"
  28 + cancel-text="取消"
  29 + @confirm="handleBatchPublish('cancelBatchPublish')"
  30 + >
  31 + <a-button color="error" :disabled="hasBatchPublish"> 批量取消发布 </a-button>
  32 + </Popconfirm> -->
  33 + </template>
  34 + <template #action="{ record }">
  35 + <TableAction
  36 + :actions="[
  37 + {
  38 + label: '发布',
  39 + icon: 'ant-design:node-expand-outlined',
  40 + onClick: handlePublish.bind(null, 'publish', record),
  41 + ifShow: () => {
  42 + return record.state === 0;
  43 + },
  44 + },
  45 + {
  46 + label: '取消发布',
  47 + icon: 'ant-design:node-collapse-outlined',
  48 + onClick: handlePublish.bind(null, 'canelPublish', record),
  49 + ifShow: () => {
  50 + return record.state === 1;
  51 + },
  52 + },
  53 + {
  54 + label: '修改',
  55 + icon: 'clarity:note-edit-line',
  56 + onClick: handleCreateOrEdit.bind(null, record),
  57 + ifShow: () => {
  58 + return record.state === 0;
  59 + },
  60 + },
  61 + {
  62 + label: '删除',
  63 + icon: 'ant-design:delete-outlined',
  64 + color: 'error',
  65 + ifShow: () => {
  66 + return record.state === 0;
  67 + },
  68 + popConfirm: {
  69 + title: '是否确认删除',
  70 + confirm: handleDeleteOrBatchDelete.bind(null, record),
  71 + },
  72 + },
  73 + ]"
  74 + />
  75 + </template>
  76 + </BasicTable>
  77 + </div>
  78 + <PublicApiForm @register="registerDrawer" @success="handleSuccess" />
  79 +</template>
  80 +<script lang="ts" setup name="list">
  81 + import { h, ref } from 'vue';
  82 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  83 + import { useDrawer } from '/@/components/Drawer';
  84 + import { columns, searchFormSchema } from './config';
  85 + import { PublicApiForm } from './index';
  86 + import {
  87 + getDataViewInterfacePage,
  88 + deleteBigViewInterface,
  89 + getPublish,
  90 + getCancelPublish,
  91 + putPublishOrCancelPublish,
  92 + } from '/@/api/bigscreen/center/bigscreenCenter';
  93 + import { Popconfirm, Modal } from 'ant-design-vue';
  94 + import { JsonPreview } from '/@/components/CodeEditor';
  95 + import { useMessage } from '/@/hooks/web/useMessage';
  96 +
  97 + const [registerTable, { reload, clearSelectedRowKeys }] = useTable({
  98 + api: getDataViewInterfacePage,
  99 + columns,
  100 + showIndexColumn: false,
  101 + clickToRowSelect: false,
  102 + showTableSetting: true,
  103 + bordered: true,
  104 + formConfig: {
  105 + labelWidth: 120,
  106 + schemas: searchFormSchema,
  107 + },
  108 + useSearchForm: true,
  109 + actionColumn: {
  110 + width: 150,
  111 + title: '操作',
  112 + dataIndex: 'action',
  113 + slots: { customRender: 'action' },
  114 + fixed: 'right',
  115 + },
  116 + });
  117 +
  118 + const [registerDrawer, { openDrawer }] = useDrawer();
  119 +
  120 + const hasBatchPublish = ref(true);
  121 +
  122 + const hasBatchDelete = ref(true);
  123 +
  124 + const batchDeleteIds = ref([]);
  125 +
  126 + const { createMessage } = useMessage();
  127 +
  128 + const handleSuccess = () => {
  129 + reload();
  130 + setStatusIsTrue();
  131 + clearSelectedRowKeys();
  132 + };
  133 +
  134 + const setStatusIsFalse = () => {
  135 + (hasBatchDelete.value = false), (hasBatchPublish.value = false);
  136 + };
  137 +
  138 + const setStatusIsTrue = () => {
  139 + (hasBatchDelete.value = true), (hasBatchPublish.value = true);
  140 + };
  141 +
  142 + const rowSelection = {
  143 + onChange: (_, selectedRows: any[]) => {
  144 + batchDeleteIds.value = selectedRows.map((it) => it.id) as never as any;
  145 + if (batchDeleteIds.value.length > 0) setStatusIsFalse();
  146 + else setStatusIsTrue();
  147 + },
  148 + getCheckboxProps: (record) => ({
  149 + disabled: record.state === 1,
  150 + }),
  151 + };
  152 +
  153 + const handleCreateOrEdit = (record) => {
  154 + const isUpdate = record === null ? false : true;
  155 + const recordContent = record === null ? null : record;
  156 + openDrawer(true, {
  157 + isUpdate,
  158 + record: recordContent,
  159 + });
  160 + };
  161 +
  162 + const handleRecordContent = (record) => {
  163 + Modal.info({
  164 + title: '接口内容',
  165 + width: 600,
  166 + content: h(JsonPreview, { data: JSON.parse(record.requestParams) }),
  167 + });
  168 + };
  169 +
  170 + const handlePublish = async (type, record) => {
  171 + type === 'publish' ? await getPublish(record.id) : await getCancelPublish(record.id);
  172 + createMessage.success(`${type === 'publish' ? '发布' : '取消发布'}成功`);
  173 + handleSuccess();
  174 + };
  175 +
  176 + const handleBatchPublish = async (type) => {
  177 + await putPublishOrCancelPublish(type, batchDeleteIds.value);
  178 + createMessage.success(`${type === 'batchPublish' ? '批量发布' : '批量取消发布'}成功`);
  179 + handleSuccess();
  180 + };
  181 +
  182 + const handleDeleteOrBatchDelete = async (record) => {
  183 + const ids = record === null ? batchDeleteIds.value : [record.id];
  184 + await deleteBigViewInterface(ids);
  185 + createMessage.success(`${record === null ? '批量删除' : '删除'}成功`);
  186 + handleSuccess();
  187 + };
  188 +</script>
@@ -53,7 +53,6 @@ @@ -53,7 +53,6 @@
53 baseColProps: { span: 8 }, 53 baseColProps: { span: 8 },
54 schemas: searchFormSchema, 54 schemas: searchFormSchema,
55 submitFunc: async () => { 55 submitFunc: async () => {
56 - pagination.current = 1;  
57 getDataSource({ pageSize: pagination.pageSize, page: 1 }); 56 getDataSource({ pageSize: pagination.pageSize, page: 1 });
58 }, 57 },
59 }); 58 });
@@ -56,6 +56,10 @@ @@ -56,6 +56,10 @@
56 56
57 const getAceClass = computed((): string => userStore.getDarkMode); 57 const getAceClass = computed((): string => userStore.getDarkMode);
58 58
  59 + const props = defineProps<{
  60 + value: Recordable;
  61 + }>();
  62 +
59 const ROUTE = useRoute(); 63 const ROUTE = useRoute();
60 64
61 const ROUTER = useRouter(); 65 const ROUTER = useRouter();