luoyifan 3 年之前
父節點
當前提交
c49028222f
共有 100 個文件被更改,包括 132710 次插入5785 次删除
  1. 0 1
      .gitignore
  2. 0 72
      build/rollup.amd.js
  3. 0 44
      build/rollup.config.js
  4. 0 64
      build/rollup.iife.js
  5. 0 79
      build/rollup.ugfi.js
  6. 66 0
      dist/DataSourceHelper.d.ts
  7. 187 0
      dist/Defaults.d.ts
  8. 16 0
      dist/ExcelImportDialog.d.ts
  9. 54 0
      dist/PropertyDescription.d.ts
  10. 26 0
      dist/PropertyDescriptionTable.d.ts
  11. 118 0
      dist/Scope.d.ts
  12. 1 0
      dist/controls/MainTab.d.ts
  13. 13 0
      dist/controls/base.d.ts
  14. 1 0
      dist/controls/button.d.ts
  15. 1 0
      dist/controls/cols.d.ts
  16. 1 0
      dist/controls/component.d.ts
  17. 1 0
      dist/controls/fieldset.d.ts
  18. 1 0
      dist/controls/form.d.ts
  19. 1 0
      dist/controls/grid.d.ts
  20. 1 0
      dist/controls/gridcolumn.d.ts
  21. 1 0
      dist/controls/iframe.d.ts
  22. 1 0
      dist/controls/input/checkbox.d.ts
  23. 1 0
      dist/controls/input/checkboxgroup.d.ts
  24. 1 0
      dist/controls/input/combo.d.ts
  25. 1 0
      dist/controls/input/combogrid.d.ts
  26. 1 0
      dist/controls/input/combogridmulti.d.ts
  27. 1 0
      dist/controls/input/combotree.d.ts
  28. 1 0
      dist/controls/input/datefield.d.ts
  29. 1 0
      dist/controls/input/datetimefield.d.ts
  30. 1 0
      dist/controls/input/datetimepicker.d.ts
  31. 1 0
      dist/controls/input/numberfield.d.ts
  32. 1 0
      dist/controls/input/pickerplus.d.ts
  33. 1 0
      dist/controls/input/radio.d.ts
  34. 1 0
      dist/controls/input/radiogroup.d.ts
  35. 1 0
      dist/controls/input/search.d.ts
  36. 1 0
      dist/controls/input/textfield.d.ts
  37. 1 0
      dist/controls/panel.d.ts
  38. 1 0
      dist/controls/rows.d.ts
  39. 1 0
      dist/controls/splitter.d.ts
  40. 5 0
      dist/controls/stores.d.ts
  41. 1 0
      dist/controls/toolbar/tbfill.d.ts
  42. 1 0
      dist/controls/toolbar/tbseparator.d.ts
  43. 1 0
      dist/controls/toolbar/toolbar.d.ts
  44. 1 0
      dist/controls/yvtree.d.ts
  45. 19 0
      dist/index.d.ts
  46. 2 0
      dist/init.d.ts
  47. 58 0
      dist/lib/ajax.d.ts
  48. 79 0
      dist/lib/config.d.ts
  49. 1 0
      dist/lib/fix.d.ts
  50. 30 0
      dist/lib/lib.d.ts
  51. 255 0
      dist/lib/systemLib.d.ts
  52. 4 0
      dist/lib/systemLibEval.d.ts
  53. 11 0
      dist/message.d.ts
  54. 24 41
      src/types.ts
  55. 9 0
      dist/utils.d.ts
  56. 101 0
      dist/xlsx.d.ts
  57. 4 2
      src/wotu-ui.css
  58. 131596 0
      dist/yvan-ext.js
  59. 1 0
      dist/yvan-ext.js.map
  60. 0 6
      doc/index.md
  61. 0 0
      rollup.build.css
  62. 0 239
      src/DataSourceHelper.ts
  63. 0 218
      src/Defaults.ts
  64. 0 313
      src/ExcelImportDialog.ts
  65. 0 106
      src/PropertyDescription.ts
  66. 0 507
      src/PropertyDescriptionTable.ts
  67. 0 357
      src/Scope.ts
  68. 0 115
      src/controls/MainTab.js
  69. 0 55
      src/controls/base.ts
  70. 0 33
      src/controls/button.js
  71. 0 24
      src/controls/cols.js
  72. 0 18
      src/controls/component.js
  73. 0 37
      src/controls/fieldset.js
  74. 0 14
      src/controls/form.js
  75. 0 817
      src/controls/grid.js
  76. 0 34
      src/controls/gridcolumn.js
  77. 0 87
      src/controls/iframe.js
  78. 0 82
      src/controls/input/checkbox.js
  79. 0 44
      src/controls/input/checkboxgroup.js
  80. 0 151
      src/controls/input/combo.js
  81. 0 442
      src/controls/input/combogrid.js
  82. 0 228
      src/controls/input/combogridmulti.js
  83. 0 187
      src/controls/input/combotree.js
  84. 0 110
      src/controls/input/datefield.js
  85. 0 147
      src/controls/input/datetimefield.js
  86. 0 391
      src/controls/input/datetimepicker.js
  87. 0 44
      src/controls/input/numberfield.js
  88. 0 13
      src/controls/input/pickerplus.js
  89. 0 44
      src/controls/input/radio.js
  90. 0 44
      src/controls/input/radiogroup.js
  91. 0 142
      src/controls/input/search.js
  92. 0 106
      src/controls/input/textfield.js
  93. 0 23
      src/controls/panel.js
  94. 0 27
      src/controls/rows.js
  95. 0 14
      src/controls/splitter.js
  96. 0 205
      src/controls/stores.js
  97. 0 17
      src/controls/toolbar/tbfill.js
  98. 0 17
      src/controls/toolbar/tbseparator.js
  99. 0 24
      src/controls/toolbar/toolbar.js
  100. 0 0
      src/controls/yvtree.js

+ 0 - 1
.gitignore

@@ -1,6 +1,5 @@
 .DS_Store
 /node_modules
-/dist
 
 # local env files
 .env.local

+ 0 - 72
build/rollup.amd.js

@@ -1,72 +0,0 @@
-import { name } from '../package.json'
-import { resolve } from 'path'
-import typescript from 'rollup-plugin-typescript'
-import postcss from 'rollup-plugin-postcss';
-import simplevars from 'postcss-simple-vars';
-import nested from 'postcss-nested';
-import cssnext from 'postcss-cssnext';
-import nodeResolve from 'rollup-plugin-node-resolve'
-import commonjs from 'rollup-plugin-commonjs'
-import amd from 'rollup-plugin-amd'
-import replace from 'rollup-plugin-replace'
-import json from '@rollup/plugin-json';
-import builtins from 'rollup-plugin-node-builtins';
-
-export default {
-    // 入口文件
-    input: resolve(__dirname, '../src/index.ts'),
-    plugins: [
-        // tsx(),
-        nodeResolve({
-            browser: true
-        }),
-        postcss({
-            extensions: ['.css'],
-            // extract: true,
-            extract: 'yvan-ext.css',
-            plugins: [
-                simplevars(),
-                nested(),
-                cssnext({ warnForDuplicates: false, }),
-                // cssnano()
-            ]
-        }),
-        typescript({
-            "include": [
-                "./src/**/*.ts",
-                "./src/**/*.js"
-            ],
-            "exclude": [
-                "./dist",
-                "./node_modules"
-            ]
-        }),
-        commonjs({
-            include: 'node_modules/**',
-            namedExports: {
-                'node_modules/react-is/index.js': ['isFragment', 'ForwardRef', 'isMemo'],
-            }
-        }),
-        replace({
-            'process.env.NODE_ENV': JSON.stringify('development')
-        }),
-        // amd({
-        //     include: 'src/**', // Optional, Default: undefined (everything)
-        //     // exclude: ['node_modules/**'], // Optional, Default: undefined (nothing)
-        //     converter: {}, // Optional, Default: undefined
-        //     rewire: function (moduleId, parentPath) { // Optional, Default: false
-        //         return './basePath/' + moduleId;
-        //     }
-        // }),
-        json(),
-        builtins()
-    ],
-    output: {
-        // 打包名称
-        name: name,
-        exports: 'named',
-        sourcemap: true,
-        file: resolve(__dirname, `../dist/${name}.js`),
-        format: 'amd',
-    },
-}

+ 0 - 44
build/rollup.config.js

@@ -1,44 +0,0 @@
-import { name } from '../package.json'
-import { resolve } from 'path'
-import typescript from 'rollup-plugin-typescript2'
-import postcss from 'rollup-plugin-postcss';
-import simplevars from 'postcss-simple-vars';
-import nested from 'postcss-nested';
-import cssnext from 'postcss-cssnext';
-
-export default {
-    // 入口文件
-    input: resolve(__dirname, '../src/index.ts'),
-    plugins: [
-        // tsx(),
-        postcss({
-            extensions: ['.css'],
-            extract: true,
-            extract: 'wotu-ui.css',
-            plugins: [
-                simplevars(),
-                nested(),
-                cssnext({ warnForDuplicates: false, }),
-                // cssnano()
-            ]
-        }),
-        typescript({
-            "include": [
-                "./src/**/*.ts",
-                "./src/**/*.tsx"
-            ],
-            "exclude": [
-                "./dist",
-                "./node_modules"
-            ]
-        }),
-    ],
-    output: {
-        // 打包名称
-        name: name,
-        exports: 'named',
-        sourcemap: true,
-        file: resolve(__dirname, `../dist/${name}.js`),
-        format: 'umd',
-    },
-}

+ 0 - 64
build/rollup.iife.js

@@ -1,64 +0,0 @@
-import { name } from '../package.json'
-import { resolve } from 'path'
-import react from 'react';
-import reactDom from 'react-dom';
-import typescript from 'rollup-plugin-typescript'
-import postcss from 'rollup-plugin-postcss';
-import simplevars from 'postcss-simple-vars';
-import nested from 'postcss-nested';
-import cssnext from 'postcss-cssnext';
-import nodeResolve from 'rollup-plugin-node-resolve'
-import commonjs from 'rollup-plugin-commonjs'
-import replace from 'rollup-plugin-replace'
-import {uglify} from 'rollup-plugin-uglify'
-
-export default {
-    // 入口文件
-    input: resolve(__dirname, '../src/index.ts'),
-    plugins: [
-        // tsx(),
-        nodeResolve({
-            browser: true
-        }),
-        postcss({
-            extensions: ['.css'],
-            extract: true,
-            extract: 'wotu-ui.css',
-            plugins: [
-                simplevars(),
-                nested(),
-                cssnext({ warnForDuplicates: false, }),
-                // cssnano()
-            ]
-        }),
-        typescript({
-            "include": [
-                "./src/**/*.ts",
-                "./src/**/*.tsx"
-            ],
-            "exclude": [
-                "./dist",
-                "./node_modules"
-            ]
-        }),
-        commonjs({
-            include: 'node_modules/**',
-            namedExports: {
-                'node_modules/react-is/index.js': ['isFragment', 'ForwardRef', 'isMemo'],
-                react: Object.keys(react),
-                'react-dom': Object.keys(reactDom)
-            }
-        }),
-        replace({
-            'process.env.NODE_ENV': JSON.stringify('production')
-        }),
-        uglify()
-    ],
-    output: {
-        // 打包名称
-        name: 'WotuUI',
-        sourcemap: true,
-        file: resolve(__dirname, `../dist/WotuUI.js`),
-        format: 'iife'
-    },
-}

+ 0 - 79
build/rollup.ugfi.js

@@ -1,79 +0,0 @@
-import { name } from '../package.json'
-import { resolve } from 'path'
-import react from 'react';
-import reactDom from 'react-dom';
-import typescript from 'rollup-plugin-typescript'
-import postcss from 'rollup-plugin-postcss';
-import simplevars from 'postcss-simple-vars';
-import nested from 'postcss-nested';
-import cssnext from 'postcss-cssnext';
-import nodeResolve from 'rollup-plugin-node-resolve'
-import commonjs from 'rollup-plugin-commonjs'
-import amd from 'rollup-plugin-amd'
-import replace from 'rollup-plugin-replace'
-import json from '@rollup/plugin-json';
-import builtins from 'rollup-plugin-node-builtins';
-import {uglify} from "rollup-plugin-uglify";
-
-
-export default {
-    // 入口文件
-    input: resolve(__dirname, '../src/index.ts'),
-    plugins: [
-        // tsx(),
-        nodeResolve({
-            browser: true
-        }),
-        postcss({
-            extensions: ['.css'],
-            extract: true,
-            extract: 'wotu-ui.css',
-            plugins: [
-                simplevars(),
-                nested(),
-                cssnext({ warnForDuplicates: false, }),
-                // cssnano()
-            ]
-        }),
-        typescript({
-            "include": [
-                "./src/**/*.ts",
-                "./src/**/*.tsx"
-            ],
-            "exclude": [
-                "./dist",
-                "./node_modules"
-            ]
-        }),
-        commonjs({
-            include: 'node_modules/**',
-            namedExports: {
-                'node_modules/react-is/index.js': ['isFragment', 'ForwardRef', 'isMemo'],
-                react: Object.keys(react),
-                'react-dom': Object.keys(reactDom)
-            }
-        }),
-        replace({
-            'process.env.NODE_ENV': JSON.stringify('development')
-        }),
-        // amd({
-        //     include: 'src/**', // Optional, Default: undefined (everything)
-        //     // exclude: ['node_modules/**'], // Optional, Default: undefined (nothing)
-        //     converter: {}, // Optional, Default: undefined
-        //     rewire: function (moduleId, parentPath) { // Optional, Default: false
-        //         return './basePath/' + moduleId;
-        //     }
-        // }),
-        json(),
-        builtins(),
-        uglify()
-    ],
-    output: {
-        // 打包名称
-        name: name,
-        exports: 'named',
-        sourcemap: true,
-        file: resolve(__dirname, `../dist/${name}.js`),
-        format: 'amd',
-    },
-}

+ 66 - 0
dist/DataSourceHelper.d.ts

@@ -0,0 +1,66 @@
+/**
+ * 通用 dataSource 解析,
+ * Tree/Combo/Grid/PageList ... 都会从这里解析
+ */
+export declare function dataSourceReload(ctl: any, extraParam?: any, _successCb?: Function, successCallback?: (data: any[]) => void, failCallback?: (msg: any) => void): Promise<any>;
+export interface DataSourceParam {
+    /**
+     * 额外附加的参数
+     */
+    extraParam?: any;
+    /**
+     * 成功后额外的调用
+     */
+    _successCb?: Function;
+    /**
+     * 设置响应成功的数据
+     */
+    successCallback: (data: any[]) => void;
+    /**
+     * 设置响应失败
+     * @param msg 错误消息(可以为空)
+     */
+    failCallback: (msg?: string) => void;
+}
+export interface DataSourceBefore extends DataSourceParam {
+    /**
+     * 取消下一步的请求
+     */
+    cancel: () => void;
+}
+/**
+ * 方法作为数据源
+ */
+export declare type DataSourceFunction<T> = (sender: T, option: DataSourceParam) => void;
+/**
+ * Ajax 数据源
+ */
+export interface DataSourceAjax<T> {
+    url: string;
+    method: string;
+    params?: {
+        [key: string]: (() => any) | any;
+    };
+}
+/**
+ * Sql 数据源
+ */
+export interface DataSourceSql<T> {
+    sqlId: string;
+    db: string;
+    params?: {
+        [key: string]: (() => any) | any;
+    };
+}
+/**
+ * 数据源配置
+ */
+export declare type DataSourceHelper<T> = DataSourceFunction<T> | DataSourceAjax<T> | DataSourceSql<T>;
+/**
+ * 数据抽取之前的设置
+ */
+export declare type OnBeforeDataLoad<T> = (sender: T, option: DataSourceBefore) => void;
+/**
+ * 数据加载完成之后的回调
+ */
+export declare type OnDataLoadComplete<T> = (sender: T) => void;

+ 187 - 0
dist/Defaults.d.ts

@@ -0,0 +1,187 @@
+export declare const windows: {
+    modal: boolean;
+    width: number;
+    height: number;
+    maximizable: boolean;
+    constrain: boolean;
+    shadow: boolean;
+};
+export declare const date: {
+    labelAlign: string;
+    labelWidth: number;
+};
+export declare const combo: {
+    labelAlign: string;
+    labelWidth: number;
+    valueField: string;
+    displayField: string;
+    autoLoad: boolean;
+    mode: string;
+    forceSelection: boolean;
+    triggerAction: string;
+    enableKeyEvents: boolean;
+};
+export declare const comboGrid: {
+    selectOnTab: boolean;
+    pickerHeight: number;
+    pickerWidth: number;
+    editEnable: any;
+};
+export declare const comboGridPicker: {
+    xtype: string;
+    layout: string;
+    selModel: {
+        selType: string;
+        mode: string;
+    };
+};
+export declare const comboGridMulti: {
+    selectOnTab: boolean;
+    pickerHeight: number;
+    pickerWidth: number;
+    editEnable: any;
+    splitChar: string;
+    displayField: string;
+    valueField: string;
+    autoLoad: boolean;
+};
+export declare const comboGridMultiPicker: {
+    selType: string;
+    selModel: {
+        type: string;
+        checkOnly: boolean;
+    };
+};
+export declare const numberfield: {
+    labelAlign: string;
+    labelWidth: number;
+};
+export declare const checkbox: {
+    labelAlign: string;
+    labelWidth: number;
+    checkedValue: boolean;
+    uncheckedValue: boolean;
+};
+export declare const checkboxgroup: {
+    labelAlign: string;
+    labelWidth: number;
+};
+export declare const radio: {
+    labelAlign: string;
+    labelWidth: number;
+};
+export declare const radiogroup: {
+    labelAlign: string;
+    labelWidth: number;
+    simpleValue: boolean;
+    layout: string;
+    defaults: {
+        xtype: string;
+        name: string;
+        margin: string;
+    };
+};
+export declare const form: {
+    margin: string;
+    border: boolean;
+    defaults: {
+        margin: string;
+        border: boolean;
+    };
+};
+export declare const column: {
+    filter: {
+        type: string;
+    };
+};
+export declare const grid: {
+    border: boolean;
+    columnLines: boolean;
+    rowLines: boolean;
+    plugins: {
+        cellediting: {
+            clicksToEdit: number;
+        };
+        gridfilters: boolean;
+    };
+    multiColumnSort: boolean;
+    viewConfig: {
+        enableTextSelection: boolean;
+        sortOnClick: boolean;
+    };
+    selModel: {
+        type: string;
+        checkOnly: boolean;
+    };
+    pagination: boolean;
+    pageSize: number;
+    pageSizeOption: string[];
+    hideFootbar: boolean;
+    hideRefresh: boolean;
+    hideExport: boolean;
+    hideAutoSize: boolean;
+    hideClearFilter: boolean;
+    hideSaveGridUIConfig: boolean;
+    hideClearGridUIConfig: boolean;
+    autoLoad: boolean;
+    remoteSort: boolean;
+    remoteFilter: boolean;
+    enableLocking: boolean;
+    syncRowHeight: boolean;
+    enableColumnMove: boolean;
+    enableColumnHide: boolean;
+    enableColumnResize: boolean;
+    hidden: boolean;
+    disabled: boolean;
+    exportExcelPageSize: number;
+    exportExcelCurrentPage: number;
+    exportExcelTotal: number;
+};
+export declare const fieldContainer: {
+    labelAlign: string;
+    labelWidth: number;
+    layout: string;
+    defaults: {
+        flex: number;
+    };
+};
+export declare const tree: {
+    autoLoad: boolean;
+    hideFilter: boolean;
+    hideToolbar: boolean;
+    hideRefresh: boolean;
+    hideExpand: boolean;
+    hideCollapse: boolean;
+};
+export declare const search: {
+    labelAlign: string;
+    labelWidth: number;
+};
+export declare const text: {
+    labelAlign: string;
+    labelWidth: number;
+    msgTarget: string;
+};
+export declare const toolbar: {
+    overflowHandler: string;
+};
+export declare const tbfill: {};
+export declare const tbseparator: {};
+export declare const button: {};
+export declare const fieldSet: {
+    margin: string;
+    border: boolean;
+    defaults: {
+        margin: string;
+        border: boolean;
+    };
+};
+export declare const panel: {};
+export declare const splitter: {};
+export declare const maintab: {};
+export declare const rows: {};
+export declare const cols: {
+    defaults: {
+        flex: number;
+    };
+};

+ 16 - 0
dist/ExcelImportDialog.d.ts

@@ -0,0 +1,16 @@
+import { Scope } from "./Scope";
+import { ImportExcelOption, ImportResult } from "./xlsx";
+export declare class ExcelImportDialog extends Scope {
+    constructor(option: ImportExcelOption);
+    onLoad(): void;
+    fileChange(sender: any): void;
+    getDataGridRowRecord(record: any, rowIndex: any, rowParams: any, store: any): string;
+    getErrGridRowRecord(record: any, rowIndex: any, rowParams: any, store: any): string;
+    dataGridClick(sender: any, td: any, cellIndex: any, record: any, item: any, index: any, e: any, eOpts: any): void;
+    errGridClick(sender: any, record: any, item: any, index: any, e: any, eOpts: any): void;
+    filterData(sender: any, newValue: any, oldValue: any, eOpts: any): void;
+    downloadTemplate(sender: any): void;
+    getData(sender: any): void;
+    importData: ImportResult;
+    importExcelOption: ImportExcelOption;
+}

+ 54 - 0
dist/PropertyDescription.d.ts

@@ -0,0 +1,54 @@
+export declare type GroupType = 'css' | 'data' | 'bind' | 'common' | 'event';
+export interface PropertyValue {
+    /**
+     * 属性名
+     */
+    name: string;
+    /**
+     * 默认值
+     */
+    default: any;
+    /**
+     * 隶属分组
+     */
+    group: GroupType;
+    /**
+     * 描述
+     */
+    desc: string;
+    /**
+     * 取值范围
+     */
+    type: 'boolean' | 'number' | 'string' | 'object' | 'dataSource' | 'valid' | 'format' | Array<string> | 'widget';
+    eventParamter?: string[];
+    eventResult?: string;
+    eventDoc?: (vjson: any) => string;
+    expr?: boolean;
+}
+export interface EventValue {
+    /**
+     * 属性名
+     */
+    name: string;
+    /**
+     * 描述
+     */
+    desc: string;
+}
+export interface PropertyDescriptionInterface {
+    props: PropertyValue[];
+    events?: EventValue[];
+}
+export declare class PropertyDescription {
+    propertyes: PropertyDescriptionInterface;
+    constructor(...args: PropertyDescriptionInterface[]);
+    merge(pd: PropertyDescriptionInterface): void;
+    /**
+     * 根据分组名 获取属性定义
+     */
+    getPropsByGroup(name: GroupType): PropertyValue[];
+    /**
+     * 获取全部事件
+     */
+    getEvents(): EventValue[];
+}

+ 26 - 0
dist/PropertyDescriptionTable.d.ts

@@ -0,0 +1,26 @@
+import { PropertyDescription, PropertyDescriptionInterface, PropertyValue } from './PropertyDescription';
+export declare const PropertyDescriptionTable: Map<String, PropertyDescription>;
+export declare const width: PropertyValue;
+export declare const height: PropertyValue;
+export declare const fieldLabel: PropertyValue;
+export declare const text: PropertyValue;
+export declare const iconCls: PropertyValue;
+export declare const borderless: PropertyValue;
+export declare const labelAlign: PropertyValue;
+export declare const type: PropertyValue;
+export declare const labelWidth: PropertyValue;
+export declare const gravity: PropertyValue;
+export declare const hidden: PropertyValue;
+export declare const readonly: PropertyValue;
+export declare const disabled: PropertyValue;
+export declare const loading: PropertyValue;
+export declare const required: PropertyValue;
+export declare const value: PropertyValue;
+export declare const prompt: PropertyValue;
+export declare const validType: PropertyValue;
+export declare const metaId: PropertyValue;
+export declare const template: PropertyValue;
+export declare const tooltip: PropertyValue;
+export declare const onClick: PropertyValue;
+export declare const YvBase: PropertyDescriptionInterface;
+export declare const YvDataSource: PropertyDescriptionInterface;

+ 118 - 0
dist/Scope.d.ts

