Commit 05e35e05e9218eacde7d1c717502dcc7b5bd6ae8

Authored by fengtao
1 parent 400760d8

feat:新增脚本管理下的脚本转换

  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 +.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 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>
... ...