Commit 84038d851e233204d347cb939bfc0bc8875744aa

Authored by fengwotao
1 parent be9da75c

替换之前重构好的相关脚本管理代码

... ... @@ -2,18 +2,17 @@
2 2 import { Button, Tag } from 'ant-design-vue';
3 3 import { h, onMounted, ref, unref, Ref } from 'vue';
4 4 import { DeviceRecord } from '/@/api/device/model/deviceModel';
5   - // import { ScriptRecord } from '/@/api/scriptmanage/model/scriptModel';
6 5 import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager';
7 6 import { Description, useDescription } from '/@/components/Description';
8 7 import { useModal } from '/@/components/Modal';
9   - import CoverScriptModal from '/@/views/rule/script/TcpConversionScript/ConverScriptModal.vue';
  8 + import { ConverScriptModal } from '/@/views/rule/script/TcpConversionScript/components';
10 9 import { SelectTypes } from 'ant-design-vue/es/select';
  10 + import { BusinessConvertScriptTextEnum } from '/@/views/rule/script/TcpConversionScript/config';
11 11
12 12 const props = defineProps<{
13 13 record: DeviceRecord['profileData']['transportConfiguration'];
14 14 }>();
15 15
16   - // const scriptInfo = ref<ScriptRecord>({} as unknown as ScriptRecord);
17 16 const authScriptIdStr = ref('');
18 17
19 18 const upScriptIdStr = ref('');
... ... @@ -87,29 +86,25 @@
87 86 const [registerModal, { openModal }] = useModal();
88 87
89 88 const handleTestAuthScript = () => {
90   - openModal(true, {
91   - isUpdate: false,
92   - isTest: true,
93   - record: unref(authScriptIdStr),
94   - isText: 'test',
95   - isTitle: 'test',
96   - });
  89 + const modalParams = {
  90 + text: BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT,
  91 + record: { id: unref(authScriptIdStr) },
  92 + };
  93 + openModal(true, modalParams);
97 94 };
98 95
99 96 const handleTestUpScript = () => {
100   - openModal(true, {
101   - isUpdate: false,
102   - isTest: true,
103   - record: unref(upScriptIdStr),
104   - isText: 'test',
105   - isTitle: 'test',
106   - });
  97 + const modalParams = {
  98 + text: BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT,
  99 + record: { id: unref(upScriptIdStr) },
  100 + };
  101 + openModal(true, modalParams);
107 102 };
108 103 </script>
109 104
110 105 <template>
111 106 <section>
112 107 <Description @register="register" />
113   - <CoverScriptModal @register="registerModal" />
  108 + <ConverScriptModal @register="registerModal" />
114 109 </section>
115 110 </template>
... ...
  1 +<template>
  2 + <div class="flex">
  3 + <div>
  4 + <Select
  5 + v-bind="$attrs"
  6 + placeholder="请选择脚本"
  7 + @change="handleChange"
  8 + v-model:value="scriptId"
  9 + style="width: 305px"
  10 + show-search
  11 + :options="selectOptions"
  12 + :filter-option="handleSearch"
  13 + allowClear
  14 + />
  15 + </div>
  16 + <div>
  17 + <span
  18 + @click="handleBusinessModal(BusinessConvertScriptTextEnum.BUSINESS_ADD_TEXT)"
  19 + class="ml-2"
  20 + style="color: #409eff; cursor: pointer"
  21 + size="small"
  22 + >新建转换脚本</span
  23 + >
  24 + </div>
  25 + </div>
  26 + <a-button
  27 + @click="handleBusinessModal(BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT)"
  28 + class="mt-4"
  29 + type="primary"
  30 + >测试脚本</a-button
  31 + >
  32 + <ConverScriptModal @register="registerModal" @success="handleSuccess" />
  33 +</template>
  34 +<script lang="ts" setup name="ScriptSelectItem">
  35 + import { ref, Ref, onMounted } from 'vue';
  36 + import { SelectTypes } from 'ant-design-vue/es/select';
  37 + import { Select } from 'ant-design-vue';
  38 + import {
  39 + BusinessConvertScriptTextEnum,
  40 + ScriptTypeEnum,
  41 + } from '/@/views/rule/script/TcpConversionScript/config';
  42 + import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager';
  43 + import { useModal } from '/@/components/Modal';
  44 + import { useMessage } from '/@/hooks/web/useMessage';
  45 + import { ConverScriptModal } from '/@/views/rule/script/TcpConversionScript/components';
  46 +
  47 + const props = defineProps({
  48 + scriptType: {
  49 + type: String,
  50 + default: ScriptTypeEnum.TRANSPORT_TCP_AUTH,
  51 + },
  52 + modelValue: {
  53 + type: String,
  54 + default: '',
  55 + },
  56 + });
  57 +
  58 + const emits = defineEmits(['update:modelValue', 'change']);
  59 +
  60 + const { createMessage } = useMessage();
  61 +
  62 + const selectOptions: Ref<SelectTypes['options']> = ref([]);
  63 +
  64 + //如果是空字符串,placeholder没提示文字
  65 + const scriptId = ref<any>(null);
  66 +
  67 + onMounted(() => {
  68 + getSelectOptions();
  69 + });
  70 +
  71 + const getSelectOptions = async () => {
  72 + selectOptions.value = await getAllScriptType(props.scriptType);
  73 + };
  74 +
  75 + const getAllScriptType = async (type) => {
  76 + const rest = await getScriptManageMeList({ scriptType: type });
  77 + return rest.map((m) => ({ label: m.name, value: m.id }));
  78 + };
  79 +
  80 + const handleSearch = (inputValue: string, option: Record<'label' | 'value', string>) => {
  81 + return option.label.includes(inputValue);
  82 + };
  83 +
  84 + const [registerModal, { openModal }] = useModal();
  85 +
  86 + // 业务弹窗
  87 + const handleBusinessModal = (text) => {
  88 + const modalParams = {
  89 + text,
  90 + record:
  91 + text !== BusinessConvertScriptTextEnum.BUSINESS_ADD_TEXT ? { id: scriptId.value } : null,
  92 + scriptType: props.scriptType,
  93 + };
  94 + if (!scriptId.value) return createMessage.error('请先选择对应脚本');
  95 + openModal(true, modalParams);
  96 + };
  97 +
  98 + const handleSuccess = () => {
  99 + getSelectOptions();
  100 + };
  101 +
  102 + const handleChange = (value) => {
  103 + emits('update:modelValue', value);
  104 + emits('change', value);
  105 + };
  106 +
  107 + const setValue = (value) => {
  108 + scriptId.value = value;
  109 + };
  110 + defineExpose({
  111 + setValue,
  112 + });
  113 +</script>
... ...
  1 +import ScriptSelectItem from './ScriptSelectItem.vue';
  2 +
  3 +export { ScriptSelectItem };
