Showing
5 changed files
with
407 additions
and
0 deletions
1 | +<template> | |
2 | + <div> | |
3 | + <BasicForm @register="registerForm"> | |
4 | + <template #scriptContent> | |
5 | + <Card title="脚本内容" :bodyStyle="{ padding: 0, height: '280px' }"> | |
6 | + <div ref="aceRef" class="overflow-hidden"></div> | |
7 | + </Card> | |
8 | + <Button @click="handleCopy" class="mt-4"> | |
9 | + <template #icon> | |
10 | + <CopyOutlined /> | |
11 | + </template> | |
12 | + copy | |
13 | + </Button> | |
14 | + </template> | |
15 | + </BasicForm> | |
16 | + </div> | |
17 | +</template> | |
18 | +<script setup lang="ts"> | |
19 | + import { ref, unref } from 'vue'; | |
20 | + import { formSchema } from './config.data'; | |
21 | + import { BasicForm, useForm } from '/@/components/Form'; | |
22 | + import ace from 'ace-builds'; | |
23 | + import { Card, Button } from 'ant-design-vue'; | |
24 | + import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题 | |
25 | + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式 | |
26 | + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js'; | |
27 | + import { CopyOutlined } from '@ant-design/icons-vue'; | |
28 | + import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | |
29 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
30 | + | |
31 | + defineEmits(['register']); | |
32 | + const { createMessage } = useMessage(); | |
33 | + const { clipboardRef, copiedRef } = useCopyToClipboard(); | |
34 | + const aceEditor = ref(); | |
35 | + const aceRef = ref(); | |
36 | + const [registerForm, { validate, resetFields }] = useForm({ | |
37 | + labelWidth: 120, | |
38 | + schemas: formSchema, | |
39 | + showActionButtonGroup: false, | |
40 | + }); | |
41 | + // 初始化编辑器 | |
42 | + const initEditor = (jsScript?: string) => { | |
43 | + aceEditor.value = ace.edit(aceRef.value, { | |
44 | + maxLines: 12, // 最大行数,超过会自动出现滚动条 | |
45 | + minLines: 12, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | |
46 | + fontSize: 14, // 编辑器内字体大小 | |
47 | + theme: 'ace/theme/chrome', // 默认设置的主题 | |
48 | + mode: 'ace/mode/javascript', // 默认设置的语言模式 | |
49 | + tabSize: 2, // 制表符设置为 4 个空格大小 | |
50 | + }); | |
51 | + | |
52 | + aceEditor.value.setOptions({ | |
53 | + enableBasicAutocompletion: true, | |
54 | + enableLiveAutocompletion: true, | |
55 | + }); | |
56 | + aceEditor.value.setValue( | |
57 | + jsScript ?? | |
58 | + ` | |
59 | + var trimSource =source.replaceAll(" ",""); | |
60 | + if(trimSource.length==26 && trimSource.startsWith("020308")){ | |
61 | + var str = ""; | |
62 | + for(var i = 6;i<20;i+=2){ | |
63 | + str += String.fromCharCode(parseInt(trimSource[i]+trimSource[i+1],16)); | |
64 | + }` | |
65 | + ); | |
66 | + beautify(aceEditor.value.session); | |
67 | + }; | |
68 | + const handleCopy = () => { | |
69 | + const valueRef = aceEditor.value.getValue(); | |
70 | + const value = unref(valueRef); | |
71 | + if (!value) { | |
72 | + createMessage.warning('请输入要拷贝的内容!'); | |
73 | + return; | |
74 | + } | |
75 | + clipboardRef.value = value; | |
76 | + if (unref(copiedRef)) { | |
77 | + createMessage.success('复制成功!'); | |
78 | + } | |
79 | + }; | |
80 | + const getFormData = async () => { | |
81 | + const value = await validate(); | |
82 | + if (!value) return; | |
83 | + return value; | |
84 | + }; | |
85 | + const resetFormData = () => { | |
86 | + resetFields(); | |
87 | + }; | |
88 | + | |
89 | + defineExpose({ | |
90 | + initEditor, | |
91 | + getFormData, | |
92 | + resetFormData, | |
93 | + }); | |
94 | +</script> | |
95 | +<style lang="less" scoped> | |
96 | + @import url('./ConverScriptModal.less'); | |
97 | +</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 ref="converScriptRef" /> | |
14 | + </BasicModal> | |
15 | + </div> | |
16 | +</template> | |
17 | +<script setup lang="ts"> | |
18 | + import { ref, computed, unref } from 'vue'; | |
19 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
20 | + import ConverScript from './ConverScript.vue'; | |
21 | + | |
22 | + const converScriptRef = ref<InstanceType<typeof ConverScript>>(); | |
23 | + const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本')); | |
24 | + const isUpdate = ref(false); | |
25 | + const isViewDetail = ref(''); | |
26 | + const [register, { setModalProps, closeModal }] = useModalInner(async (data) => { | |
27 | + setModalProps({ loading: true }); | |
28 | + isUpdate.value = data.isUpdate; | |
29 | + isViewDetail.value = data.isView; | |
30 | + converScriptRef.value?.initEditor(data.record?.configuration?.jsScript); | |
31 | + setModalProps({ loading: false }); | |
32 | + if (!unref(isViewDetail)) { | |
33 | + const title = !unref(isUpdate) ? '编辑转换脚本' : '新增转换脚本'; | |
34 | + setModalProps({ title, showOkBtn: true, showCancelBtn: true }); | |
35 | + if (!unref(isUpdate)) { | |
36 | + } | |
37 | + } else { | |
38 | + setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看转换脚本' }); | |
39 | + } | |
40 | + }); | |
41 | + const handleSubmit = async () => { | |
42 | + const val = await converScriptRef.value?.getFormData(); | |
43 | + console.log(val); | |
44 | + }; | |
45 | + const handleCancel = () => { | |
46 | + closeModal(); | |
47 | + converScriptRef.value?.resetFormData(); | |
48 | + }; | |
49 | +</script> | |
50 | +<style lang="less" scoped> | |
51 | + @import url('./ConverScriptModal.less'); | |
52 | +</style> | ... | ... |
1 | +import { BasicColumn, FormSchema } from '/@/components/Table'; | |
2 | +import moment from 'moment'; | |
3 | +import { h } from 'vue'; | |
4 | +import { Tag } from 'ant-design-vue'; | |
5 | + | |
6 | +// 表格配置 | |
7 | +export const columns: BasicColumn[] = [ | |
8 | + { | |
9 | + title: '脚本名称', | |
10 | + dataIndex: 'reportConfigName', | |
11 | + width: 80, | |
12 | + }, | |
13 | + { | |
14 | + title: '脚本状态', | |
15 | + dataIndex: 'organizationName', | |
16 | + width: 120, | |
17 | + customRender: ({ record }) => { | |
18 | + const status = record.organizationName; | |
19 | + const color = status == 1 ? 'green' : 'red'; | |
20 | + const text = status == 1 ? '启用' : '禁用'; | |
21 | + return h(Tag, { color: color }, () => text); | |
22 | + }, | |
23 | + }, | |
24 | + { | |
25 | + title: '脚本内容', | |
26 | + dataIndex: 'dataType', | |
27 | + width: 120, | |
28 | + slots: { customRender: 'dataType' }, | |
29 | + }, | |
30 | + { | |
31 | + title: '描述', | |
32 | + dataIndex: 'executeWay', | |
33 | + width: 120, | |
34 | + }, | |
35 | + { | |
36 | + title: '创建日期', | |
37 | + dataIndex: 'executeTime', | |
38 | + width: 180, | |
39 | + }, | |
40 | +]; | |
41 | + | |
42 | +// 查询配置 | |
43 | +export const searchFormSchema: FormSchema[] = [ | |
44 | + { | |
45 | + field: 'reportConfigName', | |
46 | + label: '脚本名称', | |
47 | + component: 'Input', | |
48 | + colProps: { span: 6 }, | |
49 | + componentProps: { | |
50 | + maxLength: 36, | |
51 | + placeholder: '请输入配置名称', | |
52 | + }, | |
53 | + }, | |
54 | + { | |
55 | + field: 'sendTime', | |
56 | + label: '创建时间', | |
57 | + component: 'RangePicker', | |
58 | + componentProps: { | |
59 | + showTime: { | |
60 | + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')], | |
61 | + }, | |
62 | + }, | |
63 | + colProps: { span: 6 }, | |
64 | + }, | |
65 | +]; | |
66 | + | |
67 | +// 新增编辑配置 | |
68 | +export const formSchema: FormSchema[] = [ | |
69 | + { | |
70 | + field: 'name', | |
71 | + label: '名称', | |
72 | + colProps: { span: 24 }, | |
73 | + required: true, | |
74 | + component: 'Input', | |
75 | + componentProps: { | |
76 | + maxLength: 255, | |
77 | + placeholder: '请输入脚本名称', | |
78 | + }, | |
79 | + }, | |
80 | + { | |
81 | + field: 'scriptContent', | |
82 | + label: '脚本内容', | |
83 | + required: true, | |
84 | + component: 'Input', | |
85 | + slot: 'scriptContent', | |
86 | + colProps: { span: 24 }, | |
87 | + }, | |
88 | + { | |
89 | + field: 'remark', | |
90 | + label: '备注', | |
91 | + colProps: { span: 24 }, | |
92 | + component: 'InputTextArea', | |
93 | + componentProps: { | |
94 | + rows: 6, | |
95 | + maxLength: 255, | |
96 | + placeholder: '请输入备注', | |
97 | + }, | |
98 | + }, | |
99 | +]; | ... | ... |
1 | +<template> | |
2 | + <div> | |
3 | + <BasicTable :clickToRowSelect="false" @register="registerTable" :searchInfo="searchInfo"> | |
4 | + <template #toolbar> | |
5 | + <Authority value=""> | |
6 | + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增转换脚本 </a-button> | |
7 | + </Authority> | |
8 | + <Authority value=""> | |
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 #dataType="{ 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: 'clarity:note-edit-line', | |
30 | + auth: '', | |
31 | + onClick: handleCreateOrEdit.bind(null, record), | |
32 | + }, | |
33 | + { | |
34 | + label: '删除', | |
35 | + icon: 'ant-design:delete-outlined', | |
36 | + auth: '', | |
37 | + color: 'error', | |
38 | + popConfirm: { | |
39 | + title: '是否确认删除', | |
40 | + confirm: handleDeleteOrBatchDelete.bind(null, record), | |
41 | + }, | |
42 | + }, | |
43 | + ]" | |
44 | + /> | |
45 | + </template> | |
46 | + </BasicTable> | |
47 | + <ConverScriptModal @register="registerModal" /> | |
48 | + </div> | |
49 | +</template> | |
50 | + | |
51 | +<script lang="ts" setup> | |
52 | + import { reactive, nextTick } from 'vue'; | |
53 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
54 | + import { searchFormSchema, columns } from './config.data'; | |
55 | + import { Authority } from '/@/components/Authority'; | |
56 | + import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | |
57 | + import { Popconfirm } from 'ant-design-vue'; | |
58 | + import { useModal } from '/@/components/Modal'; | |
59 | + import ConverScriptModal from './ConverScriptModal.vue'; | |
60 | + import { exportPage, deleteExportManage } from '/@/api/export/exportManager'; | |
61 | + | |
62 | + const searchInfo = reactive<Recordable>({}); | |
63 | + const [registerTable, { reload, setProps, setTableData }] = useTable({ | |
64 | + title: '转换脚本列表', | |
65 | + api: exportPage, | |
66 | + columns, | |
67 | + showIndexColumn: false, | |
68 | + clickToRowSelect: false, | |
69 | + formConfig: { | |
70 | + labelWidth: 120, | |
71 | + schemas: searchFormSchema, | |
72 | + fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']], | |
73 | + }, | |
74 | + useSearchForm: true, | |
75 | + showTableSetting: true, | |
76 | + bordered: true, | |
77 | + rowKey: 'id', | |
78 | + actionColumn: { | |
79 | + width: 200, | |
80 | + title: '操作', | |
81 | + dataIndex: 'action', | |
82 | + slots: { customRender: 'action' }, | |
83 | + fixed: 'right', | |
84 | + }, | |
85 | + }); | |
86 | + | |
87 | + const handleSuccess = () => { | |
88 | + reload(); | |
89 | + }; | |
90 | + | |
91 | + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete( | |
92 | + deleteExportManage, | |
93 | + handleSuccess, | |
94 | + setProps | |
95 | + ); | |
96 | + | |
97 | + nextTick(() => { | |
98 | + setProps(selectionOptions); | |
99 | + }); | |
100 | + | |
101 | + const [registerModal, { openModal }] = useModal(); | |
102 | + | |
103 | + // 新增或编辑 | |
104 | + const handleCreateOrEdit = (record: Recordable | null) => { | |
105 | + setTableData([ | |
106 | + { | |
107 | + id: 1, | |
108 | + reportConfigName: '11', | |
109 | + organizationName: 0, | |
110 | + dataType: '11', | |
111 | + executeWay: '11', | |
112 | + executeTime: '2022-05-21', | |
113 | + }, | |
114 | + { | |
115 | + id: 2, | |
116 | + reportConfigName: '11', | |
117 | + organizationName: 0, | |
118 | + dataType: '11', | |
119 | + executeWay: '11', | |
120 | + executeTime: '2022-05-21', | |
121 | + }, | |
122 | + ]); | |
123 | + if (record) { | |
124 | + openModal(true, { | |
125 | + isUpdate: false, | |
126 | + record, | |
127 | + isView: false, | |
128 | + }); | |
129 | + } else { | |
130 | + openModal(true, { | |
131 | + isUpdate: true, | |
132 | + isView: false, | |
133 | + }); | |
134 | + } | |
135 | + }; | |
136 | + const handleScriptView = (record: Recordable | null) => { | |
137 | + if (record) { | |
138 | + openModal(true, { | |
139 | + isUpdate: true, | |
140 | + record, | |
141 | + isView: true, | |
142 | + }); | |
143 | + } | |
144 | + }; | |
145 | +</script> | ... | ... |