Showing
12 changed files
with
617 additions
and
13 deletions
... | ... | @@ -39,6 +39,7 @@ |
39 | 39 | "@logicflow/extension": "^0.6.9", |
40 | 40 | "@vueuse/core": "^5.3.0", |
41 | 41 | "@zxcvbn-ts/core": "^1.0.0-beta.0", |
42 | + "ace-builds": "^1.4.14", | |
42 | 43 | "ant-design-vue": "2.2.6", |
43 | 44 | "axios": "^0.21.1", |
44 | 45 | "codemirror": "^5.62.2", |
... | ... | @@ -60,12 +61,10 @@ |
60 | 61 | "tinymce": "^5.8.2", |
61 | 62 | "vditor": "^3.8.6", |
62 | 63 | "vue": "3.2.2", |
63 | - "vue-baidu-map": "^0.21.22", | |
64 | 64 | "vue-i18n": "9.1.7", |
65 | 65 | "vue-json-pretty": "^2.0.4", |
66 | 66 | "vue-router": "^4.0.11", |
67 | 67 | "vue-types": "^4.0.3", |
68 | - "vue3-ace-editor": "^2.2.2", | |
69 | 68 | "xlsx": "^0.17.0" |
70 | 69 | }, |
71 | 70 | "devDependencies": { | ... | ... |
src/api/device/TransformScriptApi.ts
0 → 100644
1 | +import { defHttp } from '/@/utils/http/axios'; | |
2 | +import { TTransFormScriptParams } from './model/transformScriptModel'; | |
3 | +enum TransformScriptApi { | |
4 | + TransformScript_Page = '/convert', | |
5 | + TransformScript_Delete_Edit = '/convert/js', | |
6 | + TransformScript_ENABLE_OR_DISABLED = '/convert/update/js', | |
7 | +} | |
8 | + | |
9 | +// 脚本转换分页查询 | |
10 | +export const getConvertApi = (params: TTransFormScriptParams) => { | |
11 | + return defHttp.get({ | |
12 | + url: TransformScriptApi.TransformScript_Page, | |
13 | + params: { | |
14 | + ...params, | |
15 | + nodeType: 0, | |
16 | + }, | |
17 | + }); | |
18 | +}; | |
19 | + | |
20 | +export const deleteTransformApi = (ids: string[]) => { | |
21 | + return defHttp.delete({ | |
22 | + url: TransformScriptApi.TransformScript_Delete_Edit, | |
23 | + data: { | |
24 | + ids, | |
25 | + }, | |
26 | + }); | |
27 | +}; | |
28 | +export const createOrEditTransformScriptApi = (data) => { | |
29 | + return defHttp.post({ | |
30 | + url: TransformScriptApi.TransformScript_Delete_Edit, | |
31 | + data, | |
32 | + }); | |
33 | +}; | |
34 | + | |
35 | +export const updateTransformScriptStatusApi = (status: number, id: string) => { | |
36 | + return defHttp.post({ | |
37 | + url: TransformScriptApi.TransformScript_ENABLE_OR_DISABLED, | |
38 | + data: { | |
39 | + convertIds: ['string'], | |
40 | + nodeType: 0, | |
41 | + status, | |
42 | + id, | |
43 | + }, | |
44 | + }); | |
45 | +}; | ... | ... |
src/api/device/model/transformScriptModel.ts
0 → 100644
... | ... | @@ -11,12 +11,7 @@ |
11 | 11 | :customRequest="customUpload" |
12 | 12 | :before-upload="beforeUpload" |
13 | 13 | > |
14 | - <img | |
15 | - v-if="devicePic" | |
16 | - :src="devicePic" | |
17 | - alt="avatar" | |
18 | - style="width: 6.25rem; height: 6.25rem" | |
19 | - /> | |
14 | + <img v-if="devicePic" :src="devicePic" alt="avatar" /> | |
20 | 15 | <div v-else> |
21 | 16 | <PlusOutlined /> |
22 | 17 | <div class="ant-upload-text">图片上传</div> | ... | ... |
1 | +import { BasicColumn, FormSchema } from '/@/components/Table'; | |
2 | +import { h } from 'vue'; | |
3 | +import { Tag, Switch } from 'ant-design-vue'; | |
4 | +import { useMessage } from '/@/hooks/web/useMessage'; | |
5 | +import { updateTransformScriptStatusApi } from '/@/api/device/TransformScriptApi'; | |
6 | +export const columns: BasicColumn[] = [ | |
7 | + { | |
8 | + title: '名称', | |
9 | + dataIndex: 'name', | |
10 | + width: 100, | |
11 | + }, | |
12 | + { | |
13 | + title: '用途', | |
14 | + dataIndex: 'type', | |
15 | + width: 200, | |
16 | + customRender: () => h(Tag, { color: 'blue' }, () => '消息格式化'), | |
17 | + }, | |
18 | + { | |
19 | + title: '状态', | |
20 | + dataIndex: 'status', | |
21 | + width: 120, | |
22 | + customRender: ({ record }) => { | |
23 | + if (!Reflect.has(record, 'pendingStatus')) { | |
24 | + record.pendingStatus = false; | |
25 | + } | |
26 | + return h(Switch, { | |
27 | + checked: record.status === 1, | |
28 | + checkedChildren: '已启用', | |
29 | + unCheckedChildren: '已禁用', | |
30 | + loading: record.pendingStatus, | |
31 | + onChange(checked: boolean) { | |
32 | + record.pendingStatus = true; | |
33 | + const newStatus = checked ? 1 : 0; | |
34 | + const { createMessage } = useMessage(); | |
35 | + updateTransformScriptStatusApi(newStatus, record.id) | |
36 | + .then(() => { | |
37 | + record.status = newStatus; | |
38 | + createMessage.success(`${record.status ? '启用' : '禁用'}成功`); | |
39 | + }) | |
40 | + .finally(() => { | |
41 | + record.pendingStatus = false; | |
42 | + }); | |
43 | + }, | |
44 | + }); | |
45 | + }, | |
46 | + }, | |
47 | + { | |
48 | + title: '创建时间', | |
49 | + dataIndex: 'createTime', | |
50 | + width: 180, | |
51 | + }, | |
52 | +]; | |
53 | + | |
54 | +export const searchFormSchema: FormSchema[] = [ | |
55 | + { | |
56 | + field: 'name', | |
57 | + label: '名称', | |
58 | + component: 'Input', | |
59 | + colProps: { span: 6 }, | |
60 | + componentProps: { | |
61 | + maxLength: 36, | |
62 | + placeholder: '请输入名称', | |
63 | + }, | |
64 | + }, | |
65 | + { | |
66 | + field: 'status', | |
67 | + label: '状态', | |
68 | + component: 'Select', | |
69 | + componentProps: { | |
70 | + placeholder: '请选择状态', | |
71 | + options: [ | |
72 | + { label: '已启用', value: '1' }, | |
73 | + { label: '未启用', value: '0' }, | |
74 | + ], | |
75 | + }, | |
76 | + colProps: { span: 6 }, | |
77 | + }, | |
78 | +]; | |
79 | + | |
80 | +export const formSchema: FormSchema[] = [ | |
81 | + { | |
82 | + field: 'name', | |
83 | + label: '名称', | |
84 | + required: true, | |
85 | + component: 'Input', | |
86 | + componentProps: { | |
87 | + maxLength: 36, | |
88 | + placeholder: '请输入名称', | |
89 | + }, | |
90 | + }, | |
91 | + { | |
92 | + field: 'remark', | |
93 | + label: '说明', | |
94 | + component: 'InputTextArea', | |
95 | + componentProps: { | |
96 | + maxLength: 255, | |
97 | + autoSize: { minRows: 5, maxRows: 8 }, | |
98 | + placeholder: '请输入说明', | |
99 | + }, | |
100 | + }, | |
101 | + { | |
102 | + field: 'function', | |
103 | + label: '', | |
104 | + component: 'Input', | |
105 | + slot: 'function', | |
106 | + }, | |
107 | + { | |
108 | + field: 'id', | |
109 | + label: 'id', | |
110 | + component: 'Input', | |
111 | + ifShow: false, | |
112 | + }, | |
113 | +]; | ... | ... |
1 | +<template> | |
2 | + <div> | |
3 | + <BasicDrawer | |
4 | + v-bind="$attrs" | |
5 | + :title="getTitle" | |
6 | + @register="register" | |
7 | + width="500px" | |
8 | + showFooter | |
9 | + @ok="handleSubmit" | |
10 | + > | |
11 | + <BasicForm @register="registerForm"> | |
12 | + <template #function> | |
13 | + <Card title="转换函数" :bodyStyle="{ padding: 0, height: '280px' }"> | |
14 | + <template #extra> | |
15 | + <Tag color="blue">Transform Function</Tag> | |
16 | + <a-button @click="handleFormat" size="small">格式化</a-button> | |
17 | + </template> | |
18 | + <div class="ml-8">function Transform(msg, metadata) {</div> | |
19 | + <div ref="aceRef" class="overflow-hidden"></div> | |
20 | + <div class="ml-7">}</div> | |
21 | + </Card> | |
22 | + <a-button type="primary" class="mt-4" @click="testTransformFunc">测试转换功能</a-button> | |
23 | + </template> | |
24 | + </BasicForm> | |
25 | + </BasicDrawer> | |
26 | + </div> | |
27 | +</template> | |
28 | + | |
29 | +<script lang="ts" setup> | |
30 | + import { ref, computed } from 'vue'; | |
31 | + import { useDrawerInner, BasicDrawer } from '/@/components/Drawer/index'; | |
32 | + import { useForm, BasicForm } from '/@/components/Form/index'; | |
33 | + import { formSchema } from '../config/config.data.ts'; | |
34 | + import { Card, Tag } from 'ant-design-vue'; | |
35 | + import { createOrEditTransformScriptApi } from '/@/api/device/TransformScriptApi'; | |
36 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
37 | + import ace from 'ace-builds'; | |
38 | + import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | |
39 | + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | |
40 | + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | |
41 | + const emit = defineEmits(['register', 'isStatus', 'success']); | |
42 | + const isUpdate = ref(false); | |
43 | + const aceEditor = ref(); | |
44 | + const aceRef = ref(); | |
45 | + const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | |
46 | + const [register, { closeDrawer }] = useDrawerInner((data) => { | |
47 | + resetFields(); | |
48 | + isUpdate.value = data.isUpdate; | |
49 | + initEditor(data.record?.configuration.jsScript); | |
50 | + if (isUpdate.value) { | |
51 | + setFieldsValue(data.record); | |
52 | + } | |
53 | + }); | |
54 | + const [registerForm, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
55 | + showActionButtonGroup: false, | |
56 | + colProps: { span: 24 }, | |
57 | + schemas: formSchema, | |
58 | + }); | |
59 | + | |
60 | + const initEditor = (jsScript?: string) => { | |
61 | + aceEditor.value = ace.edit(aceRef.value, { | |
62 | + maxLines: 12, // 最大行数,超过会自动出现滚动条 | |
63 | + minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | |
64 | + fontSize: 14, // 编辑器内字体大小 | |
65 | + theme: 'ace/theme/chrome', // 默认设置的主题 | |
66 | + mode: 'ace/mode/javascript', // 默认设置的语言模式 | |
67 | + tabSize: 2, // 制表符设置为 4 个空格大小 | |
68 | + }); | |
69 | + aceEditor.value.setOptions({ | |
70 | + enableBasicAutocompletion: true, | |
71 | + enableSnippets: true, | |
72 | + enableLiveAutocompletion: true, | |
73 | + }); | |
74 | + aceEditor.value.setValue(jsScript ?? 'return {msg: msg, metadata: metadata};'); | |
75 | + beautify(aceEditor.value.session); | |
76 | + }; | |
77 | + | |
78 | + const testTransformFunc = () => { | |
79 | + closeDrawer(); | |
80 | + const jsCode = aceEditor.value.getValue(); | |
81 | + emit('isStatus', { status: 1, jsCode }); | |
82 | + }; | |
83 | + const handleSubmit = async () => { | |
84 | + const fieldsValue = getFieldsValue(); | |
85 | + try { | |
86 | + await createOrEditTransformScriptApi({ | |
87 | + configuration: { | |
88 | + jsScript: aceEditor.value.getValue(), | |
89 | + }, | |
90 | + type: 'org.thingsboard.rule.engine.transform.TbTransformMsgNode', | |
91 | + ...fieldsValue, | |
92 | + }); | |
93 | + closeDrawer(); | |
94 | + emit('success'); | |
95 | + const { createMessage } = useMessage(); | |
96 | + createMessage.success('保存成功'); | |
97 | + } catch (e) { | |
98 | + const { createMessage } = useMessage(); | |
99 | + createMessage.success('保存失败'); | |
100 | + } | |
101 | + }; | |
102 | + const handleFormat = () => { | |
103 | + beautify(aceEditor.value.session); | |
104 | + }; | |
105 | + defineExpose({ aceEditor }); | |
106 | +</script> | ... | ... |
1 | +<template> | |
2 | + <div> | |
3 | + <PageWrapper title="测试脚本功能" class="pl-4 pr-4 pt-4" :contentStyle="{ display: 'none' }" /> | |
4 | + <div class="h-full flex p-4"> | |
5 | + <div class="flex flex-col w-1/2"> | |
6 | + <div class="flex-1 mr-4 mb-4"> | |
7 | + <Card title="消息" :bodyStyle="cardStyle"> | |
8 | + <template #extra> | |
9 | + <Tag color="blue">Message</Tag> | |
10 | + <a-button @click="handleFormatJson" size="small">格式化</a-button> | |
11 | + <a-button @click="handleMiniJson" size="small" class="ml-2">收起</a-button> | |
12 | + </template> | |
13 | + <div ref="jsoneditorRef" style="height: 100%"></div> | |
14 | + </Card> | |
15 | + </div> | |
16 | + <div class="flex-1 mr-4"> | |
17 | + <Card title="转换函数" :bodyStyle="cardStyle"> | |
18 | + <template #extra> | |
19 | + <Tag color="blue">Transform Function</Tag> | |
20 | + <a-button @click="handleFormatJScript" size="small">格式化</a-button> | |
21 | + | |
22 | + <Tooltip title="帮助文档" @click="openModal"> | |
23 | + <QuestionCircleOutlined class="ml-2" style="font-size: 1rem" /> | |
24 | + </Tooltip> | |
25 | + </template> | |
26 | + <div class="ml-8">function Transform(msg, metadata) {</div> | |
27 | + <div ref="aceRef" style="height: calc(100% - 44px)"></div> | |
28 | + <div class="ml-7">}</div> | |
29 | + </Card> | |
30 | + </div> | |
31 | + </div> | |
32 | + <div class="flex flex-col w-1/2"> | |
33 | + <div class="flex-1 mb-4"> | |
34 | + <Card title="元数据" :bodyStyle="cardStyle"> | |
35 | + <template #extra> | |
36 | + <Tag color="blue">Meta Data</Tag> | |
37 | + </template> | |
38 | + <Description @register="registerDesc" /> | |
39 | + </Card> | |
40 | + </div> | |
41 | + <div class="flex-1"> | |
42 | + <Card title="输出" :bodyStyle="cardStyle"> | |
43 | + <template #extra> | |
44 | + <Tag color="blue">Output</Tag> | |
45 | + <a-button @click="handleFormatOutPutJson" size="small">格式化</a-button> | |
46 | + <a-button @click="handleCompactJson" size="small" class="ml-2">收起</a-button> | |
47 | + </template> | |
48 | + <div class="ml-8 opacity-0">site</div> | |
49 | + <div ref="outputRef" style="height: calc(100% - 44px)"></div> | |
50 | + <div class="ml-7 opacity-0">site</div> | |
51 | + </Card> | |
52 | + </div> | |
53 | + </div> | |
54 | + </div> | |
55 | + <div class="flex justify-between pl-4 pr-4"> | |
56 | + <div> | |
57 | + <a-button class="" type="primary" @click="handleTestFunc"> 测试</a-button> | |
58 | + </div> | |
59 | + <div> | |
60 | + <a-button class="ml-4" @click="handleCancel"> 取消</a-button> | |
61 | + <a-button class="ml-4" type="primary" @click="handleOk"> 保存</a-button> | |
62 | + </div> | |
63 | + </div> | |
64 | + <BasicModal | |
65 | + @register="registerModal" | |
66 | + title="转换消息功能" | |
67 | + :footer="null" | |
68 | + width="800px" | |
69 | + centered | |
70 | + v-bind="$attrs" | |
71 | + > | |
72 | + <h2> function Transform(msg,metadata): {msg: object, metadata: object} </h2> | |
73 | + <li> 将输入消息、元数据转换为输出消息的 JavaScript 函数 </li> | |
74 | + <h2>参数:</h2> | |
75 | + <ul> | |
76 | + <li>msg: {[key: string]: any} - 是消息有效负载键/值对象。</li> | |
77 | + <li>metadata: {[key: string]: string} - 是消息元数据键/值映射,其中键和值都是字符串。</li> | |
78 | + </ul> | |
79 | + <h2>返回值:</h2> | |
80 | + <ul> | |
81 | + <li> { msg?: {[key: string]: any}, metadata?: {[key: string]: string} } </li> | |
82 | + <li> 结果对象中的所有字段都是可选的,如果未指定,将从原始消息中获取。 </li> | |
83 | + </ul> | |
84 | + </BasicModal> | |
85 | + </div> | |
86 | +</template> | |
87 | +<script lang="ts" setup> | |
88 | + import { ref, onMounted, defineComponent } from 'vue'; | |
89 | + import { Card, Tag, Tooltip } from 'ant-design-vue'; | |
90 | + import { PageWrapper } from '/@/components/Page'; | |
91 | + import { Description, DescItem, useDescription } from '/@/components/Description/index'; | |
92 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
93 | + import { QuestionCircleOutlined } from '@ant-design/icons-vue'; | |
94 | + import { BasicModal, useModal } from '/@/components/Modal/index'; | |
95 | + | |
96 | + import jsoneditor from 'jsoneditor'; | |
97 | + import 'jsoneditor/dist/jsoneditor.min.css'; | |
98 | + import ace from 'ace-builds'; | |
99 | + import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | |
100 | + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | |
101 | + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | |
102 | + | |
103 | + defineComponent({ | |
104 | + Tooltip, | |
105 | + }); | |
106 | + | |
107 | + const jsonValue = ref({ | |
108 | + temperature: 22.4, | |
109 | + humidity: 78, | |
110 | + }); | |
111 | + const cardStyle = { padding: 0, height: '280px' }; | |
112 | + | |
113 | + // json 以及初始化JSON | |
114 | + const jsoneditorRef = ref(); | |
115 | + const JsonEditor = ref(); | |
116 | + const outputRef = ref(); | |
117 | + const outputEditor = ref(); | |
118 | + const aceEditor = ref(); | |
119 | + const aceRef = ref(); | |
120 | + const emit = defineEmits(['isStatus']); | |
121 | + function initEditor() { | |
122 | + let options = { | |
123 | + mode: 'code', | |
124 | + mainMenuBar: false, | |
125 | + statusBar: false, | |
126 | + onError: function (err) { | |
127 | + alert('EF1 ->' + err.toString()); | |
128 | + }, | |
129 | + }; | |
130 | + let editor = new jsoneditor(jsoneditorRef.value, options); | |
131 | + editor.set(jsonValue.value); | |
132 | + JsonEditor.value = editor; | |
133 | + let outEditor = new jsoneditor(outputRef.value, options); | |
134 | + outEditor.set(true); | |
135 | + outputEditor.value = outEditor; | |
136 | + | |
137 | + aceEditor.value = ace.edit(aceRef.value, { | |
138 | + maxLines: 12, // 最大行数,超过会自动出现滚动条 | |
139 | + minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | |
140 | + fontSize: 14, // 编辑器内字体大小 | |
141 | + theme: 'ace/theme/chrome', // 默认设置的主题 | |
142 | + mode: 'ace/mode/javascript', // 默认设置的语言模式 | |
143 | + tabSize: 2, // 制表符设置为 2 个空格大小 | |
144 | + }); | |
145 | + aceEditor.value.setOptions({ | |
146 | + enableBasicAutocompletion: true, | |
147 | + enableSnippets: true, | |
148 | + enableLiveAutocompletion: true, | |
149 | + }); | |
150 | + } | |
151 | + const mataData: any = { | |
152 | + deviceName: 'Test Device', | |
153 | + deviceType: 'default', | |
154 | + ts: Date.now(), | |
155 | + }; | |
156 | + const schema: DescItem[] = [ | |
157 | + { | |
158 | + field: 'deviceName', | |
159 | + label: 'deviceName', | |
160 | + }, | |
161 | + { | |
162 | + field: 'deviceType', | |
163 | + label: 'deviceType', | |
164 | + }, | |
165 | + { | |
166 | + field: 'ts', | |
167 | + label: 'ts', | |
168 | + }, | |
169 | + ]; | |
170 | + const [registerDesc] = useDescription({ | |
171 | + column: 1, | |
172 | + data: mataData, | |
173 | + schema, | |
174 | + }); | |
175 | + // 格式化json | |
176 | + const handleFormatJson = () => { | |
177 | + JsonEditor.value.repair(); | |
178 | + JsonEditor.value.format(); | |
179 | + }; | |
180 | + // 迷你json | |
181 | + const handleMiniJson = () => { | |
182 | + JsonEditor.value.repair(); | |
183 | + JsonEditor.value.compact(); | |
184 | + }; | |
185 | + // format json | |
186 | + const handleFormatOutPutJson = () => { | |
187 | + outputEditor.value.repair(); | |
188 | + outputEditor.value.format(); | |
189 | + }; | |
190 | + // 迷你json | |
191 | + const handleCompactJson = () => { | |
192 | + outputEditor.value.repair(); | |
193 | + outputEditor.value.compact(); | |
194 | + }; | |
195 | + | |
196 | + // 测试 | |
197 | + const handleTestFunc = () => { | |
198 | + // 收集3方数据 | |
199 | + const msg = JsonEditor.value.get(); | |
200 | + const metadata = mataData; | |
201 | + const jsCode = aceEditor.value.getValue(); | |
202 | + try { | |
203 | + // 执行动态Javascript脚本 | |
204 | + let result = Function('msg', 'metadata', jsCode)(msg, metadata); | |
205 | + // 设置输出值 | |
206 | + outputEditor.value.set(result); | |
207 | + } catch (e) { | |
208 | + console.log(e); | |
209 | + const { createMessage } = useMessage(); | |
210 | + createMessage.error(e.toString()); | |
211 | + } | |
212 | + }; | |
213 | + const [registerModal, { openModal }] = useModal(); | |
214 | + const handleCancel = () => { | |
215 | + emit('isStatus', { status: 0, emitType: 'cancel' }); | |
216 | + }; | |
217 | + const handleOk = () => { | |
218 | + emit('isStatus', { status: 0, emitType: 'ok' }); | |
219 | + }; | |
220 | + const handleFormatJScript = () => { | |
221 | + beautify(aceEditor.value.session); | |
222 | + }; | |
223 | + onMounted(() => { | |
224 | + initEditor(); | |
225 | + }); | |
226 | + defineExpose({ aceEditor }); | |
227 | +</script> | ... | ... |
src/views/device/transferScript/index.vue
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <BasicTable @register="registerTable" v-show="isStatus === 0"> | |
4 | + <template #toolbar> | |
5 | + <a-button type="primary" @click="handleCreate"> 新增转换脚本 </a-button> | |
6 | + <a-button color="error" @click="handleDeleteOrBatchDelete(null)" :disabled="hasBatchDelete"> | |
7 | + 批量删除 | |
8 | + </a-button> | |
9 | + </template> | |
10 | + <template #action="{ record }"> | |
11 | + <TableAction | |
12 | + :actions="[ | |
13 | + { | |
14 | + label: '编辑', | |
15 | + icon: 'clarity:note-edit-line', | |
16 | + | |
17 | + onClick: handleEdit.bind(null, record), | |
18 | + }, | |
19 | + { | |
20 | + label: '删除', | |
21 | + icon: 'ant-design:delete-outlined', | |
22 | + ifShow: record.status == 0, | |
23 | + color: 'error', | |
24 | + popConfirm: { | |
25 | + title: '是否确认删除', | |
26 | + confirm: handleDeleteOrBatchDelete.bind(null, record), | |
27 | + }, | |
28 | + }, | |
29 | + ]" | |
30 | + /> | |
31 | + </template> | |
32 | + </BasicTable> | |
33 | + <ScriptDrawer | |
34 | + @register="registerDrawer" | |
35 | + @isStatus="handleIsStatus" | |
36 | + ref="scriptDrawerRef" | |
37 | + @success="handleSuccess" | |
38 | + /> | |
39 | + <TestScript v-show="isStatus === 1" @isStatus="handleCancelStatus" ref="testScriptRef" /> | |
40 | + </div> | |
41 | +</template> | |
42 | + | |
43 | +<script lang="ts" setup> | |
44 | + import { ref } from 'vue'; | |
45 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
46 | + import { columns, searchFormSchema } from './config/config.data.ts'; | |
47 | + import { getConvertApi, deleteTransformApi } from '/@/api/device/TransformScriptApi'; | |
48 | + import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | |
49 | + import { useDrawer } from '/@/components/Drawer/index'; | |
50 | + import ScriptDrawer from './cpns/ScriptDrawer.vue'; | |
51 | + import TestScript from './cpns/TestScript.vue'; | |
52 | + const handleSuccess = () => { | |
53 | + reload(); | |
54 | + }; | |
55 | + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete( | |
56 | + deleteTransformApi, | |
57 | + handleSuccess | |
58 | + ); | |
59 | + const [registerTable, { reload }] = useTable({ | |
60 | + api: getConvertApi, | |
61 | + title: '转换脚本列表', | |
62 | + columns, | |
63 | + useSearchForm: true, | |
64 | + showTableSetting: true, | |
65 | + bordered: true, | |
66 | + showIndexColumn: false, | |
67 | + formConfig: { | |
68 | + labelWidth: 100, | |
69 | + schemas: searchFormSchema, | |
70 | + }, | |
71 | + actionColumn: { | |
72 | + width: 180, | |
73 | + title: '操作', | |
74 | + dataIndex: 'action', | |
75 | + slots: { customRender: 'action' }, | |
76 | + fixed: 'right', | |
77 | + }, | |
78 | + ...selectionOptions, | |
79 | + }); | |
80 | + const [registerDrawer, { openDrawer }] = useDrawer({}); | |
81 | + | |
82 | + const isStatus = ref(0); | |
83 | + const testScriptRef = ref(); | |
84 | + const scriptDrawerRef = ref(); | |
85 | + const handleIsStatus = ({ status, jsCode }) => { | |
86 | + isStatus.value = status; | |
87 | + testScriptRef.value.aceEditor.setValue(jsCode); | |
88 | + }; | |
89 | + const handleCancelStatus = ({ status, emitType }) => { | |
90 | + openDrawer(true); | |
91 | + isStatus.value = status; | |
92 | + if (emitType === 'ok') { | |
93 | + const jsCode = testScriptRef.value.aceEditor.getValue(); | |
94 | + scriptDrawerRef.value.aceEditor.setValue(jsCode); | |
95 | + } | |
96 | + }; | |
97 | + const handleCreate = () => { | |
98 | + openDrawer(true, { | |
99 | + isUpdate: false, | |
100 | + }); | |
101 | + }; | |
102 | + const handleEdit = (record: Recordable) => { | |
103 | + openDrawer(true, { isUpdate: true, record }); | |
104 | + }; | |
105 | +</script> | ... | ... |
... | ... | @@ -39,12 +39,16 @@ |
39 | 39 | /> |
40 | 40 | </template> |
41 | 41 | </BasicTable> |
42 | - <NotifyManagerDrawer @register="registerAdd" @success="handleSuccess" /> | |
42 | + <NotifyManagerDrawer | |
43 | + @register="registerAdd" | |
44 | + @success="handleSuccess" | |
45 | + ref="NotifyManagerDrawerRef" | |
46 | + /> | |
43 | 47 | <tableViewChild @register="registerDrawer" /> |
44 | 48 | </div> |
45 | 49 | </template> |
46 | 50 | <script lang="ts"> |
47 | - import { defineComponent } from 'vue'; | |
51 | + import { defineComponent, ref } from 'vue'; | |
48 | 52 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
49 | 53 | import { useDrawer } from '/@/components/Drawer'; |
50 | 54 | import NotifyManagerDrawer from './useDrawer.vue'; |
... | ... | @@ -52,7 +56,6 @@ |
52 | 56 | import { columns, searchFormSchema } from './config.d'; |
53 | 57 | import { notifyGetTableApi, notifyDeleteApi } from '/@/api/stationnotification/stationnotifyApi'; |
54 | 58 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
55 | - | |
56 | 59 | export default defineComponent({ |
57 | 60 | name: 'Notificationmannager', |
58 | 61 | components: { BasicTable, NotifyManagerDrawer, TableAction, tableViewChild }, |
... | ... | @@ -65,6 +68,7 @@ |
65 | 68 | notifyDeleteApi, |
66 | 69 | handleSuccess |
67 | 70 | ); |
71 | + const NotifyManagerDrawerRef = ref(); | |
68 | 72 | const [registerTable, { reload }] = useTable({ |
69 | 73 | api: notifyGetTableApi, |
70 | 74 | columns, |
... | ... | @@ -90,6 +94,7 @@ |
90 | 94 | openDrawerAdd(true, { |
91 | 95 | isUpdate: false, |
92 | 96 | }); |
97 | + NotifyManagerDrawerRef.value.setFieldsValue({ content: '' }); | |
93 | 98 | } |
94 | 99 | |
95 | 100 | const handleView = (record: Recordable) => { |
... | ... | @@ -116,6 +121,7 @@ |
116 | 121 | handleEdit, |
117 | 122 | handleSuccess, |
118 | 123 | handleDeleteOrBatchDelete, |
124 | + NotifyManagerDrawerRef, | |
119 | 125 | }; |
120 | 126 | }, |
121 | 127 | }); | ... | ... |