... ...
1   -import { FormSchema } from '/@/components/Form';
2   -
3   -export const tcpSchemas: FormSchema[] = [
4   - {
5   - field: 'authScriptId',
6   - label: '鉴权脚本',
7   - component: 'Input',
8   - slot: 'authScriptId',
9   - colProps: { span: 24 },
10   - required: true,
11   - },
12   - {
13   - field: 'upScriptId',
14   - label: '上行脚本',
15   - component: 'Input',
16   - slot: 'upScriptId',
17   - colProps: { span: 24 },
18   - required: true,
19   - },
20   -];
21   -
22   -// 新增编辑配置
23   -export const formSchema: FormSchema[] = [
24   - {
25   - field: 'name',
26   - label: '输入参数',
27   - colProps: { span: 24 },
28   - required: true,
29   - component: 'Input',
30   - componentProps: {
31   - maxLength: 255,
32   - placeholder: '请输入输入参数',
33   - },
34   - },
35   - {
36   - field: 'scriptContent',
37   - label: '脚本内容',
38   - required: true,
39   - component: 'Input',
40   - slot: 'scriptContent',
41   - colProps: { span: 24 },
42   - },
43   - {
44   - field: 'remark',
45   - label: '输出参数',
46   - colProps: { span: 24 },
47   - component: 'InputTextArea',
48   - componentProps: {
49   - rows: 6,
50   - maxLength: 255,
51   - placeholder: '请输入输出参数',
52   - },
53   - },
54   -];
1   -<template>
2   - <div>
3   - <a-form
4   - ref="formRef"
5   - :model="scriptForm"
6   - name="basic"
7   - :label-col="{ span: 4 }"
8   - :wrapper-col="{ span: 16 }"
9   - style="margin-left: 2.4rem"
10   - autocomplete="off"
11   - >
12   - <a-form-item
13   - v-if="deviceTypeStr !== 'SENSOR'"
14   - label="鉴权脚本"
15   - name="'params'"
16   - :rules="[{ required: true, message: '请选择鉴权脚本' }]"
17   - >
18   - <div style="display: flex; align-items: center">
19   - <div>
20   - <Select
21   - @change="handleAuthChange"
22   - placeholder="请选择"
23   - v-model:value="scriptForm.authScriptId"
24   - style="width: 305px"
25   - show-search
26   - :options="selectAuthOptions"
27   - :filter-option="handleAuthSearch"
28   - allowClear
29   - />
30   - </div>
31   - <div>
32   - <span
33   - @click="handleCreateOrEditAuth('add')"
34   - class="ml-2"
35   - style="color: #409eff; cursor: pointer"
36   - size="small"
37   - >新建转换脚本</span
38   - >
39   - </div>
40   - </div>
41   - <a-button @click="handleCreateOrEditAuth('test')" class="mt-4" type="primary"
42   - >测试脚本</a-button
43   - >
44   - </a-form-item>
45   - <a-form-item
46   - label="上行脚本"
47   - name="'params'"
48   - :rules="[{ required: true, message: '请选择上行脚本' }]"
49   - >
50   - <div style="display: flex; align-items: center">
51   - <div>
52   - <Select
53   - @change="handleUpChange"
54   - placeholder="请选择"
55   - v-model:value="scriptForm.upScriptId"
56   - style="width: 305px"
57   - show-search
58   - :options="selectUpOptions"
59   - :filter-option="handleSearch"
60   - allowClear
61   - />
62   - </div>
63   - <div>
64   - <span
65   - @click="handleCreateOrEdit('add')"
66   - class="ml-2"
67   - style="color: #409eff; cursor: pointer"
68   - size="small"
69   - >新建转换脚本</span
70   - >
71   - </div>
72   - </div>
73   - <a-button @click="handleCreateOrEdit('test')" class="mt-4" type="primary"
74   - >测试脚本</a-button
75   - >
76   - </a-form-item>
77   - </a-form>
78   - <ConverScriptModal @register="registerModal" @success="handleSuccess" />
79   - <ConverScriptModal @register="registerAuthModal" @success="handleAuthSuccess" />
80   - </div>
81   -</template>
82   -<script lang="ts" setup name="index">
83   - import { ref, Ref, onMounted, reactive } from 'vue';
84   - import { SelectTypes } from 'ant-design-vue/es/select';
85   - import { Select } from 'ant-design-vue';
86   - import { useModal } from '/@/components/Modal';
87   - import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager';
88   - import ConverScriptModal from '/@/views/rule/script/TcpConversionScript/ConverScriptModal.vue';
89   - import { useMessage } from '/@/hooks/web/useMessage';
90   -
91   - const props = defineProps({
92   - deviceTypeStr: { type: String, default: '' },
93   - });
94   -
95   - const scriptForm = reactive({
96   - authScriptId: '',
97   - upScriptId: '',
98   - });
99   - const selectUpOptions: Ref<SelectTypes['options']> = ref([]);
100   -
101   - const selectAuthOptions: Ref<SelectTypes['options']> = ref([]);
102   -
103   - const { createMessage } = useMessage();
104   -
105   - const upScriptIdStr = ref('');
106   -
107   - const authScriptIdStr = ref('');
108   -
109   - onMounted(async () => {
110   - selectUpOptions.value = await getAllScriptType('TRANSPORT_TCP_UP');
111   - selectAuthOptions.value = await getAllScriptType('TRANSPORT_TCP_AUTH');
112   - });
113   -
114   - const getAllScriptType = async (type) => {
115   - const rest = await getScriptManageMeList({ scriptType: type });
116   - return rest.map((m) => ({ label: m.name, value: m.id }));
117   - };
118   -
119   - const handleSuccess = async ({ res, text }) => {
120   - if (text !== 'test') {
121   - const rest = await getAllScriptType('TRANSPORT_TCP_UP');
122   - selectUpOptions.value = rest;
123   - scriptForm.upScriptId = res?.id;
124   - upScriptIdStr.value = res?.id;
125   - }
126   - };
127   -
128   - const handleAuthSuccess = async ({ res, text }) => {
129   - if (text !== 'test') {
130   - const rest = await getAllScriptType('TRANSPORT_TCP_AUTH');
131   - selectAuthOptions.value = rest;
132   - scriptForm.authScriptId = res?.id;
133   - authScriptIdStr.value = res?.id;
134   - }
135   - };
136   -
137   - const handleUpChange = (v) => {
138   - upScriptIdStr.value = v;
139   - scriptForm.upScriptId = v;
140   - };
141   -
142   - const handleAuthChange = (v) => {
143   - authScriptIdStr.value = v;
144   - scriptForm.authScriptId = v;
145   - };
146   -
147   - const [registerModal, { openModal }] = useModal();
148   -
149   - const [registerAuthModal, { openModal: openAuthModel }] = useModal();
150   -
151   - //TODO: 待优化
152   -
153   - const handleCreateOrEditAuth = (c) => {
154   - if (c === 'add') {
155   - openAuthModel(true, {
156   - isUpdate: true,
157   - isView: false,
158   - isTest: false,
159   - isText: 'confirm',
160   - isTitle: 'add',
161   - });
162   - } else {
163   - if (!authScriptIdStr.value) return createMessage.error('请先选择对应脚本');
164   - openAuthModel(true, {
165   - isUpdate: false,
166   - isTest: true,
167   - record: authScriptIdStr.value,
168   - isText: 'test',
169   - isTitle: 'test',
170   - });
171   - }
172   - };
173   -
174   - const handleCreateOrEdit = (c) => {
175   - if (c === 'add') {
176   - openModal(true, {
177   - isUpdate: true,
178   - isView: false,
179   - isTest: false,
180   - isText: 'confirm',
181   - isTitle: 'add',
182   - });
183   - } else {
184   - if (!upScriptIdStr.value) return createMessage.error('请先选择对应脚本');
185   - openModal(true, {
186   - isUpdate: false,
187   - isTest: true,
188   - record: upScriptIdStr.value,
189   - isText: 'test',
190   - isTitle: 'test',
191   - });
192   - }
193   - };
194   -
195   - const getFormData = async () => {
196   - if (props.deviceTypeStr === 'SENSOR') {
197   - if (!scriptForm.upScriptId) {
198   - createMessage.error('请先选择对应脚本');
199   - throw new Error('请先选择对应脚本');
200   - }
201   - } else {
202   - if (!scriptForm.authScriptId) {
203   - createMessage.error('请先选择对应脚本');
204   - throw new Error('请先选择对应脚本');
205   - }
206   - if (!scriptForm.upScriptId) {
207   - createMessage.error('请先选择对应脚本');
208   - throw new Error('请先选择对应脚本');
209   - }
210   - }
211   - return {
212   - ...scriptForm,
213   - type: 'TCP',
214   - };
215   - };
216   -
217   - const resetFormData = () => {
218   - // resetFields();
219   - };
220   -
221   - const setFormData = (v) => {
222   - scriptForm.authScriptId = v?.authScriptId;
223   - scriptForm.upScriptId = v?.upScriptId;
224   - // setFieldsValue(v);
225   - upScriptIdStr.value = v?.upScriptId;
226   - authScriptIdStr.value = v?.authScriptId;
227   - };
228   -
229   - const handleSearch = (inputValue: string, option: Record<'label' | 'value', string>) => {
230   - return option.label.includes(inputValue);
231   - };
232   -
233   - const handleAuthSearch = (inputValue: string, option: Record<'label' | 'value', string>) => {
234   - return option.label.includes(inputValue);
235   - };
236   -
237   - defineExpose({
238   - getFormData,
239   - resetFormData,
240   - setFormData,
241   - });
242   -</script>
243   -<style lang="less" scoped></style>
  1 +<template>
  2 + <div>
  3 + <a-form
  4 + ref="formRef"
  5 + :model="scriptForm"
  6 + name="basic"
  7 + :label-col="{ span: 4 }"
  8 + :wrapper-col="{ span: 16 }"
  9 + autocomplete="off"
  10 + style="margin-left: 2.4rem"
  11 + >
  12 + <a-form-item
  13 + v-if="deviceTypeStr !== TypeEnum.SENSOR"
  14 + label="鉴权脚本"
  15 + name="authScriptId"
  16 + :rules="[{ required: true, message: '请选择鉴权脚本' }]"
  17 + >
  18 + <ScriptSelectItem
  19 + ref="scriptSelectItemAuthRef"
  20 + v-model:value="scriptForm.authScriptId"
  21 + :scriptType="ScriptTypeEnum.TRANSPORT_TCP_AUTH"
  22 + />
  23 + </a-form-item>
  24 + <a-form-item
  25 + label="上行脚本"
  26 + name="upScriptId"
  27 + :rules="[{ required: true, message: '请选择上行脚本' }]"
  28 + >
  29 + <ScriptSelectItem
  30 + ref="scriptSelectItemUpRef"
  31 + v-model:value="scriptForm.upScriptId"
  32 + :scriptType="ScriptTypeEnum.TRANSPORT_TCP_UP"
  33 + />
  34 + </a-form-item>
  35 + </a-form>
  36 + </div>
  37 +</template>
  38 +<script lang="ts" setup name="index">
  39 + import { reactive, ref } from 'vue';
  40 + import { useMessage } from '/@/hooks/web/useMessage';
  41 + import { ScriptSelectItem } from './components';
  42 + import { ScriptTypeEnum } from '/@/views/rule/script/TcpConversionScript/config';
  43 + import { TypeEnum } from '/@/views/device/list/config/data';
  44 +
  45 + const props = defineProps({
  46 + deviceTypeStr: { type: String, default: '' },
  47 + });
  48 +
  49 + const scriptForm = reactive({
  50 + authScriptId: '',
  51 + upScriptId: '',
  52 + });
  53 +
  54 + const { createMessage } = useMessage();
  55 +
  56 + const scriptSelectItemAuthRef = ref<InstanceType<typeof ScriptSelectItem>>();
  57 +
  58 + const scriptSelectItemUpRef = ref<InstanceType<typeof ScriptSelectItem>>();
  59 +
  60 + const getFormData = async () => {
  61 + //业务 网关子设备没有鉴权脚本
  62 + if (props.deviceTypeStr === TypeEnum.SENSOR) Reflect.deleteProperty(scriptForm, 'authScriptId');
  63 + if (Object.values(scriptForm).some((item) => !item)) {
  64 + createMessage.error('请先选择对应脚本');
  65 + throw new Error('请先选择对应脚本');
  66 + }
  67 + return {
  68 + ...scriptForm,
  69 + type: 'TCP',
  70 + };
  71 + };
  72 +
  73 + const resetFormData = () => {};
  74 +
  75 + const setFormData = (data) => {
  76 + scriptForm.authScriptId = data?.authScriptId;
  77 + scriptForm.upScriptId = data?.upScriptId;
  78 + scriptSelectItemAuthRef.value?.setValue(data?.authScriptId);
  79 + scriptSelectItemUpRef.value?.setValue(data?.upScriptId);
  80 + };
  81 + defineExpose({
  82 + getFormData,
  83 + resetFormData,
  84 + setFormData,
  85 + });
  86 +</script>
  87 +<style lang="less" scoped></style>