@@ -0,0 +1,118 @@
+export declare class Scope {
+    /**
+     * 业务模块的唯一编号
+     */
+    id: string;
+    originalVjson: any;
+    /**
+     * 一个 ExtJS 能接受的配置对象
+     */
+    vjson: any;
+    /**
+     * 原始 vjsonModel 对象
+     */
+    model: any;
+    /**
+     * 双向绑定的模型对象
+     */
+    viewModel: any;
+    /**
+     * 构建完成之后的 Ext控件句柄
+     */
+    _handle: any;
+    /**
+     * 与 watch 装饰器配合使用.
+     * viewModel 属性更改时触发成员方法
+     */
+    _watchList: any;
+    /**
+     * 页面显示的时候带的参数 在设计刷新的时候使用
+     */
+    _vjsonOption: any;
+    _dataOption: any;
+    /**
+     * 最顶部的 scope 对象
+     */
+    topScope: any;
+    _addWatch(tplExpress: any, fn: any): void;
+    _applyWatchList(): void;
+    get isScope(): boolean;
+    /**
+     * 产生一个当前模块有效的唯一id
+     * @param key 唯一编号
+     */
+    uid(key: any): string;
+    /**
+     * 对话框"保存"成功.
+     * 关闭对话框,并响应 success 方法
+     * @param data 要傳回的數據(可以為空)
+     */
+    dialogSuccess(data?: any): void;
+    /**
+     * 设置等待状态
+     * @param value
+     * @param msg
+     */
+    setLoading(value: boolean): void;
+    /**
+     * 以对话框模式打开当前模块
+     * @param sender 发送者(按钮或Scope对象)
+     * @param vjsonOption 界面覆盖选项(可以为空)
+     * @param dataOption 数据覆盖选项(可以为空)
+     */
+    showDialog(sender: any, vjsonOption: any, dataOption: any): void;
+    /**
+     * 以标签模式打开当前模块
+     * @param vjsonOption 界面覆盖选项(可以为空)
+     * @param dataOption 数据覆盖选项(可以为空)
+     */
+    showPage(vjsonOption: any, dataOption: any): any;
+    /**
+     * 直接渲染到元素
+     * @param element 渲染目标
+     * @param vjsonOption 界面覆盖选项(可以为空)
+     * @param dataOption 数据覆盖选项(可以为空)
+     */
+    renderTo(element: any, vjsonOption: any, dataOption: any): void;
+    /**
+     * 关闭对话框(或标签页)
+     */
+    close(): void;
+    /**
+     * 获取 viewModel 里包含的数据(只读)
+     */
+    get data(): any;
+    /**
+     * 设置 viewModel 中的数据
+     * 可以是 key, value 模式
+     * 也可以是 {key:value} 模式
+     */
+    set(path: any, value: any): any;
+    /**
+     * 寻找模块内所有的 xtype 对应的对象
+     * @param xtypeKey
+     */
+    down(xtypeKey: any): any;
+    /**
+     * 获取所有设置过 Reference 名称的组件
+     */
+    get refs(): any;
+    _destroy(): void;
+    constructor({ model, vjson }: {
+        model: any;
+        vjson: any;
+    });
+    /**
+     * 模块载入完成之后的回调
+     */
+    onLoad(): void;
+    /**
+     * 组件卸载之后的回调
+     */
+    onDestroy(): void;
+}
+/**
+ * 观察装饰器,viewModel 属性更改时触发成员方法
+ * @param tplExpress tpl表达式,例如 "{form.f1}"
+ */
+export declare function watch(tplExpress: any, deep?: boolean): (target: any, propertyKey: any, pd: any) => any;

+ 1 - 0
dist/controls/MainTab.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 13 - 0
dist/controls/base.d.ts

@@ -0,0 +1,13 @@
+declare type DragType = 'rows-container' | 'cols-container' | 'col-item' | 'row-item';
+/**
+ * 构建所有组件的公共属性
+ * @param config 原始config
+ * @param dragType 组件模式
+ *      不填,代表不能在设计时被拖拽
+ *      row-container 是一个rows容器
+ *      col-container 是一个cols容器
+ *      col-item cols中的一个格子(非容器),比如 textfield / combofield 等等
+ *      row-item rows中的一行,比如 tree / grid / panel 等等
+ */
+export declare function baseConfig(config: any, dragType?: DragType): any;
+export {};

+ 1 - 0
dist/controls/button.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/cols.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/component.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/fieldset.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/form.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/grid.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/gridcolumn.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/iframe.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/checkbox.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/checkboxgroup.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/combo.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/combogrid.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/combogridmulti.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/combotree.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/datefield.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/datetimefield.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/datetimepicker.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/numberfield.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/pickerplus.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/radio.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/radiogroup.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/search.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/input/textfield.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/panel.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/rows.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/splitter.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 5 - 0
dist/controls/stores.d.ts

@@ -0,0 +1,5 @@
+/**
+ * 构建一个 grid 支持的 dataSource
+ */
+export function gridInvokeBuild(scope: any, grid: any, config: any, dataSource: any, reloadParams?: {}, isExcelExport?: boolean, excelExportCallBack?: any): void;
+export default function _default(): void;

+ 1 - 0
dist/controls/toolbar/tbfill.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/toolbar/tbseparator.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/toolbar/toolbar.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 1 - 0
dist/controls/yvtree.d.ts

@@ -0,0 +1 @@
+export default function _default(): void;

+ 19 - 0
dist/index.d.ts

@@ -0,0 +1,19 @@
+import * as Defaults from './Defaults';
+import * as axios from 'axios';
+import qs from 'qs';
+import lodash from 'lodash';
+import jquery from 'jquery';
+import json5 from 'json5';
+import moment from 'moment';
+import './wotu-ui.css';
+import { PropertyDescriptionTable } from './PropertyDescriptionTable';
+import * as recast from 'recast';
+import { msgError } from './message';
+export { axios, qs, lodash, jquery, json5, moment, Defaults, PropertyDescriptionTable, recast, msgError, };
+export * from './Scope';
+export * from './init';
+export * from './lib/ajax';
+export * from './lib/lib';
+export * from './lib/config';
+export * from './lib/systemLib';
+export * from './ExcelImportDialog';

+ 2 - 0
dist/init.d.ts

@@ -0,0 +1,2 @@
+import './lib/fix';
+export declare function init(): void;

+ 58 - 0
dist/lib/ajax.d.ts

@@ -0,0 +1,58 @@
+import { PlainObject } from "../types";
+export declare type ApiMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'download' | 'post-json' | 'post-file' | 'invoke' | 'sql' | string;
+export declare type ApiDataType = 'json' | 'form-data' | 'form';
+export interface ApiObject {
+    url: string;
+    param: PlainObject;
+    method: ApiMethod;
+    data?: object;
+    args: any[];
+    db?: string;
+    headers?: PlainObject;
+    filterModel?: {
+        [key: string]: any;
+    };
+    sortModel?: {
+        colId: string | undefined;
+        sort: string | null | undefined;
+    }[];
+    config?: {
+        withCredentials?: boolean;
+        cancelExecutor?: (cancel: Function) => void;
+    };
+    dataType?: ApiDataType;
+    /**
+     * 下载文件名
+     */
+    fileName?: string;
+    /**
+     * 上传文件(如果需要的话)
+     */
+    file?: any;
+}
+export declare type ApiFunction = (api: ApiObject) => Promise<ApiResult>;
+/**
+ * 组件中 Api 的声明
+ */
+export declare type Api = ApiFunction | ApiObject;
+export interface ApiResult {
+    rawData: object;
+    status: number;
+    headers: object;
+    data?: any;
+    pagination?: any;
+    success: boolean;
+    msg: string;
+    errors?: {
+        [propName: string]: string;
+    };
+}
+export interface CreateAjaxOption {
+    baseUrl: string;
+    timeout: number;
+}
+/**
+ * 创建一个 Ajax 客户端
+ */
+export declare function createAjax(createOption: CreateAjaxOption): ApiFunction;
+export declare function downLoad(downLoadUrl: string, filename: string, data: any, header: any, isJson?: boolean): void;

+ 79 - 0
dist/lib/config.d.ts

@@ -0,0 +1,79 @@
+import { ConfigProcess } from "../types";
+import { ApiFunction } from "./ajax";
+export declare type ServerInvokeUrlTransformFunction = (jsUrl: string, option?: any) => string | undefined;
+export declare type SqlUrlTransformFunction = (jsUrl: string, option?: any) => string | undefined;
+export interface ApiConvert {
+    /**
+     * 从表格 dataSource 属性,转换为 ExtJS.storeOption 属性
+     */
+    gridInvokeBuild: (scope: any, grid: any, config: any, dataSource: any, params: any, reloadParams: any) => object;
+}
+/**
+ * YvanUI 全局扩展配置
+ */
+export interface ConfigOption {
+    /**
+     * 是否在设计器模式
+     */
+    designMode: boolean;
+    /**
+     * 扩展自定义的 ajax 方法
+     */
+    ajax: ApiFunction;
+    /**
+     * 扩展自定义的后端请求方法
+     */
+    apiConvert: ApiConvert;
+    /**
+     * serverJS Url转换为Ajax请求
+     */
+    serverInvokeUrlTransform: ServerInvokeUrlTransformFunction;
+    /**
+     * Sql Url转换为Ajax请求
+     */
+    sqlUrlTransform: SqlUrlTransformFunction;
+    /**
+     * 获取拼音首字母的函数
+     */
+    pinyinFunction: (py: string) => string;
+    /**
+     * Scope onload 时扩展方法
+     */
+    scopeOnLoad: (scope: any) => void;
+}
+/**
+ * 全局 ajax 方法
+ */
+export declare const ajax: {
+    func?: ApiFunction;
+};
+export declare let scopeOnLoad: (scope: any) => void;
+export declare let apiConvert: ApiConvert;
+export declare const baseConfigProcessList: ConfigProcess[];
+/**
+ * 在基类添加 Config 的处理方法
+ */
+export declare function baseConfigProcess(option?: any): (target: any, propertyKey: any) => void;
+export declare function isDesignMode(): boolean;
+export declare function setDesignMode(v: boolean): void;
+/**
+ * 将业务定义的 url 转换为调用服务端 groovy 的 url
+ */
+export declare function serverInvokeUrlTransform(url: string, option?: any): string;
+/**
+ * 将业务定义的 url 转换为调用服务端 sql 的 Url
+ */
+export declare function sqlUrlTransform(url: string): string;
+/**
+ * YvanUI 全局扩展配置
+ */
+export declare function extend(option: Partial<ConfigOption>): void;
+export declare function getApiConvert(): ApiConvert;
+export declare function getPinyin(v: string): any;
+/**
+ * 适用于 Select / Tree 等,作筛选的通用方法.
+ * 1.首字母模糊匹配(不区分大小写)
+ * 2.标识的模糊匹配(不区分大小写)
+ * 3.名称的模糊匹配,且支持以逗号(全角或半角)隔开的字词匹配,并自动去空格,如“南京, 物流 ”可以匹配出“南京九州通物流技术开发有限公司”
+ */
+export declare function keywordFilter(keyword: string, label: string, value?: string): boolean;

+ 1 - 0
dist/lib/fix.d.ts

@@ -0,0 +1 @@
+export {};

+ 30 - 0
dist/lib/lib.d.ts

@@ -0,0 +1,30 @@
+import { FunctionRegiste, LibParamType } from "../types";
+import { Scope } from "../Scope";
+export declare function getRegList(): FunctionRegiste[];
+export declare function getRegParamList(methodName: string): any;
+/**
+ * 模拟点击按钮
+ */
+export declare function raiseClick(buttonHandle: any): boolean;
+/**
+ * 标注系统全局函数的参数
+ * @param title 函数名称
+ * @param type 函数类型
+ * @param allowEmpty 可否为空
+ */
+export declare function LibParam(title: string, type: LibParamType, allowEmpty?: boolean): (target: any, methodName: any, paramsIndex: any) => void;
+/**
+ * 标注函数变成"系统全局函数"
+ */
+export declare function Lib(registe: FunctionRegiste): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => any;
+/**
+ * 解析事件
+ *   'scope.私有方法名'
+ *   'system.系统函数名'
+ *   'format.格式化名'
+ */
+export declare function lookupFn(scope: Scope, event: string, errorWho?: any): Function;
+/**
+ * 从 ext.element 获取 scope 对象
+ */
+export declare function lookupScope(extHandle: any): Scope;

+ 255 - 0
dist/lib/systemLib.d.ts

@@ -0,0 +1,255 @@
+export declare const SIMPLE_RE: RegExp;
+/**
+ * 对某个表达式进行求值
+ * a:{query.a},b:{query.b} -> a:aValue,b:bValue
+ *
+ * @example
+ * calcExpress(cc.viewModel.data, "WH_ID:{query.WH_ID},C:{theGrid.selection.data.WH_ID}")
+ * 计算出来的值是: "WH_ID:queryWhId,C:JH000000001"
+ *
+ * @param data 数据环境对象
+ * @param express 表达式对象
+ */
+export declare function calcExpress(data: any, express: any): any;
+/**
+ * 对个对象进行表达式求值,不用回调
+ * @example
+ * calcObjectFlat({query:{a:'aValue',b1:'b1Value',b2:'b2Value',d1:1,d2:2}}, { a:'{query.a}', b:{b1:'{query.b1}', b2:'{query.b2}'},c:'aa',d:['{query.d1}','{query.d2}'] })
+ *
+ * {
+ *     a: '{query.a}',
+ *     b: {
+ *         b1: '{query.b1}',
+ *         b2: '{query.b2}',
+ *     },
+ *     c: 'aa',
+ *     d: [
+ *         '{query.d1}',
+ *         '{query.d2}'
+ *     ]
+ * }
+ *
+ * 计算结果为
+ * {
+ *     a: 'aValue',
+ *     b: {
+ *         b1: 'b1Value',
+ *         b2: 'b2Value'
+ *     },
+ *     c: 'aa'
+ *     d: [
+ *         '1',
+ *         '2'
+ *     ]
+ * }
+ *
+ * @param data
+ * @param paramObject
+ */
+export declare function calcObjectFlat(data: any, paramObject: any): any;
+/**
+ * 合併 data 到當前的 ViewModel 對象
+ */
+export declare function mergeViewModel(viewModel: any, propertyName: any, data: any): void;
+/**
+ * 转换内联结构的行,到平面结构
+ * company: { name:'公司1', id:'编号1' } => { company_id:'编号1', company_name:'公司1' }
+ *
+ * @param array
+ * @param flatOption
+ * @return {[]}
+ */
+export declare function flatRow(array: any): any[];
+/**
+ * 根据表达式进入写值
+ * express="{query.a}"   写值就是 viewModel.set('query.a', value)
+ * express="test-{query.a}"   写值就会失败
+ *
+ * @example
+ * tryWriteByExpress(cc.viewModel, "{query.WH_ID}", "111")
+ * 写值成功
+ *
+ * tryWriteByExpress(cc.viewModel, "test-{query.WH_ID}", "111")
+ * 写值失败
+ *
+ * @param viewModel VM对象
+ * @param express 表达式对象
+ * @param value 目标值
+ */
+export declare function tryWriteByExpress(viewModel: any, express: any, value: any): void;
+/**
+ * 尝试根据含表达式的对象回写, calcObjectFlat 的逆向方法
+ * @example
+ * tryWriteObject({ a:'{query.a}', b:{b1:'{query.b1}', b2:'{query.b2}'},c:'aa',d:['{query.d1}','{query.d2}']}, {a:'aValue', b:{b1:'b1Value', b2:'b2Value'}, c:'aa', d:[1,2]})
+ *
+ * expressObject:
+ * {
+ *     a: '{query.a}',
+ *     b: {
+ *         b1: '{query.b1}',
+ *         b2: '{query.b2}',
+ *     },
+ *     c: 'aa',
+ *     d: [
+ *         '{query.a}',
+ *         '{query.b2}'
+ *     ]
+ * }
+ *
+ * valueObject:
+ * {
+ *     a: 'aValue',
+ *     b: {
+ *         b1: 'b1Value',
+ *         b2: 'b2Value'
+ *     },
+ *     c: 'aa'
+ *     c: [
+ *         'aValue',
+ *         'b2Value'
+ *     ]
+ * }
+ *
+ * 系统会尝试回写
+ * viewModel.set('query.a', 'aValue')
+ * viewModel.set('query.b1', 'b1Value')
+ * viewModel.set('query.b2', 'b2Value')
+ *
+ * @param expressObject 含表达式的对象
+ * @param valueObject 表达式计算完成之后的结果对象
+ * @param writeFn 写入的方法 (path, value)=>void
+ */
+export declare function tryWriteObject(expressObject: any, valueObject: any, writeFn: any): void;
+/**
+ * 尝试去掉变量两边括号
+ * {a} => a
+ * a => a
+ */
+export declare function tryVarSimple(value: any): any;
+/**
+ * 对多个表达式进行求值. 异步回调的方式返回
+ *      {
+ *          a: 1,
+ *          b: '{someBind}',
+ *          c: ['a', 'b', 'c'],
+ *          d: ['a', 'b', '{someBind}'],
+ *          e: {
+ *              y: 1,
+ *              z: 2
+ *          },
+ *          f: {
+ *              y: 1,
+ *              z: '{someBind}'
+ *          }
+ *      }
+ *
+ *      // Will produce
+ *      {
+ *          b: value,
+ *          d: ['a', 'b', value],
+ *          f: {
+ *              y: 1,
+ *              z: value
+ *          }
+ *      }
+ * @param viewModel scope.viewModel对象
+ * @param paramObject 求值对象
+ */
+export declare function calcObject(viewModel: any, paramObject: any): Promise<unknown>;
+/**
+ * 用于任意组件 Ext.Component 构造时,获取当前组件对应的表格(如果不是 grid.columns 对象就会返回 undefined)
+ * @param config 组件构造函数传入的 config 配置文件
+ */
+export declare function getParentGrid(config: any): any;
+/**
+ * 解析
+ * {
+ *     condition: "{skuId}",
+ *     errorMsg: "无法编辑",
+ *     notice: 'msg'
+ * }
+ */
+export declare function tryEnable(data: any, enableSetting: any): boolean;
+/**
+ * 动态的为 combo 或 columns.combo 设置下拉框的值
+ * @param sender 目标对象
+ * @param config 目标对象的配置(在构造函数之前也可以)
+ * @param getDictFn 获取字典的方法
+ * @param bizKey 传入字典的参数
+ * @param multiValueSeparator 多个字典值的分割符号
+ */
+export declare function setComboStore(sender: any, config: any, getDictFn: any, bizKey: any, multiValueSeparator?: string): Promise<unknown>;
+/**
+ * 调用服务器 Ajax
+ */
+export declare function invokeServer(url: string, ...args: any[]): any;
+export declare function clearViewModelValues(viewModel: any, propertyName: any): void;
+export declare function reloadGrid(scope: any, gridRefName: any): void;
+/**
+ * 将 Ext.data.Model 对象 (及子属性) 转换为 js.object 对象
+ */
+export declare function toPlainObject(obj: any): any;
+export declare function confirm(msg: any, sender?: any): Promise<void>;
+/**
+ * 任何符号字符串都替换成下换线
+ */
+export declare function normId(value: string): string;
+/**
+ *
+ * @param sender
+ * @param propertyName
+ * @param gridRefName
+ */
+export declare function clearViewModelReloadGrid(sender: any, propertyName: any, gridRefName: any): void;
+export declare class SystemEventFu {
+    confirm(text: any, fn: any): (sender: any) => void;
+    gridRemoveCurrentRow(gridRefName: any): (sender: any) => void;
+    loadForm(invokeUrl: string, invokeParam: any, writeTarget: any): (sender: any) => void;
+    commit(groovyUrl: string, arg0: any, successCallback: any): (sender: any) => void;
+    formCommit(groovyUrl: string, arg0: any): (sender: any) => void;
+    dialogSuccess(lookupObject: any): (sender: any) => void;
+    clearViewModelValues(propertyName: string): (sender: any) => void;
+    getGrid(url: any): (sender: any, config: any) => void;
+    clearViewModelReloadGrid(propertyName: string, gridRefName?: string): (sender: any) => void;
+    reloadGrid(gridRefName: string): (sender: any) => void;
+    showDialog(url: string, lookupForData: any, successCallback: any): (sender: any) => void;
+    showWidget(widgetUrl: any, lookup: any): (sender: any, queryValue: any) => void;
+    clearViewModelByLookup(lookup: any): (sender: any) => void;
+    closeMe(callBack: any): (sender: any) => void;
+}
+/**
+ * 清空 viewmodel 里下属的所有属性
+ * @param viewModel VM对象
+ * @param propertyKey 要清空的属性,可以是 "a.b.c" 这种表达模式
+ * @param ignoreProps 要忽略清空的属性名集合, 比如 ["a.b","b"]
+ */
+export declare function clearViewModel(viewModel: any, propertyKey: any, ignoreProps: any): void;
+export declare function clearViewModelByLookup(sender: any, lookup: any): void;
+export declare function showWidget(widgetUrl: any, lookup: any, sender: any, queryValue: any, vjson?: {}): void;
+/**
+ * 停止事件的默认行为
+ * @param e
+ */
+export declare function stopEvent(e: any): void;
+/**
+ * 屏幕中央显示一个黑框提示
+ */
+export declare function msg(content: any): void;
+/**
+ * 错误对话框的强提醒
+ */
+export declare function showErrorDialog(msg: any, sender?: any): void;
+/**
+ * 用于计算 express 表达式
+ */
+export declare function evalFunction(data: any, express: any): any;
+/**
+ * 获取表格编辑的行数据
+ */
+export declare function getGridEditRows(grid: any): {
+    rows: any[];
+    newRows: any[];
+    modifyRows: any[];
+    removeRecords: any[];
+    err: string;
+};

+ 4 - 0
dist/lib/systemLibEval.d.ts

@@ -0,0 +1,4 @@
+/**
+ * 用于计算 express 表达式
+ */
+export function evalFunction(data: any, express: any): any;

+ 11 - 0
dist/message.d.ts

@@ -0,0 +1,11 @@
+/**
+ * 显示错误异常信息
+ * @param msg 错误内容
+ * @param sender 发送者按钮(可以为空)
+ */
+export declare function showErrorDialog(msg: any, sender?: any): void;
+export declare function msgError(msg: any, sender?: any): void;
+/**
+ * 中间灰底白字提示
+ */
+export declare function msg(message: string): void;

+ 24 - 41
src/types.ts

@@ -1,25 +1,21 @@
 export interface PlainObject {
     [propsName: string]: any;
 }
-
 export interface VJson {
     [propName: string]: any;
 }
-
 export interface Model {
-    success: boolean
-    msg: string
-    data: any
+    success: boolean;
+    msg: string;
+    data: any;
 }
-
 /**
  * 处理 VJson 的
  * @param this 是指 scope 对象
  * @param vjson 是待处理的 VJson 对象
  * @result 返回处理 VJson 的 Promise 异步结果
  */
-export type ConfigProcess = (me, config) => any
-
+export declare type ConfigProcess = (me: any, config: any) => any;
 /**
  * 参数的填写类型
  *    module 选择一个功能模块
@@ -31,9 +27,10 @@ export type ConfigProcess = (me, config) => any
  *    string 任意字符串
  *    object 任意对象 (JSON5)
  */
-export type LibParamType = 'module' | 'viewModel' | 'refs' | 'event' | 'lookup' | 'string' | 'object'
-    | (() => Promise<string[] | { id: string, value: string }[]>)
-
+export declare type LibParamType = 'module' | 'viewModel' | 'refs' | 'event' | 'lookup' | 'string' | 'object' | (() => Promise<string[] | {
+    id: string;
+    value: string;
+}[]>);
 /**
  * 注册函数中的参数
  */
@@ -48,30 +45,25 @@ export interface FunctionArgument {
      *    string 任意字符串
      *    object 任意对象 (JSON5)
      */
-    type: LibParamType
-
+    type: LibParamType;
     /**
      * 参数中文说明
      */
-    title: string
-
+    title: string;
     /**
      * 参数名称
      */
-    name: string
-
+    name: string;
     /**
      * 是否允许为空
      */
-    allowEmpty?: boolean
-
+    allowEmpty?: boolean;
     /**
      * 过滤器
      * @param list
      */
-    filter?: (items: any[]) => any[]
+    filter?: (items: any[]) => any[];
 }
-
 /**
  * 注册函数, 用在 @Lib 装饰器
  */
@@ -79,52 +71,43 @@ export interface FunctionRegiste {
     /**
      * 函数名
      */
-    name?: string
-
+    name?: string;
     /**
      * 中文说明
      */
-    title?: string
-
+    title?: string;
     /**
      * 作者
      */
-    author?: string
-
+    author?: string;
     /**
      * 创建时间
      */
-    createAt?: string
-
+    createAt?: string;
     /**
      * 更新时间
      */
-    updateAt?: string
-
+    updateAt?: string;
     /**
      * 备注
      */
-    remark?: string
-
+    remark?: string;
     /**
      * 类型
      * system: 系统方法
      * format: 格式化作用
      */
-    type: 'system' | 'format'
-
+    type: 'system' | 'format';
     /**
      * 分类名称
      */
-    category?: string
-
+    category?: string;
     /**
      * 文档链接
      */
-    link?: string
-
+    link?: string;
     /**
      * 方法体
      */
-    target?: Function
-}
+    target?: Function;
+}

+ 9 - 0
dist/utils.d.ts

@@ -0,0 +1,9 @@
+/**
+ * 调用方法
+ */
+export declare function invokeMethod(fn: any, sender: any, args: any): void;
+/**
+ * 判断事件是否为有效的输入字符
+ * @param e
+ */
+export declare function isChartEvent(e: any): boolean;

