Commit 98be976229526a67bf91cc00d2d151707854d29a

Authored by xp.Huang
1 parent 76889596

Merge branch 'ft' into 'main_dev'

fix: 修改Teambition上的问题

See merge request yunteng/thingskit-front!535

(cherry picked from commit b8da6b5459e02e32e7e4e8a832c845ec9d7fc27b)

8c259679 pref: 脚本管理,移除上报数据类型和下行数据解析
68707d7b fix: DEFECT-1133 修复产品从最后一页分页查询,然后查询出来17条,但是显示第二页,界面显示为第一页的数据,点第一页界面不变
5618db44 fix: DEFECT-1118 只修复PC端,tcp命令下发输入内容验证字母和数字
7f595afd pref: 修改TCP脚本
2d3fda8c fix: DEFECT-1149 报表配置,新增填入数据后,再去编辑,数据未回显(执行方式为立即执行时)
4524080e fix: DEFECT-1076 修复暗黑模式下新增通知白色显示框问题
2405426e fix: DEFECT-1148 websocket测试,先正常选择,测试有数据,然后把参数设置清空,再执行测试请求,依然有数据显示(应该是有缓存)
1 -import { defHttp } from '/@/utils/http/axios';  
2 -import { ScriptParam, ScriptQueryParam, ScriptRecord } from './model/scriptModel';  
3 -import { PaginationResult } from '/#/axios';  
4 -  
5 -enum ScriptManagerApi {  
6 - SCRIPT_POST_URL = '/js',  
7 - SCRIPT_GET_URL = '/js',  
8 - SCRIPT_DELETE_URL = '/js',  
9 - SCRIPT_MELIST_URL = '/js/me/list',  
10 - SCRIPT_TEST_URL = '/js/test',  
11 - SCRIPT_STATUS = '/js',  
12 -}  
13 -  
14 -export const ScriptPage = (params: ScriptQueryParam) => {  
15 - return defHttp.get<PaginationResult<ScriptRecord>>({  
16 - url: ScriptManagerApi.SCRIPT_GET_URL,  
17 - params,  
18 - });  
19 -};  
20 -  
21 -/**  
22 - * 改变转换函数状态  
23 - * @param params id status  
24 - */  
25 -export const scriptPagePutApi = (id, status) =>  
26 - defHttp.post({  
27 - url: ScriptManagerApi.SCRIPT_STATUS + '/' + id + '/' + status,  
28 - });  
29 -  
30 -//删除脚本  
31 -export const deleteScriptManage = (ids: string[]) => {  
32 - return defHttp.delete({  
33 - url: ScriptManagerApi.SCRIPT_DELETE_URL,  
34 - data: {  
35 - ids: ids,  
36 - },  
37 - });  
38 -};  
39 -  
40 -// 创建或编辑脚本  
41 -export const createOrEditScriptManage = (data) => {  
42 - return defHttp.post<ScriptParam>({  
43 - url: ScriptManagerApi.SCRIPT_POST_URL,  
44 - data,  
45 - });  
46 -};  
47 -  
48 -// 查询脚本详情  
49 -export const getScriptManageDetail = (id: string) => {  
50 - return defHttp.get({  
51 - url: ScriptManagerApi.SCRIPT_GET_URL + `/${id}`,  
52 - });  
53 -};  
54 -  
55 -// 获取脚本选项列表  
56 -export const getScriptManageMeList = () => {  
57 - return defHttp.get<ScriptRecord[]>({  
58 - url: ScriptManagerApi.SCRIPT_MELIST_URL,  
59 - });  
60 -};  
61 -  
62 -// 测试脚本执行结果  
63 -export const testScriptManage = (data) => {  
64 - return defHttp.post<ScriptParam>({  
65 - url: ScriptManagerApi.SCRIPT_TEST_URL,  
66 - data,  
67 - });  
68 -}; 1 +import { defHttp } from '/@/utils/http/axios';
  2 +import { ScriptParam, ScriptQueryParam, ScriptRecord } from './model/scriptModel';
  3 +import { PaginationResult } from '/#/axios';
  4 +
  5 +enum ScriptManagerApi {
  6 + SCRIPT_POST_URL = '/js',
  7 + SCRIPT_GET_URL = '/js',
  8 + SCRIPT_DELETE_URL = '/js',
  9 + SCRIPT_MELIST_URL = '/js/me/list',
  10 + SCRIPT_TEST_URL = '/js/test',
  11 + SCRIPT_STATUS = '/js',
  12 +}
  13 +
  14 +export const ScriptPage = (params: ScriptQueryParam) => {
  15 + return defHttp.get<PaginationResult<ScriptRecord>>({
  16 + url: ScriptManagerApi.SCRIPT_GET_URL,
  17 + params,
  18 + });
  19 +};
  20 +
  21 +/**
  22 + * 改变转换函数状态
  23 + * @param params id status
  24 + */
  25 +export const scriptPagePutApi = (id, status) =>
  26 + defHttp.post({
  27 + url: ScriptManagerApi.SCRIPT_STATUS + '/' + id + '/' + status,
  28 + });
  29 +
  30 +//删除脚本
  31 +export const deleteScriptManage = (ids: string[]) => {
  32 + return defHttp.delete({
  33 + url: ScriptManagerApi.SCRIPT_DELETE_URL,
  34 + data: {
  35 + ids: ids,
  36 + },
  37 + });
  38 +};
  39 +
  40 +// 创建或编辑脚本
  41 +export const createOrEditScriptManage = (data) => {
  42 + return defHttp.post<ScriptParam>({
  43 + url: ScriptManagerApi.SCRIPT_POST_URL,
  44 + data,
  45 + });
  46 +};
  47 +
  48 +// 查询脚本详情
  49 +export const getScriptManageDetail = (id: string) => {
  50 + return defHttp.get({
  51 + url: ScriptManagerApi.SCRIPT_GET_URL + `/${id}`,
  52 + });
  53 +};
  54 +
  55 +// 获取脚本选项列表
  56 +export const getScriptManageMeList = (params) => {
  57 + return defHttp.get<ScriptRecord[]>({
  58 + url: ScriptManagerApi.SCRIPT_MELIST_URL,
  59 + params,
  60 + });
  61 +};
  62 +
  63 +// 测试脚本执行结果
  64 +export const testScriptManage = (data) => {
  65 + return defHttp.post<ScriptParam>({
  66 + url: ScriptManagerApi.SCRIPT_TEST_URL,
  67 + data,
  68 + });
  69 +};