... ...
1   -.wrapper {
2   - margin: 10px 60px 60px 60px;
3   -}
4   -
5   -.inner {
6   - width: 400px;
7   - height: 400px;
8   -}
9   -
10   -.item {
11   - text-align: center;
12   - font-size: 200%;
13   - color: #fff;
14   -}
1   -<template>
2   - <div>
3   - <BasicModal
4   - destroyOnClose
5   - v-bind="$attrs"
6   - width="60rem"
7   - @register="register"
8   - :title="getTitle"
9   - :minHeight="500"
10   - @cancel="handleCancel"
11   - @ok="handleSubmit"
12   - >
13   - <ConverScript
14   - :view="isViewDetail"
15   - :text="isTitle"
16   - :ifAdd="isTest ? false : true"
17   - ref="converScriptRef"
18   - />
19   - </BasicModal>
20   - </div>
21   -</template>
22   -<script setup lang="ts">
23   - import { ref, computed, unref, reactive } from 'vue';
24   - import { BasicModal, useModalInner } from '/@/components/Modal';
25   - import ConverScript from './ConverScript.vue';
26   - import {
27   - createOrEditScriptManage,
28   - getScriptManageDetail,
29   - testScriptManage,
30   - } from '/@/api/scriptmanage/scriptManager';
31   - import { useMessage } from '/@/hooks/web/useMessage';
32   -
33   - const emits = defineEmits(['success', 'register']);
34   - const { createMessage } = useMessage();
35   - const converScriptRef = ref<InstanceType<typeof ConverScript>>();
36   - const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本'));
37   - const isUpdate = ref(false);
38   - const isViewDetail = ref('');
39   - const isTest = ref(false);
40   - const isText = ref('');
41   - const isTitle = ref('');
42   - const editData = reactive({
43   - data: {},
44   - });
45   - const [register, { setModalProps, closeModal }] = useModalInner(async (data) => {
46   - setModalProps({ loading: true });
47   - handleCancel(false);
48   - isUpdate.value = data.isUpdate;
49   - isViewDetail.value = data.isView;
50   - isTest.value = data.isTest;
51   - isText.value = data.isText;
52   - isTitle.value = data.isTitle;
53   - editData.data = data.record;
54   - setModalProps({ loading: false });
55   - converScriptRef.value?.initEditor();
56   - if (!unref(isViewDetail)) {
57   - const title =
58   - unref(isTitle) == 'edit'
59   - ? '编辑转换脚本'
60   - : unref(isTitle) == 'add'
61   - ? '新增转换脚本'
62   - : '测试转换脚本';
63   - const okText = isText.value == 'test' ? '测试' : '确定';
64   - if (unref(isTitle) == 'add') {
65   - converScriptRef.value?.setDefaultRadio('TRANSPORT_TCP_UP');
66   - }
67   - if (unref(isTitle) == 'edit') {
68   - converScriptRef.value?.setFormData(data.record);
69   - }
70   - if (unref(isTitle) == 'test') {
71   - if (data.record) {
72   - const res = await getScriptManageDetail(data.record);
73   - converScriptRef.value?.setFormData(res);
74   - } else {
75   - converScriptRef.value?.setDefaultRadio('TRANSPORT_TCP_UP');
76   - }
77   - }
78   - setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText });
79   - if (!unref(isUpdate)) {
80   - }
81   - } else {
82   - setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看转换脚本' });
83   - const res = await getScriptManageDetail(data.record.id);
84   - converScriptRef.value?.setFormData(res || {});
85   - }
86   - });
87   -
88   - const handleSubmit = async () => {
89   - setModalProps({ confirmLoading: true });
90   - try {
91   - const val = await converScriptRef.value?.getFormData();
92   - const tempObj = {
93   - ...editData.data,
94   - ...val,
95   - };
96   - const res: any =
97   - isText.value == 'test'
98   - ? await testScriptManage(val)
99   - : await createOrEditScriptManage(tempObj);
100   - createMessage.success(
101   - unref(isTitle) == 'edit'
102   - ? '编辑转换脚本成功'
103   - : unref(isTitle) == 'add'
104   - ? '新增转换脚本成功'
105   - : '测试转换脚本成功'
106   - );
107   - if (unref(isTitle) == 'add' || unref(isTitle) == 'edit') {
108   - setTimeout(() => {
109   - closeModal();
110   - }, 10);
111   - emits('success', {
112   - res,
113   - text: isText.value,
114   - });
115   - } else {
116   - if (res) {
117   - converScriptRef.value?.setScriptOutputData(res?.output || res?.error);
118   - }
119   - }
120   - } finally {
121   - setModalProps({ confirmLoading: false });
122   - }
123   - };
124   - const handleCancel = (flag) => {
125   - if (flag) {
126   - closeModal();
127   - }
128   - converScriptRef.value?.resetFormData();
129   - };
130   -</script>
131   -<style lang="less" scoped>
132   - @import url('./ConverScriptModal.less');
133   -</style>
1   -<template>
2   - <div>
3   - <BasicModal
4   - destroyOnClose
5   - v-bind="$attrs"
6   - width="60rem"
7   - @register="register"
8   - :title="getTitle"
9   - :minHeight="500"
10   - @cancel="handleCancel"
11   - @ok="handleSubmit"
12   - >
13   - <ConverScript
14   - :view="isViewDetail"
15   - :text="isTitle"
16   - :ifAdd="isTest ? false : true"
17   - ref="converScriptRef"
18   - />
19   - </BasicModal>
20   - </div>
21   -</template>
22   -<script setup lang="ts">
23   - import { ref, computed, unref, reactive } from 'vue';
24   - import { BasicModal, useModalInner } from '/@/components/Modal';
25   - import ConverScript from './ConverScript.vue';
26   - import {
27   - createOrEditScriptManage,
28   - getScriptManageDetail,
29   - testScriptManage,
30   - } from '/@/api/scriptmanage/scriptManager';
31   - import { useMessage } from '/@/hooks/web/useMessage';
32   -
33   - const emits = defineEmits(['success', 'register']);
34   - const { createMessage } = useMessage();
35   - const converScriptRef = ref<InstanceType<typeof ConverScript>>();
36   - const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本'));
37   - const isUpdate = ref(false);
38   - const isViewDetail = ref('');
39   - const isTest = ref(false);
40   - const isText = ref('');
41   - const isTitle = ref('');
42   - const editData = reactive({
43   - data: {},
44   - });
45   - const [register, { setModalProps, closeModal }] = useModalInner(async (data) => {
46   - setModalProps({ loading: true });
47   - handleCancel(false);
48   - isUpdate.value = data.isUpdate;
49   - isViewDetail.value = data.isView;
50   - isTest.value = data.isTest;
51   - isText.value = data.isText;
52   - isTitle.value = data.isTitle;
53   - editData.data = data.record;
54   - setModalProps({ loading: false });
55   - converScriptRef.value?.initEditor();
56   - if (!unref(isViewDetail)) {
57   - const title =
58   - unref(isTitle) == 'edit'
59   - ? '编辑转换脚本'
60   - : unref(isTitle) == 'add'
61   - ? '新增转换脚本'
62   - : '测试转换脚本';
63   - const okText = isText.value == 'test' ? '测试' : '确定';
64   - if (unref(isTitle) == 'add') {
65   - converScriptRef.value?.setDefaultRadio('TRANSPORT_TCP_UP');
66   - }
67   - if (unref(isTitle) == 'edit') {
68   - converScriptRef.value?.setFormData(data.record);
69   - }
70   - if (unref(isTitle) == 'test') {
71   - if (data.record) {
72   - const res = await getScriptManageDetail(data.record);
73   - converScriptRef.value?.setFormData({ ...res, convertJs: data?.testContent });
74   - } else {
75   - converScriptRef.value?.setFormData({ convertJs: data?.testContent });
76   - converScriptRef.value?.setDefaultRadio('TRANSPORT_TCP_UP');
77   - }
78   - }
79   - setModalProps({ title, showOkBtn: true, showCancelBtn: true, okText });
80   - if (!unref(isUpdate)) {
81   - }
82   - } else {
83   - setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看转换脚本' });
84   - const res = await getScriptManageDetail(data.record.id);
85   - converScriptRef.value?.setFormData(res || {});
86   - }
87   - });
88   -
89   - const handleSubmit = async () => {
90   - setModalProps({ confirmLoading: true });
91   - try {
92   - const val = await converScriptRef.value?.getFormData();
93   - const tempObj = {
94   - ...editData.data,
95   - ...val,
96   - };
97   - const res: any =
98   - isText.value == 'test'
99   - ? await testScriptManage(val)
100   - : await createOrEditScriptManage(tempObj);
101   - createMessage.success(
102   - unref(isTitle) == 'edit'
103   - ? '编辑转换脚本成功'
104   - : unref(isTitle) == 'add'
105   - ? '新增转换脚本成功'
106   - : '测试转换脚本成功'
107   - );
108   - if (unref(isTitle) == 'add' || unref(isTitle) == 'edit') {
109   - setTimeout(() => {
110   - closeModal();
111   - }, 10);
112   - emits('success', {
113   - res,
114   - text: isText.value,
115   - });
116   - } else {
117   - if (res) {
118   - converScriptRef.value?.setScriptOutputData(res?.output || res?.error);
119   - }
120   - }
121   - } finally {
122   - setModalProps({ confirmLoading: false });
123   - }
124   - };
125   - const handleCancel = (flag) => {
126   - if (flag) {
127   - closeModal();
128   - }
129   - converScriptRef.value?.resetFormData();
130   - };
131   -</script>
132   -<style lang="less" scoped>
133   - @import url('./ConverScriptModal.less');
134   -</style>
src/views/rule/script/TcpConversionScript/components/ConverScriptForm.vue renamed from src/views/rule/script/TcpConversionScript/ConverScript.vue
... ... @@ -6,17 +6,16 @@
6 6 name="basic"
7 7 :label-col="{ span: 4 }"
8 8 :wrapper-col="{ span: 16 }"
9   - autocomplete="off"
10 9 >
11 10 <a-form-item
12   - :label="ifAdd ? '名称' : '输入参数(params)'"
13   - :name="ifAdd ? 'name' : 'params'"
14   - :rules="[{ required: true, message: ifAdd ? '请输入脚本名称' : '请输入参数' }]"
  11 + :label="isNotTest ? '名称' : '输入参数(params)'"
  12 + :name="isNotTest ? 'name' : 'params'"
  13 + :rules="[{ required: true, message: isNotTest ? '请输入脚本名称' : '请输入参数' }]"