+ 101 - 0
dist/xlsx.d.ts

@@ -0,0 +1,101 @@
+import XLSX from 'xlsx';
+import { ExcelImportDialog } from "./ExcelImportDialog";
+import { Scope } from "./Scope";
+declare const XLSX_EXPORT: any;
+export { XLSX };
+export { XLSX_EXPORT };
+export declare function readExcel(file: File): Promise<any>;
+export declare interface ErrorMsgDataItem {
+    /** 错误id 由allData 的__importID__字段值 + "_" + field的值 表示哪一行的哪一列出错,行校验错误时候直接为allData 的__importID__ + "" */
+    errorId: string;
+    /** 对应数据行 allData 的__importID__字段值 */
+    importID: number;
+    /** 字段 */
+    dataIndex: string;
+    /** 字段值 */
+    header: string;
+    /** 字段值 */
+    value: string;
+    /** 错误信息 */
+    errormessage: string;
+}
+export declare interface ImportResult {
+    /** 所有导入的数据,如果有字典会格式化到字典,格式化错误的保持原始值 */
+    allData: any[];
+    /** 导入正确的数据 */
+    okData: any[];
+    /** 导入错误的数据 */
+    errorData: any[];
+    /** 导入错误数据的错误明细 */
+    errorMsgData: ErrorMsgDataItem[];
+}
+/** 定义参数列 */
+export declare interface Column {
+    /** 字段 */
+    dataIndex: string;
+    /** 字段名 */
+    header: string;
+    /** 校验方法,校验通过返回true, 否则返回错误信息 会记录到错误列表里面 errorMsgData */
+    validate?: ((v: ValidateObject) => true | string) | string;
+    /** 格式化,表格显示 兼容默认弹出框表格的formatter */
+    fix?: ((v: any) => any) | string;
+    /** 导入格式化 返回null或者undefined 表示格式化错误,会记录到错误列表里面 errorMsgData */
+    importFormatter?: ((v: ValidateObject) => null | undefined | string | number) | string;
+    /** 字典, 参与数据校验和表格显示格式化, 校验不通过的,会记录到错误列表里面 errorMsgData 同时兼容默认弹出框表格的字典 */
+    data?: any | {
+        id: string | number;
+        text: string;
+    };
+}
+/** 格式化及校验的参数 */
+export declare interface ValidateObject {
+    column: Column;
+    ov: any;
+    nv: any;
+    rowIndex: number;
+    data: any;
+    rowDatas: any[];
+}
+/** 行数据校验的参数 */
+export declare interface RowValidateObject {
+    columns: Column[];
+    data: any;
+    rowIndex: number;
+    rowDatas: any[];
+}
+/**
+ * 定义切口,可以在外部修改数据
+ */
+export declare type AfterClientValidate = ((importResult: ImportResult, resolve: (value?: (ImportResult | PromiseLike<ImportResult> | undefined)) => void) => ImportResult) | undefined;
+export declare function readExcelWithColumnsSet(topScope: Scope, file: File, columnsSet: any[], dataStartRow?: number, titleRowNumber?: number, rowValidate?: ((rv: RowValidateObject) => true | string) | undefined, otherValidate?: AfterClientValidate, fieldValidate?: ((columns: Column[], columnTitles: string[]) => boolean) | undefined): Promise<ImportResult>;
+export declare interface ImportExcelOption {
+    columns: Column[];
+    fieldValidate?: ((columns: Column[], columnTitles: string[]) => boolean) | string | undefined;
+    rowValidate?: ((rv: RowValidateObject) => true | string) | string | undefined;
+    afterClientValidate?: AfterClientValidate | string;
+    dataStartRow?: number;
+    titleRowNumber?: number;
+    onImportAfter?: ((result: ImportResult) => {}) | string | undefined;
+    hidAllDataGrid?: boolean;
+    hidOKDataGrid?: boolean;
+    hidErrorDataGrid?: boolean;
+    hidErrorMsgGrid?: boolean;
+    dataGridPageSize?: 0 | 10 | 20 | 50 | 100 | 200 | 500 | 1000;
+    errorMsgGridPageSize?: 0 | 10 | 20 | 50 | 100 | 200 | 500 | 1000;
+    templateName?: string;
+    dowLoadUrl?: string;
+    title?: string;
+    height?: string;
+    width?: string;
+    defaultShowData?: "allData" | "okData" | "errorData";
+    errMsgGridColWidths?: number[];
+    toolBar?: any[];
+    onClose?: string | (() => void);
+    tQButtonText?: string | null | undefined;
+}
+/**
+ * 打开excel导入的方法
+ * @param option 参数配置
+ * @param sender
+ */
+export declare function importExcel(option: ImportExcelOption, sender: any): ExcelImportDialog;

+ 4 - 2
src/wotu-ui.css

@@ -448,7 +448,8 @@
     left: -10px;
     bottom: -1px;
     padding: 0 10px;
-    box-sizing: content-box;
+    -webkit-box-sizing: content-box;
+            box-sizing: content-box;
     z-index: 9999;
 }
 