@@ -160,6 +160,9 @@ @@ -160,6 +160,9 @@
160 skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value, 160 skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value,
161 content_css: 161 content_css:
162 publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css', 162 publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css',
  163 + content_style: `.mce-content-body {background: ${
  164 + skinName.value === 'oxide' ? '#ffffff' : '#222f3e'
  165 + };}`,
163 ...options, 166 ...options,
164 setup: (editor) => { 167 setup: (editor) => {
165 editorRef.value = editor; 168 editorRef.value = editor;
@@ -104,7 +104,13 @@ @@ -104,7 +104,13 @@
104 if (isWebSocketType.value === '2') { 104 if (isWebSocketType.value === '2') {
105 socketUrls.value = url; 105 socketUrls.value = url;
106 socketMessage.server = `${socketUrls.value}?token=${token}`; 106 socketMessage.server = `${socketUrls.value}?token=${token}`;
107 - websocketRequest(params); 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 + }
108 } else { 114 } else {
109 const resp = await otherHttpRequest(apiType, apiUrl?.split('{?')[0], headers, params, body); 115 const resp = await otherHttpRequest(apiType, apiUrl?.split('{?')[0], headers, params, body);
110 if (!resp) return; 116 if (!resp) return;
@@ -765,6 +765,21 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] = @@ -765,6 +765,21 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] =
765 minRows: 6, 765 minRows: 6,
766 }, 766 },
767 }, 767 },
  768 + dynamicRules: () => {
  769 + return [
  770 + {
  771 + required: false,
  772 + validator: (_, value) => {
  773 + const zg = /^[0-9a-zA-Z]*$/;
  774 + if (!zg.test(value)) {
  775 + return Promise.reject('输入的内容只能是字母和数字的组合');
  776 + } else {
  777 + return Promise.resolve();
  778 + }
  779 + },
  780 + },
  781 + ];
  782 + },
768 }, 783 },
769 { 784 {
770 field: 'commandValue', 785 field: 'commandValue',
@@ -53,6 +53,7 @@ @@ -53,6 +53,7 @@
53 baseColProps: { span: 8 }, 53 baseColProps: { span: 8 },
54 schemas: searchFormSchema, 54 schemas: searchFormSchema,
55 submitFunc: async () => { 55 submitFunc: async () => {
  56 + pagination.current = 1;
56 getDataSource({ pageSize: pagination.pageSize, page: 1 }); 57 getDataSource({ pageSize: pagination.pageSize, page: 1 });
57 }, 58 },
58 }); 59 });
1 -import { FormSchema } from '/@/components/Form';  
2 -  
3 -export const tcpSchemas: FormSchema[] = [  
4 - {  
5 - field: 'script',  
6 - label: '转换脚本',  
7 - component: 'Input',  
8 - slot: 'script',  
9 - colProps: { span: 24 },  
10 - },  
11 -];  
12 -  
13 -// 新增编辑配置  
14 -export const formSchema: FormSchema[] = [  
15 - {  
16 - field: 'name',  
17 - label: '输入参数',  
18 - colProps: { span: 24 },  
19 - required: true,  
20 - component: 'Input',  
21 - componentProps: {  
22 - maxLength: 255,  
23 - placeholder: '请输入输入参数',  
24 - },  
25 - },  
26 - {  
27 - field: 'scriptContent',  
28 - label: '脚本内容',  
29 - required: true,  
30 - component: 'Input',  
31 - slot: 'scriptContent',  
32 - colProps: { span: 24 },  
33 - },  
34 - {  
35 - field: 'remark',  
36 - label: '输出参数',  
37 - colProps: { span: 24 },  
38 - component: 'InputTextArea',  
39 - componentProps: {  
40 - rows: 6,  
41 - maxLength: 255,  
42 - placeholder: '请输入输出参数',  
43 - },  
44 - },  
45 -]; 1 +import { FormSchema } from '/@/components/Form';
  2 +
  3 +export const tcpSchemas: FormSchema[] = [
  4 + {
  5 + field: 'upScriptId',
  6 + label: '上行脚本',
  7 + component: 'Input',
  8 + slot: 'upScriptId',
  9 + colProps: { span: 24 },
  10 + },
  11 + {
  12 + field: 'authScriptId',
  13 + label: '鉴权脚本',
  14 + component: 'Input',
  15 + slot: 'authScriptId',
  16 + colProps: { span: 24 },
  17 + },
  18 +];
  19 +
  20 +// 新增编辑配置
  21 +export const formSchema: FormSchema[] = [
  22 + {
  23 + field: 'name',
  24 + label: '输入参数',
  25 + colProps: { span: 24 },
  26 + required: true,
  27 + component: 'Input',
  28 + componentProps: {
  29 + maxLength: 255,
  30 + placeholder: '请输入输入参数',
  31 + },
  32 + },
  33 + {
  34 + field: 'scriptContent',
  35 + label: '脚本内容',
  36 + required: true,
  37 + component: 'Input',
  38 + slot: 'scriptContent',
  39 + colProps: { span: 24 },
  40 + },
  41 + {
  42 + field: 'remark',
  43 + label: '输出参数',
  44 + colProps: { span: 24 },
  45 + component: 'InputTextArea',
  46 + componentProps: {
  47 + rows: 6,
  48 + maxLength: 255,
  49 + placeholder: '请输入输出参数',
  50 + },
  51 + },
  52 +];