15 14 >
16 15 <a-input-group compact>
17 16 <a-input
18 17 style="width: calc(100% - 200px)"
19   - v-if="ifAdd"
  18 + v-if="isNotTest"
20 19 :maxlength="36"
21 20 @change="handleInputChange"
22 21 v-model:value="scriptForm.name"
... ... @@ -28,7 +27,13 @@
28 27 v-model:value="scriptForm.params"
29 28 placeholder="请输入参数"
30 29 />
31   - <a-button @click="onHandleClick(text)" v-show="ifAdd && !view" type="primary">
  30 + <a-button
  31 + @click="
  32 + handleInnerTestClick(BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT, 'innerTest')
  33 + "
  34 + v-show="isNotTest && !isView"
  35 + type="primary"
  36 + >
32 37 测试
33 38 </a-button>
34 39 </a-input-group>
... ... @@ -46,36 +51,35 @@
46 51 />
47 52 </a-space>
48 53 </a-form-item>
49   - <a-form-item label="脚本内容" :name="ifAdd ? 'convertJs' : 'script'">
50   - <Card title="脚本内容" :bodyStyle="{ padding: 0 }">
  54 + <a-form-item label="脚本内容" :name="isNotTest ? 'convertJs' : 'script'">
  55 + <Card title="编写脚本内容" :bodyStyle="{ padding: 0 }">
51 56 <template #extra>
52 57 <Button
53   - v-show="ifAdd && !view"
54   - @click="onHandleTestExampleGateway(scriptForm.scriptType)"
55   - style="position: relative; top: -4rem; right: -6.6rem"
  58 + v-show="isNotTest && !isView"
  59 + @click="onHandleTestExample(true, scriptForm.scriptType)"
  60 + class="button-text"
56 61 type="primary"
57 62 >
58 63 直连/子设备用例</Button
59 64 >
60 65 <Button
61   - class="ml-2"
62   - v-show="ifAdd && !view"
63   - @click="onHandleTestExample(scriptForm.scriptType)"
64   - style="position: relative; top: -4rem; right: -6.6rem"
  66 + class="ml-2 button-text"
  67 + v-show="isNotTest && !isView"
  68 + @click="onHandleTestExample(false, scriptForm.scriptType)"
65 69 type="primary"
66 70 >
67 71 网关用例</Button
68 72 >
69 73 <a-button @click="handleFormat" size="small">格式化</a-button>
70 74 <Tooltip
71   - v-if="scriptForm.scriptType !== 'TRANSPORT_TCP_UP'"
  75 + v-if="scriptForm.scriptType !== ScriptTypeEnum.TRANSPORT_TCP_UP"
72 76 :title="defaultAuthTitle"
73 77 class="ml-2"
74 78 >
75   - <QuestionCircleOutlined style="font-size: 1rem" />
  79 + <QuestionCircleOutlined />
76 80 </Tooltip>
77 81 <Tooltip v-else :title="defaultUpTitle" class="ml-2">
78   - <QuestionCircleOutlined style="font-size: 1rem" />
  82 + <QuestionCircleOutlined />