@@ -472,7 +473,8 @@
 }
 
 .wotu-ui.x-keyboard-mode .x-btn-focus.x-btn-default-toolbar-small {
-    box-shadow: none;
+    -webkit-box-shadow: none;
+            box-shadow: none;
 }
 
 .wotu-ui .x-btn.x-btn-disabled {

File diff suppressed because it is too large
+ 131596 - 0
dist/yvan-ext.js


File diff suppressed because it is too large
+ 1 - 0
dist/yvan-ext.js.map


+ 0 - 6
doc/index.md

@@ -1,6 +0,0 @@
-# 上下左右布局
-```js
-export default {
-    layout: 'border'
-}
-```

+ 0 - 0
rollup.build.css


+ 0 - 239
src/DataSourceHelper.ts

@@ -1,239 +0,0 @@
-import {ajax} from './lib/config'
-import _ from 'lodash'
-import {lookupFn, lookupScope} from "./lib/lib";
-
-/**
- * 通用 dataSource 解析,
- * Tree/Combo/Grid/PageList ... 都会从这里解析
- */
-export function dataSourceReload(ctl: any, extraParam?: any, _successCb?: Function,
-                                 successCallback?: (data: any[]) => void,
-                                 failCallback?: (msg) => void): Promise<any> {
-    const {config} = ctl
-
-    return new Promise<any>((resolve, reject) => {
-        if (!config.dataSource) {
-            // 没有设置数据源,直接置空
-            return Promise.resolve()
-        }
-        const option: DataSourceParam = {
-            extraParam,
-            _successCb,
-            successCallback: (value) => {
-                if (typeof successCallback === "function") {
-                    successCallback(value)
-                } else {
-                    ctl.setData(value)
-                }
-                ctl.fireEvent('dataLoadComplete', ctl, true, value);
-                ctl.setLoading(false)
-                resolve(value)
-            },
-            failCallback: (error) => {
-                if (typeof failCallback === "function") {
-                    failCallback(error)
-                }
-                ctl.fireEvent('dataLoadComplete', ctl, false);
-                ctl.setLoading(false)
-                reject(error)
-            }
-        }
-
-        // 请求前要求确认一下
-        let isCanceled: boolean = false
-        ctl.fireEvent('dataBeforeLoad', ctl, {
-            cancel: () => {
-                isCanceled = true
-            },
-            ...option
-        });
-
-        if (!isCanceled) {
-            // 请求没有被取消
-            // 调用异步接口返回 Promise
-            return _innerReload(ctl, option)
-        }
-        return reject()
-    })
-}
-
-function _innerReload(ctl: any, option: DataSourceParam) {
-    const {config} = ctl
-    ctl.setLoading(true)
-
-    const scope = lookupScope(ctl)
-    let dataSource = config.dataSource
-    if (typeof dataSource == 'string') {
-        dataSource = lookupFn(scope, config.dataSource)
-    }
-
-    if (typeof dataSource === 'function') {
-        // @ts-ignore
-        dataSource.call(scope, ctl, option)
-        return
-
-    } else if (typeof dataSource?.url === 'string' || typeof dataSource?.sqlId === 'string') {
-
-        if (!ajax.func) {
-            console.error("没有配置 ajax")
-            return
-        }
-
-        const params: any = {}
-        let sortModel: any = null;
-        let filterModel: any = null;
-        if (option.extraParam && option.extraParam.filterModel) {
-            filterModel = option.extraParam.filterModel;
-        }
-        if (option.extraParam && option.extraParam.sortModel) {
-            sortModel = option.extraParam.sortModel;
-        }
-
-        _.forOwn(option.extraParam, (v: any, key) => {
-            if (key != "filterModel" && key != "sortModel") {
-                if (typeof v === 'function') {
-                    params[key] = v()
-                } else {
-                    params[key] = v
-                }
-            }
-        })
-        const ds: DataSourceAjax<any> = dataSource
-
-        _.forOwn(ds.params, (v: any, key) => {
-            if (typeof v === 'function') {
-                params[key] = v()
-            } else {
-                params[key] = v
-            }
-        })
-
-        if (typeof dataSource?.url === 'string') {
-            // @ts-ignore
-            ajax.func({
-                method: dataSource.method,
-                url: ds.url,
-                data: params,
-                filterModel,
-                sortModel,
-            }).then(res => {
-                if (res.success) {
-                    option.successCallback(res.data)
-
-                } else {
-                    option.failCallback(res.msg)
-                }
-
-            }).catch(e => {
-                option.failCallback(e)
-
-            })
-
-        } else if (typeof dataSource?.sqlId === 'string') {
-
-            const ds: DataSourceSql<any> = ctl.dataSource
-
-            // @ts-ignore
-            Extend.ajax.func({
-                url: ds.sqlId,
-                data: params,
-                db: ds.db,
-                method: 'sql',
-                filterModel,
-                sortModel,
-            }).then(res => {
-                if (res.success) {
-                    option.successCallback(res.data)
-
-                } else {
-                    option.failCallback(res.msg)
-                }
-
-            }).catch(e => {
-                option.failCallback(e)
-
-            }).finally(() => {
-                ctl.loading = false
-            })
-
-            return
-        } else {
-            console.error("非法的 dataSource", ctl.dataSource)
-            debugger
-            throw new Error("非法的 dataSource")
-        }
-    }
-}
-
-export interface DataSourceParam {
-    /**
-     * 额外附加的参数
-     */
-    extraParam?: any
-
-    /**
-     * 成功后额外的调用
-     */
-    _successCb?: Function
-
-    /**
-     * 设置响应成功的数据
-     */
-    successCallback: (data: any[]) => void
-
-    /**
-     * 设置响应失败
-     * @param msg 错误消息(可以为空)
-     */
-    failCallback: (msg?: string) => void
-}
-
-export interface DataSourceBefore extends DataSourceParam {
-
-    /**
-     * 取消下一步的请求
-     */
-    cancel: () => void
-}
-
-/**
- * 方法作为数据源
- */
-export type DataSourceFunction<T> = (sender: T, option: DataSourceParam) => void
-
-/**
- * Ajax 数据源
- */
-export interface DataSourceAjax<T> {
-    url: string,
-    method: string,
-    params?: {
-        [key: string]: (() => any) | any
-    }
-}
-
-/**
- * Sql 数据源
- */
-export interface DataSourceSql<T> {
-    sqlId: string,
-    db: string,
-    params?: {
-        [key: string]: (() => any) | any
-    }
-}
-
-/**
- * 数据源配置
- */
-export type DataSourceHelper<T> = DataSourceFunction<T> | DataSourceAjax<T> | DataSourceSql<T>
-
-/**
- * 数据抽取之前的设置
- */
-export type OnBeforeDataLoad<T> = (sender: T, option: DataSourceBefore) => void
-
-/**
- * 数据加载完成之后的回调
- */
-export type OnDataLoadComplete<T> = (sender: T) => void

+ 0 - 218
src/Defaults.ts

@@ -1,218 +0,0 @@
-const labelWidth = 80
-
-export const windows = {
-    modal: true,
-    width: 900,
-    height: 600,
-    maximizable: true,
-    constrain: true,
-    shadow: false,
-    // manageHeight: true,
-    // draggable: true,
-    // scrollable: true,
-}
-
-export const date = {
-    labelAlign: 'right',
-    labelWidth,
-}
-
-export const combo = {
-    labelAlign: 'right',
-    labelWidth,
-    valueField: 'id',
-    displayField: 'text',
-    autoLoad: true,
-    mode: 'local',
-    forceSelection: true,
-    triggerAction: 'all',
-    enableKeyEvents: true,
-}
-
-export const comboGrid = {
-    selectOnTab: true,
-    pickerHeight: 500,
-    pickerWidth: 850,
-    editEnable: null,
-}
-
-export const comboGridPicker = {
-    xtype: 'yvgrid',
-    layout: 'fit',
-    selModel: {
-        selType: 'rowmodel',
-        mode: 'SINGLE'
-    },
-}
-
-export const comboGridMulti = {
-    selectOnTab: true,
-    pickerHeight: 500,
-    pickerWidth: 850,
-    editEnable: null,
-    splitChar: ',',
-    displayField: 'text',
-    valueField: 'id',
-    autoLoad: true,
-}
-
-export const comboGridMultiPicker = {
-    selType: 'checkboxmodel',
-    selModel: {
-        type: 'checkboxmodel',
-        checkOnly: false
-    },
-}
-
-export const numberfield = {
-    labelAlign: 'right',
-    labelWidth,
-}
-
-export const checkbox = {
-    labelAlign: 'right',
-    labelWidth,
-    checkedValue: true,
-    uncheckedValue: false,
-}
-
-export const checkboxgroup = {
-    labelAlign: 'right',
-    labelWidth,
-}
-
-export const radio = {
-    labelAlign: 'right',
-    labelWidth,
-}
-
-export const radiogroup = {
-    labelAlign: 'right',
-    labelWidth,
-    simpleValue: true,
-    layout: 'hbox',
-    defaults: {
-        xtype: 'radio',
-        name: 'type',
-        margin: '0 15 0 0'
-    },
-}
-
-export const form = {
-    margin: '5 5 0 0',
-    border: false,
-    defaults: {
-        margin: '0 0 5 0',
-        border: false,
-    },
-}
-
-export const column = {
-    filter: {type: 'string'},
-}
-
-export const grid = {
-    border: true,
-    columnLines: true,
-    rowLines: true,
-    plugins: {
-        cellediting: {
-            clicksToEdit: 1
-        },
-        gridfilters: true
-    },
-    multiColumnSort: true,
-    viewConfig: {
-        enableTextSelection: true,
-        sortOnClick: false,
-    },
-    selModel: {
-        type: 'checkboxmodel',
-        checkOnly: false
-    },
-    pagination: true,
-    pageSize: 50,
-    pageSizeOption: ['20', '50', '100', '200', '300'],
-    hideFootbar: false,
-    hideRefresh: false,
-    hideExport: false,
-    hideAutoSize: false,
-    hideClearFilter: false,
-    hideSaveGridUIConfig: false,
-    hideClearGridUIConfig: false,
-    autoLoad: true,
-    remoteSort: false,
-    remoteFilter: false,
-    enableLocking: true,
-    syncRowHeight: false,
-    enableColumnMove: true,
-    enableColumnHide: true,
-    enableColumnResize: true,
-    hidden: false,
-    disabled: false,
-    exportExcelPageSize: 100,
-    exportExcelCurrentPage: 1,
-    exportExcelTotal: 0,
-}
-
-export const fieldContainer = {
-    labelAlign: 'right',
-    labelWidth,
-    layout: 'hbox',
-    defaults: {
-        flex: 1,
-    }
-}
-
-export const tree = {
-    autoLoad: true,
-    hideFilter: false,
-    hideToolbar: false,
-    hideRefresh: false,
-    hideExpand: false,
-    hideCollapse: false,
-}
-
-export const search = {
-    labelAlign: 'right',
-    labelWidth,
-}
-
-export const text = {
-    labelAlign: 'right',
-    labelWidth,
-    msgTarget: 'qtip',
-}
-
-export const toolbar = {
-    overflowHandler: 'menu',
-}
-
-export const tbfill = {}
-
-export const tbseparator = {}
-
-export const button = {}
-
-export const fieldSet = {
-    margin: '5 5 0 0',
-    border: false,
-    defaults: {
-        margin: '0 0 5 0',
-        border: false,
-    },
-}
-
-export const panel = {}
-
-export const splitter = {}
-
-export const maintab = {}
-
-export const rows = {}
-
-export const cols = {
-    defaults: {
-        flex: 1
-    },
-}

+ 0 - 313
src/ExcelImportDialog.ts

@@ -1,313 +0,0 @@
-import XLSX from 'xlsx'
-import {Scope} from "./Scope"
-import {Column, ImportExcelOption, ImportResult, readExcelWithColumnsSet} from "./xlsx";
-import {lookupFn, lookupScope} from "./lib/lib";
-import {msg} from "./message";
-import _ from "lodash";
-
-export class ExcelImportDialog extends Scope {
-    constructor(option: ImportExcelOption) {
-        const vjson = vjsonFunc(option)
-        super({model, vjson});
-        this.importExcelOption = option;
-    }
-
-    onLoad() {
-        super.onLoad();
-    }
-
-    fileChange(sender) {
-        let file = sender.fileInputEl.dom.files[0]
-        // const senderScope = lookupScope(sender)
-        const topScope = this.topScope
-        let rowValidate: any = this.importExcelOption.rowValidate
-        if (this.importExcelOption.rowValidate && typeof this.importExcelOption.rowValidate === 'string') {
-            rowValidate = lookupFn(topScope, this.importExcelOption.rowValidate).bind(topScope)
-        }
-        let afterClientValidate: any = this.importExcelOption.afterClientValidate
-        if (this.importExcelOption.afterClientValidate && typeof this.importExcelOption.afterClientValidate === 'string') {
-            afterClientValidate = lookupFn(topScope, this.importExcelOption.afterClientValidate).bind(topScope)
-        }
-        let fieldValidate: any = this.importExcelOption.fieldValidate
-        if (this.importExcelOption.fieldValidate && typeof this.importExcelOption.fieldValidate === 'string') {
-            fieldValidate = lookupFn(topScope, this.importExcelOption.fieldValidate).bind(topScope)
-        }
-
-        this.setLoading(true)
-
-        readExcelWithColumnsSet(
-            topScope,
-            file,
-            this.importExcelOption.columns,
-            this.importExcelOption.dataStartRow,
-            this.importExcelOption.titleRowNumber,
-            rowValidate,
-            afterClientValidate,
-            fieldValidate
-        ).then(res => {
-            this.importData = res
-            this.refs.dataGrid.setData(res.allData)
-            this.viewModel.set("dataCount", res.allData.length)
-            this.refs.errGrid.setData(res.errorMsgData)
-            this.viewModel.set("errMsgCount", res.errorMsgData.length)
-        }).catch(e => {
-            this.importData = null
-            this.refs.dataGrid.setData()
-            this.refs.errGrid.setData()
-            msg(e.toString())
-        }).finally(() => {
-            this.setLoading(false)
-        })
-    }
-
-    getDataGridRowRecord(record, rowIndex, rowParams, store) {
-        if (record.get('__hasError__')) {
-            return "x-grid-record-bg-red"
-        }
-    }
-
-    getErrGridRowRecord(record, rowIndex, rowParams, store) {
-        return "x-grid-record-bg-red"
-    }
-
-    dataGridClick(sender, td, cellIndex, record, item, index, e, eOpts) {
-        const id = record.data.__importID__;
-        const subId = this.refs.dataGrid.headerCt.getGridColumns()[cellIndex].dataIndex
-        let selectRecord = null
-        let dataIndex = -1
-        const rows = this.refs.errGrid.getStore().getData().items?.map(r => r.data);
-        for (let i = 0; i < rows.length; i++) {
-            if (rows[i].importID === id) {
-                selectRecord = this.refs.errGrid.getStore().getAt(i)
-                dataIndex = i
-            }
-            if (rows[i].errorId === id + "_" + subId) {
-                selectRecord = this.refs.errGrid.getStore().getAt(i)
-                dataIndex = i
-                break
-            }
-        }
-        if (selectRecord) {
-            this.refs.errGrid.ensureVisible(selectRecord)
-            this.refs.errGrid.selModel.select(dataIndex)
-            // this.refs.errGrid.reload()
-        }
-    }
-
-    errGridClick(sender, record, item, index, e, eOpts) {
-        const id = record.data.importID;
-        const rows = this.refs.dataGrid.getStore().getData().items?.map(r => r.data);
-        let selectRecord = null
-        let dataIndex = -1
-        for (let i = 0; i < rows.length; i++) {
-            if (rows[i].__importID__ === id) {
-                selectRecord = this.refs.dataGrid.getStore().getAt(i)
-                dataIndex = i
-                break
-            }
-        }
-
-        if (selectRecord) {
-            this.refs.dataGrid.ensureVisible(selectRecord)
-            this.refs.dataGrid.selModel.select(dataIndex)
-            // this.refs.dataGrid.reload()
-        }
-    }
-
-    filterData(sender, newValue, oldValue, eOpts) {
-        this.viewModel.set("dataType", newValue)
-        if (this.importData) {
-            this.refs.dataGrid.setData(this.importData[newValue])
-            this.viewModel.set("dataCount", this.importData[newValue].length)
-        }
-    }
-
-    downloadTemplate(sender) {
-        if (this.importExcelOption.dowLoadUrl && this.importExcelOption.dowLoadUrl.length > 0) {
-            window.location.href = this.importExcelOption.dowLoadUrl;
-            return
-        }
-        let xt: string[] = []
-        _.forEach(this.importExcelOption.columns, (v) => {
-            xt.push(v.header);
-        })
-        let filename = this.importExcelOption.templateName ? this.importExcelOption.templateName : "模版"; //文件名称
-        if (filename.endsWith(".xlsx")) {
-            filename = filename.split(".xlsx")[0];
-        }
-        filename = filename + ".xlsx"
-        var ws_name = "Sheet1"; //Excel第一个sheet的名称
-        var wb = XLSX.utils.book_new(), ws = XLSX.utils.aoa_to_sheet([xt]);
-        XLSX.utils.book_append_sheet(wb, ws, ws_name);  //将数据添加到工作薄
-        XLSX.writeFile(wb, filename); //导出Excel
-    }
-
-    getData(sender) {
-        _.each(this.importData.okData, item=>{
-            delete item.id
-            delete item.__hasError__
-            delete item.__importID__
-            delete item._origin
-        })
-        _.each(this.importData.allData, item=>{
-            delete item.id
-            delete item.__hasError__
-            delete item.__importID__
-            delete item._origin
-        })
-        _.each(this.importData.errorData, item=>{
-            delete item.id
-            delete item.__hasError__
-            delete item.__importID__
-            delete item._origin
-        })
-        this.dialogSuccess(this.importData)
-    }
-    importData: ImportResult
-    importExcelOption: ImportExcelOption
-}
-
-const model = {
-    data: {
-        dataType: "all",
-        errMsgCount: 0,
-        dataCount: 0
-    }
-}
-const vjsonFunc = (option) => {
-    return {
-        title: option.title || 'excel导入',
-        layout: 'fit',
-        items: [
-            {
-                layout: 'border',
-                tbar: {
-                    xtype: "form",
-                    items: [
-                        {
-                            xtype: "cols",
-                            items: [
-                                {
-                                    xtype: "filefield",
-                                    fieldLabel: 'excel文件',
-                                    buttonText: '请选择excel文件',
-                                    accept: ".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel",
-                                    flex: 3,
-                                    listeners: {
-                                        change: "scope.fileChange"
-                                    }
-                                }, {
-                                    xtype: "button",
-                                    iconCls: "x-fa fa-download",
-                                    text: "下载模版",
-                                    listeners: {
-                                        click: "scope.downloadTemplate"
-                                    }
-                                }, {
-                                    xtype: 'container',
-                                    border: false,
-                                    layout: 'hbox',
-                                }, {
-                                    xtype: "button",
-                                    iconCls: "x-fa fa-upload",
-                                    text: option.tQButtonText || "提取数据",
-                                    listeners: {
-                                        click: "scope.getData"
-                                    }
-                                }
-                            ]
-                        },
-                    ]
-                },
-                items: [
-                    {
-                        tbar: {
-                            xtype: "toolbar",
-                            title: "导入的数据",
-                            items: [{
-                                xtype: 'label',
-                                html: '<span style="font-size: 14px; font-weight: bold">导入的数据</span>',
-                            }, {
-                                xtype: 'radiogroup',
-                                items: [
-                                    {
-                                        boxLabel: '所有数据',
-                                        checked: true,
-                                        inputValue: 'allData',
-                                    }, {
-                                        boxLabel: '正确数据',
-                                        inputValue: 'okData',
-                                    }, {
-                                        boxLabel: '错误数据',
-                                        inputValue: 'errorData',
-                                    }],
-                                listeners: {
-                                    change: 'scope.filterData',
-                                },
-                            }, {
-                                xtype: "textfield",
-                                readOnly: true,
-                                fieldLabel: "条目数",
-                                bind: "{dataCount}"
-                            }]
-                        },
-                        xtype: 'yvgrid',
-                        reference: 'dataGrid',
-                        layout: 'fit',
-                        pagination: false,
-                        // pageSize: 50,
-                        getRowClass: 'scope.getDataGridRowRecord',
-                        columns: option.columns,
-                        region: 'center',
-                        split: true,
-                        listeners: {
-                            cellclick: "scope.dataGridClick",
-                        },
-                        selModel: {
-                            // type: 'rowmodel',
-                            mode: 'SINGLE',
-                        },
-                    }, {
-                        tbar: {
-                            xtype: "toolbar", items: [
-                                {
-                                    xtype: 'label',
-                                    html: '<span style="font-size: 14px; font-weight: bold; color: red">错误信息</span>',
-                                }, {
-                                    xtype: "textfield",
-                                    readOnly: true,
-                                    fieldLabel: "条目数",
-                                    bind: "{errMsgCount}"
-                                }
-                            ]
-                        },
-                        xtype: 'yvgrid',
-                        reference: 'errGrid',
-                        layout: 'fit',
-                        pagination: false,
-                        getRowClass: 'scope.getErrGridRowRecord',
-                        height: "40%",
-                        columns: [
-                            {dataIndex: "errorId", header: "ID", hidden: true},
-                            {dataIndex: "importID", header: "行号", width: 80},
-                            {dataIndex: "errormessage", header: "错误信息", width: 200},
-                            {dataIndex: "value", header: "值", width: 120},
-                            {dataIndex: "header", header: "字段名", width: 120},
-                            {dataIndex: "dataIndex", header: "字段", width: 120}
-                        ],
-                        region: 'south',
-                        split: true,
-                        listeners: {
-                            itemclick: "scope.errGridClick"
-                        },
-                        selModel: {
-                            // type: 'rowmodel',
-                            mode: 'SINGLE',
-                        },
-                    },
-                ],
-            },
-        ],
-        referenceHolder: true,
-    }
-}

+ 0 - 106
src/PropertyDescription.ts

@@ -1,106 +0,0 @@
-import _ from 'lodash'
-
-export type GroupType = 'css' | 'data' | 'bind' | 'common' | 'event'
-
-export interface PropertyValue {
-  /**
-   * 属性名
-   */
-  name: string
-
-  /**
-   * 默认值
-   */
-  default: any
-
-  /**
-   * 隶属分组
-   */
-  group: GroupType
-
-  /**
-   * 描述
-   */
-  desc: string
-
-  /**
-   * 取值范围
-   */
-  type:
-    | 'boolean'
-    | 'number'
-    | 'string'
-    | 'object'
-    | 'dataSource'
-    | 'valid'
-    | 'format'
-    | Array<string>
-    | 'widget'
-
-  eventParamter?: string[]
-
-  eventResult?: string
-
-  eventDoc?:(vjson:any)=>string
-
-  expr?: boolean,
-}
-
-export interface EventValue {
-  /**
-   * 属性名
-   */
-  name: string
-
-  /**
-   * 描述
-   */
-  desc: string
-}
-
-export interface PropertyDescriptionInterface {
-  props: PropertyValue[]
-  events?: EventValue[]
-}
-
-export class PropertyDescription {
-  propertyes: PropertyDescriptionInterface = {
-    props: [],
-    events: []
-  }
-
-  constructor(...args: PropertyDescriptionInterface[]) {
-    _.each(args, arg => {
-      this.merge(arg)
-    })
-  }
-
-  merge(pd: PropertyDescriptionInterface) {
-    this.propertyes.props = <any>(
-      _.uniqBy([...this.propertyes.props, ...pd.props], 'name')
-    )
-    if (pd.events) {
-      if (this.propertyes.events) {
-        this.propertyes.events = <any>(
-          _.uniqBy([...this.propertyes.events, ...pd.events], 'name')
-        )
-      } else {
-        this.propertyes.events = <any>_.uniqBy([...pd.events], 'name')
-      }
-    }
-  }
-
-  /**
-   * 根据分组名 获取属性定义
-   */
-  getPropsByGroup(name: GroupType): PropertyValue[] {
-    return _.filter(this.propertyes.props, i => i.group === name)
-  }
-
-  /**
-   * 获取全部事件
-   */
-  getEvents(): EventValue[] {
-    return this.propertyes.events!
-  }
-}

+ 0 - 507
src/PropertyDescriptionTable.ts

@@ -1,507 +0,0 @@
-import _ from 'lodash'
-import {PropertyDescription, PropertyDescriptionInterface, PropertyValue} from './PropertyDescription'
-
-export const PropertyDescriptionTable = new Map<String, PropertyDescription>()
-
-PropertyDescriptionTable.set(
-    'tabCell',
-    new PropertyDescription({
-        props: [
-            {
-                name: 'header',
-                default: '',
-                group: 'common',
-                desc: '选项卡名称',
-                type: 'string'
-            },
-            {
-                name: 'close',
-                default: '',
-                group: 'common',
-                desc: '是否允许关闭',
-                type: 'boolean'
-            },
-        ]
-    })
-)
-
-export const width: PropertyValue = {
-    name: 'width',
-    default: '',
-    group: 'common',
-    desc: '宽',
-    type: 'number'
-}
-
-export const height: PropertyValue = {
-    name: 'height',
-    default: '',
-    group: 'common',
-    desc: '高',
-    type: 'number'
-}
-
-export const fieldLabel: PropertyValue = {
-    name: 'fieldLabel',
-    default: '',
-    group: 'common',
-    desc: '文本描述',
-    type: 'string',
-    expr: true,
-};
-
-export const text: PropertyValue = {
-    name: 'text',
-    default: '',
-    group: 'common',
-    desc: '文本描述',
-    type: 'string',
-    expr: true,
-};
-
-export const iconCls: PropertyValue = {
-    name: 'iconCls',
-    default: '',
-    group: 'common',
-    desc: '图标',
-    type: 'string',
-    expr: true,
-};
-
-export const borderless: PropertyValue = {
-    name: 'borderless',
-    default: '',
-    group: 'css',
-    desc: '是否有边框',
-    type: 'boolean',
-};
-export const labelAlign: PropertyValue = {
-    name: 'labelAlign',
-    default: '',
-    group: 'common',
-    desc: '描述对齐方式',
-    type: ['left', 'right', 'center']
-};
-export const type: PropertyValue = {
-    name: 'type',
-    default: '',
-    group: 'css',
-    desc: '容器内部线类型',
-    type: ['line', 'clean', 'wide', 'space', 'form']
-};
-export const labelWidth: PropertyValue = {
-    name: 'labelWidth',
-    default: undefined,
-    group: 'common',
-    desc: '文本宽度',
-    type: 'number'
-};
-export const gravity: PropertyValue = {
-    name: 'gravity',
-    default: 1,
-    group: 'common',
-    desc: '占位权重',
-    type: 'number'
-};
-export const hidden: PropertyValue = {
-    name: 'hidden',
-    default: false,
-    group: 'common',
-    desc: '隐藏',
-    type: 'boolean',
-    expr: true,
-};
-export const readonly: PropertyValue = {
-    name: 'readonly',
-    default: false,
-    group: 'common',
-    desc: '只读',
-    type: 'boolean',
-    expr: true,
-};
-export const disabled: PropertyValue = {
-    name: 'disabled',
-    default: false,
-    group: 'common',
-    desc: '禁用',
-    type: 'boolean',
-    expr: true,
-};
-export const loading: PropertyValue = {
-    name: 'loading',
-    default: false,
-    group: 'common',
-    desc: '载入中',
-    type: 'boolean',
-    expr: true,
-};
-export const required: PropertyValue = {
-    name: 'required',
-    default: false,
-    group: 'common',
-    desc: '必填',
-    type: 'boolean',
-    expr: true,
-};
-export const value: PropertyValue = {
-    name: 'value',
-    default: '',
-    group: 'common',
-    desc: '字段值',
-    type: 'string',
-    expr: true,
-};
-export const prompt: PropertyValue = {
-    name: 'prompt',
-    default: '请输入',
-    group: 'common',
-    desc: '水印',
-    type: 'string'
-};
-export const validType: PropertyValue = {
-    name: 'validType',
-    default: '',
-    group: 'common',
-    desc: '校验类型',
-    type: 'valid'
-};
-export const metaId: PropertyValue = {
-    name: 'metaId',
-    default: '',
-    group: 'bind',
-    desc: '元数据ID',
-    type: 'string'
-};
-export const template: PropertyValue = {
-    name: 'template',
-    default: '',
-    group: 'common',
-    desc: 'HTML内容',
-    type: 'string',
-    expr: true,
-}
-
-export const tooltip: PropertyValue = {
-    name: 'tooltip',
-    default: '',
-    group: 'common',
-    desc: '悬停提示',
-    type: 'string'
-}
-
-export const onClick: PropertyValue = {
-    name: 'onClick',
-    default: '',
-    group: 'event',
-    desc: '点击事件',
-    eventParamter: [
-        'sender: YvanUI.CtlButton',
-        'e: any'
-    ],
-    eventDoc(vjson) {
-        return (vjson['text'] ? vjson['text'] : '按钮') + '被点击后触发';
-    },
-    type: 'string'
-}
-
-PropertyDescriptionTable.set(
-    'rows',
-    new PropertyDescription({
-        props: [
-            gravity,
-            width
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'cols',
-    new PropertyDescription({
-        props: [
-            gravity,
-            height
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'window',
-    new PropertyDescription({
-        props: [
-            {
-                name: '_designMode',
-                default: 'module',
-                group: 'common',
-                desc: '设计类型',
-                type: ['none', 'dialog', 'scroll-dialog']
-            },
-            {
-                name: 'title',
-                default: '',
-                group: 'common',
-                desc: '对话框标题',
-                type: 'string'
-            },
-            {
-                name: 'modal',
-                default: '',
-                group: 'common',
-                desc: '是否模态',
-                type: 'boolean'
-            },
-            _.merge(_.cloneDeep(width), {default: 200}),
-            _.merge(_.cloneDeep(height), {default: 200}),
-            {
-                name: 'top',
-                default: 200,
-                group: 'common',
-                desc: '顶像素',
-                type: 'number'
-            },
-            {
-                name: 'left',
-                default: 200,
-                group: 'common',
-                desc: '左像素',
-                type: 'number'
-            }
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'layout',
-    new PropertyDescription({
-        props: [
-            {
-                name: 'borderless',
-                default: true,
-                group: 'css',
-                desc: '有无边框',
-                type: 'boolean'
-            },
-            {
-                name: 'type',
-                default: '',
-                group: 'css',
-                desc: '布局类型',
-                type: ['line', 'clean', 'wide', 'space', 'form']
-            },
-            {
-                name: '_designMode',
-                default: 'module',
-                group: 'common',
-                desc: '设计类型',
-                type: ['none', 'module', 'scroll-module']
-            }
-        ]
-    })
-)
-
-export const YvBase: PropertyDescriptionInterface = {
-    props: [
-        {
-            name: 'bind',
-            default: '',
-            group: 'bind',
-            desc: '实体类名',
-            type: 'string'
-        },
-        {
-            name: 'ref',
-            default: '',
-            group: 'bind',
-            desc: '控件名',
-            type: 'string'
-        },
-        {
-            name: 'css',
-            default: '',
-            group: 'css',
-            desc: '样式类名',
-            type: 'string'
-        },
-        {
-            name: 'hidden',
-            default: false,
-            group: 'common',
-            desc: '是否显示',
-            type: 'boolean'
-        },
-        {
-            name: 'padding',
-            default: undefined,
-            group: 'css',
-            desc: '内边距',
-            type: 'object'
-        },
-        {
-            name: 'margin',
-            default: undefined,
-            group: 'css',
-            desc: '外边距',
-            type: 'object'
-        },
-        {
-            name: 'ff',
-            default: 0,
-            group: 'common',
-            desc: '自动定焦时间',
-            type: 'number'
-        },
-        width, height,
-        {
-            name: 'autowidth',
-            default: false,
-            group: 'common',
-            desc: '自动计算宽度',
-            type: 'boolean'
-        },
-        {
-            name: 'autoheight',
-            default: false,
-            group: 'common',
-            desc: '自动计算高度',
-            type: 'boolean'
-        },
-    ],
-    events: [
-        {name: 'onRender', desc: '第一次控件被渲染时触发'}
-    ]
-}
-
-export const YvDataSource: PropertyDescriptionInterface = {
-    props: [
-        {
-            name: 'type',
-            default: '',
-            group: 'data',
-            desc: '数据源类型',
-            type: 'dataSource'
-        }
-    ],
-    events: [{name: 'onDataComplete', desc: '数据绑定完成后触发'}]
-}
-
-PropertyDescriptionTable.set(
-    'template',
-    new PropertyDescription(YvBase, {
-        props: [
-            template
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'fieldset',
-    new PropertyDescription(YvBase, {
-        props: [
-            {
-                name: 'label',
-                default: '',
-                group: 'common',
-                desc: '字段组标题',
-                type: 'string'
-            }
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'iframe',
-    new PropertyDescription(YvBase, {
-        props: [
-            {
-                name: 'src',
-                default: '',
-                group: 'common',
-                desc: '地址路径',
-                type: 'string'
-            }
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'uploader',
-    new PropertyDescription(YvBase, {
-        props: [
-            width, height,
-            {
-                name: 'value',
-                default: '上传',
-                group: 'common',
-                desc: '文本描述',
-                type: 'string'
-            },
-            {
-                name: 'upload',
-                default: '/upload',
-                group: 'common',
-                desc: '上传地址',
-                type: 'string'
-            },
-        ],
-        events: [
-            {name: 'onFileUpload', desc: '文件上传成功结束时触发'},
-            {name: 'onFileUploadError', desc: '在上传过程中发生服务器端错误时触发'},
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'viewer',
-    new PropertyDescription(YvBase, {
-        props: [
-            value,
-            gravity,
-            {
-                name: 'imgWidth',
-                default: '',
-                group: 'common',
-                desc: '图片宽',
-                type: 'string'
-            },
-            {
-                name: 'imgHeight',
-                default: '',
-                group: 'common',
-                desc: '图片高',
-                type: 'string'
-            }
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'image',
-    new PropertyDescription(YvBase, {
-        props: [
-            value,
-            gravity,
-            {
-                name: 'imgWidth',
-                default: '',
-                group: 'common',
-                desc: '图片宽',
-                type: 'string'
-            },
-            {
-                name: 'imgHeight',
-                default: '',
-                group: 'common',
-                desc: '图片高',
-                type: 'string'
-            }
-        ]
-    })
-)
-
-PropertyDescriptionTable.set(
-    'scrollview',
-    new PropertyDescription(YvBase, {
-        props: [
-            width, height
-        ]
-    })
-)

+ 0 - 357
src/Scope.ts

@@ -1,357 +0,0 @@
-import _ from 'lodash'
-import {invokeMethod} from "./utils"
-import {windows} from './Defaults'
-import {lookupScope} from "./lib/lib";
-import {scopeOnLoad} from './lib/config'
-
-export class Scope {
-
-    /**
-     * 业务模块的唯一编号
-     */
-    id = _.uniqueId('scope_')
-
-    originalVjson
-
-    /**
-     * 一个 ExtJS 能接受的配置对象
-     */
-    vjson
-
-    /**
-     * 原始 vjsonModel 对象
-     */
-    model
-
-    /**
-     * 双向绑定的模型对象
-     */
-    viewModel
-
-    /**
-     * 构建完成之后的 Ext控件句柄
-     */
-    _handle
-
-    /**
-     * 与 watch 装饰器配合使用.
-     * viewModel 属性更改时触发成员方法
-     */
-    _watchList
-
-    /**
-     * 页面显示的时候带的参数 在设计刷新的时候使用
-     */
-    _vjsonOption
-    _dataOption
-
-    /**
-     * 最顶部的 scope 对象
-     */
-    topScope
-
-    _addWatch(tplExpress, fn) {
-        if (!this._watchList) {
-            this._watchList = []
-        }
-        this._watchList.push({watch: tplExpress, fn})
-    }
-
-    _applyWatchList() {
-        _.forEach(this._watchList, item => {
-            this.viewModel.bind(item.watch, item.fn.bind(this))
-        })
-    }
-
-    get isScope() {
-        return true;
-    }
-
-    /**
-     * 产生一个当前模块有效的唯一id
-     * @param key 唯一编号
-     */
-    uid(key) {
-        return this.id + key
-    }
-
-    /**
-     * 对话框"保存"成功.
-     * 关闭对话框,并响应 success 方法
-     * @param data 要傳回的數據(可以為空)
-     */
-    dialogSuccess(data?) {
-        this._handle.fireEvent('success', this, data)
-        const sender = this._handle.config.animateTarget
-        const scope = lookupScope(sender)
-        if (typeof this['success'] === 'function') {
-            this['success'].call(scope, sender, data)
-        }
-        this.close()
-    }
-
-    /**
-     * 设置等待状态
-     * @param value
-     * @param msg
-     */
-    setLoading(value: boolean) {
-        const scope = this
-        scope._handle?.setLoading(value)
-    }
-
-    /**
-     * 以对话框模式打开当前模块
-     * @param sender 发送者(按钮或Scope对象)
-     * @param vjsonOption 界面覆盖选项(可以为空)
-     * @param dataOption 数据覆盖选项(可以为空)
-     */
-    showDialog(sender, vjsonOption, dataOption) {
-        const that = this
-
-        const vmodel = _.defaultsDeep({
-            //
-
-        }, dataOption, that.model)
-
-        this.viewModel = new Ext.app.ViewModel(vmodel);
-        this.viewModel.yvanScope = this
-        this._applyWatchList()
-        this["scopeKey"] = "dialog-" + getVjsonHash(JSON.stringify(this.vjson) + JSON.stringify(vjsonOption))
-        const config = _.defaultsDeep({
-            animateTarget: sender,
-            viewModel: this.viewModel,
-            yvanScope: this,
-            referenceHolder: true,
-
-        }, vjsonOption, that.vjson, windows)
-
-        if (config.height === 'unset') {
-            delete config.height
-        }
-        if (config.width === 'unset') {
-            delete config.width
-        }
-        // const holder = sender?.lookupReferenceHolder()
-        // delete config.constrain
-        const topScope = lookupScope(sender)?.topScope
-        if (topScope) {
-            config.constrain = true
-            this.topScope = topScope
-        }
-        const win = new Ext.Window(config);
-        // if (holder) {
-        //     holder.add(win)
-        // }
-        if (topScope) {
-            topScope._handle.add(win)
-        }
-
-        win.addListener('beforerender', function (sender) {
-            // 记录句柄
-            if (sender && !that._handle) {
-                that._handle = sender
-            }
-        })
-        win.addListener('afterrender', function (sender) {
-            // 调用onLoad回调
-            try {
-                that.onLoad()
-            } catch (e) {
-                console.error('errorAt onLoad', e)
-            }
-        })
-        win.addListener('destroy', this._destroy.bind(this))
-
-        win.show();
-    }
-
-    /**
-     * 以标签模式打开当前模块
-     * @param vjsonOption 界面覆盖选项(可以为空)
-     * @param dataOption 数据覆盖选项(可以为空)
-     */
-    showPage(vjsonOption, dataOption) {
-        const that = this
-        this._vjsonOption = vjsonOption;
-        this._dataOption = dataOption;
-        const vmodel = _.defaultsDeep({
-            data: {}
-        }, that.model, dataOption)
-
-        this.viewModel = new Ext.app.ViewModel(vmodel);
-        this.viewModel.yvanScope = this
-        this._applyWatchList()
-
-        this["scopeKey"] = "page-" + getVjsonHash(JSON.stringify(this.vjson) + JSON.stringify(vjsonOption))
-        // 根级不能设置id
-        delete that.vjson.id
-
-        const config = _.defaultsDeep({
-            viewModel: this.viewModel,
-            yvanScope: this,
-            referenceHolder: true,
-
-        }, vjsonOption, that.vjson)
-
-        const tt = Ext.getCmp('TT')
-        const handle = tt.addScope(this, config, (handle) => {
-            handle.addListener('added', function (sender) {
-                // 记录句柄
-                if (sender && !that._handle) {
-                    that._handle = sender
-                }
-            })
-            handle.addListener('afterrender', function (sender) {
-                // 调用onLoad回调
-                try {
-                    that.onLoad()
-                } catch (e) {
-                    console.error('errorAt onLoad', e)
-                }
-            })
-            handle.addListener('destroy', this._destroy.bind(this))
-        })
-
-        return handle
-    }
-
-    /**
-     * 直接渲染到元素
-     * @param element 渲染目标
-     * @param vjsonOption 界面覆盖选项(可以为空)
-     * @param dataOption 数据覆盖选项(可以为空)
-     */
-    renderTo(element, vjsonOption, dataOption) {
-        const that = this
-        this._vjsonOption = vjsonOption;
-        this._dataOption = dataOption;
-        const vmodel = _.defaultsDeep({
-            data: {}
-        }, that.model, dataOption)
-        this["scopeKey"] = "render-" + getVjsonHash(JSON.stringify(this.vjson) + JSON.stringify(vjsonOption))
-        this.viewModel = new Ext.app.ViewModel(vmodel);
-        this.viewModel.yvanScope = this
-        this._applyWatchList()
-
-        const config = _.defaultsDeep({
-            viewModel: this.viewModel,
-            yvanScope: this,
-            referenceHolder: true,
-            renderTo: element,
-
-            listeners: {
-                afterrender(sender) {
-                    // 记录句柄
-                    if (sender && !that._handle) {
-                        that._handle = sender
-                    }
-
-                    // 调用onLoad回调
-                    try {
-                        that.onLoad()
-                    } catch (e) {
-                        console.error('errorAt onLoad', e)
-                    }
-
-                    // 如果vjson中配置了 afterrender ,需要恢复状态
-                    invokeMethod(that.vjson.listeners?.afterrender, that, arguments)
-                },
-
-            },
-
-        }, vjsonOption, that.vjson)
-
-        new Ext.container.Viewport(config);
-    }
-
-    /**
-     * 关闭对话框(或标签页)
-     */
-    close() {
-        this._handle.close()
-    }
-
-    /**
-     * 获取 viewModel 里包含的数据(只读)
-     */
-    get data() {
-        return this.viewModel.getData()
-    }
-
-    /**
-     * 设置 viewModel 中的数据
-     * 可以是 key, value 模式
-     * 也可以是 {key:value} 模式
-     */
-    set(path, value) {
-        return this.viewModel.set(path, value)
-    }
-
-    /**
-     * 寻找模块内所有的 xtype 对应的对象
-     * @param xtypeKey
-     */
-    down(xtypeKey) {
-        return this._handle.down(xtypeKey)
-    }
-
-    /**
-     * 获取所有设置过 Reference 名称的组件
-     */
-    get refs() {
-        return this._handle.getReferences()
-    }
-
-    _destroy() {
-        const that = this
-
-        that.onDestroy()
-        delete that._watchList
-        delete that._handle
-    }
-
-    constructor({model, vjson}) {
-        const that = this
-        this.model = model
-        this.originalVjson = _.cloneDeep(vjson)
-        this.vjson = this.originalVjson // this.buildVjson()
-    }
-
-    /**
-     * 模块载入完成之后的回调
-     */
-    onLoad() {
-        if (scopeOnLoad && typeof scopeOnLoad === 'function') {
-            scopeOnLoad(this)
-        }
-    }
-
-    /**
-     * 组件卸载之后的回调
-     */
-    onDestroy() {
-    }
-
-}
-
-/**
- * 观察装饰器,viewModel 属性更改时触发成员方法
- * @param tplExpress tpl表达式,例如 "{form.f1}"
- */
-export function watch(tplExpress, deep = false) {
-    return function (target, propertyKey, pd) {
-        target._addWatch({bindTo: tplExpress, deep}, target[propertyKey])
-        return target[propertyKey]
-    }
-}
-
-// 获取vjson的hash值
-function getVjsonHash(str: string): string {
-    let hash =   3465217896,i,ch;
-    for (i = str.length - 1; i >= 0; i--) {
-        ch = str.charCodeAt(i);
-        hash ^= ((hash << 5) + ch + (hash >> 2));
-    }
-    return  (hash & 0x7FFFFFFF) + "";
-}

+ 0 - 115
src/controls/MainTab.js

@@ -1,115 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import qs from 'qs'
-import {invokeMethod} from "../utils";
-import * as system from "../lib/systemLib"
-
-export default function () {
-
-    Ext.define('Yvan.MainTab', {
-        extend: 'Ext.tab.Panel',
-        xtype: 'maintab',
-
-        plugins: Ext.create('Ext.ux.TabCloseMenu', {
-            closeTabText: '关闭',
-            closeOthersTabsText: '关闭其他',
-            closeAllTabsText: '关闭所有'
-        }),
-
-        constructor(config) {
-            const me = this
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, config)
-            this.superclass.constructor.call(me, newConfig)
-        },
-
-        initComponent() {
-            const me = this
-            this.on({
-                tabchange(tabPanel, newCard, oldCard, eOpts) {
-                    _.defer(() => {
-                        me.changeHash(newCard.id)
-                        window['cp'] = newCard.yvanScope
-                    })
-
-                    $(window).trigger('tabChange', {
-                        tabPanel, newCard, oldCard, eOpts
-                    });
-                },
-                afterrender() {
-                    _.defer(() => {
-                        me.tryRestoryPage()
-                    })
-                }
-            })
-            this.superclass.initComponent.call(me)
-        },
-
-        tryRestoryPage() {
-            const me = this
-            let hash = '' + window.location.hash
-            if (hash && hash.indexOf('page=') > 0) {
-                if (hash.startsWith('#')) {
-                    hash = hash.substr(1)
-                }
-                if (hash) {
-                    const {page} = qs.parse(hash)
-                    if (page) {
-                        // this.openScope(page)
-                        me.fireEvent('restorypage', page)
-                    }
-                }
-            }
-        },
-
-        changeHash(id) {
-            window.location.hash = qs.stringify({page: id})
-        },
-
-        /**
-         * 添加一个业务模块实例到选项卡
-         * @param scopeInstance 业务对象实例
-         * @param config ExtJS配置对象
-         * @param panelInitCallback panel初始化之后会调用函数进行构造前的加工
-         */
-        addScope(scopeInstance, config, panelInitCallback) {
-            scopeInstance.topScope = scopeInstance
-
-            const me = this
-            if (config.path) {
-                for (let i = 0; i < this.items.items.length; i++) {
-                    // 找到当前 tabs 里有没有已经打开过
-                    const tab = this.items.items[i]
-                    if (_.isEqual(tab.path, config.path)) {
-                        // 激活
-                        this.setActiveTab(tab);
-                        return tab
-                    }
-                }
-            }
-
-            const newPanel = new Ext.panel.Panel({
-                closable: true,
-                ...config
-            })
-            if (typeof panelInitCallback === 'function') {
-                panelInitCallback(newPanel)
-            }
-
-            // 添加业务模块
-            const newTab = this.add(newPanel)
-            this.setActiveTab(newTab);
-            newTab.on({
-                destroy(sender) {
-                    me.changeHash('')
-                    delete window['cp']
-                }
-            })
-
-            return newTab
-        }
-    });
-
-}

+ 0 - 55
src/controls/base.ts

@@ -1,55 +0,0 @@
-import _ from 'lodash'
-
-type DragType = 'rows-container' | 'cols-container' | 'col-item' | 'row-item'
-
-/**
- * 构建所有组件的公共属性
- * @param config 原始config
- * @param dragType 组件模式
- *      不填,代表不能在设计时被拖拽
- *      row-container 是一个rows容器
- *      col-container 是一个cols容器
- *      col-item cols中的一个格子(非容器),比如 textfield / combofield 等等
- *      row-item rows中的一行,比如 tree / grid / panel 等等
- */
-export function baseConfig(config, dragType?: DragType) {
-    if (config && config.designMode && dragType) {
-
-        let cc = ''
-        switch (dragType) {
-            case "cols-container":
-                cc = 'design_cols_container'
-                break
-
-            case "col-item":
-                cc = 'design_col_item'
-                break
-
-            case "rows-container":
-                cc = 'design_rows_container'
-                break
-
-            case "row-item":
-                cc = 'design_row_item'
-                break
-        }
-
-        if (typeof config.cls === 'string') {
-            _.extend(config, {
-                cls: [config.cls, 'yvan_design', cc]
-            })
-
-        } else if (_.isArray(config.cls)) {
-            _.extend(config, {
-                cls: [...config.cls, 'yvan_design', cc]
-            })
-
-        } else {
-            _.extend(config, {
-                cls: ['yvan_design', cc]
-            })
-        }
-    }
-
-    return config
-}

+ 0 - 33
src/controls/button.js

@@ -1,33 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import {baseConfig} from "./base";
-import {button} from "../Defaults";
-import {
-    disabled,
-    text,
-    iconCls,
-    width, height,
-    PropertyDescriptionTable,
-    YvBase
-} from "../PropertyDescriptionTable";
-import {PropertyDescription} from "../PropertyDescription";
-
-export default function () {
-    /**
-     *
-     */
-    const ct = Ext.button.Button.prototype.constructor
-    Ext.button.Button.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "col-item"), button)
-            ct.call(this, newConfig)
-        }
-    });
-
-    PropertyDescriptionTable.set(
-        'button',
-        new PropertyDescription(YvBase, {
-            props: [ text, disabled, height, width, iconCls],
-        })
-    )
-}

+ 0 - 24
src/controls/cols.js

@@ -1,24 +0,0 @@
-import _ from 'lodash'
-import {cols} from '../Defaults'
-import {baseConfig} from "./base";
-
-export default function () {
-
-    Ext.define('Yvan.Cols', {
-        extend: 'Ext.container.Container',
-        xtype: 'cols',
-
-        constructor(config) {
-            const self = this
-            const newConfig = _.defaultsDeep({
-                // 强制性属性
-                layout: 'hbox',
-                minHeight: config.designMode ? 32 : 0
-
-            }, baseConfig(config, 'cols-container'), config, cols)
-
-            this.superclass.constructor.call(self, newConfig)
-        },
-    });
-
-}

+ 0 - 18
src/controls/component.js

@@ -1,18 +0,0 @@
-import _ from 'lodash'
-import {baseConfigProcessList} from "../lib/config";
-
-export default function () {
-    const ct = Ext.Component.prototype.constructor
-    Ext.Component.override({
-        constructor: function (config) {
-            if (!window["IS_DESIGN_MODE"] && config) {
-                const me = this
-                // 任意组件 Ext.Component 构造时调用的方法, 可以用来在渲染之前加工处理 VJSON
-                _.each(baseConfigProcessList, process => {
-                    process.call(me, me, config)
-                })
-            }
-            ct.call(this, config)
-        }
-    });
-}

+ 0 - 37
src/controls/fieldset.js

@@ -1,37 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import {baseConfig} from "./base";
-import {fieldSet} from "../Defaults";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../PropertyDescriptionTable";
-import {PropertyDescription} from "../PropertyDescription";
-
-export default function () {
-    /**
-     *
-     */
-    const ct = Ext.form.FieldSet.prototype.constructor
-    Ext.form.FieldSet.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "rows-container"), fieldSet)
-            ct.call(this, newConfig)
-        }
-    });
-
-    PropertyDescriptionTable.set(
-        'fieldSet',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-}

+ 0 - 14
src/controls/form.js

@@ -1,14 +0,0 @@
-import _ from 'lodash'
-import {form} from '../Defaults'
-import {baseConfig} from "./base";
-
-export default function () {
-
-    const ct = Ext.form.Panel.prototype.constructor
-    Ext.form.Panel.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "cols-container"), form)
-            ct.call(this, newConfig)
-        }
-    });
-}

+ 0 - 817
src/controls/grid.js

@@ -1,817 +0,0 @@
-import _ from 'lodash'
-import {grid} from '../Defaults'
-import {baseConfig} from "./base";
-import {lookupFn, lookupScope} from "../lib/lib";
-import LAY_EXCEL from "lay-excel"
-import {
-    disabled,
-    fieldLabel,
-    gravity,
-    height,
-    metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value,
-    width,
-    YvBase
-} from "../PropertyDescriptionTable";
-import {PropertyDescription} from "../PropertyDescription";
-import {gridInvokeBuild} from "./stores";
-import {msg} from 'src/message';
-
-
-const defaultGrid = grid
-export default function () {
-
-    Ext.define('Yvan.Grid', {
-        extend: 'Ext.grid.Panel',
-        xtype: 'yvgrid',
-
-        constructor(config) {
-            const me = this
-            const {dataSource} = config
-            if (!window["IS_DESIGN_MODE"]) {
-                this.columnConfigCacheKey = this.makeColumnConfigCacheKey(config)
-                if (Array.isArray(config.columns) && config.columns.length > 0) {
-                    const cacheData = this.getColumnConfigCache()
-                    if (Array.isArray(cacheData) && cacheData.length > 0) {
-                        const newColumns = []
-
-                        for (let j = 0; j < cacheData.length; j++) {
-                            const itData = cacheData[j]
-                            for (let i = 0; i < config.columns.length; i++) {
-                                const column = config.columns[i]
-                                if (itData.dataIndex === column.dataIndex) {
-                                    if (itData.width) {
-                                        column.width = itData.width
-                                    }
-                                    column.hidden = itData.hidden
-                                    column.locked = itData.locked
-                                    newColumns.push(column)
-                                    break
-                                }
-                            }
-                        }
-                        config.columns = newColumns
-                    }
-                }
-            }
-            const newConfig = _.defaultsDeep({
-                // 强制性属性 bug.
-                // lock 属性会造成 Cannot read properties of undefined (reading 'els')
-                // enableLocking: false,
-                // syncRowHeight: false,
-
-            }, baseConfig(config, 'row-item'), config, grid)
-
-            // 在面板上的组件
-            const scope = newConfig.$initParent.yvanScope || newConfig.$initParent.lookupReferenceHolder().yvanScope;
-
-            const buttons = []
-
-            const {getRowClass} = newConfig
-            if (typeof getRowClass === 'string' && (
-                _.startsWith(getRowClass, "scope.") ||
-                _.startsWith(getRowClass, "system."))
-            ) {
-                const fn = lookupFn(scope, getRowClass)
-                _.set(newConfig, 'viewConfig.getRowClass', fn)
-            }
-
-            if (!newConfig.hideExport) {
-                buttons.push({
-                    xtype: 'button',
-                    tooltip: '导出Excel',
-                    iconCls: 'x-fa fa-download',
-                    listeners: {
-                        click: this.exportExcel
-                    },
-                })
-            }
-            if (!newConfig.hideAutoSize) {
-                buttons.push({
-                    xtype: 'button',
-                    iconCls: 'x-fa fa-text-width',
-                    tooltip: '自适应宽度',
-                    listeners: {
-                        click: this.autoSizeColumns
-                    }
-                })
-            }
-            if (!newConfig.hideClearFilter) {
-                buttons.push({
-                    xtype: 'button',
-                    tooltip: '清空筛选',
-                    iconCls: 'x-fa fa-filter',
-                    handler: this.clearFilter
-                })
-            }
-            if (!newConfig.hideSaveGridUIConfig) {
-                buttons.push({
-                    xtype: 'button',
-                    tooltip: '保存表格自定义配置',
-                    iconCls: 'x-fa fa-cogs',
-                    handler: this.saveGridUIConfig
-                })
-            }
-            if (!newConfig.hideClearGridUIConfig) {
-                buttons.push({
-                    xtype: 'button',
-                    tooltip: '还原表格自定义配置',
-                    iconCls: 'x-fa fa-reply-all',
-                    handler: this.clearGridUIConfig
-                })
-            }
-
-            if (!newConfig.hideFootbar) {
-                if (newConfig.pagination) {
-                    newConfig.bbar = new Ext.PagingToolbar({
-                        // pageSize: newConfig.pageSize, 这个值是无效的
-                        displayInfo: true,
-                        store: this.store,
-                        emptyMsg: '没有记录',
-                        items: [
-                            {
-                                xtype: 'combobox',
-                                tooltip: '分页',
-                                queryMode: 'local',
-                                editable: false,
-                                allowBlank: true,
-                                labelAlign: 'right',
-                                width: 90,
-                                // labelWidth: 30,
-                                listConfig: {
-                                    minWidth: null
-                                },
-                                value: 50,
-                                valueField: undefined,
-                                displayField: undefined,
-                                hideClear: true,
-                                store: newConfig.pageSizeOption,
-                                listeners: {
-                                    change: (sender, nv, ov) => {
-                                        this.store.pageSize = nv;
-                                        this.store.loadPage(1);
-                                    }
-                                }
-                            },
-                            ...buttons
-                        ]
-                    })
-                } else {
-                    newConfig.bbar = {
-                        xtype: 'toolbar', overflowHandler: 'menu',
-                        items: [
-                            {
-                                xtype: 'button',
-                                tooltip: '刷新',
-                                iconCls: 'x-fa fa-refresh',
-                                handler: () => {
-                                    this.reload()
-                                }
-                            },
-                            '-',
-                            ...buttons,
-                        ]
-                    }
-                }
-            }
-
-            _.each(newConfig.columns, c => {
-                const {renderer} = c
-                if (typeof renderer === 'string' && (
-                    _.startsWith(renderer, "scope.") ||
-                    _.startsWith(renderer, "system."))
-                ) {
-                    if (newConfig.$initParent) {
-                        if (scope) {
-                            const rendererFn = lookupFn(scope, renderer)
-                            c.renderer = rendererFn
-                        }
-                    }
-                }
-            })
-
-            this.superclass.constructor.call(this, newConfig)
-            this.store.pageSize = newConfig.pageSize
-        },
-
-        setData(value) {
-            const me = this
-            me._setDataReal(value)
-        },
-
-        /**
-         * 添加行,并进入编辑状态
-         * @param record 新行的属性集
-         * @param editRowCol 要编辑的列序号,或 dataIndex 的名称
-         */
-        appendEditRow(record, editRowCol) {
-            const records = this.getStore().add(record)
-            const recNew = records[0]
-            this.setSelection(records)
-
-            if (typeof editRowCol === 'string' && editRowCol) {
-                editRowCol = this.columns.findIndex((c) => c.dataIndex === editRowCol)
-            }
-
-            if (typeof editRowCol === 'number') {
-                const ce = this.findPlugin('cellediting')
-                this.editingPlugin = ce
-                ce.startEdit(recNew, editRowCol)
-            }
-        },
-
-        /**
-         * 移除行
-         * @param record 如果记录传空,就是当前选中的行
-         */
-        removeEditRow(record) {
-            if (!record) {
-                record = this.selection
-            }
-
-            if (!record) {
-                msg('请选中要删除的行')
-                return
-            }
-
-            this.getStore().remove(record)
-        },
-
-        /**
-         * 获取全部原始数据
-         */
-        getDataRows() {
-            return this.getStore().data.items.map(r => r.data)
-        },
-
-        getEditRecord() {
-            const me = this
-            const editingPlugin = me.editingPlugin || me.ownerGrid.editingPlugin
-            const rowIdx = editingPlugin?.activeEditor?.context?.rowIdx
-
-            let record;
-            if (!rowIdx) {
-                record = me.getSelectionModel().getLastSelected()
-            } else {
-                record = me.store.getAt(rowIdx)
-            }
-
-            return record
-        },
-
-        getEditRow() {
-            const me = this
-            return me.getEditRecord()?.data
-        },
-
-        setEditRow(rowValues) {
-            const me = this
-            const record = me.getEditRecord()
-            if (record) {
-                _.forOwn(rowValues, (v, k) => {
-                    record.set(k, v)
-                })
-            }
-        },
-
-        _transform(data) {
-            // 无论是 grid._setDataReal 还是 stores.gridInvokeBuild 都会走这个函数,设值前都可以改变表格值
-            _.forEach(data, row => {
-                row._origin = _.clone(row)
-            })
-        },
-
-        _setDataReal(value) {
-            const me = this
-            this._transform(value)
-            me.setStore(new Ext.data.Store({
-                fields: getFileds(this),
-                data: value
-            }))
-        },
-
-        /**
-         * 轻量级刷新
-         */
-        refreshData() {
-            const store = this.getStore()
-            if (store) {
-                store.reload()
-            }
-        },
-
-        /**
-         * 为表格强制设置焦点
-         * @param seq 顺序号
-         */
-        focusRow(seq) {
-            this.setSelection(this.store.getAt(seq))
-            this.getView().focusRow(seq)
-        },
-
-        /**
-         * 重新载入数据(重新计算参数)
-         */
-        reload(reloadParams = {}) {
-            const me = this
-            const {config} = me
-
-            if (config.dataSourceCallbackFn) {
-                // 函数请求刷新
-                const scope = lookupScope(this)
-                _.defer(() => {
-                    me.setLoading(true)
-                })
-                config.dataSourceCallbackFn.call(scope, me, {
-                    successCallback(value) {
-                        me._setDataReal(value)
-                        _.defer(() => {
-                            me.setLoading(false)
-                        })
-                        me.fireEvent('dataLoadComplete', me, true, value);
-                    },
-                    failCallback(error) {
-                        _.defer(() => {
-                            me.setLoading(false)
-                        })
-                        me.fireEvent('dataLoadComplete', me, false, error);
-                    }
-                })
-                return
-            }
-
-            // if (this.store) {
-            //     this.store.reload({aaaa: 1, bbbb: 2})
-            // }
-            const {dataSource} = config
-            if (_.isPlainObject(dataSource) && !window["IS_DESIGN_MODE"]) {
-                const scope = lookupScope(me)
-                gridInvokeBuild(scope, me, config, dataSource, reloadParams)
-            }
-        },
-
-        exportCurrentExcelClick() {
-            const me = this
-            const {config} = me
-            const scope = lookupScope(me)
-            let excelFileName = config.excelFileName || scope.vjson.title || _.uniqueId("excel-")
-            if (excelFileName.endsWith(".xlsx")) {
-                excelFileName = excelFileName.split(".xlsx")[0]
-            }
-            excelFileName += ".xlsx"
-            const rowsAll = this.getStore().getData().items?.map(r => r.data);
-            const excelData = me.makeExcelData(rowsAll)
-            LAY_EXCEL.exportExcel(excelData, excelFileName, 'xlsx')
-
-        },
-
-        exportExcelClick(excelExportParams) {
-            const me = this
-            const {config} = me
-            excelExportParams.isExcelExport = true
-            const scope = lookupScope(me)
-            const {dataSource} = config
-
-            scope.setLoading(true)
-
-            let excelFileName = config.excelFileName || scope.vjson.title || _.uniqueId("excel-")
-
-            gridInvokeBuild(scope, me, config, dataSource, excelExportParams, true, (responseData) => {
-                let page = parseInt(responseData.pagination?.current) || 1
-                const size = parseInt(responseData.pagination?.size) || me.exportExcelPageSize
-                const total = parseInt(responseData.pagination?.total) || responseData.data?.length || 0
-
-                me.exportExcelCurrentPage = page
-                me.exportExcelPageSize = size
-                me.exportExcelTotal = total
-
-                if (excelFileName.endsWith(".xlsx")) {
-                    excelFileName = excelFileName.split(".xlsx")[0]
-                }
-                excelFileName += "(第" + me.exportExcelCurrentPage + "页,共" + Math.ceil(total / size) + "页、" + total + "条)"
-                excelFileName += ".xlsx"
-                const excelData = me.makeExcelData(responseData.data)
-                LAY_EXCEL.exportExcel(excelData, excelFileName, 'xlsx')
-
-                if (page < total / size) {
-                    page++
-                    me.exportExcelCurrentPage = page
-                }
-                scope.setLoading(false)
-            })
-        },
-
-        makeExcelData(jsonData) {
-            const me = this
-            me.fireEvent('onExcelDataLoadCompleted', me, jsonData);
-            if (!Array.isArray(jsonData) || jsonData.length === 0) {
-                return
-            }
-            const data = [];
-            // 获取表格的列定义
-            const headerTextArr = []
-            const headers = []
-            for (let i = 0; i < me.headerCt.getGridColumns().length; i++) {
-                const header = me.headerCt.getGridColumns()[i]
-                if (!header.isHidden()) {
-                    const textStr = _.trim(header.text)
-                    const dataIndexStr = _.trim(header.dataIndex)
-                    if (dataIndexStr) {
-                        if (textStr === '') {
-                            headerTextArr.push(dataIndexStr)
-                        } else {
-                            headerTextArr.push(textStr)
-                        }
-                        headers.push(header)
-                    }
-                }
-            }
-            if (headers.length === 0) {
-                return
-            }
-
-            data.push(headerTextArr)
-            for (let i = 0; i < jsonData.length; i++) {
-                const dataRow = jsonData[i]
-                const row = []
-                for (let j = 0; j < headers.length; j++) {
-                    const key = headers[j].dataIndex
-                    let value = dataRow[key]
-                    if (!value && value !== 0) {
-                        value = ''
-                    }
-                    const oValue = value
-                    if (typeof headers[j].renderer === 'function') {
-                        try {
-                            value = headers[j].renderer(value)
-                            if (!value && value !== 0) {
-                                value = oValue
-                            }
-                        } catch (e) {
-
-                            value = oValue
-                        }
-                    }
-                    row.push(value)
-                }
-                data.push(row)
-            }
-            return data
-        },
-
-        initComponent() {
-            const me = this
-            const {config} = me
-            const scope = lookupScope(this)
-
-            if (!window["IS_DESIGN_MODE"]) {
-                // 转换 dataSource 属性
-                convertDataSource(me, scope, config)
-            }
-
-            this.on({
-                afterrender(sender) {
-                    const me = this
-                    const {config} = this
-                    const {dataSource} = config
-
-                    if (config.autoLoad) {
-                        if (config.dataSourceCallbackFn) {
-                            me.reload()
-
-                        } else if (_.isPlainObject(dataSource)) {
-                            me.reload()
-                        }
-                    }
-
-                    if (config.contextMenu === true && _.isArray(config.tbar)) {
-                        const vm = this.lookupViewModel()
-                        this.contextMenu = this.add(new Ext.menu.Menu({
-                            viewModel: vm,
-                            items: _.map(config.tbar, item => {
-                                const menuItem = {
-                                    ...item
-                                }
-                                if (menuItem.xtype === 'button') {
-                                    delete menuItem.xtype
-                                }
-                                return menuItem
-                            })
-                        }))
-
-                    } else if (_.isPlainObject(config.contextMenu)) {
-                        this.contextMenu = this.add(config.contextMenu)
-                    }
-
-                    const $dom = $(sender.el.dom)
-                    $dom.on('keydown', (e) => {
-                        me.fireEvent('keydown', me, e,)
-
-                    }).on('keyup', (e) => {
-                        me.fireEvent('keyup', me, e,)
-                    })
-                },
-                itemcontextmenu(view, rec, node, index, e) {
-                    if (this.contextMenu) {
-                        e.stopEvent();
-                        this.contextMenu.show().setLocalXY(e.getXY());
-                        return false;
-                    }
-                },
-                // columnmove(sender, column, fromIndex, toIndex, eOpts) {
-                //     this.setColumnConfigCache()
-                // },
-                // columnhide(sender, column, eOpts) {
-                //     this.setColumnConfigCache()
-                // },
-                // columnshow(sender, column, eOpts) {
-                //     this.setColumnConfigCache()
-                // },
-                // columnresize(sender, column, width, eOpts) {
-                //     this.setColumnConfigCache()
-                // },
-                destory() {
-                },
-            })
-
-
-            if (this.store?.proxy) {
-                // 为 stores.proxy.buildRequest 做准备
-                this.store.proxy.$owner = this
-            }
-
-            this.superclass.initComponent.call(this)
-        },
-
-        // 生成列自定义的缓存key
-        makeColumnConfigCacheKey(config) {
-            const me = this
-            const scope = config.$initParent.yvanScope || config.$initParent.lookupReferenceHolder().yvanScope;
-            let key = "gridColumnCache-" + scope.scopeKey + "-"
-            if (config.reference) {
-                key += config.reference
-            } else {
-                let subKey = ""
-                for (let i = 0; i < config.columns.length; i++) {
-                    const column = config.columns[i]
-                    if (column.dataIndex) {
-                        subKey += column.dataIndex
-                    }
-                }
-                key += subKey
-            }
-            return key
-        },
-
-        getColumnConfigCache() {
-            const key = this.columnConfigCacheKey
-            const dataStr = localStorage.getItem(key)
-            if (dataStr) {
-                return JSON.parse(dataStr)
-            }
-            return ""
-        },
-
-        setColumnConfigCache() {
-            const key = this.columnConfigCacheKey
-            const cacheData = []
-            const columns = this.headerCt.getGridColumns()
-            let index = 0
-            for (let i = 0; i < columns.length; i++) {
-                const column = columns[i]
-                if (column.dataIndex) {
-                    cacheData.push({
-                        dataIndex: column.dataIndex,
-                        width: column.width,
-                        hidden: column.hidden,
-                        locked: column.locked,
-                        index
-                    })
-                    index++
-                }
-            }
-            localStorage.setItem(key, JSON.stringify(cacheData))
-        },
-
-        autoSizeColumns(sender) {
-            const grid = sender.up('grid')
-            // const columns = grid.columns;
-            // for (let i = 0; i < columns.length; i++) {
-            //     const column = columns[i];
-            //     grid.getView().autoSizeColumn(column);
-            //     column.setWidth(column.getWidth() + 5);
-            // }
-            for (let i = 1; i < grid.headerCt.getColumnCount(); i++) {
-                grid.headerCt.getGridColumns()[i].autoSize(i);
-                grid.headerCt.getGridColumns()[i].setWidth(grid.headerCt.getGridColumns()[i].getWidth() + 15);
-            }
-        },
-
-        clearFilter(sender) {
-            const grid = sender.up('grid')
-            grid.filters.clearFilters()
-            grid.getStore().sorters.removeAll()
-            // grid.getStore().reload()
-        },
-
-        saveGridUIConfig(sender) {
-            const grid = sender.up('grid')
-            grid.setColumnConfigCache()
-            msg('保存设置成功!')
-        },
-
-        clearGridUIConfig(sender) {
-            const grid = sender.up('grid')
-            const key = grid.columnConfigCacheKey
-            localStorage.setItem(key, "")
-            msg('清空设置成功,重新打开后生效!')
-        },
-
-        setLoading(value) {
-            if (value) {
-                this.mask('读取中')
-            } else {
-                this.unmask()
-            }
-        },
-
-        exportExcel(sender) {
-            const rect = sender.btnEl.dom.getBoundingClientRect()
-            const scope = lookupScope(this)
-            const grid = sender.up('grid')
-            const treeMenu = new Ext.menu.Menu(
-                {
-                    xtype: 'menu',
-                    floated: false,
-                    width: 300,
-                    docked: 'left',
-                    items: [{
-                        text: '导出表格当前的数据',
-                        iconCls: 'x-fa fa-download',
-                        listeners: {
-                            click: (sender, value) => {
-                                grid.exportCurrentExcelClick()
-                            }
-                        }
-                    }, {
-                        xtype: "textfield",
-                        fieldLabel: '当前导出页',
-                        maskRe: /[0-9]/,
-                        value: grid.exportExcelCurrentPage,
-                        listeners: {
-                            render: (sender) => {
-                                grid.exportExcelCurrentPageCmp = sender
-                            },
-                            change: (sender, value) => {
-                                let v = parseInt(value)
-                                if (isNaN(v) || v === 0) {
-                                    window['system'].msg("页码不能为0")
-                                    v = 1
-                                    sender.setValue(v)
-                                }
-                                const size = parseInt(grid.exportExcelPageSize)
-                                const total = parseInt(grid.exportExcelTotal)
-                                if (v > total / size) {
-                                    v = parseInt(total / size + "")
-                                }
-                                grid.exportExcelCurrentPage = v + ""
-                            }
-                        }
-                    }, {
-                        xtype: "textfield",
-                        fieldLabel: '导出页大小',
-                        maskRe: /[0-9]/,
-                        value: grid.exportExcelPageSize,
-                        listeners: {
-                            render: (sender) => {
-                                grid.exportExcelPageSizeCmp = sender
-                            },
-                            change: (sender, value) => {
-                                let v = parseInt(value)
-                                if (isNaN(v) || v === 0) {
-                                    window['system'].msg("导出页大小不能为0")
-                                    v = defaultGrid.exportExcelPageSize
-                                    sender.setValue(v);
-                                }
-                                if (v > 10000) {
-                                    window['system'].msg("导出页大小不能大于10000")
-                                    v = 10000
-                                    sender.setValue(v);
-                                }
-                                let page = parseInt(grid.exportExcelCurrentPage)
-                                const total = parseInt(grid.exportExcelTotal)
-                                if (page > total / v) {
-                                    page = parseInt(total / v + "") + 1
-                                    grid.exportExcelCurrentPageCmp.setValue(page)
-                                }
-                                grid.exportExcelPageSize = v + ""
-                            }
-                        }
-                    }, {
-                        xtype: "textfield",
-                        fieldLabel: '总条数',
-                        value: grid.exportExcelTotal,
-                        readOnly: true
-                    }, {
-                        text: '导出',
-                        iconCls: 'x-fa fa-download',
-                        listeners: {
-                            click: (sender, value) => {
-                                grid.exportExcelClick({
-                                    exportExcelPageSize: grid.exportExcelPageSize,
-                                    exportExcelCurrentPage: grid.exportExcelCurrentPage
-                                })
-                            }
-                        }
-                    }]
-                }
-            );
-            treeMenu.showAt(rect.left, rect.top - 120);
-
-            // for (let i = 1; i < grid.headerCt.getColumnCount(); i++) {
-            //     grid.headerCt.getGridColumns()[i].autoSize(i);
-            //     grid.headerCt.getGridColumns()[i].setWidth(grid.headerCt.getGridColumns()[i].getWidth() + 15);
-            // }
-        }
-
-        // reload() {
-        //     dataSourceReload(this)
-        // },
-    })
-
-
-    PropertyDescriptionTable.set(
-        'yvgrid',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-}
-
-/**
- * 获取 columns 中所有的 dataIndex
- */
-function getFileds(newConfig) {
-    const fields = []
-    _.forEach(newConfig.columns, c => {
-        if (c.dataIndex) {
-            fields.push(c.dataIndex)
-        }
-    })
-    return fields
-}
-
-function convertDataSource(sender, scope, newConfig) {
-    if (typeof newConfig.store !== 'undefined') {
-        // 有 store 属性的情况下,不做任何事
-        return
-    }
-
-    if (typeof newConfig.dataSource === 'undefined') {
-        // 没有定义 dataSource 的情况下,不做任何事
-        return
-    }
-
-    if (_.isArray(newConfig.data)) {
-        // 有 data 属性赋值的情况下
-        newConfig.store = {
-            fields: getFileds(newConfig),
-            data: newConfig.data
-        }
-        delete newConfig.data
-        return
-    }
-
-    let {dataSource} = newConfig
-    if (typeof dataSource === 'string') {
-        // dataSource 是字符串的情况下,找到成员函数
-        dataSource = lookupFn(scope, dataSource)
-    }
-
-    if (typeof dataSource === 'function') {
-        // dataSource 是函数的情况下,在 afterrender 之后进行回调
-        newConfig.store = new Ext.data.Store({
-            fields: getFileds(newConfig),
-            // data: [],
-            autoLoad: true,
-            proxy: {
-                type: 'memory',
-                data: [],
-                // reader: {
-                //     type: 'json',
-                //     rootProperty: 'users'
-                // }
-            }
-        })
-        newConfig.dataSourceCallbackFn = dataSource
-        return
-    }
-
-
-    // throw new TypeError('无法识别的调用方法')
-}

+ 0 - 34
src/controls/gridcolumn.js

@@ -1,34 +0,0 @@
-import _ from "lodash";
-import {baseConfig} from "./base";
-import {column} from "../Defaults";
-
-export default function () {
-
-    const ct = Ext.grid.column.Column.prototype.constructor
-    Ext.grid.column.Column.override({
-        constructor: function (config) {
-            const newConfig = _.defaults({}, config, column)
-            ct.call(this, newConfig)
-        }
-    });
-
-    // 227573
-    // const {onTitleElClick} = Ext.grid.column.Column.prototype
-    // Ext.define('Yvan.ColumnOverride', {
-    //     override: 'Ext.grid.column.Column',
-    //
-    //     config: {
-    //         enableSortOnClick: false,
-    //     },
-    //
-    //     // /**@Overrides*/
-    //     onTitleElClick: function (e, t, sortOnClick) {
-    //         // return this.callParent([e, t, this.enableSortOnClick && sortOnClick]);
-    //         if (!$(e.target).is('.x-column-header-trigger')) {
-    //             // 不是点击菜单的情况下,让列自适应宽度
-    //             this.autoSize()
-    //         }
-    //         return onTitleElClick.call(this, e, t, false)
-    //     }
-    // });
-}

+ 0 - 87
src/controls/iframe.js

@@ -1,87 +0,0 @@
-export default function () {
-    Ext.define('Ext.ux.IFrame', {
-        extend: 'Ext.Component',
-        alias: 'widget.uxiframe',
-        loadMask: 'Loading...',
-        src: 'about:blank',
-        renderTpl: [
-            '<iframe src="{src}" id="{id}-iframeEl" data-ref="iframeEl" name="{frameName}" width="100%" height="100%" frameborder="0"></iframe>'
-        ],
-        childEls: ['iframeEl'],
-
-        initComponent: function () {
-            this.superclass.initComponent.call(this)
-            this.superclass.initEvents.call(this)
-            this.frameName = this.frameName || this.id + '-frame';
-        },
-
-        initEvents: function () {
-            var me = this;
-            this.superclass.initEvents.call(this)
-            me.iframeEl.on('load', me.onLoad, me);
-        },
-
-        initRenderData: function () {
-            return Ext.apply(this.superclass.initRenderData.call(this), {
-                src: this.src,
-                frameName: this.frameName
-            });
-        },
-
-        getBody: function () {
-            var doc = this.getDoc();
-            return doc.body || doc.documentElement;
-        },
-
-        getDoc: function () {
-            try {
-                return this.getWin().document;
-            } catch (ex) {
-                return null;
-            }
-        },
-
-        getWin: function () {
-            var me = this,
-                name = me.frameName,
-                win = Ext.isIE ? me.iframeEl.dom.contentWindow : window.frames[name];
-            return win;
-        },
-
-        getFrame: function () {
-            var me = this;
-            return me.iframeEl.dom;
-        },
-
-        onLoad: function () {
-            var me = this,
-                doc = me.getDoc();
-
-            if (doc) {
-                this.el.unmask();
-                this.fireEvent('load', this);
-
-            } else if (me.src) {
-
-                this.el.unmask();
-                this.fireEvent('error', this);
-            }
-
-
-        },
-
-        load: function (src) {
-            var me = this,
-                text = me.loadMask,
-                frame = me.getFrame();
-
-            if (me.fireEvent('beforeload', me, src) !== false) {
-                if (text && me.el) {
-                    me.el.mask(text);
-                }
-
-                frame.src = me.src = (src || me.src);
-            }
-        }
-    });
-}

+ 0 - 82
src/controls/input/checkbox.js

@@ -1,82 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {checkbox} from "../../Defaults";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    const cc = Ext.form.field.Checkbox.prototype.constructor
-    const {initComponent, getValue, setValue} = Ext.form.field.Checkbox.prototype
-    Ext.form.field.Checkbox.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, baseConfig(config, 'col-item'), config, checkbox)
-
-            cc.call(this, newConfig)
-        },
-
-        getValue() {
-            const {checkedValue, uncheckedValue} = this
-            const ov = getValue.call(this)
-            // const ov = this.getRawValue()
-            return (ov ? checkedValue : uncheckedValue)
-        },
-
-
-        setValue(nv) {
-            const me = this
-            const {checkedValue, uncheckedValue} = this
-            let value
-            if (nv === checkedValue) {
-                value = true
-            } else if (nv === uncheckedValue) {
-                value = false
-            } else {
-                value = !!nv
-            }
-
-            // me.setRawValue(value)
-            // me.checked = value
-            // return me.mixins.field.setValue.call(me, value);
-            setValue.call(this, value)
-        },
-
-        updateCheckedCls: function (checked) {
-            const me = this;
-            const {uncheckedValue, checkedValue} = this
-            checked = checked != null ? checked : me.getValue();
-            if (checked === uncheckedValue) {
-                checked = false
-            } else if (checked === checkedValue) {
-                checked = true
-            }
-            me[checked ? 'addCls' : 'removeCls'](me.checkedCls);
-        },
-
-        initComponent() {
-            initComponent.call(this)
-        },
-    });
-
-    PropertyDescriptionTable.set(
-        'checkbox',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 44
src/controls/input/checkboxgroup.js

@@ -1,44 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {checkboxgroup} from "../../Defaults";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    const cc = Ext.form.CheckboxGroup.prototype.constructor
-    const {initComponent} = Ext.form.CheckboxGroup.prototype
-    Ext.form.CheckboxGroup.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, baseConfig(config, 'col-item'), config, checkboxgroup)
-
-            cc.call(this, newConfig)
-        },
-
-        initComponent() {
-            initComponent.call(this)
-        },
-    });
-
-    PropertyDescriptionTable.set(
-        'checkboxgroup',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 151
src/controls/input/combo.js

@@ -1,151 +0,0 @@
-import _ from 'lodash'
-import {combo} from '../../Defaults'
-import {baseConfig} from "../base";
-import {dataSourceReload} from "../../DataSourceHelper";
-import {keywordFilter} from '../../lib/config'
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-    const cc = Ext.form.field.ComboBox.prototype.constructor
-    const {initComponent, setData} = Ext.form.field.ComboBox.prototype
-    Ext.form.field.ComboBox.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制性属性
-
-            }, baseConfig(config, 'col-item'), config, combo)
-
-            if (typeof newConfig.store == 'undefined') {
-                if (_.isArray(newConfig.data)) {
-                    // ExtJS 无法直接接受数组模式
-                    newConfig.store = {
-                        fields: [newConfig.valueField, newConfig.displayField],
-                        data: newConfig.data
-                    }
-                    delete newConfig.data
-
-                } else if (typeof newConfig.data !== 'object') {
-                    newConfig.store = {
-                        fields: [newConfig.valueField, newConfig.displayField],
-                        data: []
-                    }
-                    delete newConfig.data
-                }
-            }
-
-            cc.call(this, newConfig)
-        },
-
-        setData(value) {
-            if (!value) {
-                return
-            }
-            const {config} = value
-            if (!this.store) {
-                this.store = new Ext.data.Store({
-                    fields: [config.valueField, config.displayField],
-                    data: value
-                })
-            } else {
-                this.store.getProxy().setData(value)
-                this.store.load()
-            }
-        },
-
-        setLoading(value) {
-            if (value) {
-                if (!this.loadMask) {
-                    this.loadMask = new Ext.LoadMask(this, {msg: "loading..."});
-                }
-            } else {
-                if (this.loadMask) {
-                    this.loadMask.destroy()
-                    delete this.loadMask
-                }
-            }
-        },
-
-        reload() {
-            dataSourceReload(this)
-        },
-
-        initComponent() {
-            const that = this
-            const toggle = function (e) {
-                const {readOnly, disabled} = that
-                if (readOnly || disabled) {
-                    return
-                }
-
-                if ($(e.target).is('.x-form-trigger')) {
-                    return
-                }
-
-                // 点击后下拉
-                if (that.isExpanded) {
-                    that.collapse()
-
-                } else {
-                    that.expand();
-                    that.doQuery(that.allQuery, true);
-                }
-            }
-
-            this.on({
-                afterrender() {
-                    const {config} = this
-
-                    if (config.dataSource && config.autoLoad) {
-                        dataSourceReload(this)
-                    }
-
-                    // 点击后下拉
-                    $(this.el.dom).on('click', toggle.bind(this))
-                },
-                destory() {
-                    $(this.el.dom).off('click', toggle.bind(this))
-                },
-                // beforequery(e) {
-                //     const {query, combo} = e
-                //
-                //     if (!e.forceAll && query) {
-                //         combo.store.filterBy(function (record, id) {
-                //             const text = record.get(combo.displayField)
-                //             // 用拼音筛选的方式
-                //             return keywordFilter(query, text, id)
-                //         });
-                //         combo.expand();
-                //         return false;
-                //     }
-                //
-                //     combo.store.clearFilter()
-                //     combo.expand();
-                //     return false;
-                // }
-            })
-
-            initComponent.call(this)
-        },
-
-    });
-
-    PropertyDescriptionTable.set(
-        'combo',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 442
src/controls/input/combogrid.js

@@ -1,442 +0,0 @@
-import _ from 'lodash'
-import {comboGrid, comboGridPicker} from '../../Defaults'
-import {
-    calcObjectFlat,
-    lookupScope,
-    tryEnable,
-    stopEvent,
-    tryVarSimple,
-    tryWriteObject
-} from "../..";
-import {msg} from "../../message";
-import {isChartEvent} from '../../utils'
-
-export default function () {
-
-    Ext.define('Yvan.ComboGrid', {
-        extend: 'Ext.form.field.Picker',
-        // extend: 'Yvan.PickerAlignCenter',
-        xtype: 'combogrid',
-
-        triggerCls: Ext.baseCSSPrefix + 'form-search-trigger',
-
-        triggers: {
-            clear: {
-                weight: 0,
-                cls: Ext.baseCSSPrefix + 'form-clear-trigger',
-                hidden: true,
-                handler: 'onClearClick',
-            },
-        },
-
-        config: {
-            ...comboGrid
-        },
-
-        editable: true,
-        _superBlur: false,
-        allowCustomInput: false,
-
-        initComponent() {
-            const that = this
-
-            this.on({
-                blur(sender, e) {
-                    if (this._superBlur) {
-                        // 挂起时不恢复内容
-                        return
-                    }
-
-                    // 离开焦点时,恢复原来的值
-                    sender.setRawValue(sender.value)
-                },
-                afterrender(sender) {
-                    const $dom = $(sender.inputEl.dom)
-                    that.scope = lookupScope(sender)
-
-                    if (sender.column) {
-                        // 列模式,拦截 keydown
-                        $dom.on('keydown', (e) => {
-                            if (isChartEvent(e) && !that.tryEnable()) {
-                                // 没有达成 editEnable 条件,不用响应
-                                stopEvent(e)
-                                return
-                            }
-
-                            if (e.key === 'Enter') {
-                                stopEvent(e)
-                                that.onTriggerClick(that, that.getPickerTrigger(), e);
-                                return
-                            }
-                        })
-
-                    } else {
-                        // 常规模式,拦截 keyup
-                        $dom.on('keyup', (e) => {
-                            if (e.key === 'Escape' || e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
-                                return
-                            }
-
-                            if (isChartEvent(e) && !that.tryEnable()) {
-                                // 没有达成 editEnable 条件,不用响应
-                                stopEvent(e)
-                                return
-                            }
-
-                            if (e.key === 'Enter') {
-                                stopEvent(e)
-                                that.onTriggerClick(that, that.getPickerTrigger(), e);
-                                return
-                            }
-
-                            if (!that.allowCustomInput) {
-                                // 取消 keyup 事件,让 ext 不要吧当前输入的值记录到 value 中
-                                stopEvent(e)
-                            }
-                        })
-                        $dom.on('change', e => {
-                            // 这里注释掉,是因为 当鼠标点击触发弹出后,会导致取"e.target.value"值无效
-                            // if (that.isExpanded) {
-                            //     that.filterChange(that, e.target.value)
-                            // }
-                            stopEvent(e)
-                        })
-                    }
-                    $dom.on('input', e => {
-                        stopEvent(e)
-                    })
-                },
-                // 这里不能用 specialkey, 在表格编辑时可能出 bug
-                // specialkey(sender, e) {
-                //     const me = this
-                //     if (e.getKey() === e.ENTER) {
-                //         _.defer(() => {
-                //             toggle();
-                //         })
-                //         e.stopEvent()
-                //         return
-                //     }
-                // },
-            })
-
-            this.superclass.initComponent.apply(this, arguments)
-        },
-
-        createPicker() {
-            const me = this
-            const cfg = {
-                layout: 'fit',
-                border: 5,
-                style: {
-                    borderColor: 'black',
-                    borderWidth: '5px',
-                    borderStyle: 'solid'
-                },
-                shadow: 'side',
-                shadowOffset: 100,
-                baseCls: Ext.baseCSSPrefix + 'boundlist',
-                shrinkWrapDock: 2,
-                floating: true,
-                width: me.pickerWidth,
-                height: me.pickerHeight,
-                minWidth: me.pickerWidth,
-                minHeight: me.pickerHeight,
-                maxWidth: me.pickerWidth,
-                maxHeight: me.pickerHeight,
-                items: [
-                    {
-                        ...comboGridPicker,
-                        ...me.grid,
-                        tbar: {
-                            xtype: 'toolbar',
-                            items: [
-                                {xtype: 'textfield', fieldLabel: '筛选'},
-                                {
-                                    xtype: 'button',
-                                    text: '查询',
-                                    iconCls: 'x-fa fa-search',
-                                    cssType: 'primary',
-                                    listeners: {
-                                        click: () => {
-                                            me.reloadGrid()
-                                        }
-                                    }
-                                },
-                            ]
-                        },
-                        autoLoad: false,
-                        listeners: {
-                            afterrender(grid) {
-                                me.grid = grid
-                                grid.focus()
-                                grid.on({
-                                    rowdblclick(sender, row) {
-                                        me.selectItem(row)
-                                    },
-                                    dataLoadComplete(sender) {
-                                        _.defer(() => {
-                                            me.setFocus()
-                                        })
-                                    },
-                                    keydown(sender, e) {
-                                        if (me.column) {
-                                            // 列模式,拦截 keydown
-                                            me.processKey(e)
-                                        }
-                                    },
-                                    keyup(sender, e) {
-                                        if (!me.column) {
-                                            // 常规模式,拦截 keyup
-                                            me.processKey(e)
-                                        }
-                                    }
-                                })
-                            },
-                        }
-                    }
-                ]
-            }
-            // @ts-ignore
-            const picker = new Ext.container.Container(cfg)
-            return picker;
-        },
-
-        setFocus() {
-            if (this.grid.store.getCount() > 0) {
-                this.grid.focusRow(0)
-            }
-        },
-
-        processKey(e) {
-            if (e.key === 'Enter') {
-                this.selectItem(this.grid.selection)
-                stopEvent(e)
-
-            } else if (e.key === 'Escape') {
-                this.collapse()
-            }
-        },
-
-        repaintPickerView() {
-            const style = this.picker.getView().getEl().dom.style;
-            style.display = style.display;
-        },
-
-        onItemClick(view, record, node, rowIndex, e) {
-            this.selectItem(record);
-        },
-
-        onPickerKeyDown(treeView, record, item, index, e) {
-            const key = e.getKey();
-            if (key === e.ENTER || (key === e.TAB && this.selectOnTab)) {
-                this.selectItem(record);
-            }
-        },
-
-        filterChange: _.debounce((sender, value) => {
-            sender.onExpand()
-
-        }, 1000),
-
-        selectItem(record) {
-            const me = this;
-            const {lookup} = this
-            const scope = lookupScope(this)
-
-            me.fireEvent('select', me, record)
-
-            if (record.isModel) {
-                record = record.data
-            }
-
-            tryWriteObject(lookup, record, (path, value) => {
-                me._lookupSet(path, value)
-            })
-            // lookup
-            // fromColumn: 'toTarget'
-            // fromColumn: 'toTarget'
-            // fromColumn: 'toTarget'
-            _.forOwn(lookup, (toTarget, fromColumn) => {
-                const value = _.get(record, fromColumn)
-                me._lookupSet(toTarget, value)
-            })
-
-            // 选定之后不能做清空
-            // const {lookupClearOnChange} = me
-            // if (_.isArray(lookupClearOnChange)) {
-            //     _.each(lookupClearOnChange, item => {
-            //         me._lookupSet(item, '')
-            //     })
-            // }
-
-            me.collapse();
-        },
-
-        onExpand() {
-            // 展开时,根据 lookup 带入查询参数
-            const expressData = this.getExpressData()
-            const txtField = this.grid.down('toolbar').down('textfield')
-            txtField.setValue(expressData.queryValue)
-            this.reloadGrid()
-        },
-
-        reloadGrid() {
-            // 展开时,根据 lookup 带入查询参数
-            const expressData = this.getExpressData()
-            const reloadParam = calcObjectFlat(expressData, this.param) || {}
-
-            const txtField = this.grid.down('toolbar').down('textfield')
-
-            // 每个 combogrid 默认带上 __queryValue 属性
-            reloadParam["__queryValue"] = txtField.getValue()
-            this.grid.reload(reloadParam)
-        },
-
-        onTriggerClick(sender) {
-            const {isExpanded, readOnly, disabled, grid,} = this
-
-            if (!grid) {
-                msg('正在初始化,请稍后')
-                return
-            }
-
-            if (!this.tryEnable()) {
-                // 没有达成 editEnable 条件,不用弹出
-                return
-            }
-
-            if (isExpanded || readOnly || disabled) {
-                // 已弹出、只读、禁用状态下,不允许弹出
-                return
-            }
-
-            this._superBlur = true
-            this.superclass.onTriggerClick.apply(this, arguments)
-            this._superBlur = false
-        },
-
-        onCollapse() {
-            // 每次收回时,删除下拉组件
-            // delete this.picker
-        },
-
-        /**
-         * 本方法只会从 API 或外部调用,键盘输入的内容不会记录在内
-         */
-        setValue(value) {
-            const me = this
-
-            // 设值用户看到的表面内容
-            this.setRawValue(value)
-
-            // 设值 setValue 调用链,正常触发 change 事件等
-            return me.mixins.field.setValue.call(me, value)
-        },
-
-        _lookupSet(path, value) {
-            const me = this
-            path = tryVarSimple(path)
-
-            if (me.column) {
-
-                // 判断写入目标,是否与自己绑定的属性相等
-                if (path === 'queryValue' || me.column.dataIndex === path) {
-                    me.setValue(value)
-                }
-
-                // 列模式下,写当前编辑行
-                const parentRecord = me._lookupEditorRecord()
-                if (parentRecord) {
-                    // Ext.data.Record / Ext.data.Model
-                    parentRecord.set(path, value)
-                } else {
-                    debugger
-                }
-
-            } else {
-                // 常规模式下,写 viewModel
-                me.scope.viewModel.set(path, value)
-            }
-        },
-
-        _lookupGrid() {
-            return this.column.up('grid')
-        },
-
-        _lookupEditorRecord() {
-            // parentGrid.getSelectionModel().getLastSelected()
-            const grid = this._lookupGrid()
-            const rowIdx = grid.editingPlugin?.activeEditor?.context?.rowIdx
-            if (_.isNumber(rowIdx)) {
-                return grid.store.getAt(rowIdx)
-            } else {
-                return grid.getSelectionModel().getLastSelected()
-            }
-        },
-
-        onChange: function (newVal, oldVal) {
-            const me = this
-            const value = newVal
-
-            if (value) {
-                me.getTrigger('clear').show();
-                me.updateLayout();
-            } else {
-                me.getTrigger('clear').hide();
-                me.updateLayout();
-            }
-        },
-
-        /**
-         * 得到能用于 express 表达式计算的上下文数据
-         */
-        getExpressData() {
-            const queryValue = this.getRawValue()
-
-            if (this.column) {
-                // 列模式, 准备好判断 editEnable 表达式用的数据
-                const parentRecord = this._lookupEditorRecord()
-                if (!parentRecord) {
-                    debugger
-                }
-
-                return {
-                    ...this.scope.viewModel.data,
-                    ...parentRecord.data,
-                    queryValue,
-                }
-
-            } else {
-                // 编辑模式,准备好判断用的数据
-                return {
-                    ...this.scope.viewModel.data,
-                    queryValue,
-                }
-            }
-        },
-
-        tryEnable() {
-            return tryEnable(this.getExpressData(), this.editEnable)
-        },
-
-        /**
-         * 清空所有值
-         */
-        onClearClick(sender, e) {
-            const me = this
-            const {lookup, lookupClearOnChange} = me
-
-            me.fireEvent('clear', sender, e)
-
-            me.setValue('')
-            _.forOwn(lookup, (toTarget, fromColumn) => {
-                me._lookupSet(toTarget, '')
-            })
-
-            _.each(lookupClearOnChange, item => {
-                me._lookupSet(item, '')
-            })
-        }
-    });
-
-}

+ 0 - 228
src/controls/input/combogridmulti.js

@@ -1,228 +0,0 @@
-import _ from 'lodash'
-import {comboGridMulti, comboGridMultiPicker} from '../../Defaults'
-import {msg} from "../../message";
-import {dataSourceReload} from "../../DataSourceHelper";
-
-export default function () {
-
-    Ext.define('Yvan.LocalComboGrid', {
-        extend: 'Ext.form.field.Picker',
-        // extend: 'Yvan.PickerAlignCenter',
-        xtype: 'combogridmulti',
-
-        triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
-
-        config: {
-            ...comboGridMulti,
-            store: null,
-            displayField: null,
-            columns: null,
-            selectOnTab: true,
-            maxPickerHeight: 300,
-            minPickerHeight: 100,
-            minPickerWidth: 350,
-            rootVisible: true,
-        },
-
-        editable: false,
-
-        initComponent() {
-            this.on({
-                afterrender() {
-                    const {config} = this
-
-                    if (config.dataSource && config.autoLoad) {
-                        dataSourceReload(this)
-                    }
-                },
-            })
-
-            this.superclass.initComponent.apply(this, arguments)
-        },
-
-        setStore(store) {
-            this.store = store
-            const me = this;
-            if (me.store) {
-                if (me.picker) {
-                    me.picker.setStore(store)
-                    if (me.isExpanded) {
-                        me.collapse()
-                        delete me.picker
-                        me.expand()
-                    }
-                }
-                this.onLoad()
-                me.mon(me.store, {
-                    scope: me,
-                    load: me.onLoad,
-                    update: me.onUpdate
-                });
-            }
-        },
-
-        reload() {
-            dataSourceReload(this)
-        },
-
-        setData(value) {
-            const me = this
-            const {config} = me
-            if (!value) {
-                return
-            }
-
-            if (!this.store) {
-                this.store = new Ext.data.Store({
-                    fields: [config.valueField, config.displayField],
-                    data: value
-                })
-            } else {
-                this.store.getProxy().setData(value)
-                this.store.load()
-            }
-
-            this.onLoad()
-        },
-
-        createPicker() {
-            const me = this
-            const picker = new Ext.grid.Panel({
-                    ...comboGridMultiPicker,
-                    border: false,
-                    baseCls: Ext.baseCSSPrefix + 'boundlist',
-                    shrinkWrapDock: 2,
-                    store: me.store,
-                    floating: true,
-                    displayField: me.displayField,
-                    columns: me.columns,
-                    minHeight: me.minPickerHeight,
-                    maxHeight: me.maxPickerHeight,
-                    minWidth: me.minPickerWidth,
-                    manageHeight: false,
-                    shadow: false,
-                    scrollable: true,
-                    listeners: {
-                        scope: me,
-                        selectionchange: me.onSelectionChange,
-                        itemkeydown: me.onPickerKeyDown
-                    }
-                }),
-                view = picker.getView();
-
-            if (Ext.isIE9 && Ext.isStrict) {
-                view.on({
-                    scope: me,
-                    highlightitem: me.repaintPickerView,
-                    unhighlightitem: me.repaintPickerView,
-                    afteritemexpand: me.repaintPickerView,
-                    afteritemcollapse: me.repaintPickerView
-                });
-            }
-            return picker;
-        },
-
-        repaintPickerView() {
-            const style = this.picker.getView().getEl().dom.style;
-            style.display = style.display;
-        },
-
-        onSelectionChange(view, record, node, rowIndex, e) {
-            this.selectItem(view, record);
-        },
-
-        onPickerKeyDown(treeView, record, item, index, e) {
-            const key = e.getKey();
-            if (key === e.ENTER || (key === e.TAB && this.selectOnTab)) {
-                this.selectItem(treeView, record);
-            }
-        },
-
-        selectItem(sender, record) {
-            const me = this;
-            const ids = []
-            _.forEach(me.picker.getSelection(), record => {
-                ids.push(record.get(me.valueField))
-            })
-            me.fireEvent('select', me, record);
-            me.setValue(ids.join(me.splitChar));
-            // me.collapse();
-        },
-
-        onExpand() {
-            const me = this
-            const picker = this.picker;
-            const value = this.value;
-
-            if (!me.store) {
-                msg('正在初始化数据,请稍后')
-                me.collapse()
-                return
-            }
-
-            const vs = _.split(value, me.splitChar)
-            const records = me.store.queryRecordsBy((r) => _.findIndex(vs, (i) => r.get(me.valueField) === i) >= 0)
-            picker.setSelection(records)
-        },
-
-        setValue(value) {
-            const me = this;
-            console.log('setValue', value)
-            me.value = value;
-
-            if (!me.store || me.store.loading) {
-                // Called while the Store is loading. Ensure it is processed by the onLoad method.
-                return me.mixins.field.setValue.call(me, value);
-                // return me;
-            }
-
-            const vs = _.split(value, me.splitChar)
-
-            const displayValues = []
-            _.forEach(vs, v => {
-                const record = me.store.queryRecordsBy((r) => r.get(me.valueField) === v)
-                const dv = record[0]?.get(me.displayField)
-                if (dv) {
-                    displayValues.push(dv)
-                } else {
-                    displayValues.push(v)
-                }
-            })
-
-            // set the raw value to the record's display field if a record was found
-            me.setRawValue(displayValues.join(me.splitChar));
-
-            return me.mixins.field.setValue.call(me, value);
-        },
-
-        getSubmitValue() {
-            return this.value;
-        },
-
-        getValue() {
-            return this.value;
-        },
-
-        onLoad() {
-            const value = this.value;
-
-            if (value) {
-                this.setValue(value);
-            }
-        },
-
-        onUpdate(store, rec, type, modifiedFieldNames) {
-            const display = this.displayField;
-            const me = this
-
-            if (type === 'edit' && modifiedFieldNames &&
-                Ext.Array.contains(modifiedFieldNames, display) &&
-                this.value === rec.getId()) {
-
-                me.mixins.field.setValue.call(me, this.value);
-                this.setRawValue(rec.get(display));
-            }
-        }
-    });
-
-}

+ 0 - 187
src/controls/input/combotree.js

@@ -1,187 +0,0 @@
-export default function () {
-
-    Ext.define('Yvan.ComboTree', {
-        extend: 'Ext.form.field.Picker',
-        xtype: 'combotree',
-
-        triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
-
-        config: {
-            store: null,
-            displayField: null,
-            columns: null,
-            selectOnTab: true,
-            maxPickerHeight: 300,
-            minPickerHeight: 100,
-            minPickerWidth: 350,
-            rootVisible: true,
-        },
-
-        editable: false,
-
-        setStore(store) {
-            this.store = store
-            const me = this;
-            if (me.store) {
-                if (me.picker) {
-                    me.picker.setStore(store)
-                    if (me.isExpanded) {
-                        me.collapse()
-                        delete me.picker
-                        me.expand()
-                    }
-                }
-                this.onLoad()
-                me.mon(me.store, {
-                    scope: me,
-                    load: me.onLoad,
-                    update: me.onUpdate
-                });
-            }
-        },
-
-        createPicker() {
-            const me = this
-            const picker = new Ext.tree.Panel({
-                    border: false,
-                    baseCls: Ext.baseCSSPrefix + 'boundlist',
-                    shrinkWrapDock: 2,
-                    store: me.store,
-                    floating: true,
-                    rootVisible: me.rootVisible,
-                    displayField: me.displayField,
-                    columns: me.columns,
-                    minHeight: me.minPickerHeight,
-                    maxHeight: me.maxPickerHeight,
-                    minWidth: me.minPickerWidth,
-                    manageHeight: false,
-                    shadow: false,
-                    scrollable: true,
-                    // modal: true,
-                    // constrain: true,
-                    // constrainTo: topScope._handle.el.dom,
-                    // renderTo: topScope._handle.el.dom,
-                    // alignTarget: topScope._handle,
-                    listeners: {
-                        scope: me,
-                        itemclick: me.onItemClick,
-                        itemkeydown: me.onPickerKeyDown
-                    }
-                }),
-                view = picker.getView();
-
-            if (Ext.isIE9 && Ext.isStrict) {
-                view.on({
-                    scope: me,
-                    highlightitem: me.repaintPickerView,
-                    unhighlightitem: me.repaintPickerView,
-                    afteritemexpand: me.repaintPickerView,
-                    afteritemcollapse: me.repaintPickerView
-                });
-            }
-            return picker;
-        },
-
-        repaintPickerView() {
-            const style = this.picker.getView().getEl().dom.style;
-            style.display = style.display;
-        },
-
-        onItemClick(view, record, node, rowIndex, e) {
-            this.selectItem(view, record);
-        },
-
-        onPickerKeyDown(treeView, record, item, index, e) {
-            const key = e.getKey();
-            if (key === e.ENTER || (key === e.TAB && this.selectOnTab)) {
-                this.selectItem(treeView, record);
-            }
-        },
-
-        selectItem(sender, record) {
-            var me = this;
-            me.setValue(record.getId());
-            me.fireEvent('select', me, record);
-            me.collapse();
-        },
-
-        onExpand() {
-            const picker = this.picker;
-            const store = picker.store;
-            const value = this.value;
-            let node;
-
-            if (value) {
-                node = store.getNodeById(value);
-            }
-
-            if (!node) {
-                node = store.getRoot();
-            }
-
-            picker.ensureVisible(node, {
-                select: true,
-                focus: true
-            });
-        },
-
-        setValue(value) {
-            const me = this;
-            console.log('setValue', value)
-            me.value = value;
-
-            if (!me.store || me.store.loading) {
-                // Called while the Store is loading. Ensure it is processed by the onLoad method.
-                return me.mixins.field.setValue.call(me, value);
-                // return me;
-            }
-
-            let record = value ? me.store.getNodeById(value) : me.store.getRoot();
-            if (value === undefined) {
-                record = me.store.getRoot();
-                console.log('setValue', record.getId())
-                me.value = record.getId();
-                return me.mixins.field.setValue.call(me, value);
-
-            } else {
-                record = me.store.getNodeById(value);
-            }
-
-            // set the raw value to the record's display field if a record was found
-            me.setRawValue(record ? record.get(me.displayField) : '');
-
-            return me.mixins.field.setValue.call(me, value);
-        },
-
-        getSubmitValue() {
-            return this.value;
-        },
-
-        getValue() {
-            return this.value;
-        },
-
-        onLoad() {
-            const value = this.value;
-
-            if (value) {
-                this.setValue(value);
-            }
-        },
-
-        onUpdate(store, rec, type, modifiedFieldNames) {
-            const display = this.displayField;
-            const me = this
-
-            if (type === 'edit' && modifiedFieldNames &&
-                Ext.Array.contains(modifiedFieldNames, display) &&
-                this.value === rec.getId()) {
-
-                me.mixins.field.setValue.call(me, this.value);
-                this.setRawValue(rec.get(display));
-            }
-        }
-
-    });
-
-}

+ 0 - 110
src/controls/input/datefield.js

@@ -1,110 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {date} from "../../Defaults";
-import {dataSourceReload} from "../../DataSourceHelper";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    const cc = Ext.form.field.Date.prototype.constructor
-    const {initComponent, getValue, valueToRaw} = Ext.form.field.Date.prototype
-    Ext.form.field.Date.override({
-        format: 'Y-m-d',
-        altFormats: 'Y-m-d',
-
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-            }, baseConfig(config, 'col-item'), config, date)
-
-            cc.call(this, newConfig)
-        },
-
-        getValue() {
-            const ov = getValue.call(this)
-            const nv = Ext.util.Format.date(ov, 'Y-m-d')
-            // console.log('cc:', nv, ov)
-            return nv
-        },
-
-        initComponent() {
-            const that = this
-            const toggle = function (e) {
-                // @ts-ignore
-                const config = this.config
-                const {readOnly, disabled} = config
-                if (readOnly || disabled) {
-                    return
-                }
-
-                if ($(e.target).is('.x-form-trigger')) {
-                    return
-                }
-                if (that.isExpanded) {
-                    that.collapse()
-
-                } else {
-                    that.expand();
-                }
-            }
-
-            this.on({
-                afterrender() {
-                    const {config} = this
-                    // 日期框,不要默认弹出
-                    // $(this.el.dom).on('click', toggle.bind(this))
-                },
-                destory() {
-                    // 日期框,不要默认弹出
-                    // $(this.el.dom).off('click', toggle.bind(this))
-                },
-                change: {
-                    fn(sender) {
-                        if (sender.format === 'Y-m-d') {
-                            // 年月日格式
-                            const value = sender.getRawValue()
-                            if (/^\d{8}$/.test(value)) {
-                                // 8位数字,自动转换为 YYYY-MM-DD
-                                const newValue = [
-                                    value.substr(0, 4),
-                                    value.substr(4, 2),
-                                    value.substr(6, 2)
-                                ].join('-')
-                                sender.setValue(newValue)
-                            }
-                        }
-                    },
-                }
-                // focus: {
-                //     // 获得焦点后自动下拉
-                //     fn(sender) {
-                //         sender.expand();
-                //         this.doQuery(this.allQuery, true);
-                //     },
-                // },
-            })
-
-            initComponent.call(this)
-        },
-    });
-
-    PropertyDescriptionTable.set(
-        'datefield',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 147
src/controls/input/datetimefield.js

@@ -1,147 +0,0 @@
-import _ from "lodash";
-import {baseConfig} from "../base";
-import {date} from "../../Defaults";
-
-export default function () {
-
-    Ext.define('Yvan.DateTimeField', {
-        extend: 'Ext.form.field.Date',
-        xtype: 'datetimefield',
-        alternateClassName: ['Ext.form.DateTimeField', 'Ext.form.DateTime'],
-        triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
-
-        showTime: true,
-        format: "Y-m-d H:i:s",
-
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, baseConfig(config, 'col-item'), config, date)
-
-            this.superclass.constructor.call(this, newConfig)
-        },
-
-        initComponent() {
-            this.superclass.initComponent.call(this)
-
-            const setInitValue = function () {
-                const value = this.getRawValue()
-                if (!value) {
-                    // 没填内容的时候,自动设置当前时间
-                    this.setValue(
-                        Ext.util.Format.date(new Date(), this.format)
-                    )
-                }
-            }
-
-            this.on({
-                afterrender() {
-                    const {config} = this
-                    // 日期框,不要默认弹出
-                    $(this.el.dom).on('click', setInitValue.bind(this))
-                },
-                destory() {
-                    // 日期框,不要默认弹出
-                    $(this.el.dom).off('click', setInitValue.bind(this))
-                },
-                change: {
-                    fn(sender) {
-                        if (sender.format === "Y-m-d H:i:s") {
-                            // 年月日格式
-                            const value = sender.getRawValue()
-                            if (/^\d{14}$/.test(value)) {
-                                // 8位数字,自动转换为 YYYY-MM-DD
-                                const newValue = [
-                                    value.substr(0, 4),
-                                    '-',
-                                    value.substr(4, 2),
-                                    '-',
-                                    value.substr(6, 2),
-                                    ' ',
-                                    value.substr(8, 2),
-                                    ':',
-                                    value.substr(10, 2),
-                                    ':',
-                                    value.substr(12, 2)
-                                ].join('')
-                                sender.setValue(newValue)
-                            }
-                        }
-                    },
-                }
-            })
-        },
-
-        getValue() {
-            const ov = this.getRawValue(); //this.superclass.getValue.call(this)
-            const nv = Ext.util.Format.date(ov, 'Y-m-d H:i:s')
-            // console.log('cc:', nv, ov)
-            return nv
-        },
-
-        onExpand: function () {
-            var strValue = this.getValue()
-            let value = Ext.Date.clearTime(new Date())
-            if (/^\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d$/.test(strValue)) {
-                value = new Date(
-                    parseInt(strValue.substr(0, 4)),
-                    parseInt(strValue.substr(5, 2)) - 1,
-                    parseInt(strValue.substr(8, 2)),
-                    parseInt(strValue.substr(11, 2)),
-                    parseInt(strValue.substr(14, 2)),
-                    parseInt(strValue.substr(17, 2))
-                )
-
-            } else if (/^\d\d\d\d-\d\d-\d\d$/.test(strValue)) {
-                value = new Date(
-                    parseInt(strValue.substr(0, 4)),
-                    parseInt(strValue.substr(5, 2)) - 1,
-                    parseInt(strValue.substr(8, 2)),
-                )
-
-            } else {
-                // value = Ext.Date.clearTime(new Date())
-                value = new Date()
-            }
-            this.picker.setValue(value)
-        },
-
-        createPicker: function () {
-            var me = this,
-                format = Ext.String.format;
-
-            //@ts-ignore
-            return new Yvan.DateTimePicker({
-                pickerField: me,
-                ownerCt: me.ownerCt,
-                renderTo: document.body,
-                floating: true,
-                hidden: true,
-                focusOnShow: true,
-                minDate: me.minValue,
-                maxDate: me.maxValue,
-                disabledDatesRE: me.disabledDatesRE,
-                disabledDatesText: me.disabledDatesText,
-                disabledDays: me.disabledDays,
-                disabledDaysText: me.disabledDaysText,
-                format: me.format,
-                showToday: me.showToday,
-                showTime: me.showTime,
-                startDay: me.startDay,
-                minText: format(me.minText, me.formatDate(me.minValue)),
-                maxText: format(me.maxText, me.formatDate(me.maxValue)),
-                listeners: {
-                    scope: me,
-                    select: me.onSelect
-                },
-                keyNavConfig: {
-                    esc: function () {
-                        me.collapse();
-                    }
-                }
-            });
-        },
-
-    });
-}