1 -<template>  
2 - <div>  
3 - <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register">  
4 - <template #script>  
5 - <div style="display: flex; align-items: center">  
6 - <div>  
7 - <Select  
8 - placeholder="请选择转换脚本"  
9 - v-model:value="selectScript.script"  
10 - style="width: 305px"  
11 - show-search  
12 - :options="selectOptions"  
13 - :filter-option="handleSearch"  
14 - allowClear  
15 - />  
16 - </div>  
17 - <div>  
18 - <span  
19 - @click="handleCreateOrEdit('add')"  
20 - class="ml-2"  
21 - style="color: #409eff; cursor: pointer"  
22 - size="small"  
23 - >新建转换脚本</span  
24 - >  
25 - </div>  
26 - </div>  
27 - <a-button @click="handleCreateOrEdit('test')" class="mt-4" type="primary"  
28 - >测试脚本</a-button  
29 - >  
30 - </template>  
31 - </BasicForm>  
32 - <ConverScriptModal @register="registerModal" @success="handleSuccess" />  
33 - </div>  
34 -</template>  
35 -<script lang="ts" setup>  
36 - import { ref, Ref, reactive, onMounted } from 'vue';  
37 - import { BasicForm, useForm } from '/@/components/Form';  
38 - import { tcpSchemas } from './config';  
39 - import { SelectTypes } from 'ant-design-vue/es/select';  
40 - import { Select } from 'ant-design-vue';  
41 - import { useModal } from '/@/components/Modal';  
42 - import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager';  
43 - import ConverScriptModal from '/@/views/scriptmanage/converscript/ConverScriptModal.vue';  
44 -  
45 - const selectScript = reactive<Record<'script', Nullable<string>>>({  
46 - script: null,  
47 - });  
48 - const selectOptions: Ref<SelectTypes['options']> = ref([]);  
49 - onMounted(async () => {  
50 - const res = await getScriptManageMeList();  
51 - selectOptions.value = res.map((m) => {  
52 - return {  
53 - label: m.name,  
54 - value: m.id,  
55 - };  
56 - });  
57 - });  
58 - const handleSuccess = async (opt) => {  
59 - if (opt.text !== 'test') {  
60 - selectScript.script = opt?.res?.id;  
61 - const res = await getScriptManageMeList();  
62 - selectOptions.value = res.map((m) => {  
63 - return {  
64 - label: m.name,  
65 - value: m.id,  
66 - };  
67 - });  
68 - }  
69 - };  
70 -  
71 - const [register] = useForm({  
72 - labelWidth: 180,  
73 - schemas: tcpSchemas,  
74 - actionColOptions: {  
75 - span: 14,  
76 - },  
77 - });  
78 - const [registerModal, { openModal }] = useModal();  
79 -  
80 - // 新增或编辑  
81 - const handleCreateOrEdit = (c) => {  
82 - if (c === 'add') {  
83 - openModal(true, {  
84 - isUpdate: true,  
85 - isView: false,  
86 - isTest: false,  
87 - isText: 'confirm',  
88 - isTitle: 'add',  
89 - });  
90 - } else {  
91 - console.log(selectScript);  
92 - openModal(true, {  
93 - isUpdate: false,  
94 - isTest: true,  
95 - record: selectScript.script,  
96 - isText: 'test',  
97 - isTitle: 'test',  
98 - });  
99 - }  
100 - };  
101 -  
102 - const getFormData = () => {  
103 - const value = {  
104 - ...{  
105 - scriptId: selectScript.script,  
106 - dataFormat: 'HEX',  
107 - type: 'TCP',  
108 - },  
109 - };  
110 - return value;  
111 - };  
112 - const resetFormData = () => {  
113 - selectScript.script = null;  
114 - };  
115 - const setFormData = (v) => {  
116 - selectScript.script = v?.scriptId;  
117 - };  
118 -  
119 - const handleSearch = (inputValue: string, option: Record<'label' | 'value', string>) => {  
120 - return option.label.includes(inputValue);  
121 - };  
122 -  
123 - defineExpose({  
124 - getFormData,  
125 - resetFormData,  
126 - setFormData,  
127 - });  
128 -</script>  
129 -<style lang="less" scoped></style> 1 +<template>
  2 + <div>
  3 + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register">
  4 + <template #upScriptId="{ model, field }">
  5 + <div style="display: flex; align-items: center">
  6 + <div>
  7 + <Select
  8 + @change="handleUpChange"
  9 + placeholder="请选择"
  10 + v-model:value="model[field]"
  11 + style="width: 305px"
  12 + show-search
  13 + :options="selectUpOptions"
  14 + :filter-option="handleSearch"
  15 + allowClear
  16 + />
  17 + </div>
  18 + <div>
  19 + <span
  20 + @click="handleCreateOrEdit('add')"
  21 + class="ml-2"
  22 + style="color: #409eff; cursor: pointer"
  23 + size="small"
  24 + >新建转换脚本</span
  25 + >
  26 + </div>
  27 + </div>
  28 + <a-button @click="handleCreateOrEdit('test')" class="mt-4" type="primary"
  29 + >测试脚本</a-button
  30 + >
  31 + </template>
  32 + <template #authScriptId="{ model, field }">
  33 + <div style="display: flex; align-items: center">
  34 + <div>
  35 + <Select
  36 + @change="handleAuthChange"
  37 + placeholder="请选择"
  38 + v-model:value="model[field]"
  39 + style="width: 305px"
  40 + show-search
  41 + :options="selectAuthOptions"
  42 + :filter-option="handleAuthSearch"
  43 + allowClear
  44 + />
  45 + </div>
  46 + <div>
  47 + <span
  48 + @click="handleCreateOrEditAuth('add')"
  49 + class="ml-2"
  50 + style="color: #409eff; cursor: pointer"
  51 + size="small"
  52 + >新建转换脚本</span
  53 + >
  54 + </div>
  55 + </div>
  56 + <a-button @click="handleCreateOrEditAuth('test')" class="mt-4" type="primary"
  57 + >测试脚本</a-button
  58 + >
  59 + </template>
  60 + </BasicForm>
  61 + <ConverScriptModal @register="registerModal" @success="handleSuccess" />
  62 + <ConverScriptModal @register="registerAuthModal" @success="handleAuthSuccess" />
  63 + </div>
  64 +</template>
  65 +<script lang="ts" setup name="index">
  66 + import { ref, Ref, onMounted } from 'vue';
  67 + import { BasicForm, useForm } from '/@/components/Form';
  68 + import { tcpSchemas } from './config';
  69 + import { SelectTypes } from 'ant-design-vue/es/select';
  70 + import { Select } from 'ant-design-vue';
  71 + import { useModal } from '/@/components/Modal';
  72 + import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager';
  73 + import ConverScriptModal from '/@/views/scriptmanage/converscript/ConverScriptModal.vue';
  74 + import { useMessage } from '/@/hooks/web/useMessage';
  75 +
  76 + const selectUpOptions: Ref<SelectTypes['options']> = ref([]);
  77 +
  78 + const selectAuthOptions: Ref<SelectTypes['options']> = ref([]);
  79 +
  80 + const { createMessage } = useMessage();
  81 +
  82 + const upScriptIdStr = ref('');
  83 +
  84 + const authScriptIdStr = ref('');
  85 +
  86 + onMounted(async () => {
  87 + selectUpOptions.value = await getAllScriptType('TRANSPORT_TCP_UP');
  88 + selectAuthOptions.value = await getAllScriptType('TRANSPORT_TCP_AUTH');
  89 + });
  90 +
  91 + const getAllScriptType = async (type) => {
  92 + const rest = await getScriptManageMeList({ scriptType: type });
  93 + return rest.map((m) => ({ label: m.name, value: m.id }));
  94 + };
  95 +
  96 + const handleSuccess = async ({ res, text }) => {
  97 + if (text !== 'test') {
  98 + const rest = await getAllScriptType('TRANSPORT_TCP_UP');
  99 + selectUpOptions.value = rest;
  100 + setFieldsValue({ upScriptId: res?.id });
  101 + upScriptIdStr.value = res?.id;
  102 + }
  103 + };
  104 +
  105 + const handleAuthSuccess = async ({ res, text }) => {
  106 + if (text !== 'test') {
  107 + const rest = await getAllScriptType('TRANSPORT_TCP_AUTH');
  108 + selectAuthOptions.value = rest;
  109 + setFieldsValue({ authScriptId: res?.id });
  110 + authScriptIdStr.value = res?.id;
  111 + }
  112 + };
  113 +
  114 + const [register, { getFieldsValue, resetFields, setFieldsValue }] = useForm({
  115 + labelWidth: 180,
  116 + schemas: tcpSchemas,
  117 + actionColOptions: {
  118 + span: 14,
  119 + },
  120 + });
  121 +
  122 + const handleUpChange = (v) => (upScriptIdStr.value = v);
  123 +
  124 + const handleAuthChange = (v) => (authScriptIdStr.value = v);
  125 +
  126 + const [registerModal, { openModal }] = useModal();
  127 +
  128 + const [registerAuthModal, { openModal: openAuthModel }] = useModal();
  129 +
  130 + //TODO: 待优化
  131 +
  132 + const handleCreateOrEditAuth = (c) => {
  133 + if (c === 'add') {
  134 + openAuthModel(true, {
  135 + isUpdate: true,
  136 + isView: false,
  137 + isTest: false,
  138 + isText: 'confirm',
  139 + isTitle: 'add',
  140 + });
  141 + } else {
  142 + if (!authScriptIdStr.value) return createMessage.error('请先选择对应脚本');
  143 + openAuthModel(true, {
  144 + isUpdate: false,
  145 + isTest: true,
  146 + record: authScriptIdStr.value,
  147 + isText: 'test',
  148 + isTitle: 'test',
  149 + });
  150 + }
  151 + };
  152 +
  153 + const handleCreateOrEdit = (c) => {
  154 + if (c === 'add') {
  155 + openModal(true, {
  156 + isUpdate: true,
  157 + isView: false,
  158 + isTest: false,
  159 + isText: 'confirm',
  160 + isTitle: 'add',
  161 + });
  162 + } else {
  163 + if (!upScriptIdStr.value) return createMessage.error('请先选择对应脚本');
  164 + openModal(true, {
  165 + isUpdate: false,
  166 + isTest: true,
  167 + record: upScriptIdStr.value,
  168 + isText: 'test',
  169 + isTitle: 'test',
  170 + });
  171 + }
  172 + };
  173 +
  174 + const getFormData = () => {
  175 + const values = getFieldsValue();
  176 + return {
  177 + ...values,
  178 + type: 'TCP',
  179 + };
  180 + };
  181 +
  182 + const resetFormData = () => {
  183 + resetFields();
  184 + };
  185 +
  186 + const setFormData = (v) => {
  187 + setFieldsValue(v);
  188 + upScriptIdStr.value = v?.upScriptId;
  189 + authScriptIdStr.value = v?.authScriptId;
  190 + };
  191 +
  192 + const handleSearch = (inputValue: string, option: Record<'label' | 'value', string>) => {
  193 + return option.label.includes(inputValue);
  194 + };
  195 +
  196 + const handleAuthSearch = (inputValue: string, option: Record<'label' | 'value', string>) => {
  197 + return option.label.includes(inputValue);
  198 + };
  199 +
  200 + defineExpose({
  201 + getFormData,
  202 + resetFormData,
  203 + setFormData,
  204 + });
  205 +</script>
  206 +<style lang="less" scoped></style>
