ymy 1 vuosi sitten
vanhempi
säilyke
f42922c6da

BIN
dist.zip


+ 4 - 4
npminstall-debug.log

@@ -3,9 +3,9 @@
   registry: 'https://registry.npmmirror.com',
   pkgs: [
     {
-      name: '',
-      version: 'antv/g2',
-      type: 'git',
+      name: '@types/monaco-editor-vue',
+      version: 'latest',
+      type: 'tag',
       alias: undefined,
       arg: [Result]
     }
@@ -15,7 +15,7 @@
   cacheDir: null,
   env: {
     npm_config_registry: 'https://registry.npmmirror.com',
-    npm_config_argv: '{"remain":[],"cooked":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\Administrator\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","antv/g2","--save"],"original":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\Administrator\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","antv/g2","--save"]}',
+    npm_config_argv: '{"remain":[],"cooked":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\Administrator\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","--save-dev","@types/monaco-editor-vue"],"original":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\Administrator\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","--save-dev","@types/monaco-editor-vue"]}',
     npm_config_user_agent: 'npminstall/7.6.0 npm/? node/v18.15.0 win32 x64',
     NODE: 'D:\\nodejs\\node.exe',
     npm_node_execpath: 'D:\\nodejs\\node.exe',

+ 10 - 0
package.json

@@ -13,14 +13,21 @@
     "@riophae/vue-treeselect": "^0.4.0",
     "axios": "^1.3.5",
     "clipboard": "^2.0.11",
+    "codemirror": "^6.0.1",
+    "compression-webpack-plugin": "^10.0.0",
     "core-js": "^3.8.3",
     "echarts": "^5.4.2",
     "element-ui": "^2.15.13",
     "file-saver": "^2.0.5",
     "fuse.js": "^6.6.2",
+    "js-beautify": "^1.14.8",
     "js-cookie": "^3.0.1",
     "jsencrypt": "^3.3.2",
     "lodash": "^4.17.21",
+    "monaco-editor": "^0.39.0",
+    "monaco-editor-locales-plugin": "^0.0.3",
+    "monaco-editor-nls": "^3.1.0",
+    "monaco-editor-vue": "^1.0.10",
     "node-polyfill-webpack-plugin": "^2.0.1",
     "nprogress": "^0.2.0",
     "register-service-worker": "^1.7.2",
@@ -30,6 +37,7 @@
     "uuid": "^9.0.0",
     "vue": "^2.6.14",
     "vue-class-component": "^7.2.3",
+    "vue-codemirror": "^6.1.1",
     "vue-cropper": "^0.6.2",
     "vue-property-decorator": "^9.1.2",
     "vue-router": "^3.5.1",
@@ -49,6 +57,8 @@
     "@vue/cli-plugin-typescript": "~5.0.0",
     "@vue/cli-plugin-vuex": "~5.0.0",
     "@vue/cli-service": "~5.0.0",
+    "monaco-editor-esm-webpack-plugin": "^2.1.0",
+    "monaco-editor-webpack-plugin": "^7.0.1",
     "sass": "^1.32.7",
     "sass-loader": "^12.0.0",
     "typescript": "~4.5.5",

+ 46 - 0
src/api/printTemplate.ts

@@ -0,0 +1,46 @@
+import request from '@/benyun/utils/request'
+
+//查询
+export function query(data:any){
+	return request({
+		url: '/print/printTemplate/page',
+		method: 'GET',
+    params:data,
+    headers:{
+      'Print-User':'admin'
+    }
+	})
+}
+//新增数据
+export function add(data:any){
+  return request({
+		url: '/print/printTemplate/save',
+		method: 'POST',
+    data:data,
+    headers:{
+      'Print-User':'admin'
+    }
+	})
+}
+//修改数据
+export function update(data:any){
+  return request({
+		url: '/print/printTemplate/update',
+		method: 'POST',
+    data:data,
+    headers:{
+      'Print-User':'admin'
+    }
+	})
+}
+//删除数据
+export function del(data:any){
+  return request({
+		url: '/print/printTemplate/delete',
+		method: 'POST',
+    params:data,
+    headers:{
+      'Print-User':'admin'
+    }
+	})
+}

+ 123 - 0
src/benyun/components/byMonacoEditor/byMonacoEditor.vue

@@ -0,0 +1,123 @@
+<template>
+  <div class="monaco-editor" ref="editor">
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import VueViews from '@/benyun/compVue/VueViews';
+
+import * as monaco from "monaco-editor";
+
+@Component
+export default class ByMonacoEditor extends VueViews {
+  @Watch('propValue')
+  propValueChange(){ }
+  id:string=this.getUuid();
+  getUuid(){
+    return (((1 + Math.random()) * 0x10000000000) | 0).toString(16).substring(1);
+  }
+  editor:any=null;
+  value:any=`<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+    <title></title>
+</head>
+<body>
+	
+</body>
+</html> `
+  mounted(){
+    this.init();
+  }
+  init(){
+    this.editor = monaco.editor.create((this as any).$refs.editor, {
+      value:this.value,
+      language:'html',
+      tabSize:2,
+      foldingStrategy: 'indentation', // 代码可分小段折叠
+      acceptSuggestionOnCommitCharacter: true, // 接受关于提交字符的建议
+      acceptSuggestionOnEnter: 'on', // 接受输入建议 "on" | "off" | "smart" 
+      accessibilityPageSize: 10, // 辅助功能页面大小 Number 说明:控制编辑器中可由屏幕阅读器读出的行数。警告:这对大于默认值的数字具有性能含义。
+      accessibilitySupport: 'on', // 辅助功能支持 控制编辑器是否应在为屏幕阅读器优化的模式下运行。
+      autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
+      autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
+      autoClosingOvertype: 'always', // 是否关闭改写 即使用insert模式时是覆盖后面的文字还是不覆盖后面的文字 "always" | "never" | "auto"
+      autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
+      autoIndent: 'none', // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
+      automaticLayout: true, // 自动布局
+      codeLens: false, // 是否显示codeLens 通过 CodeLens,你可以在专注于工作的同时了解代码所发生的情况 – 而无需离开编辑器。 可以查找代码引用、代码更改、关联的 Bug、工作项、代码评审和单元测试。
+      codeLensFontFamily: '', // codeLens的字体样式
+      codeLensFontSize: 14, // codeLens的字体大小
+      colorDecorators: true, // 呈现内联色彩装饰器和颜色选择器
+      comments: {
+        ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
+        insertSpace: true // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
+      }, // 注释配置
+      contextmenu: true, // 启用上下文菜单
+      columnSelection: false, // 启用列编辑 按下shift键位然后按↑↓键位可以实现列选择 然后实现列编辑
+      autoSurround: 'never', // 是否应自动环绕选择
+      copyWithSyntaxHighlighting: true, // 是否应将语法突出显示复制到剪贴板中 即 当你复制到word中是否保持文字高亮颜色
+      cursorBlinking: 'blink', // 光标动画样式
+      cursorSmoothCaretAnimation: 'on', // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
+      cursorStyle: 'line-thin', // "Block"|"BlockOutline"|"Line"|"LineThin"|"Underline"|"UnderlineThin" 光标样式
+      cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
+      cursorSurroundingLinesStyle: 'all', // "default" | "all" 光标环绕样式
+      cursorWidth: 2, // <=25 光标宽度
+      minimap: {
+        enabled: false // 是否启用预览图
+      }, // 预览图设置
+      folding: true, // 是否启用代码折叠
+      links: true, // 是否点击链接
+      overviewRulerBorder: true, // 是否应围绕概览标尺绘制边框
+      renderLineHighlight: 'gutter', // 当前行突出显示方式
+      roundedSelection: false, // 选区是否有圆角
+      scrollBeyondLastLine: false, // 设置编辑器是否可以滚动到最后一行之后
+      readOnly: false, // 是否为只读模式
+      theme: 'hc-black'// vs, hc-black, or vs-dark
+    })
+    // 编辑器内容发生改变时触发
+    this.editor.onDidChangeModelContent(() => {
+      this.onChange();
+    })
+  }
+  clearValue(){
+    this.value = `<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+    <title></title>
+</head>
+<body>
+	
+</body>
+</html> `;
+    if(this.editor){
+      this.editor.setValue(this.value);
+    }
+  }
+  setValue(v:any){
+    this.value = v;
+    if(this.editor){
+      this.editor.setValue(this.value);
+    }
+  }
+  getValue(){
+    return this.editor.getValue()
+  }
+  onChange(){
+    this.$emit('onChange',this.getValue());
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.monaco-editor{
+  height: 500px;
+  width: 100%;
+  border: solid 1px #EEE;
+}
+</style>

+ 4 - 0
src/benyun/plugins/componentRegister.ts

@@ -55,6 +55,10 @@ const comps: Array<ComBase> = [
     name: "textChange",
     component: () => import("@/benyun/components/textChange/textChange.vue"),
   },
+  {
+    name: "byMonacoEditor",
+    component: () => import("@/benyun/components/byMonacoEditor/byMonacoEditor.vue"),
+  },
 ];
 
 const install = function (Vue: any) {

+ 0 - 1
src/benyun/utils/request.ts

@@ -34,7 +34,6 @@ service.interceptors.request.use((config:any) => {
   }
   if (getToken() && !isToken) {
     config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
-		// config.headers['tenantId'] = '000000';
   }
   // get请求映射params参数
   if ((config.method === 'get' || config.method === 'post') && config.params) {

+ 1 - 1
src/views/oms/shop/index.vue

@@ -793,7 +793,7 @@ export default class Shop extends Vue {
     }
 
     if(n == 'onSave'){
-      this.onSave();
+      (this.$refs.view as any).getFormValidate(this.onSave)
     }
   }
   //表格工具栏按钮事件

+ 362 - 0
src/views/print/printTemplate/index.vue

@@ -0,0 +1,362 @@
+<template>
+  <div class="print-template">
+    <module-view :propConfig="config" ref="view" v-loading="load" @pagination="pagination" @onRefresh="getList" @resert="queryList" @search="queryList" 
+    @modalHandle="modalHandle" @clickHandle="clickHandle" @detail="detail"/>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import {query,add,update,del} from '@/api/printTemplate'
+@Component({components:{}})
+export default class PrintTemplate extends Vue {
+  load=false;
+  isSearch=false
+  timeNum = 0;
+  config:any={
+    attr:{
+      calculateH:true
+    },
+    search:{
+      attr:{
+        size:'small'
+      },
+      columns:[
+        [{
+          span:8,
+          label:'模板名称',
+          prop:'templateName',
+          component:'by-input',
+          compConfig:{
+            attr:{
+              clearable:true
+            }
+          }
+        },{
+          span:8,
+          label:'模板引擎',
+          prop:'templateEngine',
+          component:'by-select',
+          compConfig:{
+            attr:{
+              clearable:true,
+              data:[{
+                label:'freemarker',
+                value:'freemarker'
+              },{
+                label:'thymeleaf',
+                value:'thymeleaf'
+              }]
+            }
+          }
+        }]
+      ]
+    },
+    tool:{
+      tools:{
+        search:true,
+        refresh:true,
+        add:true,
+        delete:true
+      }
+    },
+    table:{
+      attr:{
+        size:'mini',
+        seq:true
+      },
+      columns:[{
+        title:'模板名称',
+        isDetail:true,
+        field:'templateName'
+      },{
+        title:'模板引擎',
+        field:'templateEngine',
+        width:130,
+      },{
+        title:'打印次数限制',
+        field:'printLimit',
+        width:130
+      },{
+        title:'创建时间',
+        field:'createTime',
+        width:140
+      },{
+        title:'操作',
+        action:true,
+        width:100,
+        plugins:[{
+          name:'删除',
+          event:{
+            click:(item:any) => {
+              this.singleDel(item);
+            }
+          }
+        }]
+      }]
+    },
+    modal:{
+      tool:{
+        tools:{
+          return:true,
+          add:true
+        }
+      },
+      form:{
+        attr:{
+          size:'small',
+          width:'1200px',
+          rules:{
+            templateName:[
+              { required: true, message: '模版名称不能为空!', trigger: 'blur' }
+            ],
+            templateEngine:[
+              { required: true, message: '请选择模板引擎!', trigger: 'change' }
+            ],
+            templateHtml:[
+              { required: true, message: '模板内容不能为空!', trigger: 'change' }
+            ],
+            dataExample:[
+              {validator: (rule:any, value:any, callback:Function) => {
+                try {
+                  if (value && typeof (JSON.parse(value)) === 'number') {
+                    callback(new Error('输入项非JSON,请检查!'))
+                  }else{
+                    callback()
+                  }
+                } catch (e) {
+                  callback(new Error('输入项非JSON,请检查!'))
+                }
+              }, trigger: 'blur' }
+            ],
+            printLimit:[
+              {required: true, message: '打印次数限制不能为空!', trigger: 'blur'}
+            ]
+          }
+        },
+        columns:[
+          [{
+            label:'模版名称',
+            prop:'templateName',
+            component:'by-input',
+            compConfig:{
+              attr:{
+                clearable:true
+              }
+            }
+          }],
+          [{
+            label:'模板引擎',
+            prop:'templateEngine',
+            component:'by-select',
+            compConfig:{
+              attr:{
+                clearable:true,
+                data:[{
+                  label:'freemarker',
+                  value:'freemarker'
+                },{
+                  label:'thymeleaf',
+                  value:'thymeleaf'
+                }]
+              }
+            }
+          },{
+            label:'打印次数限制',
+            labelWidth:'120px',
+            prop:'printLimit',
+            component:'by-input',
+            compConfig:{
+              attr:{
+                clearable:true,
+                type:'integer'
+              }
+            }
+          }],
+          [{
+            label:'模板内容',
+            prop:'templateHtml',
+            component:'byMonacoEditor',
+          }],
+          [{
+            label:'示例数据',
+            prop:'dataExample',
+            component:'by-input',
+            compConfig:{
+              attr:{
+                defaultValue:'{}',
+                type:'textarea'
+              }
+            }
+          }]
+        ]
+      }
+    }
+  }
+  mounted(){
+    this.$nextTick(()=>{
+      this.getList()
+    })
+  }
+  singleDel(item:any){
+    let data=[item.id];
+    console.log(data);
+    this.$confirm('此操作将永久删除“'+item.templateName+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.del(data);
+    }).catch(() => {});
+  }
+  multipleDel(){
+    let data = (this.$refs.view as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择需要删除的数据!')
+      return
+    }
+    let ids:Array<any>=[];
+    let names='';
+    for(const item of data){
+      ids.push(item.id);
+      if(names){
+        names = names + ',' + item.templateName
+      }else{
+        names = item.templateName;
+      }
+    }
+    this.$confirm('此操作将永久删除“'+names+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.del(ids);
+    }).catch(() => {});
+  }
+  //删除
+  del(data:Array<any>){
+    this.load = true;
+    del({ids:data}).then(()=>{
+      this.load = false;
+      this.$message({
+        message:'删除成功!',
+        type:'success'
+      })
+      this.pagination();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //分页
+  pagination(){
+    if(this.isSearch){
+      this.queryList();
+    }else{
+      this.getList()
+    }
+  }
+  //列表请求(只有分页,不包含搜素条件)
+  getList(){
+    if(!this.$refs.view){
+      if(this.timeNum > 5){
+        return
+      }
+      setTimeout(()=>{
+        this.getList()
+      },500) 
+      this.timeNum ++;
+      return
+    }
+    this.isSearch = false;
+    let data = (this.$refs.view as any).getPage();
+    this.requestList(data);
+  }
+  //列表请求(包含分页和搜素条件)
+  queryList(){
+    this.isSearch = true;
+    let data = (this.$refs.view as any).getQuery();
+    delete data.total;
+    this.requestList(data);
+  }
+  requestList(data:any){
+    this.load = true;
+    query(data).then((res:any) => {
+      this.load = false;
+      (this.$refs.view as any).setTableValue(res.data.records);
+      let page = {
+        pageNo: res.data.current, //当前页
+        pageSize: res.data.size, //每页条数
+        total: res.data.total //总条数
+      };
+      (this.$refs.view as any).setPage(page)
+
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  modalHandle(n:string){
+    if(n == 'onAdd'){
+      (this.$refs.view as any).getFormValidate(this.onAdd)
+    }
+
+    if(n == 'onSave'){
+      (this.$refs.view as any).getFormValidate(this.onSave)
+    }
+  }
+  onAdd(){
+    let value = (this.$refs.view as any).getFormValue();
+    if(value){
+      this.load = true;
+      add(value).then((res:any)=>{
+        this.load = false;
+        this.$message({
+          message:res.msg,
+          type:'success'
+        });
+        (this.$refs.view as any).closeModal();
+        this.getList();
+      }).catch(()=>{
+        this.load = false;
+      })
+    }
+  }
+  onSave(){
+    let data = (this.$refs.view as any).getFormValue();
+    this.load = true;
+    update(data).then((res:any) => {
+      this.$message({
+        message:res.msg,
+        type:'success'
+      });
+      this.load = false;
+      (this.$refs.view as any).closeModal();
+      this.pagination();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  clickHandle(n:string){
+    if(n == 'onAdd'){
+      this.config.modal.tool.tools.add = true;
+      delete this.config.modal.tool.tools.save;
+      (this.$refs.view as any).initFormTool();
+    }
+    if(n == 'onDelete'){
+      this.multipleDel()
+    }
+  }
+  //点击详情
+  detail(){
+    this.config.modal.tool.tools.save = true;
+    delete this.config.modal.tool.tools.add;
+    (this.$refs.view as any).initFormTool();
+  }
+}
+</script>
+<style lang="scss" scoped>
+.print-template{
+  height: 100%;
+  width: 100%;
+  overflow-y: hidden;
+}
+</style>

+ 13 - 3
vue.config.js

@@ -4,11 +4,14 @@ function resolve(dir) {
   return path.join(__dirname, dir)
 }
 const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
+// const CompressionPlugin = require('compression-webpack-plugin')
 
 const name = process.env.VUE_APP_TITLE || 'SaaS协同平台' // 网页标题
 
 const port = process.env.port || process.env.npm_config_port || 80 // 端口
 
+const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
+
 module.exports = defineConfig({
   transpileDependencies: true,
   // 部署生产环境和开发环境下的URL。
@@ -56,15 +59,22 @@ module.exports = defineConfig({
         '@': resolve('src')
       }
     },
+    entry: {
+      'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js'
+    },
     plugins: [
       // new CompressionPlugin({
-      //   cache: false,                   // 不启用文件缓存
+      //   // cache: false,                   // 不启用文件缓存
       //   test: /\.(js|css|html)?$/i,     // 压缩文件格式
       //   filename: '[path].gz[query]',   // 压缩后的文件名
       //   algorithm: 'gzip',              // 使用gzip压缩
       //   minRatio: 0.8                   // 压缩率小于1才会压缩
-      // })
-      new NodePolyfillPlugin()
+      // }),
+      new NodePolyfillPlugin(),
+      new MonacoWebpackPlugin({
+        languages: ["javascript","css","html","json","java"],
+        features: ["coreCommands", "find", "format", "folding", 'smartSelect', 'snippets', 'suggest', 'hover']
+      }),
     ],
   },
   chainWebpack(config) {