+ 0 - 391
src/controls/input/datetimepicker.js

@@ -1,391 +0,0 @@
-import _ from 'lodash'
-
-export default function () {
-    Ext.define('Yvan.DateTimePicker', {
-        extend: 'Ext.picker.Date',
-        alias: 'datetimepicker',
-        alternateClassName: 'Ext.DateTimePicker',
-
-        renderTpl: [
-            '<div id="{id}-innerEl" data-ref="innerEl" role="presentation">',
-            '<div class="{baseCls}-header">',
-            '<div id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-prev {baseCls}-arrow" role="presentation" title="{prevText}"></div>',
-            '<div id="{id}-middleBtnEl" data-ref="middleBtnEl" class="{baseCls}-month" role="heading">{%this.renderMonthBtn(values, out)%}</div>',
-            '<div id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-next {baseCls}-arrow" role="presentation" title="{nextText}"></div>',
-            '</div>',
-            '<table role="grid" id="{id}-eventEl" data-ref="eventEl" class="{baseCls}-inner" cellspacing="0" tabindex="0" aria-readonly="true">',
-            '<thead>',
-            '<tr role="row">',
-            '<tpl for="dayNames">',
-            '<th role="columnheader" class="{parent.baseCls}-column-header" aria-label="{.}">',
-            '<div role="presentation" class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>',
-            '</th>',
-            '</tpl>',
-            '</tr>',
-            '</thead>',
-            '<tbody>',
-            '<tr role="row">',
-            '<tpl for="days">',
-            '{#:this.isEndOfWeek}',
-            '<td role="gridcell">',
-            '<div hidefocus="on" class="{parent.baseCls}-date"></div>',
-            '</td>',
-            '</tpl>',
-            '</tr>',
-            '</tbody>',
-            '</table>',
-            '<tpl if="showToday">',
-            '<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer">{%this.renderTodayBtn(values, out)%}</div>',
-            '</tpl>',
-            // These elements are used with Assistive Technologies such as screen readers
-            '<div id="{id}-todayText" class="' + Ext.baseCSSPrefix + 'hidden-clip">{todayText}.</div>',
-            '<div id="{id}-ariaMinText" class="' + Ext.baseCSSPrefix + 'hidden-clip">{ariaMinText}.</div>',
-            '<div id="{id}-ariaMaxText" class="' + Ext.baseCSSPrefix + 'hidden-clip">{ariaMaxText}.</div>',
-            '<div id="{id}-ariaDisabledDaysText" class="' + Ext.baseCSSPrefix + 'hidden-clip">{ariaDisabledDaysText}.</div>',
-            '<div id="{id}-ariaDisabledDatesText" class="' + Ext.baseCSSPrefix + 'hidden-clip">{ariaDisabledDatesText}.</div>',
-            '</div>',
-            {
-                firstInitial: function (value) {
-                    return Ext.picker.Date.prototype.getDayInitial(value);
-                },
-                isEndOfWeek: function (value) {
-                    // convert from 1 based index to 0 based
-                    // by decrementing value once.
-                    value--;
-                    // eslint-disable-next-line vars-on-top
-                    var end = value % 7 === 0 && value !== 0;
-                    return end ? '</tr><tr role="row">' : '';
-                },
-                renderTodayBtn: function (values, out) {
-                    Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);
-                },
-                renderMonthBtn: function (values, out) {
-                    Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);
-                }
-            }
-        ],
-
-        beforeRender() {
-            var me = this,
-                today = Ext.Date.format(new Date(), me.format);
-
-            this.superclass.beforeRender.call(this)
-
-            function handleInput(extHandle, $input) {
-                const $dom = $(extHandle.el.dom)
-                // const $up = $dom.find('.x-form-spinner-up')
-                // const $down = $dom.find('.x-form-spinner-down')
-                // debugger
-                // $up.on('mousedown', () => {
-                //     debugger
-                // });
-                // $up.on('click', () => {
-                //     debugger
-                // });
-                extHandle.on('click', (sender) => {
-                    const hideBak = me.hide
-                    me.hide = Ext.emptyFn
-                    extHandle.focus()
-                    me.hide = hideBak
-                })
-
-                const changeValue = (delta) => {
-                    if (_.trim(extHandle.getValue()) === '') {
-                        extHandle.setValue(extHandle.minValue)
-                    } else {
-                        const v = parseInt('' + extHandle.getValue())
-                        if (v + delta > extHandle.maxValue) {
-                            extHandle.setValue(extHandle.minValue)
-
-                        } else if (v + delta < extHandle.minValue) {
-                            extHandle.setValue(extHandle.maxValue)
-
-                        } else {
-                            extHandle.setValue(v + delta)
-                        }
-                    }
-                }
-
-                $input.on('mousewheel', (e) => {
-                    e.stopPropagation()
-                    const event = e.originalEvent
-                    let delta = 0
-                    let eventDelta = event.wheelDelta || -event.deltaY + 40
-                    // if (event.wheelDelta) {
-                    //     delta = event.wheelDelta / 120;
-                    // } else if (event.detail) {
-                    //     delta = -event.detail / 3;
-                    // }
-                    let zoomSize = Math.ceil(eventDelta / 120)
-                    changeValue(zoomSize)
-                    // console.log('delta', delta)
-                    // $input.focus()
-                })
-            }
-
-            me.input1 = Ext.create('Ext.form.field.Number', {
-                minValue: 0,
-                maxValue: 23,
-                flex: 1,
-                enableKeyEvents: true,
-                fieldLabel: '时',
-                labelWidth: 20,
-                hideLabel: true,
-                spinDownEnabled: false,
-                spinUpEnabled: false,
-                style: {
-                    marginLeft: '5px',
-                },
-                listeners: {
-                    afterrender(sender) {
-                        const $input = $(sender.inputEl.dom)
-                        handleInput(me.input1, $input)
-                    },
-                    change(sender, e) {
-                        if (me.getValue()) {
-                            me.value.setHours(sender.getValue());
-                        }
-                    },
-                }
-            });
-
-            me.input2 = Ext.create('Ext.form.field.Number', {
-                minValue: 0,
-                maxValue: 59,
-                flex: 1,
-                enableKeyEvents: true,
-                fieldLabel: ' ',
-                hideLabel: false,
-                labelWidth: 8,
-                spinDownEnabled: false,
-                spinUpEnabled: false,
-                listeners: {
-                    afterrender(sender) {
-                        const $input = $(sender.inputEl.dom)
-                        handleInput(me.input2, $input)
-                    },
-                    change(sender, e) {
-                        if (me.getValue()) {
-                            me.value.setMinutes(sender.getValue());
-                        }
-                    },
-                }
-            });
-
-            me.input3 = Ext.create('Ext.form.field.Number', {
-                minValue: 0,
-                maxValue: 59,
-                flex: 1,
-                enableKeyEvents: true,
-                fieldLabel: ' ',
-                hideLabel: false,
-                labelWidth: 8,
-                spinDownEnabled: false,
-                spinUpEnabled: false,
-                style: {
-                    marginRight: '5px',
-                },
-                listeners: {
-                    afterrender(sender) {
-                        const $input = $(sender.inputEl.dom)
-                        handleInput(me.input3, $input)
-                    },
-                    change(sender, e) {
-                        if (me.getValue()) {
-                            me.value.setSeconds(sender.getValue());
-                        }
-                    },
-                }
-            });
-
-            me.confirmBtn = new Ext.button.Button({
-                text: '确认',
-                handler: me.confirmClick,
-                scope: me
-            });
-
-            me.tdBtn = new Ext.button.Button({
-                text: '现在',
-                handler: me.selectToday,
-                scope: me
-            });
-
-            me.todayBtn = Ext.create('Ext.container.Container', {
-                layout: 'anchor', border: false,
-                defaults: {
-                    border: false, anchor: '100%',
-                    margin: '0 0 5 0',
-                },
-                items: [
-                    {
-                        layout: 'hbox',
-                        items: [
-                            me.input1,
-                            me.input2,
-                            me.input3,
-                        ]
-                    },
-                    {
-                        layout: 'hbox',
-                        items: [
-                            me.confirmBtn,
-                            me.tdBtn,
-                        ]
-                    }
-                ]
-            });
-        },
-
-        // finishRenderChildren() {
-        //     var me = this;
-        //
-        //     this.superclass.finishRenderChildren.call(this);
-        //     //*
-        //     me.input1.finishRender();
-        //     me.input2.finishRender();
-        //     me.input3.finishRender();
-        //     //
-        //     me.tdBtn.finishRender();
-        //     me.confirmBtn.finishRender();
-        // },
-
-        setValue(value) {
-            //this.value = Ext.Date.clearTime(value, true);
-            this.value = value;
-            this.input1.setValue(this.value.getHours());
-            this.input2.setValue(this.value.getMinutes());
-            this.input3.setValue(this.value.getSeconds());
-            return this.update(this.value);
-        },
-
-        selectDate: function (value) {
-            if (this.showTime) {
-                value.setHours(this.input1.getValue());
-                value.setMinutes(this.input2.getValue());
-                value.setSeconds(this.input3.getValue());
-            }
-            this.value = value;
-            return this.update(this.value);
-        },
-
-        setDisabledStatus(disabled) {
-            var me = this;
-
-            debugger
-            // me.callParent();
-
-            if (me.showTime) {
-                me.confirmBtn.setDisabled(disabled);
-            }
-            if (me.isShowFooter()) {
-                me.footerContainer.setDisabled(disabled);
-            }
-        },
-
-        handleDateClick(e, t) {
-            var me = this,
-                handler = me.handler;
-
-            // e.stopEvent();
-            if (!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) {
-                me.doCancelFocus = me.focusOnSelect === false;
-
-                me.selectDate(new Date(t.dateValue));
-
-                delete me.doCancelFocus;
-
-                /* 有时间输入时单击事件不退出选择,只移动光标 */
-                if (me.showTime) {
-                    return;
-                }
-
-                me.fireEvent('select', me, me.value);
-                if (handler) {
-                    handler.call(me.scope || me, me, me.value);
-                }
-                me.onSelect();
-            }
-        },
-
-        selectToday() {
-            var me = this,
-                btn = me.todayBtn,
-                handler = me.handler;
-
-            if (btn && !btn.disabled) {
-                me.value = new Date();
-                me.update(me.value);
-
-                me.fireEvent('select', me, me.value);
-                if (handler) {
-                    handler.call(me.scope || me, me, me.value);
-                }
-                me.onSelect();
-                me.hide();
-            }
-            return me;
-        },
-
-        confirmClick() {
-            var me = this,
-                btn = me.confirmBtn,
-                handler = me.handler;
-
-            if (btn && !btn.disabled) {
-                me.fireEvent('select', me, me.value);
-                if (handler) {
-                    handler.call(me.scope || me, me, me.value);
-                }
-                me.onSelect();
-                me.hide();
-            }
-            return me;
-        },
-
-        selectedUpdate(date) {
-            var me = this,
-                //t         = date.getTime(),
-                t = Ext.Date.clearTime(date, true).getTime(),
-                cells = me.cells,
-                cls = me.selectedCls,
-                cellItems = cells.elements,
-                c,
-                cLen = cellItems.length,
-                cell;
-
-            cells.removeCls(cls);
-
-            for (c = 0; c < cLen; c++) {
-                cell = Ext.fly(cellItems[c]);
-
-                if (cell.dom.firstChild.dateValue == t) {
-                    me.fireEvent('highlightitem', me, cell);
-                    cell.addCls(cls);
-
-                    if (me.isVisible() && !me.doCancelFocus) {
-                        Ext.fly(cell.dom.firstChild).focus(50);
-                    }
-
-                    break;
-                }
-            }
-        },
-
-        // private, inherit docs
-        beforeDestroy() {
-            var me = this;
-
-            if (me.rendered) {
-                Ext.destroy(
-                    me.input1,
-                    me.input2,
-                    me.input3,
-                    me.confirmBtn,
-                    me.tdBtn,
-                    me.todayBtn
-                );
-            }
-            me.superclass.beforeDestroy.call(this)
-        }
-    })
-}