@@ -218,7 +218,7 @@ @@ -218,7 +218,7 @@
218 editResData = await reportEditDetailPage(data.record.id); 218 editResData = await reportEditDetailPage(data.record.id);
219 //回显基础数据 219 //回显基础数据
220 editId.value = editResData.data.id; 220 editId.value = editResData.data.id;
221 - const spanDisance = editResData.data.executeContent.split(' '); 221 + const spanDisance = editResData.data.executeContent?.split(' ');
222 await setFieldsValue(editResData.data); 222 await setFieldsValue(editResData.data);
223 //回显嵌套数据 223 //回显嵌套数据
224 await setFieldsValue({ 224 await setFieldsValue({
@@ -28,15 +28,6 @@ @@ -28,15 +28,6 @@
28 /> 28 />
29 </a-form-item> 29 </a-form-item>
30 <a-form-item 30 <a-form-item
31 - label="上报数据类型"  
32 - name="dataType"  
33 - :rules="[{ required: false, message: '请选择上报数据类型' }]"  
34 - >  
35 - <a-space direction="vertical">  
36 - <a-radio-group v-model:value="scriptForm.dataType" :options="typeOptions" />  
37 - </a-space>  
38 - </a-form-item>  
39 - <a-form-item  
40 label="脚本类型" 31 label="脚本类型"
41 name="scriptType" 32 name="scriptType"
42 :rules="[{ required: true, message: '请选择脚本类型' }]" 33 :rules="[{ required: true, message: '请选择脚本类型' }]"
@@ -66,7 +57,6 @@ @@ -66,7 +57,6 @@
66 <QuestionCircleOutlined style="font-size: 1rem" /> 57 <QuestionCircleOutlined style="font-size: 1rem" />
67 </Tooltip> 58 </Tooltip>
68 </template> 59 </template>
69 - {{ getAceClass }}  
70 <div ref="aceRef" class="overflow-hidden"></div> 60 <div ref="aceRef" class="overflow-hidden"></div>
71 </Card> 61 </Card>
72 <Button @click="handleCopy" class="mt-4"> 62 <Button @click="handleCopy" class="mt-4">
@@ -88,7 +78,8 @@ @@ -88,7 +78,8 @@
88 :maxlength="255" 78 :maxlength="255"
89 /> 79 />
90 <a-textarea 80 <a-textarea
91 - :rows="3" 81 + disabled
  82 + :rows="5"
92 v-else 83 v-else
93 v-model:value="scriptForm.output" 84 v-model:value="scriptForm.output"
94 placeholder="输出参数为服务端返回的内容" 85 placeholder="输出参数为服务端返回的内容"
@@ -126,18 +117,16 @@ @@ -126,18 +117,16 @@
126 script: '', 117 script: '',
127 params: '', 118 params: '',
128 output: '', 119 output: '',
129 - dataType: 'HEX',  
130 scriptType: 'TRANSPORT_TCP_UP', 120 scriptType: 'TRANSPORT_TCP_UP',
131 saveOriginalData: 'true', 121 saveOriginalData: 'true',
132 }); 122 });
133 123
134 const reportTypeOptions = reactive({ 124 const reportTypeOptions = reactive({
135 - typeOptions: [],  
136 originalOptions: [], 125 originalOptions: [],
137 scriptTypeOptions: [], 126 scriptTypeOptions: [],
138 }); 127 });
139 128
140 - const { originalOptions, typeOptions, scriptTypeOptions } = toRefs(reportTypeOptions); 129 + const { originalOptions, scriptTypeOptions } = toRefs(reportTypeOptions);
141 130
142 const { createMessage } = useMessage(); 131 const { createMessage } = useMessage();
143 132
@@ -151,8 +140,7 @@ @@ -151,8 +140,7 @@
151 140
152 const getAceClass = computed((): string => userStore.getDarkMode); 141 const getAceClass = computed((): string => userStore.getDarkMode);
153 142
154 - const setDefaultRadio = (p1, p2, p3) => {  
155 - scriptForm.dataType = p1; 143 + const setDefaultRadio = (p2, p3) => {
156 scriptForm.saveOriginalData = p2; 144 scriptForm.saveOriginalData = p2;
157 scriptForm.scriptType = p3; 145 scriptForm.scriptType = p3;
158 }; 146 };
@@ -167,7 +155,6 @@ @@ -167,7 +155,6 @@
167 }; 155 };
168 156
169 onMounted(async () => { 157 onMounted(async () => {
170 - reportTypeOptions.typeOptions = (await getDictValue('report_data_type')) as never as any;  
171 reportTypeOptions.originalOptions = (await getDictValue('original_data')) as never as any; 158 reportTypeOptions.originalOptions = (await getDictValue('original_data')) as never as any;
172 reportTypeOptions.scriptTypeOptions = (await getDictValue('script_type')) as never as any; 159 reportTypeOptions.scriptTypeOptions = (await getDictValue('script_type')) as never as any;
173 }); 160 });
@@ -199,12 +186,6 @@ @@ -199,12 +186,6 @@
199 }; 186 };
200 187
201 const switchScriptTypeGetContent = (type) => { 188 const switchScriptTypeGetContent = (type) => {
202 - if (type === 'TRANSPORT_TCP_DOWN')  
203 - Reflect.set(  
204 - defaultScriptTypeContent,  
205 - 'TRANSPORT_TCP_DOWN',  
206 - `out.datas = "${scriptForm.params}";out.deviceName = "sensor";`  
207 - );  
208 aceEditor.value.setValue(defaultScriptTypeContent[type]); 189 aceEditor.value.setValue(defaultScriptTypeContent[type]);
209 }; 190 };
210 191
@@ -271,7 +252,6 @@ @@ -271,7 +252,6 @@
271 nextTick(() => { 252 nextTick(() => {
272 setTimeout(() => { 253 setTimeout(() => {
273 scriptForm.saveOriginalData = v.saveOriginalData === false ? 'false' : 'true'; 254 scriptForm.saveOriginalData = v.saveOriginalData === false ? 'false' : 'true';
274 - scriptForm.dataType = v.dataType;  
275 }, 10); 255 }, 10);
276 }); 256 });
277 aceEditor.value.setValue(v.convertJs); 257 aceEditor.value.setValue(v.convertJs);
@@ -294,7 +274,10 @@ @@ -294,7 +274,10 @@
294 scriptForm.output = v; 274 scriptForm.output = v;
295 }; 275 };
296 276
297 - const handleFormat = () => beautify(aceEditor.value.session); 277 + const handleFormat = () => {
  278 + beautify(aceEditor.value.session);
  279 + aceEditor.value.getSession().setUseWrapMode(true);
  280 + };