79 83 </Tooltip>
80 84 </template>
81 85 <div ref="aceRef"></div>
... ... @@ -88,12 +92,12 @@
88 92 </Button>
89 93 </a-form-item>
90 94 <a-form-item
91   - :label="ifAdd ? '备注' : '输出参数(output)'"
92   - :name="ifAdd ? 'description' : 'output'"
  95 + :label="isNotTest ? '备注' : '输出参数(output)'"
  96 + :name="isNotTest ? 'description' : 'output'"
93 97 >
94 98 <a-textarea
95 99 :rows="3"
96   - v-if="ifAdd"
  100 + v-if="isNotTest"
97 101 v-model:value="scriptForm.description"
98 102 placeholder="请输入备注"
99 103 :maxlength="255"
... ... @@ -107,7 +111,7 @@
107 111 />
108 112 </a-form-item>
109 113 </a-form>
110   - <TestScriptModal @register="registerModal" />
  114 + <ConverScriptModal @register="registerModal" />
111 115 </div>
112 116 </template>
113 117 <script setup lang="ts">
... ... @@ -130,18 +134,25 @@
130 134 defaultTestUpExample,
131 135 defaultTestAuthExample,
132 136 defaultTestSubGatewayUpExample,
133   - } from './config.data';
  137 + ScriptTypeEnum,
  138 + aceEditorAttribtes,
  139 + aceEditorOptions,
  140 + } from '../config';
134 141 import { useAppStore } from '/@/store/modules/app';
135   - import TestScriptModal from './TestScriptModal.vue';
  142 + import { ConverScriptModal } from './index';
136 143 import { useModal } from '/@/components/Modal';
  144 + import { useHooks } from '../hooks/index.hooks';
  145 + import { BusinessConvertScriptTextEnum } from '../config';
137 146
138 147 defineEmits(['register']);
  148 +
139 149 const props = defineProps({
140   - ifAdd: { type: Boolean, default: true },
141   - text: { type: String, default: '' },
142   - view: { type: Boolean, default: false },
  150 + isNotTest: { type: Boolean, default: true },
  151 + isView: { type: Boolean, default: false },
143 152 });
144 153
  154 + const { validateContentError, validateContentLengthError } = useHooks();
  155 +