+ 0 - 44
src/controls/input/numberfield.js

@@ -1,44 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {numberfield} from "../../Defaults";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    const cc = Ext.form.field.Number.prototype.constructor
-    const {initComponent} = Ext.form.field.Number.prototype
-    Ext.form.field.Number.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, baseConfig(config, 'col-item'), config, numberfield)
-
-            cc.call(this, newConfig)
-        },
-
-        initComponent() {
-            initComponent.call(this)
-        },
-    });
-
-    PropertyDescriptionTable.set(
-        'numberfield',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 13
src/controls/input/pickerplus.js

@@ -1,13 +0,0 @@
-export default function () {
-    Ext.define('Yvan.PickerAlignCenter', {
-        extend: 'Ext.form.field.Picker',
-
-        /**
-         * Performs the alignment on the picker using the class defaults
-         * @private
-         */
-        doAlign: function () {
-            // 不要挪动就好
-        },
-    })
-}

+ 0 - 44
src/controls/input/radio.js

@@ -1,44 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {radio} from "../../Defaults";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    const cc = Ext.form.field.Radio.prototype.constructor
-    const {initComponent} = Ext.form.field.Radio.prototype
-    Ext.form.field.Radio.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, baseConfig(config, 'col-item'), config, radio)
-
-            cc.call(this, newConfig)
-        },
-
-        initComponent() {
-            initComponent.call(this)
-        },
-    });
-
-    PropertyDescriptionTable.set(
-        'radio',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 44
src/controls/input/radiogroup.js

@@ -1,44 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {radiogroup} from "../../Defaults";
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    const cc = Ext.form.RadioGroup.prototype.constructor
-    const {initComponent} = Ext.form.RadioGroup.prototype
-    Ext.form.RadioGroup.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-
-            }, baseConfig(config, 'col-item'), config, radiogroup)
-
-            cc.call(this, newConfig)
-        },
-
-        initComponent() {
-            initComponent.call(this)
-        },
-    });
-
-    PropertyDescriptionTable.set(
-        'radiogroup',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 142
src/controls/input/search.js

@@ -1,142 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base";
-import {search} from "../../Defaults";
-import {invokeMethod} from '../../utils'
-import {clearViewModelByLookup, showWidget, stopEvent} from "../../lib/systemLib"
-import {
-    disabled,
-    fieldLabel,
-    gravity, height, metaId,
-    PropertyDescriptionTable,
-    tooltip,
-    value, width,
-    YvBase
-} from "../../PropertyDescriptionTable";
-import {PropertyDescription} from "../../PropertyDescription";
-
-export default function () {
-
-    Ext.define('Yvan.Search', {
-        extend: 'Ext.form.field.Text',
-        alias: 'widget.searchfield',
-        xtype: 'searchfield',
-
-        constructor(config) {
-            const self = this
-            const newConfig = _.defaultsDeep({
-                // 强制性属性
-                triggers: {
-                    clear: {
-                        weight: 0,
-                        cls: Ext.baseCSSPrefix + 'form-clear-trigger',
-                        hidden: true,
-                        handler: 'onClearClick',
-                    },
-                    search: {
-                        weight: 1,
-                        cls: Ext.baseCSSPrefix + 'form-search-trigger',
-                        handler: 'onSearchClick'
-                    },
-                },
-
-                listeners: {
-                    blur(sender, e) {
-                        this.revertOnblur()
-                    },
-                    specialkey(sender, e) {
-                        const me = this
-                        if (e.getKey() === e.ENTER) {
-                            me.onSearchClick(sender, {}, e);
-                            return
-                        }
-                        invokeMethod(config.listeners?.afterrender, sender, e)
-                    },
-                    afterrender(sender, e) {
-                        this.replaceRawInputEvent()
-                        invokeMethod(config.listeners?.afterrender, sender, e)
-                    }
-                },
-
-            }, baseConfig(config, 'col-item'), config, search)
-
-            this.superclass.constructor.call(self, newConfig)
-        },
-
-        revertOnblur() {
-            this.setRawValue(this.lastValue)
-        },
-
-        onSearchClick(sender, vv, e) {
-            const me = this
-            const {config} = me
-            const {widget, vjson, lookup} = config
-
-
-            if (e) {
-                e.preventDefault()
-                e.stopPropagation()
-            }
-
-            this.fireEvent('search', sender, e)
-            if (!widget) {
-                return
-            }
-            showWidget(widget, lookup, sender, me.getRawValue(), vjson)
-        },
-
-        replaceRawInputEvent() {
-            const me = this
-            const $dom = $(me.inputEl.dom)
-            $dom.on('input', e => {
-                stopEvent(e)
-                // console.log('has input', e)
-            })
-            $dom.on('keyup', e => {
-                if (e.key === "Enter") {
-                    me.onSearchClick(me, {}, e)
-                    return
-                }
-                stopEvent(e)
-            })
-            $dom.on('change', e => {
-                stopEvent(e)
-            })
-        },
-
-        onChange: function (newVal, oldVal) {
-            const me = this
-            const value = newVal
-
-            if (value) {
-                me.getTrigger('clear').show();
-                me.updateLayout();
-            } else {
-                me.getTrigger('clear').hide();
-                me.updateLayout();
-            }
-        },
-
-        /**
-         * 清空所有值
-         */
-        onClearClick(sender, e) {
-            const me = this
-            const {config} = me
-            const {lookup} = config
-
-            me.setValue('')
-
-            clearViewModelByLookup(sender, lookup)
-        }
-    });
-}
-
-PropertyDescriptionTable.set(
-    'searchfield',
-    new PropertyDescription(YvBase, {
-        props: [
-            fieldLabel, value, disabled,
-            gravity, tooltip, metaId, width, height
-        ],
-    })
-)

+ 0 - 106
src/controls/input/textfield.js

@@ -1,106 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "../base"
-import {text} from "../../Defaults"
-import {
-    PropertyDescriptionTable,
-    YvBase,
-    fieldLabel,
-    value,
-    disabled,
-    gravity,
-    tooltip,
-    metaId,
-    width,
-    height
-} from "../../PropertyDescriptionTable"
-import $ from 'jquery'
-import {PropertyDescription} from "../../PropertyDescription"
-
-export default function () {
-
-    const cc = Ext.form.field.Text.prototype.constructor
-    const {initComponent} = Ext.form.field.Text.prototype
-    Ext.form.field.Text.override({
-        constructor(config) {
-            const newConfig = _.defaultsDeep({
-                // 强制属性
-                triggers: {
-                    clear: {
-                        weight: -1,
-                        cls: Ext.baseCSSPrefix + 'form-clear-trigger',
-                        hidden: true,
-                        handler: 'onClearClick',
-                    },
-                }
-
-            }, baseConfig(config, 'col-item'), config, text)
-
-            cc.call(this, newConfig)
-        },
-
-        /**
-         * 清空所有值
-         */
-        onClearClick(sender, e) {
-            const me = this
-            me.setValue('')
-        },
-
-        initComponent() {
-
-            /**
-             * 改变必填项之前加星号
-             */
-            if (this.allowBlank === false || this.validateBlank === true) {
-                // this.beforeLabelTextTpl = [
-                //     '<span style="color:red;font-weight:bold" data-qtip="必填选项">*</span>'
-                // ];
-                this.afterLabelTextTpl = [
-                    '<span style="color:red;font-weight:bold" data-qtip="必填选项">*</span>'
-                ];
-            }
-
-            const me = this
-            this.on({
-                change(sender, newVal) {
-                    const {hideTrigger, disabled, readOnly, hideClear} = sender
-                    if (hideTrigger || disabled || readOnly || hideClear) {
-                        // 禁用、隐藏、只读、隐藏清空状态下,不需要显示清空按钮
-                        return
-                    }
-
-                    const value = newVal
-
-                    if (value) {
-                        me.getTrigger('clear').show();
-                        me.updateLayout();
-                    } else {
-                        me.getTrigger('clear').hide();
-                        me.updateLayout();
-                    }
-                },
-                afterrender(sender) {
-                    if(sender.inputEl?.dom) {
-                        sender.inputEl.dom.setAttribute('spellcheck', "false");
-                        $(sender.inputEl.dom).on('click', (e)=>{
-                            sender.fireEvent('click', this, e)
-                        })
-                    }
-                }
-            })
-
-            initComponent.call(this)
-        }
-    });
-
-    PropertyDescriptionTable.set(
-        'textfield',
-        new PropertyDescription(YvBase, {
-            props: [
-                fieldLabel, value, disabled,
-                gravity, tooltip, metaId, width, height
-            ],
-        })
-    )
-
-}

+ 0 - 23
src/controls/panel.js

@@ -1,23 +0,0 @@
-import _ from 'lodash'
-import {baseConfig} from "./base";
-import {panel, fieldContainer} from "../Defaults";
-
-export default function () {
-    /**
-     *
-     */
-    const ct = Ext.panel.Panel.prototype.constructor
-    Ext.panel.Panel.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "rows-container"), panel)
-            ct.call(this, newConfig)
-        }
-    });
-
-    const ss = Ext.form.FieldContainer.prototype
-    Ext.form.FieldContainer.override({
-        config: {
-            ...fieldContainer
-        }
-    })
-}