298 281
299 defineExpose({ 282 defineExpose({
300 initEditor, 283 initEditor,
@@ -57,7 +57,7 @@ @@ -57,7 +57,7 @@
57 : '测试转换脚本'; 57 : '测试转换脚本';
58 const okText = isText.value == 'test' ? '测试' : '确定'; 58 const okText = isText.value == 'test' ? '测试' : '确定';
59 if (unref(isTitle) == 'add') { 59 if (unref(isTitle) == 'add') {
60 - converScriptRef.value?.setDefaultRadio('HEX', 'true', 'TRANSPORT_TCP_UP'); 60 + converScriptRef.value?.setDefaultRadio('true', 'TRANSPORT_TCP_UP');
61 } 61 }
62 if (unref(isTitle) == 'edit') { 62 if (unref(isTitle) == 'edit') {
63 converScriptRef.value?.setFormData(data.record); 63 converScriptRef.value?.setFormData(data.record);
@@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
67 const res = await getScriptManageDetail(data.record); 67 const res = await getScriptManageDetail(data.record);
68 converScriptRef.value?.setFormData(res); 68 converScriptRef.value?.setFormData(res);
69 } else { 69 } else {
70 - converScriptRef.value?.setDefaultRadio('HEX', 'true', 'TRANSPORT_TCP_UP'); 70 + converScriptRef.value?.setDefaultRadio('true', 'TRANSPORT_TCP_UP');
71 } 71 }
72 } 72 }
73 setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText }); 73 setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText });
@@ -79,9 +79,9 @@ export const defaultTitle = h('div', { style: 'background:#404040' }, [ @@ -79,9 +79,9 @@ export const defaultTitle = h('div', { style: 'background:#404040' }, [
79 ]), 79 ]),
80 ]); 80 ]);
81 81
  82 +// TRANSPORT_TCP_DOWN: 'out.datas = "";out.deviceName = "sensor";',