145 156 const scriptForm = reactive({
146 157 name: '',
147 158 description: '',
... ... @@ -170,49 +181,42 @@
170 181
171 182 const getAceClass = computed((): string => userStore.getDarkMode);
172 183
173   - const setDefaultRadio = (p3) => {
174   - scriptForm.scriptType = p3;
  184 + const setDefaultRadio = (defaultRadio) => {
  185 + scriptForm.scriptType = defaultRadio;
175 186 };
176 187
177 188 const getDictValue = async (dict_type) => {
178 189 const res = await findDictItemByCode({
179 190 dictCode: dict_type,
180 191 });
181   - return res.map((m) => {
182   - return { label: m.itemText, value: m.itemValue };
183   - });
  192 + return res.map((m) => ({ label: m.itemText, value: m.itemValue }));
  193 + };
  194 +
  195 + const getScriptType = async () => {
  196 + reportTypeOptions.scriptTypeOptions = (await getDictValue('script_type')) as any;
184 197 };
185 198
186   - onMounted(async () => {
187   - reportTypeOptions.scriptTypeOptions = (await getDictValue('script_type')) as never as any;
  199 + onMounted(() => {
  200 + getScriptType();
  201 + initEditor();
188 202 });
189 203
190   - // 初始化编辑器
  204 + // 初始化Ace编辑器
191 205 const initEditor = () => {
192   - aceEditor.value = ace.edit(aceRef.value, {
193   - maxLines: 16, // 最大行数,超过会自动出现滚动条
194   - minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
195   - fontSize: 14, // 编辑器内字体大小
196   - theme: 'ace/theme/chrome', // 默认设置的主题
197   - mode: 'ace/mode/javascript', // 默认设置的语言模式
198   - tabSize: 2, // 制表符设置为 4 个空格大小
199   - });
200   -
  206 + aceEditor.value = ace.edit(aceRef.value, aceEditorAttribtes);
201 207 aceEditor.value.setOptions({
202   - enableBasicAutocompletion: true,
203   - enableLiveAutocompletion: true,
204   - enableSnippets: true,
205   - enableEmmet: true,
  208 + ...aceEditorOptions,
206 209 theme: getAceClass.value === 'dark' ? 'ace/theme/terminal' : 'ace/theme/chrome',
207 210 });
208 211 aceEditor.value.setValue('');
209 212 beautify(aceEditor.value.session);
210   - switchScriptTypeGetContent('TRANSPORT_TCP_UP');
  213 + switchScriptTypeGetContent(ScriptTypeEnum.TRANSPORT_TCP_UP);
211 214 };
212 215
213 216 const handleScriptType = ({ target }) => {
214 217 const { value } = target;
215 218 scriptForm.scriptType = value;
  219 + //业务 编辑不允许切换
216 220 if (convertJsContent.value) return;
217 221 switchScriptTypeGetContent(value);
218 222 };
... ... @@ -221,23 +225,17 @@
221 225 aceEditor.value.setValue(defaultScriptTypeContent[type]);
222 226 };
223 227
224   - const onHandleTestExample = (example) => {
225   - if (example === 'TRANSPORT_TCP_UP') {
226   - aceEditor.value?.setValue(defaultTestUpExample);
227   - } else {
228   - aceEditor.value?.setValue(defaultTestAuthExample);
229   - }
230   - handleFormat();
231   - };
232   -
233   - const onHandleTestExampleGateway = (example) => {
234   - if (example === 'TRANSPORT_TCP_UP') {
  228 + const onHandleTestExample = (status, example) => {
  229 + if (status && example === ScriptTypeEnum.TRANSPORT_TCP_UP) {
235 230 aceEditor.value?.setValue(defaultTestSubGatewayUpExample);
236 231 } else {
237   - aceEditor.value?.setValue(defaultTestAuthExample);
  232 + example === ScriptTypeEnum.TRANSPORT_TCP_UP
  233 + ? aceEditor.value?.setValue(defaultTestUpExample)
  234 + : aceEditor.value?.setValue(defaultTestAuthExample);
238 235 }
239 236 handleFormat();
240 237 };
  238 +
241 239 const handleCopy = () => {
242 240 const valueRef = aceEditor.value.getValue();
243 241 const value = unref(valueRef);
... ... @@ -255,61 +253,41 @@
255 253
256 254 const getFormData = async () => {
257 255 const value = await formRef.value.validateFields();
258   - if (props.ifAdd) {
  256 + if (props.isNotTest) {
259 257 scriptForm.convertJs = aceEditor.value.getValue();
260   - if (scriptForm.convertJs == '') {
261   - createMessage.error('请编写脚本内容');
262   - throw '请编写脚本内容';
263   - }
  258 + if (scriptForm.convertJs == '') return validateContentError();
264 259 } else {
265 260 scriptForm.script = aceEditor.value.getValue();
266   - if (scriptForm.script == '') {
267   - createMessage.error('请编写脚本内容');
268   - throw '请编写脚本内容';
269   - }
  261 + if (scriptForm.script == '') return validateContentError();
270 262 }
271 263 if (!value) return;
272   - if (scriptForm.params) {
273   - const trimParams = scriptForm.params.replace(/\s*/g, '');
274   - Reflect.set(value, 'params', trimParams);
275   - }
276   - if (scriptForm.convertJs.length > 1000) {
277   - createMessage.error('脚本内容长度不能大于1000');
278   - throw '脚本内容长度不能大于1000';
279   - }
  264 + if (scriptForm.params) removeTrim(true, scriptForm.params);
  265 + if (scriptForm.convertJs.length > 1000) return validateContentLengthError();
280 266 return {
281 267 ...value,
282   - ...{ convertJs: props.ifAdd ? scriptForm.convertJs : null },
283   - ...{ script: !props.ifAdd ? scriptForm.script : null },
  268 + ...{ convertJs: props.isNotTest ? scriptForm.convertJs : null },
  269 + ...{ script: !props.isNotTest ? scriptForm.script : null },
284 270 };
285 271 };
286 272
287   - const handleInputChange = (e) => {
288   - const trimParams = e.target.value.replace(/\s*/g, '');
  273 + const removeTrim = (status, e) => {
  274 + //去除空格
  275 + const value = status ? e : e.target.value;
  276 + const trimParams = value.replace(/\s*/g, '');
289 277 Reflect.set(scriptForm, 'params', trimParams);
290   - if (scriptForm.scriptType === 'TRANSPORT_TCP_DOWN') {
291   - aceEditor.value.setValue(`out.datas = "${scriptForm.params}";out.deviceName = "sensor";`);
292   - }
293 278 };
294 279
295   - const getRecordId = ref('');
  280 + const handleInputChange = (e) => removeTrim(false, e);
296 281
297 282 const convertJsContent = ref('');
298 283
299 284 const setFormData = (v) => {
300   - if (v) {
301   - getRecordId.value = v?.id;
302   - for (let i in scriptForm) {
303   - Reflect.set(scriptForm, i, v[i]);
304   - }
305   - aceEditor.value.setValue(v.convertJs);
306   - convertJsContent.value = v.convertJs;
307   - handleFormat();
  285 + if (!v) return;
  286 + for (let i in scriptForm) {
  287 + Reflect.set(scriptForm, i, v[i]);
308 288 }
309   - };
310   -
311   - const setScriptContentData = (v) => {
312   - aceEditor.value.setValue(v);
  289 + aceEditor.value.setValue(v.convertJs);
  290 + convertJsContent.value = v.convertJs;
313 291 handleFormat();
314 292 };
315 293
... ... @@ -317,6 +295,7 @@
317 295 for (let i in scriptForm) {
318 296 Reflect.set(scriptForm, i, '');
319 297 }
  298 + setDefaultRadio(ScriptTypeEnum.TRANSPORT_TCP_UP);
320 299 };
321 300
322 301 const setScriptOutputData = (v) => {
... ... @@ -332,29 +311,39 @@
332 311
333 312 const [registerModal, { openModal }] = useModal();
334 313
335   - const onHandleClick = (o) => {
  314 + const handleInnerTestClick = (text, innerTest) => {
336 315 const getTestContent = aceEditor.value?.getValue();
337   - openModal(true, {
338   - isAuth: '',
339   - isUpdate: o,
340   - record: o === 'add' ? null : getRecordId.value,
341   - testContent: getTestContent,
342   - isTest: true,
343   - isText: 'test',
344   - isTitle: 'test',
  316 + const modalParams = {
  317 + innerTest,
  318 + text,
  319 + record: {
  320 + convertJs: getTestContent,
  321 + scriptType: scriptForm.scriptType,
  322 + },
  323 + };
  324 + openModal(true, modalParams);
  325 + };
  326 +
  327 + const setDisableRadio = (value) => {
  328 + reportTypeOptions.scriptTypeOptions.forEach((item: any) => {
  329 + if (item.value === value) item.disabled = false;
  330 + else item.disabled = true;
345 331 });
346 332 };
347 333
348 334 defineExpose({
349   - initEditor,
350 335 getFormData,
351 336 resetFormData,
352 337 setFormData,
353   - setScriptContentData,
354 338 setScriptOutputData,
355 339 setDefaultRadio,
  340 + setDisableRadio,
356 341 });
357 342 </script>
358 343 <style lang="less" scoped>
359   - @import url('./ConverScriptModal.less');
  344 + .button-text {
  345 + position: relative;
  346 + top: -4rem;
  347 + right: -6.6rem;
  348 + }
360 349 </style>
... ...
  1 +<template>
  2 + <div>
  3 + <BasicModal
  4 + destroyOnClose
  5 + v-bind="$attrs"
  6 + width="60rem"
  7 + @register="register"
  8 + :minHeight="500"
  9 + @cancel="handleCancel"
  10 + @ok="handleSubmit"
  11 + >
  12 + <ConverScriptForm
  13 + ref="converScriptFormRef"
  14 + :isNotTest="businessText !== BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT"
  15 + :isView="businessText === BusinessConvertScriptTextEnum.BUSINESS_VIEW_TEXT"
  16 + />
  17 + </BasicModal>
  18 + </div>
  19 +</template>
  20 +<script setup lang="ts">
  21 + import { ref, nextTick, reactive } from 'vue';
  22 + import { BasicModal, useModalInner } from '/@/components/Modal';
  23 + import { ConverScriptForm } from './index';
  24 + import {
  25 + createOrEditScriptManage,
  26 + getScriptManageDetail,
  27 + testScriptManage,
  28 + } from '/@/api/scriptmanage/scriptManager';
  29 + import { useMessage } from '/@/hooks/web/useMessage';
  30 + import { BusinessConvertScriptTextEnum } from '../config';
  31 + import { useHooks } from '../hooks/index.hooks';
  32 + import { useThrottleFn } from '@vueuse/shared';
  33 +
  34 + const emits = defineEmits(['success', 'register']);
  35 +
  36 + const { createMessage } = useMessage();
  37 +
  38 + const { setPropsForModal, businessTextIsTest } = useHooks();
  39 +
  40 + const converScriptFormRef = ref<InstanceType<typeof ConverScriptForm>>();
  41 +
  42 + const businessText = ref('');
  43 +
  44 + const restData = reactive({
  45 + data: {},
  46 + });
  47 +
  48 + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => {
  49 + try {
  50 + await nextTick();
  51 + businessText.value = data.text;
  52 + restData.data = data.record;
  53 + setModalProps(setPropsForModal(data.text));
  54 + handleCancel(false);
  55 + if (!data.record) return;
  56 + if (!data.innerTest) {
  57 + const rest = await getScriptManageDetail(data.record?.id);
  58 + converScriptFormRef.value?.setFormData(rest);
  59 + } else converScriptFormRef.value?.setFormData(data.record);
  60 + if (data.scriptType) {
  61 + converScriptFormRef.value?.setDisableRadio(data.scriptType);
  62 + }
  63 + } finally {
  64 + setModalProps({
  65 + loading: false,
  66 + });
  67 + }
  68 + });
  69 +
  70 + const handleSubmit = () => useThrottle();
  71 +
  72 + const useThrottle = useThrottleFn(() => {
  73 + getValue();
  74 + }, 2000);
  75 +
  76 + const getValue = async () => {
  77 + try {
  78 + setModalProps({ confirmLoading: true });
  79 + const formData = await converScriptFormRef.value?.getFormData();
  80 + const rest = businessTextIsTest(businessText.value)
  81 + ? ((await testScriptManage(formData)) as any)
  82 + : ((await createOrEditScriptManage({ ...restData.data, ...formData })) as any);
  83 + if (businessTextIsTest(businessText.value)) {
  84 + createMessage.success(`${businessText.value}成功`);
  85 + converScriptFormRef.value?.setScriptOutputData(rest?.output || rest?.error);
  86 + } else {
  87 + createMessage.success(`${businessText.value}成功`);
  88 + closeModal();
  89 + emits('success', {
  90 + rest,
  91 + text: businessText.value,
  92 + });
  93 + }
  94 + } finally {
  95 + setModalProps({ confirmLoading: false });
  96 + }
  97 + };
  98 +
  99 + const handleCancel = (flag) => {
  100 + if (flag) {
  101 + closeModal();
  102 + }
  103 + converScriptFormRef.value?.resetFormData();
  104 + };
  105 +</script>
  106 +<style lang="less" scoped></style>
... ...
  1 +import ConverScriptModal from './ConverScriptModal.vue';
  2 +import ConverScriptForm from './ConverScriptForm.vue';
  3 +
  4 +export { ConverScriptModal, ConverScriptForm };
... ...
src/views/rule/script/TcpConversionScript/config/index.ts renamed from src/views/rule/script/TcpConversionScript/config.data.ts
1   -import { BasicColumn, FormSchema } from '/@/components/Table';
  1 +import { BasicColumn, BasicTableProps, FormSchema } from '/@/components/Table';
2 2 import moment from 'moment';
3 3 import { h } from 'vue';
4 4
  5 +//业务权限配置
  6 +export enum PermissionConvertScriptEnum {
  7 + PERMISSION_POST = 'api:yt:js:post',
  8 + PERMISSION_DELETE = 'api:yt:js:delete',
  9 + PERMISSION_TEST = 'api:yt:js:test',
  10 + PERMISSION_UPDATE = 'api:yt:js:update',
  11 + PERMISSION_UPDATE_STATUS = 'api:yt:js:update:status',
  12 +}
  13 +
  14 +//业务文字描述配置
  15 +export enum BusinessConvertScriptTextEnum {
  16 + BUSINESS_ENABLE_SUCCESS = '启用成功',
  17 + BUSINESS_DISABLE_SUCCESS = '禁用成功',
  18 + BUSINESS_ADD_TEXT = '新增转换脚本',
  19 + BUSINESS_DELETE_TEXT = '批量删除',
  20 + BUSINESS_VIEW_TEXT = '查看转换脚本',
  21 + BUSINESS_TEST_TEXT = '测试转换脚本',
  22 + BUSINESS_EDIT_TEXT = '编辑转换脚本',
  23 + BUSINESS_SUBMIT_TEXT = '确定',
  24 +}
  25 +
  26 +//业务脚本类型枚举
  27 +export enum ScriptTypeEnum {
  28 + //上行脚本
  29 + TRANSPORT_TCP_UP = 'TRANSPORT_TCP_UP',
  30 + //设备鉴权
  31 + TRANSPORT_TCP_AUTH = 'TRANSPORT_TCP_AUTH',
  32 +}
  33 +
  34 +//Ace编辑器通用配置
  35 +export const aceEditorAttribtes = {
  36 + maxLines: 16, // 最大行数,超过会自动出现滚动条
  37 + minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
  38 + fontSize: 14, // 编辑器内字体大小
  39 + theme: 'ace/theme/chrome', // 默认设置的主题
  40 + mode: 'ace/mode/javascript', // 默认设置的语言模式
  41 + tabSize: 2, // 制表符设置为 4 个空格大小
  42 +};
  43 +
  44 +export const aceEditorOptions = {
  45 + enableBasicAutocompletion: true,
  46 + enableLiveAutocompletion: true,
  47 + enableSnippets: true,
  48 + enableEmmet: true,
  49 +};
  50 +
5 51 // 表格配置
6 52 export const columns: BasicColumn[] = [
7 53 {
... ... @@ -33,7 +79,26 @@ export const columns: BasicColumn[] = [
33 79 },
34 80 ];
35 81
36   -// 查询配置
  82 +//表格通用属性配置
  83 +export const defaultTableAttribtes: BasicTableProps = {
  84 + columns,
  85 + title: '转换脚本列表',
  86 + showIndexColumn: false,
  87 + clickToRowSelect: false,
  88 + useSearchForm: true,
  89 + showTableSetting: true,
  90 + bordered: true,
  91 + rowKey: 'id',
  92 + actionColumn: {
  93 + width: 200,
  94 + title: '操作',
  95 + dataIndex: 'action',
  96 + slots: { customRender: 'action' },
  97 + fixed: 'right',
  98 + },
  99 +};
  100 +
  101 +// 表格查询配置
37 102 export const searchFormSchema: FormSchema[] = [
38 103 {
39 104 field: 'name',
... ... @@ -58,6 +123,7 @@ export const searchFormSchema: FormSchema[] = [
58 123 },
59 124 ];
60 125
  126 +//示例配置
61 127 export const defaultAuthTitle = h('div', { style: 'background:#404040' }, [
62 128 h('h3', { style: 'color:white' }, '设备鉴权示例'),
63 129 h('h3', { style: 'color:white' }, '输入参数:为16进制字符串'),
... ... @@ -84,7 +150,7 @@ export const defaultUpTitle = h('div', { style: 'background:#404040' }, [
84 150 ),
85 151 ]);
86 152
87   -// TRANSPORT_TCP_DOWN: 'out.datas = "";out.deviceName = "sensor";',
  153 +//用例配置
88 154 export const defaultScriptTypeContent = {
89 155 TRANSPORT_TCP_UP: `/*网关上行脚本*/
90 156 var teleData = {};
... ... @@ -104,21 +170,9 @@ out.success = params;
104 170 `,
105 171 };
106 172
107   -export const defaultTestUpExample = `/*网关上行脚本*/
108   -var teleData = {};
109   -/*物模型数据(可选):原始数据*/
110   -teleData.source= params;
111   -/*网关设备:slaveDevice是网关子设备的“设备标识”*/
112   -slaveDevice = params.substr(0,2);
113   -teleData[slaveDevice]= params;
114   -out.datas = teleData;
115   -out.telemetry = true;/*必填:true表示设备上报的遥测数据,false表示命令下发的响应数据*/`;
  173 +export const defaultTestUpExample = defaultScriptTypeContent['TRANSPORT_TCP_UP'];
116 174
117   -export const defaultTestAuthExample = `/*必填:设备的访问令牌*/
118   -out.password = params;
119   -/*选填:设备鉴权成功后响应给设备的信息*/
120   -out.success = params;
121   -`;
  175 +export const defaultTestAuthExample = defaultScriptTypeContent['TRANSPORT_TCP_AUTH'];
122 176
123 177 export const defaultTestSubGatewayUpExample = `/*params为TCP上报的标准ModBus数据,实际使用或测试时请删除*/
124 178 var params = "010304026C00883BF0"
... ...
  1 +import { BusinessConvertScriptTextEnum } from '../config';
  2 +import { useMessage } from '/@/hooks/web/useMessage';
  3 +
  4 +export const useHooks = () => {
  5 + const { createMessage } = useMessage();
  6 +
  7 + //映射弹窗底部按钮文字
  8 + const getModalButtonText = (text) => {
  9 + return text === BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT
  10 + ? BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT.slice(0, 2)
  11 + : BusinessConvertScriptTextEnum.BUSINESS_SUBMIT_TEXT;
  12 + };
  13 +
  14 + //判断业务文字是否为测试
  15 + const businessTextIsTest = (text) => text === BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT;
  16 +
  17 + //验证脚本内容
  18 + const validateContentError = () => {
  19 + createMessage.error('请编写脚本内容');
  20 + throw '请编写脚本内容';
  21 + };
  22 +
  23 + const validateContentLengthError = () => {
  24 + createMessage.error('请编写脚本内容');
  25 + throw '请编写脚本内容';
  26 + };
  27 +
  28 + //Modal弹窗属性
  29 + const setPropsForModal = (text) => {
  30 + return {
  31 + loading: true,
  32 + title: text,
  33 + okText: getModalButtonText(text),
  34 + showOkBtn: text !== BusinessConvertScriptTextEnum.BUSINESS_VIEW_TEXT,
  35 + showCancelBtn: text !== BusinessConvertScriptTextEnum.BUSINESS_VIEW_TEXT,
  36 + };
  37 + };
  38 + return {
  39 + getModalButtonText,
  40 + businessTextIsTest,
  41 + validateContentError,
  42 + validateContentLengthError,
  43 + setPropsForModal,
  44 + };
  45 +};
... ...
1   -export { default as TcpConversionScript } from './index.vue';
  1 +export { default as TcpConversionScript } from './index.vue';
... ...
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, unref } from 'vue';
72   - import { BasicTable, useTable, TableAction } from '/@/components/Table';
73   - import { 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 props = defineProps<{ searchInfo: Recordable }>();
87   - const searchInfo = reactive<Recordable>({});
88   - const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({
89   - title: '转换脚本列表',
90   - api: ScriptPage,
91   - columns,
92   - showIndexColumn: false,
93   - clickToRowSelect: false,
94   - showTableSetting: true,
95   - bordered: true,
96   - rowKey: 'id',
97   - beforeFetch: (params: Recordable) => {
98   - return { ...unref(props.searchInfo), ...params };
99   - },
100   - actionColumn: {
101   - width: 200,
102   - title: '操作',
103   - dataIndex: 'action',
104   - slots: { customRender: 'action' },
105   - fixed: 'right',
106   - },
107   - });
108   -
109   - const handleSuccess = () => {
110   - reload();
111   - };
112   -
113   - const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
114   - useBatchDelete(deleteScriptManage, handleSuccess, setProps);
115   - selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => {
116   - // Demo:status为1的选择框禁用
117   - if (record.status === 1) {
118   - return { disabled: true };
119   - } else {
120   - return { disabled: false };
121   - }
122   - };
123   -
124   - nextTick(() => {
125   - setProps(selectionOptions);
126   - });
127   -
128   - const [registerModal, { openModal }] = useModal();
129   -
130   - // 新增或编辑
131   - const handleCreateOrEdit = (record: Recordable | null) => {
132   - if (record) {
133   - openModal(true, {
134   - isUpdate: false,
135   - record,
136   - isAuth: '',
137   - isView: false,
138   - isTest: false,
139   - isText: 'confirm',
140   - isTitle: 'edit',
141   - });
142   - } else {
143   - openModal(true, {
144   - isAuth: '',
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   - isAuth: '',
157   - isUpdate: false,
158   - record: record.id,
159   - isTest: true,
160   - isText: 'test',
161   - isTitle: 'test',
162   - });
163   - }
164   - };
165   - const handleScriptView = (record: Recordable | null) => {
166   - if (record) {
167   - openModal(true, {
168   - isUpdate: true,
169   - record,
170   - isView: true,
171   - });
172   - }
173   - };
174   - const statusChange = async (checked, record) => {
175   - setProps({
176   - loading: true,
177   - });
178   - setSelectedRowKeys([]);
179   - resetSelectedRowKeys();
180   - const newStatus = checked ? 1 : 0;
181   - const { createMessage } = useMessage();
182   - try {
183   - await scriptPagePutApi(record.id, newStatus);
184   - if (newStatus) {
185   - createMessage.success(`启用成功`);
186   - } else {
187   - createMessage.success('禁用成功');
188   - }
189   - } finally {
190   - setProps({
191   - loading: false,
192   - });
193   - reload();
194   - }
195   - };
196   -
197   - defineExpose({
198   - reload: () => {
199   - reload();
200   - },
201   - });
202   -</script>
  1 +<template>
  2 + <div>
  3 + <BasicTable :clickToRowSelect="false" @register="registerTable" :searchInfo="searchInfo">
  4 + <template #toolbar>
  5 + <Authority :value="PermissionConvertScriptEnum.PERMISSION_POST">
  6 + <a-button
  7 + type="primary"
  8 + @click="handleBusinessModal(BusinessConvertScriptTextEnum.BUSINESS_ADD_TEXT, null)"
  9 + >
  10 + {{ BusinessConvertScriptTextEnum.BUSINESS_ADD_TEXT }}
  11 + </a-button>
  12 + </Authority>
  13 + <Authority :value="PermissionConvertScriptEnum.PERMISSION_DELETE">
  14 + <Popconfirm
  15 + title="您确定要批量删除数据"
  16 + ok-text="确定"
  17 + cancel-text="取消"
  18 + @confirm="handleDeleteOrBatchDelete(null)"
  19 + >
  20 + <a-button type="primary" color="error" :disabled="hasBatchDelete">
  21 + {{ BusinessConvertScriptTextEnum.BUSINESS_DELETE_TEXT }}
  22 + </a-button>
  23 + </Popconfirm>
  24 + </Authority>
  25 + </template>
  26 + <template #convertJs="{ record }">
  27 + <a-button
  28 + type="text"
  29 + @click="handleBusinessModal(BusinessConvertScriptTextEnum.BUSINESS_VIEW_TEXT, record)"
  30 + >
  31 + <span style="color: #377dff">{{
  32 + BusinessConvertScriptTextEnum.BUSINESS_VIEW_TEXT.slice(0, 2)
  33 + }}</span>
  34 + </a-button>
  35 + </template>
  36 + <template #action="{ record }">
  37 + <TableAction
  38 + :actions="[
  39 + {
  40 + label: BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT.slice(0, 2),
  41 + icon: 'ant-design:font-size-outlined',
  42 + auth: PermissionConvertScriptEnum.PERMISSION_TEST,
  43 + onClick: handleBusinessModal.bind(
  44 + null,
  45 + BusinessConvertScriptTextEnum.BUSINESS_TEST_TEXT,
  46 + record
  47 + ),
  48 + },
  49 + {
  50 + label: BusinessConvertScriptTextEnum.BUSINESS_EDIT_TEXT.slice(0, 2),
  51 + icon: 'clarity:note-edit-line',
  52 + auth: PermissionConvertScriptEnum.PERMISSION_UPDATE,
  53 + onClick: handleBusinessModal.bind(
  54 + null,
  55 + BusinessConvertScriptTextEnum.BUSINESS_EDIT_TEXT,
  56 + record
  57 + ),
  58 + ifShow: record.status == 0,
  59 + },
  60 + {
  61 + label: BusinessConvertScriptTextEnum.BUSINESS_DELETE_TEXT.slice(-2),
  62 + icon: 'ant-design:delete-outlined',
  63 + auth: PermissionConvertScriptEnum.PERMISSION_DELETE,
  64 + color: 'error',
  65 + ifShow: record.status == 0,
  66 + popConfirm: {
  67 + title: '是否确认删除',
  68 + confirm: handleDeleteOrBatchDelete.bind(null, record),
  69 + },
  70 + },
  71 + ]"
  72 + />
  73 + </template>
  74 + <template #status="{ record }">
  75 + <Authority :value="PermissionConvertScriptEnum.PERMISSION_UPDATE_STATUS">
  76 + <Switch
  77 + :checked="record.status === 1"
  78 + :loading="record.pendingStatus"
  79 + checkedChildren="启用"
  80 + unCheckedChildren="禁用"
  81 + @change="(checked:boolean)=>statusChange(checked,record)"
  82 + />
  83 + </Authority>
  84 + </template>
  85 + </BasicTable>
  86 + <ConverScriptModal @register="registerModal" @success="handleSuccess" />
  87 + </div>
  88 +</template>
  89 +
  90 +<script lang="ts" setup name="index">
  91 + import { reactive, nextTick, unref } from 'vue';
  92 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  93 + import { Authority } from '/@/components/Authority';
  94 + import { useModal } from '/@/components/Modal';
  95 + import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
  96 + import { Switch, Popconfirm } from 'ant-design-vue';
  97 + import { useMessage } from '/@/hooks/web/useMessage';
  98 + import {
  99 + ScriptPage,
  100 + deleteScriptManage,
  101 + scriptPagePutApi,
  102 + } from '/@/api/scriptmanage/scriptManager';
  103 + import {
  104 + PermissionConvertScriptEnum,
  105 + searchFormSchema,
  106 + defaultTableAttribtes,
  107 + BusinessConvertScriptTextEnum,
  108 + } from './config';
  109 + import { ConverScriptModal } from './components';
  110 +
  111 + const props = defineProps<{ searchInfo: Recordable }>();
  112 +
  113 + const searchInfo = reactive<Recordable>({});
  114 +
  115 + const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({
  116 + api: ScriptPage,
  117 + ...defaultTableAttribtes,
  118 + beforeFetch: (params: Recordable) => {
  119 + return { ...unref(props.searchInfo), ...params };
  120 + },
  121 + formConfig: {
  122 + labelWidth: 120,
  123 + schemas: searchFormSchema,
  124 + fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']],
  125 + },
  126 + });
  127 +
  128 + const handleSuccess = () => {
  129 + reload();
  130 + };
  131 +
  132 + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
  133 + useBatchDelete(deleteScriptManage, handleSuccess, setProps) as any;
  134 + selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => {
  135 + if (record.status === 1) return { disabled: true };
  136 + else return { disabled: false };
  137 + };
  138 +
  139 + nextTick(() => {
  140 + setProps(selectionOptions);
  141 + });
  142 +
  143 + const [registerModal, { openModal }] = useModal();
  144 +
  145 + // 业务弹窗
  146 + const handleBusinessModal = (text, record: Recordable | null) => {
  147 + const modalParams = {
  148 + text,
  149 + record,
  150 + };
  151 + openModal(true, modalParams);
  152 + };
  153 +
  154 + const setPropsLoading = (loading) => {
  155 + setProps({
  156 + loading,
  157 + });
  158 + setSelectedRowKeys([]);
  159 + resetSelectedRowKeys();
  160 + };
  161 +
  162 + const statusChange = async (checked, record) => {
  163 + setPropsLoading(true);
  164 + const newStatus = checked ? 1 : 0;
  165 + const { createMessage } = useMessage();
  166 + try {
  167 + await scriptPagePutApi(record.id, newStatus);
  168 + if (newStatus)
  169 + return createMessage.success(BusinessConvertScriptTextEnum.BUSINESS_ENABLE_SUCCESS);
  170 + else return createMessage.success(BusinessConvertScriptTextEnum.BUSINESS_DISABLE_SUCCESS);
  171 + } finally {
  172 + setPropsLoading(false);
  173 + reload();
  174 + }
  175 + };
  176 +
  177 + defineExpose({
  178 + reload: () => {
  179 + reload();
  180 + },
  181 + });
  182 +</script>
... ...