+ 0 - 27
src/controls/rows.js

@@ -1,27 +0,0 @@
-import _ from 'lodash'
-import {rows} from '../Defaults'
-import {baseConfig} from "./base";
-
-export default function () {
-
-    Ext.define('Yvan.Rows', {
-        extend: 'Ext.container.Container',
-        xtype: 'rows',
-
-        constructor(config) {
-            const self = this
-            const newConfig = _.defaultsDeep({
-                // 强制性属性
-                layout: 'anchor', border: false,
-                defaults: {
-                    border: false, anchor: '100%',
-                    margin: '0 0 5 0',
-                },
-
-            }, baseConfig(config, 'rows-container'), config, rows)
-
-            this.superclass.constructor.call(self, newConfig)
-        },
-    });
-
-}

+ 0 - 14
src/controls/splitter.js

@@ -1,14 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import {baseConfig} from "./base";
-import {splitter} from "../Defaults";
-
-export default function () {
-    const ct = Ext.resizer.Splitter.prototype.constructor
-    Ext.resizer.Splitter.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "row-item"), splitter)
-            ct.call(this, newConfig)
-        }
-    });
-}

+ 0 - 205
src/controls/stores.js

@@ -1,205 +0,0 @@
-import _ from 'lodash'
-import {lookupFn, lookupScope} from "../lib/lib";
-import {apiConvert, serverInvokeUrlTransform} from "../lib/config";
-import {calcObjectFlat} from '../lib/systemLib'
-
-/**
- * 构建一个 grid 支持的 dataSource
- */
-export function gridInvokeBuild(scope, grid, config, dataSource, reloadParams = {}, isExcelExport = false, excelExportCallBack = null) {
-    const me = grid
-    const params = calcObjectFlat(scope.viewModel.data, dataSource.params)
-    let storeOption = {}
-    if (dataSource.method === 'invoke') {
-
-        const fields = []
-        _.forEach(grid.columns, col => {
-            const c = {}
-            if (col.dataIndex) {
-                c.name = col.dataIndex
-                fields.push(c)
-            }
-            if (col.dataType) {
-                c.type = col.dataType
-            }
-        })
-
-        // 默认支持 gridInvoke
-        storeOption = {
-            fields,
-            remoteSort: config.remoteSort,
-            remoteFilter: config.remoteFilter,
-            autoLoad: true,
-            pageSize: me.store.pageSize || config.pageSize,
-            proxy: {
-                type: 'jsonAjax',
-                $owner: me,
-                url: serverInvokeUrlTransform(dataSource.url, {scope, grid, isExcelExport, excelExportCallBack}),
-                extraParams: _.defaultsDeep({}, reloadParams, params),
-                reader: {
-                    type: 'json',
-                    rootProperty: 'data',
-                    totalProperty: 'pagination.total',
-                    successProperty: 'success',
-                    messageProperty: 'msg',
-                    transform: function (data) {
-                        if (typeof grid._transform === 'function') {
-                            // 系统转换函数
-                            grid._transform(data.data)
-                        }
-                        if (grid.dataTransform) {
-                            if (typeof grid.dataTransform === 'string') {
-                                grid.dataTransform = lookupFn(lookupScope(grid), grid.dataTransform)
-                            }
-
-                            return grid.dataTransform.call(scope, grid, data)
-                        }
-                        return data
-                    }
-                }
-            },
-            listeners: {
-                load: function (store, records, successful, operation) {
-                    const rep = operation.getResponse()?.responseJson
-                    me.exportExcelTotal = rep?.pagination?.total || rep?.data?.length || 0
-                    if (isExcelExport) {
-                        if (typeof excelExportCallBack === 'function') {
-                            excelExportCallBack(rep);
-                        } else if (excelExportCallBack) {
-                            console.error("导出回调方法错误!")
-                        }
-                        me.fireEvent('excelDataLoadComplete', me, successful, records);
-                    } else {
-                        me.fireEvent('dataLoadComplete', me, successful, records);
-                    }
-                }
-            }
-        }
-
-    } else if (apiConvert) {
-        // 外部扩展的 apiConvert
-        storeOption = apiConvert.gridInvokeBuild(scope, grid, config, dataSource, params, reloadParams)
-
-    } else {
-        throw new TypeError("不支持的 API 请求方式")
-    }
-
-    if (isExcelExport) {
-        const excelStore = new Ext.data.Store(storeOption);
-        excelStore.load()
-    } else {
-        me.setStore(new Ext.data.Store(storeOption))
-    }
-}
-
-export default function () {
-
-    Ext.define('Yvan.JsonAjaxProxy', {
-        extend: 'Ext.data.proxy.Ajax',
-        alias: 'proxy.jsonAjax',
-        actionMethods: {
-            create: "POST",
-            read: "POST",
-            update: "POST",
-            destroy: "POST"
-        },
-        buildRequest: function (operation) {
-            // 参考源码 ext-all-debug.js:71468 method:buildRequest
-            const me = this
-            const {$owner} = me // 在 grid.initComponent 中赋值 $owner
-            const scope = lookupScope($owner)
-
-            const gridParam = me.getParams(operation)
-            const customParam = {}
-
-            // 提取 srot 元素
-            if (gridParam.sort) {
-                const sort = JSON.parse(gridParam.sort)
-                // 字符串 [{"property":"BRANCHID","direction":"ASC"}]
-                // 转换为对象 [{colId: "BRANCHID", sort: "asc"}]
-                customParam.sortModel = []
-                _.forEach(sort, s => {
-                    customParam.sortModel.push({
-                        colId: s.property,
-                        sort: _.toLower(s.direction)
-                    })
-                })
-                delete gridParam.sort
-            }
-
-            // 提取筛选元素
-            if (gridParam.filter) {
-                const filter = JSON.parse(gridParam.filter)
-                // "[{"operator":"like","value":"1","property":"id"}]"
-                // 转换为 filterModel: {BRANCHID: {filterType: "text", type: "contains", filter: "12"}}
-                customParam.filterModel = {}
-                _.forEach(filter, s => {
-                    const newFilterItem = {}
-                    if (s.operator === 'like') {
-                        newFilterItem.filterType = 'text';
-                        newFilterItem.type = 'contains';
-                        newFilterItem.filter = s.value;
-                    } else {
-                        // 无法识别的筛选类型
-                        debugger
-                    }
-                    customParam.filterModel[s.property] = newFilterItem
-                })
-                delete gridParam.filter
-            }
-
-            // 被 grid.constructor 作为方法存在
-            const extraParams = _.cloneDeep(me.getExtraParams())
-            const params = _.defaultsDeep(gridParam, extraParams)
-
-            // var request = this.superclass.buildRequest.apply(this, arguments);
-            let request = new Ext.data.Request({
-                params: {},
-                action: operation.getAction(),
-                records: operation.getRecords(),
-                url: me.buildUrl(),
-                jsonData: {
-                    args: [
-                        params
-                    ],
-                    ...customParam
-                },
-                proxy: me
-            });
-
-            operation.setRequest(request);
-            return request;
-        },
-        afterRequest: function (req, res) {
-            // Extend.afterExtRequest(req, res)
-        }
-    });
-
-
-    Ext.define('Ext.ux.data.MyReader', {
-        extend: 'Ext.data.reader.Json',
-        xtype: 'yvgridreader',
-
-        useSimpleAccessors: false,
-
-        // 重写解析 data 的方法
-        // extractData: function (data) {
-        //     // callParent 要换写成 this.superclass.XXX.call(this, ...)
-        //     // return me.callParent([data]);
-        //
-        //     if (this.metaData && Ext.isArray(this.metaData.fields)) {
-        //         // data : [][] 换写成数组
-        //         data = _.map(data, row => {
-        //             const newRow = {}
-        //             for (var i = 0; i < this.metaData.fields.length; i++) {
-        //                 newRow[this.metaData.fields[i]] = row[i]
-        //             }
-        //             return newRow
-        //         })
-        //     }
-        //
-        //     const rr = this.superclass.extractData.call(this, data);
-        //     return rr;
-        // }
-    });
-}