82 export const defaultScriptTypeContent = { 83 export const defaultScriptTypeContent = {
83 TRANSPORT_TCP_UP: 84 TRANSPORT_TCP_UP:
84 'var attrData = {};var teleData = {};teleData.source= params;out.datas = teleData;out.telemetry =true;out.ackMsg = params;out.deviceName = "sensor";out.ts = Date.now();', 85 'var attrData = {};var teleData = {};teleData.source= params;out.datas = teleData;out.telemetry =true;out.ackMsg = params;out.deviceName = "sensor";out.ts = Date.now();',
85 - TRANSPORT_TCP_DOWN: 'out.datas = "";out.deviceName = "sensor";',  
86 TRANSPORT_TCP_AUTH: 'out.password = params;out.success = params;', 86 TRANSPORT_TCP_AUTH: 'out.password = params;out.success = params;',
87 }; 87 };
1 -<template>  
2 - <div>  
3 - <BasicTable :clickToRowSelect="false" @register="registerTable" :searchInfo="searchInfo">  
4 - <template #toolbar>  
5 - <Authority value="api:yt:js:post">  
6 - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增转换脚本 </a-button>  
7 - </Authority>  
8 - <Authority value="api:yt:js:delete">  
9 - <Popconfirm  
10 - title="您确定要批量删除数据"  
11 - ok-text="确定"  
12 - cancel-text="取消"  
13 - @confirm="handleDeleteOrBatchDelete(null)"  
14 - >  
15 - <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>  
16 - </Popconfirm>  
17 - </Authority>  
18 - </template>  
19 - <template #convertJs="{ record }">  
20 - <a-button type="text" @click="handleScriptView(record)">  
21 - <span style="color: #377dff">查看脚本</span>  
22 - </a-button>  
23 - </template>  
24 - <template #action="{ record }">  
25 - <TableAction  
26 - :actions="[  
27 - {  
28 - label: '测试',  
29 - icon: 'ant-design:font-size-outlined',  
30 - auth: 'api:yt:js:test',  
31 - onClick: handleBindTest.bind(null, record),  
32 - },  
33 - {  
34 - label: '编辑',  
35 - icon: 'clarity:note-edit-line',  
36 - auth: 'api:yt:js:update',  
37 - onClick: handleCreateOrEdit.bind(null, record),  
38 - ifShow: record.status == 0,  
39 - },  
40 - {  
41 - label: '删除',  
42 - icon: 'ant-design:delete-outlined',  
43 - auth: 'api:yt:js:delete',  
44 - color: 'error',  
45 - ifShow: record.status == 0,  
46 - popConfirm: {  
47 - title: '是否确认删除',  
48 - confirm: handleDeleteOrBatchDelete.bind(null, record),  
49 - },  
50 - },  
51 - ]"  
52 - />  
53 - </template>  
54 - <template #status="{ record }">  
55 - <Authority value="api:yt:js:update:status">  
56 - <Switch  
57 - :checked="record.status === 1"  
58 - :loading="record.pendingStatus"  
59 - checkedChildren="启用"  
60 - unCheckedChildren="禁用"  
61 - @change="(checked:boolean)=>statusChange(checked,record)"  
62 - />  
63 - </Authority>  
64 - </template>  
65 - </BasicTable>  
66 - <ConverScriptModal @register="registerModal" @success="handleSuccess" />  
67 - </div>  
68 -</template>  
69 -  
70 -<script lang="ts" setup>  
71 - import { reactive, nextTick } from 'vue';  
72 - import { BasicTable, useTable, TableAction } from '/@/components/Table';  
73 - import { searchFormSchema, columns } from './config.data';  
74 - import { Authority } from '/@/components/Authority';  
75 - import { useBatchDelete } from '/@/hooks/web/useBatchDelete';  
76 - import { Switch, Popconfirm } from 'ant-design-vue';  
77 - import { useModal } from '/@/components/Modal';  
78 - import ConverScriptModal from './ConverScriptModal.vue';  
79 - import {  
80 - ScriptPage,  
81 - deleteScriptManage,  
82 - scriptPagePutApi,  
83 - } from '/@/api/scriptmanage/scriptManager';  
84 - import { useMessage } from '/@/hooks/web/useMessage';  
85 -  
86 - const searchInfo = reactive<Recordable>({});  
87 - const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({  
88 - title: '转换脚本列表',  
89 - api: ScriptPage,  
90 - columns,  
91 - showIndexColumn: false,  
92 - clickToRowSelect: false,  
93 - formConfig: {  
94 - labelWidth: 120,  
95 - schemas: searchFormSchema,  
96 - fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']],  
97 - },  
98 - useSearchForm: true,  
99 - showTableSetting: true,  
100 - bordered: true,  
101 - rowKey: 'id',  
102 - actionColumn: {  
103 - width: 200,  
104 - title: '操作',  
105 - dataIndex: 'action',  
106 - slots: { customRender: 'action' },  
107 - fixed: 'right',  
108 - },  
109 - });  
110 -  
111 - const handleSuccess = () => {  
112 - reload();  
113 - };  
114 -  
115 - const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =  
116 - useBatchDelete(deleteScriptManage, handleSuccess, setProps);  
117 - selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => {  
118 - // Demo:status为1的选择框禁用  
119 - if (record.status === 1) {  
120 - return { disabled: true };  
121 - } else {  
122 - return { disabled: false };  
123 - }  
124 - };  
125 -  
126 - nextTick(() => {  
127 - setProps(selectionOptions);  
128 - });  
129 -  
130 - const [registerModal, { openModal }] = useModal();  
131 -  
132 - // 新增或编辑  
133 - const handleCreateOrEdit = (record: Recordable | null) => {  
134 - if (record) {  
135 - openModal(true, {  
136 - isUpdate: false,  
137 - record,  
138 - isView: false,  
139 - isTest: false,  
140 - isText: 'confirm',  
141 - isTitle: 'edit',  
142 - });  
143 - } else {  
144 - openModal(true, {  
145 - isUpdate: true,  
146 - isView: false,  
147 - isTest: false,  
148 - isText: 'confirm',  
149 - isTitle: 'add',  
150 - });  
151 - }  
152 - };  
153 - const handleBindTest = (record: Recordable | null) => {  
154 - if (record) {  
155 - openModal(true, {  
156 - isUpdate: false,  
157 - record: record.id,  
158 - isTest: true,  
159 - isText: 'test',  
160 - isTitle: 'test',  
161 - });  
162 - }  
163 - };  
164 - const handleScriptView = (record: Recordable | null) => {  
165 - if (record) {  
166 - openModal(true, {  
167 - isUpdate: true,  
168 - record,  
169 - isView: true,  
170 - });  
171 - }  
172 - };  
173 - const statusChange = async (checked, record) => {  
174 - setProps({  
175 - loading: true,  
176 - });  
177 - setSelectedRowKeys([]);  
178 - resetSelectedRowKeys();  
179 - const newStatus = checked ? 1 : 0;  
180 - const { createMessage } = useMessage();  
181 - try {  
182 - await scriptPagePutApi(record.id, newStatus);  
183 - if (newStatus) {  
184 - createMessage.success(`启用成功`);  
185 - } else {  
186 - createMessage.success('禁用成功');  
187 - }  
188 - } finally {  
189 - setProps({  
190 - loading: false,  
191 - });  
192 - reload();  
193 - }  
194 - };  
195 -</script> 1 +<template>
  2 + <div>
  3 + <BasicTable :clickToRowSelect="false" @register="registerTable" :searchInfo="searchInfo">
  4 + <template #toolbar>
  5 + <Authority value="api:yt:js:post">
  6 + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增转换脚本 </a-button>
  7 + </Authority>
  8 + <Authority value="api:yt:js:delete">
  9 + <Popconfirm
  10 + title="您确定要批量删除数据"
  11 + ok-text="确定"
  12 + cancel-text="取消"
  13 + @confirm="handleDeleteOrBatchDelete(null)"
  14 + >
  15 + <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
  16 + </Popconfirm>
  17 + </Authority>
  18 + </template>
  19 + <template #convertJs="{ record }">
  20 + <a-button type="text" @click="handleScriptView(record)">
  21 + <span style="color: #377dff">查看脚本</span>
  22 + </a-button>
  23 + </template>
  24 + <template #action="{ record }">
  25 + <TableAction
  26 + :actions="[
  27 + {
  28 + label: '测试',
  29 + icon: 'ant-design:font-size-outlined',
  30 + auth: 'api:yt:js:test',
  31 + onClick: handleBindTest.bind(null, record),
  32 + },
  33 + {
  34 + label: '编辑',
  35 + icon: 'clarity:note-edit-line',
  36 + auth: 'api:yt:js:update',
  37 + onClick: handleCreateOrEdit.bind(null, record),
  38 + ifShow: record.status == 0,
  39 + },
  40 + {
  41 + label: '删除',
  42 + icon: 'ant-design:delete-outlined',
  43 + auth: 'api:yt:js:delete',
  44 + color: 'error',
  45 + ifShow: record.status == 0,
  46 + popConfirm: {
  47 + title: '是否确认删除',
  48 + confirm: handleDeleteOrBatchDelete.bind(null, record),
  49 + },
  50 + },
  51 + ]"
  52 + />
  53 + </template>
  54 + <template #status="{ record }">
  55 + <Authority value="api:yt:js:update:status">
  56 + <Switch
  57 + :checked="record.status === 1"
  58 + :loading="record.pendingStatus"
  59 + checkedChildren="启用"
  60 + unCheckedChildren="禁用"
  61 + @change="(checked:boolean)=>statusChange(checked,record)"
  62 + />
  63 + </Authority>
  64 + </template>
  65 + </BasicTable>
  66 + <ConverScriptModal @register="registerModal" @success="handleSuccess" />
  67 + </div>
  68 +</template>
  69 +
  70 +<script lang="ts" setup>
  71 + import { reactive, nextTick } from 'vue';
  72 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  73 + import { searchFormSchema, columns } from './config.data';
  74 + import { Authority } from '/@/components/Authority';
  75 + import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
  76 + import { Switch, Popconfirm } from 'ant-design-vue';
  77 + import { useModal } from '/@/components/Modal';
  78 + import ConverScriptModal from './ConverScriptModal.vue';
  79 + import {
  80 + ScriptPage,
  81 + deleteScriptManage,
  82 + scriptPagePutApi,
  83 + } from '/@/api/scriptmanage/scriptManager';
  84 + import { useMessage } from '/@/hooks/web/useMessage';
  85 +
  86 + const searchInfo = reactive<Recordable>({});
  87 + const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({
  88 + title: '转换脚本列表',
  89 + api: ScriptPage,
  90 + columns,
  91 + showIndexColumn: false,
  92 + clickToRowSelect: false,
  93 + formConfig: {
  94 + labelWidth: 120,
  95 + schemas: searchFormSchema,
  96 + fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']],
  97 + },
  98 + useSearchForm: true,
  99 + showTableSetting: true,
  100 + bordered: true,
  101 + rowKey: 'id',
  102 + actionColumn: {
  103 + width: 200,
  104 + title: '操作',
  105 + dataIndex: 'action',
  106 + slots: { customRender: 'action' },
  107 + fixed: 'right',
  108 + },
  109 + });
  110 +
  111 + const handleSuccess = () => {
  112 + reload();
  113 + };
  114 +
  115 + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
  116 + useBatchDelete(deleteScriptManage, handleSuccess, setProps);
  117 + selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => {
  118 + // Demo:status为1的选择框禁用
  119 + if (record.status === 1) {
  120 + return { disabled: true };
  121 + } else {
  122 + return { disabled: false };
  123 + }
  124 + };
  125 +
  126 + nextTick(() => {
  127 + setProps(selectionOptions);
  128 + });
  129 +
  130 + const [registerModal, { openModal }] = useModal();
  131 +
  132 + // 新增或编辑
  133 + const handleCreateOrEdit = (record: Recordable | null) => {
  134 + if (record) {
  135 + openModal(true, {
  136 + isUpdate: false,
  137 + record,
  138 + isAuth: '',
  139 + isView: false,
  140 + isTest: false,
  141 + isText: 'confirm',
  142 + isTitle: 'edit',
  143 + });
  144 + } else {
  145 + openModal(true, {
  146 + isAuth: '',
  147 + isUpdate: true,
  148 + isView: false,
  149 + isTest: false,
  150 + isText: 'confirm',
  151 + isTitle: 'add',
  152 + });
  153 + }
  154 + };
  155 + const handleBindTest = (record: Recordable | null) => {
  156 + if (record) {
  157 + openModal(true, {
  158 + isAuth: '',
  159 + isUpdate: false,
  160 + record: record.id,
  161 + isTest: true,
  162 + isText: 'test',
  163 + isTitle: 'test',
  164 + });
  165 + }
  166 + };
  167 + const handleScriptView = (record: Recordable | null) => {
  168 + if (record) {
  169 + openModal(true, {
  170 + isUpdate: true,
  171 + record,
  172 + isView: true,
  173 + });
  174 + }
  175 + };
  176 + const statusChange = async (checked, record) => {
  177 + setProps({
  178 + loading: true,
  179 + });
  180 + setSelectedRowKeys([]);
  181 + resetSelectedRowKeys();
  182 + const newStatus = checked ? 1 : 0;
  183 + const { createMessage } = useMessage();
  184 + try {
  185 + await scriptPagePutApi(record.id, newStatus);
  186 + if (newStatus) {
  187 + createMessage.success(`启用成功`);
  188 + } else {
  189 + createMessage.success('禁用成功');
  190 + }
  191 + } finally {
  192 + setProps({
  193 + loading: false,
  194 + });
  195 + reload();
  196 + }
  197 + };
  198 +</script>