浏览代码

预期到货通知的编辑

luoyifan 3 年之前
父节点
当前提交
f18b2b8f36
共有 8 个文件被更改,包括 260 次插入42 次删除
  1. 1 0
      src/Defaults.ts
  2. 16 1
      src/controls/grid.js
  3. 139 40
      src/controls/input/combogrid.js
  4. 1 0
      src/index.ts
  5. 48 0
      src/lib/systemLib.ts
  6. 21 0
      src/lib/systemLibEval.js
  7. 33 0
      src/utils.ts
  8. 1 1
      tsconfig.json

+ 1 - 0
src/Defaults.ts

@@ -30,6 +30,7 @@ export const comboGrid = {
     selectOnTab: true,
     pickerHeight: 500,
     pickerWidth: 850,
+    editEnable: null,
 }
 
 export const comboGridPicker = {

+ 16 - 1
src/controls/grid.js

@@ -214,7 +214,22 @@ export default function () {
                         }
                     }
 
-                    if (config.contextMenu) {
+                    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)
                     }
 

+ 139 - 40
src/controls/input/combogrid.js

@@ -1,7 +1,15 @@
 import _ from 'lodash'
 import {comboGrid, comboGridPicker} from '../../Defaults'
-import {calcObjectFlat, clearViewModelByLookup, lookupScope, stopEvent, tryWriteByExpress, tryWriteObject} from "../..";
+import {
+    calcObjectFlat,
+    lookupScope,
+    tryEnable,
+    stopEvent,
+    tryVarSimple,
+    tryWriteObject
+} from "../..";
 import {msg} from "../../message";
+import {isChartEvent} from '../../utils'
 
 export default function () {
 
@@ -43,9 +51,17 @@ export default function () {
                 },
                 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);
@@ -56,6 +72,16 @@ export default function () {
                     } 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);
@@ -64,15 +90,14 @@ export default function () {
                             // 取消 keyup 事件,让 ext 不要吧当前输入的值记录到 value 中
                             stopEvent(e)
                         })
+                        $dom.on('change', e => {
+                            if (that.isExpanded) {
+                                that.filterChange(that, e.target.value)
+                            }
+                            stopEvent(e)
+                        })
                     }
                     $dom.on('input', e => {
-                        // that.filterChange(that, e.target.value)
-                        stopEvent(e)
-                    })
-                    $dom.on('change', e => {
-                        if (that.isExpanded) {
-                            that.filterChange(that, e.target.value)
-                        }
                         stopEvent(e)
                     })
                 },