+ 0 - 17
src/controls/toolbar/tbfill.js

@@ -1,17 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import {baseConfig} from "../base";
-import {tbfill} from "../../Defaults";
-
-export default function () {
-    /**
-     *
-     */
-    const ct = Ext.toolbar.Fill.prototype.constructor
-    Ext.toolbar.Fill.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "col-item"), tbfill)
-            ct.call(this, newConfig)
-        }
-    });
-}

+ 0 - 17
src/controls/toolbar/tbseparator.js

@@ -1,17 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import {baseConfig} from "../base";
-import {tbseparator} from "../../Defaults";
-
-export default function () {
-    /**
-     *
-     */
-    const ct = Ext.toolbar.Separator.prototype.constructor
-    Ext.toolbar.Separator.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({}, config, baseConfig(config, "col-item"), tbseparator)
-            ct.call(this, newConfig)
-        }
-    });
-}

+ 0 - 24
src/controls/toolbar/toolbar.js

@@ -1,24 +0,0 @@
-import _ from 'lodash'
-import $ from 'jquery'
-import initTbFill from './tbfill'
-import initTbSeparator from './tbseparator'
-import {baseConfig} from "../base";
-import {toolbar} from "../../Defaults";
-
-export default function () {
-    /**
-     *
-     */
-    const ct = Ext.toolbar.Toolbar.prototype.constructor
-    Ext.toolbar.Toolbar.override({
-        constructor: function (config) {
-            const newConfig = _.defaultsDeep({
-                // 强制性属性
-            }, baseConfig(config, 'cols-container'), config, toolbar)
-
-            ct.call(this, newConfig)
-        }
-    });
-    initTbFill();
-    initTbSeparator();
-}

+ 0 - 0
src/controls/yvtree.js


Some files were not shown because too many files changed in this diff