@@ -203,49 +228,47 @@ export default function () {
             }
 
             tryWriteObject(lookup, record, (path, value) => {
-                if (path === 'queryValue') {
-                    me.setValue(value)
-                } else {
-                    if (me.column) {
-                        // 列模式下,写当前编辑行
-                        const parentGrid = me.column.up('grid')
-                        const parentRecord = parentGrid.getSelectionModel().getLastSelected()
-                        // Ext.data.Record / Ext.data.Model
-                        parentRecord.set(path, value)
-
-                    } else {
-                        // 常规模式下,写 viewModel
-                        scope.viewModel.set(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 {param} = this
-            const scope = lookupScope(this)
-            const queryValue = this.getRawValue()
-
-            const reloadParam = calcObjectFlat({
-                ...scope.viewModel.data,
-                queryValue
-            }, param)
+            const reloadParam = calcObjectFlat(this.getExpressData(), this.param)
 
-            console.log('reload', reloadParam)
             this.grid.reload(reloadParam)
         },
 
-        onTriggerClick() {
-            const {isExpanded, readOnly, disabled, grid} = this
+        onTriggerClick(sender) {
+            const {isExpanded, readOnly, disabled, grid,} = this
 
             if (!grid) {
                 msg('正在初始化,请稍后')
                 return
             }
 
+            if (!this.tryEnable()) {
+                // 没有达成 editEnable 条件,不用弹出
+                return
+            }
+
             if (isExpanded || readOnly || disabled) {
                 // 已弹出、只读、禁用状态下,不允许弹出
                 return
@@ -265,13 +288,52 @@ export default function () {
          * 本方法只会从 API 或外部调用,键盘输入的内容不会记录在内
          */
         setValue(value) {
-            const me = this;
+            const me = this
 
             // 设值用户看到的表面内容
-            this.setRawValue(value);
+            this.setRawValue(value)
 
             // 设值 setValue 调用链,正常触发 change 事件等
-            return me.mixins.field.setValue.call(me, value);
+            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)
+            }
         },
 
         onChange: function (newVal, oldVal) {
@@ -288,17 +350,54 @@ export default function () {
         },
 
         /**
+         * 得到能用于 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 {config} = me
-            const {lookup} = config
+            const {lookup, lookupClearOnChange} = me
 
             me.fireEvent('clear', sender, e)
 
             me.setValue('')
-            clearViewModelByLookup(sender, lookup)
+            _.forOwn(lookup, (toTarget, fromColumn) => {
+                me._lookupSet(toTarget, '')
+            })
+
+            _.each(lookupClearOnChange, item => {
+                me._lookupSet(item, '')
+            })
         }
     });
 

+ 1 - 0
src/index.ts

@@ -26,3 +26,4 @@ export * from './lib/ajax'
 export * from './lib/Lib'
 export * from './lib/config'
 export * from './lib/systemLib'
+export * from './lib/systemLibEval'

+ 48 - 0
src/lib/systemLib.ts

@@ -2,6 +2,7 @@ import _ from 'lodash'
 import {Lib, lookupScope} from './lib'
 import {ajax} from "./config";
 import {msg, showErrorDialog} from "../message";
+import {evalFunction} from "./systemLibEval";
 
 export const SIMPLE_RE = /^(?:\{(?:(\d+)|([a-z_][\w\.]*))\})$/i
 
@@ -213,6 +214,19 @@ export function tryWriteObject(expressObject, valueObject, writeFn) {
 }
 
 /**
+ * 尝试去掉变量两边括号
+ * {a} => a
+ * a => a
+ */
+export function tryVarSimple(value) {
+    if (SIMPLE_RE.test(value)) {
+        // If we have '{foo}' alone it is a literal 简单表达式
+        return value.substring(1, value.length - 1);
+    }
+    return value
+}
+
+/**
  * 对多个表达式进行求值. 异步回调的方式返回
  *      {
  *          a: 1,
@@ -269,6 +283,40 @@ export function getParentGrid(config) {
 }
 
 /**
+ * 解析
+ * {
+ *     condition: "{skuId}",
+ *     errorMsg: "无法编辑",
+ *     notice: 'msg'
+ * }
+ */
+export function tryEnable(data, enableSetting) {
+    if (!enableSetting) {
+        // 没有这一段配置,可以编辑
+        return true
+    }
+
+    const {condition, errorMsg, notice} = enableSetting
+
+    if (!evalFunction(data, condition)) {
+        // 没有达成 condition 条件
+
+        // 计算 msg 消息内容
+        const msgContent = calcExpress(data, errorMsg)
+        if (msgContent) {
+            if (!notice || notice === 'msg') {
+                // 进行提示
+                msg(msgContent)
+            }
+        }
+
+        return false
+    }
+
+    return true
+}
+
+/**
  * 动态的为 combo 或 columns.combo 设置下拉框的值
  * @param sender 目标对象
  * @param config 目标对象的配置(在构造函数之前也可以)

+ 21 - 0
src/lib/systemLibEval.js

@@ -0,0 +1,21 @@
+import _ from "lodash";
+
+/**
+ * 用于计算 express 表达式
+ */
+export function evalFunction(data, express) {
+    const keys = []
+    const values = []
+    _.forOwn(data, (value, key) => {
+        keys.push(key)
+        values.push(value)
+    })
+
+    const func = Function(...keys, 'return ' + express)
+
+    try {
+        return func(...values)
+    } catch (e) {
+        return
+    }
+}

+ 33 - 0
src/utils.ts

@@ -7,4 +7,37 @@ export function invokeMethod(fn: any, sender: any, args: any) {
     }
 }
 
+/**
+ * 判断事件是否为有效的输入字符
+ * @param e
+ */
+export function isChartEvent(e) {
+    if (
+        e.key === 'Shift' ||
+        e.key === 'Control' ||
+        e.key === 'Alt' ||
+        e.key === 'Escape' ||
+        e.key === 'ArrowRight' ||
+        e.key === 'Tab' ||
+        e.key === 'ArrowLeft'
+    ) {
+        return false
+    }
+
+    if (e.keyCode >= 48 && e.keyCode <= 57) {
+        // 0-9
+        return true
+    }
+
+    if (e.keyCode >= 65 && e.keyCode <= 90) {
+        // a-z
+        return true
+    }
+
+    if (e.keyCode >= 96 && e.keyCode <= 111 && e.keyCode !== 108) {
+        // 小键盘 0-9
+        return true
+    }
 
+    return false
+}

+ 1 - 1
tsconfig.json

@@ -4,7 +4,7 @@
     "module": "esnext",
 //    "outFile": "../dist/wotu-ui.js",
     "moduleResolution": "node",
-    "strict": true,
+    "strict": false,
     "allowJs": true,
     "checkJs": true,
     "importHelpers": true,