Commit 66892ba1a626018e4ca117ba796fcf9f162ba7c4
1 parent
299f7534
fix: DEFECT-1118 修复控制组件绑定tcp设备时无法下发字符串命令
Showing
1 changed file
with
426 additions
and
69 deletions
... | ... | @@ -6895,11 +6895,26 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
6895 | 6895 | TCP_COMMAND: 'tcpCommand', |
6896 | 6896 | |
6897 | 6897 | /** |
6898 | + * @description json命令 | |
6899 | + */ | |
6900 | + JSON_COMMAND: 'jsonCommand', | |
6901 | + | |
6902 | + /** | |
6898 | 6903 | * @description 命令下发方式 |
6899 | 6904 | */ |
6900 | 6905 | COMMAND_TYPE: 'commandType', |
6901 | 6906 | |
6902 | 6907 | /** |
6908 | + * @description 服务命令 | |
6909 | + */ | |
6910 | + SERVICE_COMMAND: 'serviceCommand', | |
6911 | + | |
6912 | + /** | |
6913 | + * @description 服务原始配置 | |
6914 | + */ | |
6915 | + SERVICE_ORIGINAL_CONFIGURATION: 'serviceOriginalConfiguration', | |
6916 | + | |
6917 | + /** | |
6903 | 6918 | * @description 服务 |
6904 | 6919 | */ |
6905 | 6920 | SERVICE: 'service', |
... | ... | @@ -7028,22 +7043,28 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7028 | 7043 | */ |
7029 | 7044 | function echoFormData(data) { |
7030 | 7045 | const { content = {} } = data |
7046 | + console.log(data) | |
7031 | 7047 | const val = { |
7032 | 7048 | [enumConst.ACTION]: content.type, |
7033 | 7049 | [enumGetValue[content.type]]: content.value, |
7050 | + | |
7051 | + // 参数设置 | |
7052 | + [enumConst.JSON_COMMAND]: content[enumConst.JSON_COMMAND], | |
7034 | 7053 | [enumConst.WAY]: content[enumConst.WAY], |
7035 | 7054 | [enumConst.COMMAND_TYPE]: content[enumConst.COMMAND_TYPE], |
7036 | - [enumConst.SERVICE]: content[enumConst.SERVICE], | |
7037 | - [enumConst.COMMAND]: content[enumConst.COMMAND], | |
7038 | 7055 | [enumConst.TCP_COMMAND]: content[enumConst.TCP_COMMAND], |
7056 | + [enumConst.TRANSPORTTYPE]: content[enumConst.TRANSPORTTYPE], | |
7057 | + [enumConst.SERVICE]: content[enumConst.SERVICE], | |
7058 | + [enumConst.SERVICE_COMMAND]: content[enumConst.SERVICE_COMMAND], | |
7059 | + [enumConst.SERVICE_ORIGINAL_CONFIGURATION]: content[enumConst.SERVICE_ORIGINAL_CONFIGURATION], | |
7039 | 7060 | } |
7040 | 7061 | |
7041 | 7062 | |
7042 | - const isTCPTransportType = !!content[enumConst.TCP_COMMAND] | |
7063 | + const isTCPTransportType = content[enumConst.TRANSPORTTYPE] === 'TCP' | |
7043 | 7064 | const isCustom = content[enumConst.COMMAND_TYPE] === COMMAND_TYPE_ENUM.CUSTOM |
7044 | 7065 | |
7045 | 7066 | if (content[enumConst.SERVICE] && !isCustom) { |
7046 | - form.val(enumActionEl.INPUT_DATA_FORM_FILTER, content[enumConst.COMMAND]) | |
7067 | + form.val(enumActionEl.INPUT_DATA_FORM_FILTER, content[enumConst.SERVICE_COMMAND]) | |
7047 | 7068 | } |
7048 | 7069 | |
7049 | 7070 | controlFormDisplay(content.type, isTCPTransportType, isCustom) |
... | ... | @@ -7111,31 +7132,29 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7111 | 7132 | if (isParamsSetting) { |
7112 | 7133 | const isTCPTransportType = formVal[enumConst.TRANSPORTTYPE] === 'TCP' |
7113 | 7134 | const isCustom = formVal[enumConst.COMMAND_TYPE] === COMMAND_TYPE_ENUM.CUSTOM |
7114 | - const inputData = form.val(enumActionEl.INPUT_DATA_FORM_FILTER) | |
7135 | + let inputData = form.val(enumActionEl.INPUT_DATA_FORM_FILTER) | |
7115 | 7136 | |
7116 | 7137 | const validateParamsSetting = () => { |
7117 | 7138 | if (isCustom) { |
7118 | - if (isTCPTransportType && !formVal[enumConst.TCP_COMMAND]) { | |
7119 | - UseLayUi.topErrorMsg('请输入自定义下发指令') | |
7120 | - return false | |
7121 | - } | |
7122 | - if (!isTCPTransportType && !isJson(formVal[enumConst.COMMAND])) { | |
7123 | - UseLayUi.topErrorMsg('命令配置存在错误') | |
7124 | - return false | |
7139 | + if (isTCPTransportType) { | |
7140 | + if (!formVal[enumConst.TCP_COMMAND]) { | |
7141 | + UseLayUi.topErrorMsg('请输入自定义下发指令') | |
7142 | + return false | |
7143 | + } | |
7144 | + if (!isJson(formVal[enumConst.JSON_COMMAND])) { | |
7145 | + UseLayUi.topErrorMsg('命令配置存在错误') | |
7146 | + return false | |
7147 | + } | |
7125 | 7148 | } |
7126 | 7149 | } else { |
7127 | 7150 | if (!formVal[enumConst.SERVICE]) { |
7128 | 7151 | UseLayUi.topErrorMsg('请选择服务') |
7129 | 7152 | return false |
7153 | + } else { | |
7154 | + const { flag, value } = UseLayUi.validateThingsModelInputDataForm(Utils.stringToJSON(formVal[enumConst.SERVICE_ORIGINAL_CONFIGURATION], []), inputData) | |
7155 | + inputData = value | |
7156 | + return flag | |
7130 | 7157 | } |
7131 | - // if ((!inputData && !isTCPTransportType) || (!formVal[enumConst.TCP_COMMAND] && isTCPTransportType)) { | |
7132 | - // UseLayUi.topErrorMsg('请选择服务') | |
7133 | - // return false | |
7134 | - // } | |
7135 | - // if (!inputData || !formVal[enumConst.TCP_COMMAND]) { | |
7136 | - // UseLayUi.topErrorMsg('请选择服务') | |
7137 | - // return false | |
7138 | - // } | |
7139 | 7158 | } |
7140 | 7159 | return true |
7141 | 7160 | } |
... | ... | @@ -7143,8 +7162,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7143 | 7162 | if (!validateParamsSetting()) return |
7144 | 7163 | |
7145 | 7164 | // 选择服务的方式下发命令 |
7146 | - if (!isCustom && formVal[enumConst.SERVICE]) { | |
7147 | - formVal[enumConst.COMMAND] = inputData | |
7165 | + if (!isCustom && formVal[enumConst.SERVICE] && !isTCPTransportType) { | |
7166 | + formVal[enumConst.SERVICE_COMMAND] = inputData | |
7148 | 7167 | } |
7149 | 7168 | } |
7150 | 7169 | |
... | ... | @@ -7159,11 +7178,14 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7159 | 7178 | type: formVal[enumConst.ACTION], |
7160 | 7179 | value: formVal[enumGetValue[formVal[enumConst.ACTION]]], |
7161 | 7180 | ...(isParamsSetting ? { |
7162 | - [enumConst.COMMAND]: formVal[enumConst.COMMAND], | |
7181 | + [enumConst.JSON_COMMAND]: formVal[enumConst.JSON_COMMAND], | |
7163 | 7182 | [enumConst.WAY]: formVal[enumConst.WAY], |
7164 | 7183 | [enumConst.COMMAND_TYPE]: formVal[enumConst.COMMAND_TYPE], |
7165 | - [enumConst.SERVICE]: formVal[enumConst.SERVICE], | |
7166 | 7184 | [enumConst.TCP_COMMAND]: formVal[enumConst.TCP_COMMAND], |
7185 | + [enumConst.TRANSPORTTYPE]: formVal[enumConst.TRANSPORTTYPE], | |
7186 | + [enumConst.SERVICE]: formVal[enumConst.SERVICE], | |
7187 | + [enumConst.SERVICE_COMMAND]: formVal[enumConst.SERVICE_COMMAND], | |
7188 | + [enumConst.SERVICE_ORIGINAL_CONFIGURATION]: formVal[enumConst.SERVICE_ORIGINAL_CONFIGURATION], | |
7167 | 7189 | } : {}), |
7168 | 7190 | }, |
7169 | 7191 | } |
... | ... | @@ -7195,8 +7217,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7195 | 7217 | */ |
7196 | 7218 | function generateCommandTypeOptions() { |
7197 | 7219 | const options = [ |
7198 | - { name: '自定义', id: COMMAND_TYPE_ENUM.CUSTOM }, | |
7199 | - { name: '服务', id: COMMAND_TYPE_ENUM.SERVICE }, | |
7220 | + { name: '自定义命令', id: COMMAND_TYPE_ENUM.CUSTOM }, | |
7221 | + { name: '服务调用', id: COMMAND_TYPE_ENUM.SERVICE }, | |
7200 | 7222 | ] |
7201 | 7223 | return UseLayUi.generateOptionTemplate({ dataSource: options, addPlaceholderOption: false }) |
7202 | 7224 | } |
... | ... | @@ -7216,6 +7238,9 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7216 | 7238 | let transportType |
7217 | 7239 | let deviceProfileServices = [] |
7218 | 7240 | |
7241 | + /** | |
7242 | + * @description 动作下拉 change event | |
7243 | + */ | |
7219 | 7244 | form.on(`select(${enumActionEl.ACTION_SELECT_FILTER})`, (data) => { |
7220 | 7245 | const { value } = data |
7221 | 7246 | if (value === enumActionType.PARAMS_SETTING && !dataSource.deviceProfileId) { |
... | ... | @@ -7228,6 +7253,9 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7228 | 7253 | controlFormDisplay(value, transportType, isCustom) |
7229 | 7254 | }) |
7230 | 7255 | |
7256 | + /** | |
7257 | + * @description 命令类型下拉 change event | |
7258 | + */ | |
7231 | 7259 | form.on(`select(${enumActionEl.COMMAND_TYPE_EL})`, (data) => { |
7232 | 7260 | const { value } = data |
7233 | 7261 | const flag = value === COMMAND_TYPE_ENUM.CUSTOM |
... | ... | @@ -7237,8 +7265,12 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7237 | 7265 | $(`#${enumActionEl.TCP_COMMAND_INPUT}`).css({ display: isTCPTransportType && flag ? 'block' : 'none' }) |
7238 | 7266 | $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: !isTCPTransportType && flag ? 'flex' : 'none' }) |
7239 | 7267 | form.val(enumActionEl.FORM_FILTER, { [enumConst.TCP_COMMAND]: '', [enumConst.SERVICE]: '', [enumConst.COMMAND]: '' }) |
7268 | + $(`#${enumActionEl.INPUT_DATA_FORM}`).html('') | |
7240 | 7269 | }) |
7241 | 7270 | |
7271 | + /** | |
7272 | + * @description 服务下拉选择change event | |
7273 | + */ | |
7242 | 7274 | form.on(`select(${enumActionEl.SERVICE_EL})`, (data) => { |
7243 | 7275 | const { value } = data |
7244 | 7276 | const needRender = deviceProfileServices.find(item => item.identifier === value) || {} |
... | ... | @@ -7248,10 +7280,9 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7248 | 7280 | const template = UseLayUi.genThingsModelInputDataForm(needRender.functionJson?.inputData || [], 120) |
7249 | 7281 | $(`#${enumActionEl.INPUT_DATA_FORM}`).html(template) |
7250 | 7282 | } else { |
7251 | - console.log(needRender) | |
7252 | - form.val(enumActionEl.FORM_FILTER, { [enumConst.TCP_COMMAND]: needRender.functionJson?.inputData?.[0]?.serviceCommand || '' }) | |
7253 | - console.log(form.val(enumActionEl.FORM_FILTER)) | |
7283 | + form.val(enumActionEl.FORM_FILTER, { [enumConst.SERVICE_COMMAND]: needRender.functionJson?.inputData?.[0]?.serviceCommand || '' }) | |
7254 | 7284 | } |
7285 | + form.val(enumActionEl.FORM_FILTER, { [enumConst.SERVICE_ORIGINAL_CONFIGURATION]: JSON.stringify(needRender.functionJson?.inputData || []) }) | |
7255 | 7286 | }) |
7256 | 7287 | |
7257 | 7288 | try { |
... | ... | @@ -7272,7 +7303,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7272 | 7303 | if (transportType !== 'TCP') { |
7273 | 7304 | const template = UseLayUi.genThingsModelInputDataForm(needRender.functionJson?.inputData || [], 120) |
7274 | 7305 | $(`#${enumActionEl.INPUT_DATA_FORM}`).html(template) |
7275 | - form.val(enumActionEl.INPUT_DATA_FORM_FILTER, content[enumConst.COMMAND]) | |
7306 | + form.val(enumActionEl.INPUT_DATA_FORM_FILTER, content[enumConst.SERVICE_COMMAND]) | |
7276 | 7307 | } |
7277 | 7308 | } |
7278 | 7309 | |
... | ... | @@ -7318,13 +7349,13 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7318 | 7349 | fontSize: 14, // 编辑器内字体大小 |
7319 | 7350 | tabSize: 2, // 制表符设置为 4 个空格大小 |
7320 | 7351 | }); |
7321 | - if (record.content && record.content[enumConst.COMMAND]) defaultValue = jsonParse(record.content[enumConst.COMMAND]) | |
7352 | + if (record.content && record.content[enumConst.JSON_COMMAND]) defaultValue = jsonParse(record.content[enumConst.JSON_COMMAND]) | |
7322 | 7353 | const stringValue = JSON.stringify(defaultValue, null, 2) |
7323 | 7354 | editor.insert(stringValue) |
7324 | - $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumConst.COMMAND}"]`).val(stringValue) | |
7355 | + $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumConst.JSON_COMMAND}"]`).val(stringValue) | |
7325 | 7356 | editor.session.setMode("ace/mode/json"); |
7326 | 7357 | editor.getSession().on('change', (event, editor) => { |
7327 | - $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumConst.COMMAND}"]`).val(editor.getValue()) | |
7358 | + $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumConst.JSON_COMMAND}"]`).val(editor.getValue()) | |
7328 | 7359 | }) |
7329 | 7360 | } |
7330 | 7361 | |
... | ... | @@ -7387,10 +7418,16 @@ DataFormatPanel.prototype.addDataFont = function (container) { |
7387 | 7418 | </select> |
7388 | 7419 | </div> |
7389 | 7420 | </div> |
7390 | - <div id="${enumActionEl.EDITOR_CONTAINER}" style="display: none; margin-bottom: 15px;"> | |
7421 | + <div style="display: none;"> | |
7422 | + <input type="text" name="${enumConst.SERVICE_COMMAND}" placeholder="服务命令" /> | |
7423 | + </div> | |
7424 | + <div style="display: none;"> | |
7425 | + <input type="text" name="${enumConst.SERVICE_ORIGINAL_CONFIGURATION}" placeholder="服务命令" /> | |
7426 | + </div> | |
7427 | + <div id="${enumActionEl.EDITOR_CONTAINER}" class="layui-form-item" style="display: none; margin-bottom: 15px;"> | |
7391 | 7428 | <div style="width: 120px; text-align: right; padding: 9px 15px;flex: 0 0 120px;">命令 ${createHelpMessage('用户预览模式下,点击参数设置后。输入的变量值将作为"attrPlaceholder"的值,并以JSON格式下发给服务器。', 'command')}</div> |
7392 | 7429 | <div id="${enumActionEl.EDITOR}" style="width: 100%; height: 100%;border: 2px solid #eee;"></div> |
7393 | - <textarea name="${enumConst.COMMAND}" style="display: none;" /> | |
7430 | + <textarea name="${enumConst.JSON_COMMAND}" class="layui-textarea" style="display: none;" /> | |
7394 | 7431 | </div> |
7395 | 7432 | <div id="${enumActionEl.TCP_COMMAND_INPUT}" style="display: none;"> |
7396 | 7433 | <label class="layui-form-label" style="width: 120px;">命令 ${createHelpMessage('用户预览模式下,点击参数设置后。输入的变量值将作为"attrPlaceholder"的值,并以JSON格式下发给服务器。', 'command')}</label> |
... | ... | @@ -12486,6 +12523,19 @@ class UseLayUi { |
12486 | 12523 | |
12487 | 12524 | static dynamicAttr = (attr, value) => value ? `${attr}="${value}"` : '' |
12488 | 12525 | |
12526 | + | |
12527 | + static createHelpMessage(message, className) { | |
12528 | + return ` | |
12529 | + <div class="thingskit-help-message ${className}"> | |
12530 | + <img src="${Proxy_Prefix}/images/thingskit/question.svg"/> | |
12531 | + <div class="thingskit-help-container"> | |
12532 | + <div class="thingskit-help-content">${message}</div> | |
12533 | + <div class="thingskit-help-arrow"></div> | |
12534 | + </div> | |
12535 | + </div> | |
12536 | + ` | |
12537 | + } | |
12538 | + | |
12489 | 12539 | /** |
12490 | 12540 | * @description 生成输入框控件 |
12491 | 12541 | * @param {{label: string, value: string, labelWidth: number, numberInput: boolean}} params |
... | ... | @@ -12536,6 +12586,67 @@ class UseLayUi { |
12536 | 12586 | </form>` |
12537 | 12587 | return template |
12538 | 12588 | } |
12589 | + /** | |
12590 | + * | |
12591 | + * @param {{ | |
12592 | + * accessMode: 'r' | 'w', | |
12593 | + * functionName: string, | |
12594 | + * id: string, | |
12595 | + * identifier: string, | |
12596 | + * dataType: { | |
12597 | + * type: 'TEXT' | 'INT' | 'DOUBLE' | 'STRUCT', | |
12598 | + * specs: { unit: {value: string, label: string}, | |
12599 | + * unitName: string, | |
12600 | + * valueRange: {min: number, max: number}, | |
12601 | + * length: number | |
12602 | + * }}}[]} inputData | |
12603 | + * @param {Record<string, any>} value = 80 | |
12604 | + */ | |
12605 | + static validateThingsModelInputDataForm(inputData, value, needFormat = false) { | |
12606 | + let flag = true | |
12607 | + const error = (message) => { | |
12608 | + UseLayUi.topErrorMsg(message) | |
12609 | + return false | |
12610 | + } | |
12611 | + | |
12612 | + const validate = (item) => { | |
12613 | + const { dataType, identifier, functionName } = item | |
12614 | + const { type } = dataType || {} | |
12615 | + const identifierValue = value[identifier] | |
12616 | + switch (type) { | |
12617 | + case UseLayUi.thingsModelType.INT: | |
12618 | + if (isNaN(identifierValue)) return error(`${functionName}字段需要一个数字`) | |
12619 | + needFormat && (value[identifier] = parseInt(identifierValue)) | |
12620 | + break | |
12621 | + case UseLayUi.thingsModelType.DOUBLE: | |
12622 | + if (isNaN(identifierValue)) return error(`${functionName}字段需要一个数字`) | |
12623 | + needFormat && (value[identifier] = Number(identifierValue)) | |
12624 | + break | |
12625 | + case UseLayUi.thingsModelType.STRUCT: | |
12626 | + if (!Utils.stringIsJSON(identifierValue)) return error(`${functionName}字段需要一个JSON对象`) | |
12627 | + needFormat && (value[identifier] = Utils.stringToJSON(identifierValue)) | |
12628 | + break | |
12629 | + default: | |
12630 | + break | |
12631 | + } | |
12632 | + return true | |
12633 | + } | |
12634 | + | |
12635 | + for (const item of inputData) { | |
12636 | + if (!validate(item)) return { flag: false, value } | |
12637 | + | |
12638 | + } | |
12639 | + | |
12640 | + return { flag, value } | |
12641 | + | |
12642 | + } | |
12643 | + | |
12644 | + static thingsModelType = { | |
12645 | + TEXT: 'TEXT', | |
12646 | + INT: 'INT', | |
12647 | + DOUBLE: 'DOUBLE', | |
12648 | + STRUCT: 'STRUCT', | |
12649 | + } | |
12539 | 12650 | |
12540 | 12651 | /** |
12541 | 12652 | * @description format data source to tree structure |
... | ... | @@ -12985,6 +13096,33 @@ class UseLayUi { |
12985 | 13096 | } |
12986 | 13097 | } |
12987 | 13098 | |
13099 | +class Utils { | |
13100 | + /** | |
13101 | + * @description 字符串是否能转换为对象 | |
13102 | + * @param {string} value | |
13103 | + */ | |
13104 | + static stringIsJSON(value) { | |
13105 | + try { | |
13106 | + JSON.parse(value) | |
13107 | + return true | |
13108 | + } catch (error) { | |
13109 | + return false | |
13110 | + } | |
13111 | + } | |
13112 | + | |
13113 | + /** | |
13114 | + * @description 字符串转对象 | |
13115 | + * @param {string} value | |
13116 | + * @returns | |
13117 | + */ | |
13118 | + static stringToJSON(value, defaultValue = {}) { | |
13119 | + try { | |
13120 | + return JSON.parse(value) | |
13121 | + } catch (error) { | |
13122 | + return defaultValue | |
13123 | + } | |
13124 | + } | |
13125 | +} | |
12988 | 13126 | |
12989 | 13127 | /** |
12990 | 13128 | * @description use to function capture await throw error |
... | ... | @@ -14841,25 +14979,153 @@ class HandleDataInteraction { |
14841 | 14979 | const enumActionEl = { |
14842 | 14980 | CONTAINER: 'container', |
14843 | 14981 | EDITOR: 'editor', |
14844 | - ISSUED_WAY_FILTER: 'wayFilter' | |
14982 | + ISSUED_WAY_FILTER: 'wayFilter', | |
14983 | + | |
14984 | + /** | |
14985 | + * @description 表单filter | |
14986 | + */ | |
14987 | + FORM_FILTER: 'formFilter', | |
14988 | + | |
14989 | + /** | |
14990 | + * @description 编辑器容器 | |
14991 | + */ | |
14992 | + EDITOR_CONTAINER: 'editorContainer', | |
14993 | + | |
14994 | + /** | |
14995 | + * @description 编辑器 | |
14996 | + */ | |
14997 | + EDITOR: 'editor', | |
14998 | + | |
14999 | + /** | |
15000 | + * @description 自定义TCP下发命令 | |
15001 | + */ | |
15002 | + CUSTOM_TCP_COMMAND: 'customTCPCommand', | |
15003 | + | |
15004 | + /** | |
15005 | + * @description 自定义JSON下发命令 | |
15006 | + */ | |
15007 | + CUSTOM_JSON_COMMAND: 'customJSONCommand', | |
14845 | 15008 | |
15009 | + /** | |
15010 | + * @description 服务TCP命令 | |
15011 | + */ | |
15012 | + SERVICE_TCP_COMMAND: 'serviceTCPCommand', | |
15013 | + | |
15014 | + /** | |
15015 | + * @description 服务JSON命令 | |
15016 | + */ | |
15017 | + SERVICE_JSON_COMMAND: 'serviceTCPCommand', | |
14846 | 15018 | } |
14847 | 15019 | |
14848 | - function createContent() { | |
14849 | - const { command, tcpCommand, } = content | |
15020 | + function createCustomTCPParams() { | |
14850 | 15021 | return ` |
14851 | - <div> | |
14852 | - <div class="layui-form" lay-filter="${enumActionEl.ISSUED_WAY_FILTER}"> | |
14853 | - <div class="layui-form-item"> | |
14854 | - <label class="layui-form-label">下发值</label> | |
14855 | - <div class="layui-input-block"> | |
14856 | - <input type="text" name="${enumConst.VALUE}" lay-verify="required" autocomplete="off" placeholder="请输入下发值" class="layui-input"> | |
15022 | + <div> | |
15023 | + <div class="layui-form" lay-filter="${enumActionEl.CUSTOM_TCP_COMMAND}"> | |
15024 | + <div class="layui-form-item"> | |
15025 | + <label class="layui-form-label" style="width: 120px;">自定义下发值</label> | |
15026 | + <div class="layui-input-block" style="margin-left: 150px;"> | |
15027 | + <input type="text" name="${enumActionEl.CUSTOM_TCP_COMMAND}" lay-verify="required" autocomplete="off" placeholder="请输入下发值" class="layui-input"> | |
15028 | + </div> | |
14857 | 15029 | </div> |
14858 | 15030 | </div> |
14859 | 15031 | </div> |
14860 | - </div>` | |
15032 | + ` | |
14861 | 15033 | } |
14862 | 15034 | |
15035 | + function createEditor() { | |
15036 | + if (content.transportType === 'TCP' || content.commandType === '1') return | |
15037 | + console.log('enter') | |
15038 | + const jsonCommand = content.jsonCommand || '' | |
15039 | + let defaultValue = { [enumConst.ATTR_PLACEHOLDER]: 0 } | |
15040 | + const editor = ace.edit(enumActionEl.EDITOR, { | |
15041 | + maxLines: 18, // 最大行数,超过会自动出现滚动条 | |
15042 | + minLines: 10, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小 | |
15043 | + fontSize: 14, // 编辑器内字体大小 | |
15044 | + tabSize: 2, // 制表符设置为 4 个空格大小 | |
15045 | + }); | |
15046 | + if (jsonCommand) defaultValue = jsonParse(jsonCommand) | |
15047 | + const stringValue = JSON.stringify(defaultValue, null, 2) | |
15048 | + editor.insert(stringValue) | |
15049 | + $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumActionEl.CUSTOM_JSON_COMMAND}"]`).val(stringValue) | |
15050 | + editor.session.setMode("ace/mode/json"); | |
15051 | + editor.getSession().on('change', (event, editor) => { | |
15052 | + $(`#${enumActionEl.EDITOR_CONTAINER}`).parent().find(`textarea[name="${enumActionEl.CUSTOM_JSON_COMMAND}"]`).val(editor.getValue()) | |
15053 | + }) | |
15054 | + console.log(editor) | |
15055 | + } | |
15056 | + | |
15057 | + function createCustomJSONParams() { | |
15058 | + return ` | |
15059 | + <div id="${enumActionEl.EDITOR_CONTAINER}" class="layui-form-item" style="disable: flex;"> | |
15060 | + <div style="width: 120px; text-align: right; padding: 9px 15px;flex: 0 0 120px;text-align: left;">命令</div> | |
15061 | + <div id="${enumActionEl.EDITOR}" style="width: 100%; height: 100%;border: 2px solid #eee;"></div> | |
15062 | + <textarea name="${enumActionEl.CUSTOM_JSON_COMMAND}" class="layui-textarea" style="display: none;" /> | |
15063 | + </div> | |
15064 | + ` | |
15065 | + } | |
15066 | + | |
15067 | + function createServiceTCPParams() { | |
15068 | + return ` | |
15069 | + <div> | |
15070 | + <div class="layui-form" lay-filter="${enumActionEl.SERVICE_TCP_COMMAND}"> | |
15071 | + <div class="layui-form-item"> | |
15072 | + <label class="layui-form-label" style="width: 120px;">自定义下发值</label> | |
15073 | + <div class="layui-input-block" style="margin-left: 150px;"> | |
15074 | + <input type="text" name="${enumActionEl.SERVICE_TCP_COMMAND}" lay-verify="required" autocomplete="off" placeholder="请输入下发值" class="layui-input"> | |
15075 | + </div> | |
15076 | + </div> | |
15077 | + </div> | |
15078 | + </div> | |
15079 | + ` | |
15080 | + } | |
15081 | + | |
15082 | + function createServiceInputDataParams() { | |
15083 | + const inputData = jsonParse(content.serviceOriginalConfiguration) | |
15084 | + return UseLayUi.genThingsModelInputDataForm(inputData) | |
15085 | + } | |
15086 | + | |
15087 | + function createContent() { | |
15088 | + const { commandType, tcpCommand, jsonCommand, serviceCommand, serviceOriginalConfiguration, transportType } = content | |
15089 | + const isCustom = commandType === '0' | |
15090 | + const isTCP = transportType === 'TCP' | |
15091 | + | |
15092 | + let template | |
15093 | + if (isCustom) { | |
15094 | + if (isTCP) { | |
15095 | + template = createCustomTCPParams() | |
15096 | + } else { | |
15097 | + template = createCustomJSONParams() | |
15098 | + } | |
15099 | + } else { | |
15100 | + if (isTCP) { | |
15101 | + template = createServiceTCPParams() | |
15102 | + } else { | |
15103 | + template = createServiceInputDataParams() | |
15104 | + } | |
15105 | + } | |
15106 | + return `<form class="layui-form" lay-filter="${enumActionEl.FORM_FILTER}">${template}</form>` | |
15107 | + } | |
15108 | + | |
15109 | + function echoPresetValue() { | |
15110 | + form.val(enumActionEl.FORM_FILTER, { | |
15111 | + // 如果是自定义并且不是TCP设备 回显inputData | |
15112 | + ...(content.commandType === '1' && content.transportType !== 'TCP' ? content.serviceCommand : {}), | |
15113 | + [enumActionEl.CUSTOM_JSON_COMMAND]: content.jsonCommand, | |
15114 | + [enumActionEl.CUSTOM_TCP_COMMAND]: content.tcpCommand, | |
15115 | + [enumActionEl.SERVICE_TCP_COMMAND]: content.serviceCommand, | |
15116 | + }) | |
15117 | + } | |
15118 | + | |
15119 | + function isJson(value) { | |
15120 | + try { | |
15121 | + JSON.parse(value) | |
15122 | + return true | |
15123 | + } catch (error) { | |
15124 | + return false | |
15125 | + } | |
15126 | + } | |
15127 | + | |
15128 | + | |
14863 | 15129 | function jsonParse(value) { |
14864 | 15130 | try { |
14865 | 15131 | return JSON.parse(value) |
... | ... | @@ -14868,12 +15134,49 @@ class HandleDataInteraction { |
14868 | 15134 | } |
14869 | 15135 | } |
14870 | 15136 | |
15137 | + const validateSwitchCommand = () => { | |
15138 | + const { commandType, transportType } = content | |
15139 | + const isCustom = commandType === '0' | |
15140 | + const isTCP = transportType === 'TCP' | |
15141 | + let { attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {} | |
15142 | + | |
15143 | + let flag = false | |
15144 | + let value | |
15145 | + | |
15146 | + if (isCustom) { | |
15147 | + if (isTCP) { | |
15148 | + value = content.tcpCommand | |
15149 | + if (value) flag = true | |
15150 | + } else { | |
15151 | + const replaceValue = currentNode.getAttribute(SWITCH_SEND_VALUE) | |
15152 | + value = jsonParse(content.jsonCommand) | |
15153 | + value = replaceAttrPlaceholder(value, attr, replaceValue) | |
15154 | + if (value) flag = true | |
15155 | + } | |
15156 | + } else { | |
15157 | + if (isTCP) { | |
15158 | + value = content.serviceCommand | |
15159 | + if (value) flag = true | |
15160 | + } else { | |
15161 | + value = content.serviceCommand | |
15162 | + const { flag: validateFlag, value: validateValue } = UseLayUi.validateThingsModelInputDataForm(Utils.stringToJSON(content.serviceOriginalConfiguration), value, true) | |
15163 | + if (validateFlag) { | |
15164 | + value = validateValue | |
15165 | + flag = true | |
15166 | + } | |
15167 | + } | |
15168 | + } | |
15169 | + return { flag, value } | |
15170 | + } | |
15171 | + | |
14871 | 15172 | function handleSwitchComponent() { |
14872 | 15173 | const state = currentNode.getAttribute(SWITCH_STATE) |
14873 | - const value = currentNode.getAttribute(SWITCH_SEND_VALUE) | |
14874 | 15174 | if (state === SWITCH_STATE_NONE) { |
14875 | 15175 | return |
14876 | 15176 | } |
15177 | + const { flag, value } = validateSwitchCommand() | |
15178 | + if (!flag) return | |
15179 | + | |
14877 | 15180 | layer.confirm('是否确认下发命令?', async function (index) { |
14878 | 15181 | defaultHandler(value, () => layer.close(index)) |
14879 | 15182 | }); |
... | ... | @@ -14886,7 +15189,7 @@ class HandleDataInteraction { |
14886 | 15189 | |
14887 | 15190 | for (const key of Object.keys(oldValue)) { |
14888 | 15191 | if (key === enumConst.ATTR_PLACEHOLDER) { |
14889 | - newValue[replaceAttr] = replaceValue | |
15192 | + newValue[replaceAttr] = replaceValue ? replaceValue : oldValue[key] | |
14890 | 15193 | continue |
14891 | 15194 | } |
14892 | 15195 | if (typeof oldValue[key] === 'object') { |
... | ... | @@ -14899,38 +15202,79 @@ class HandleDataInteraction { |
14899 | 15202 | return newValue |
14900 | 15203 | } |
14901 | 15204 | |
15205 | + const validate = (data) => { | |
15206 | + const { commandType, transportType } = content | |
15207 | + let { attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {} | |
15208 | + let flag = false | |
15209 | + let value | |
15210 | + | |
15211 | + const isCustom = commandType === '0' | |
15212 | + const isTCP = transportType === 'TCP' | |
15213 | + | |
15214 | + let template | |
15215 | + if (isCustom) { | |
15216 | + if (isTCP) { | |
15217 | + value = data[enumActionEl.CUSTOM_TCP_COMMAND] | |
15218 | + const validate = new Validate([ | |
15219 | + { value, required: true, message: '下发值是必填项' }, | |
15220 | + ]) | |
15221 | + if (validate.begin()) flag = true | |
15222 | + } else { | |
15223 | + value = data[enumActionEl.CUSTOM_JSON_COMMAND] | |
15224 | + const validate = new Validate([ | |
15225 | + { value, required: true, message: '下发值是必填项' }, | |
15226 | + { value, message: 'json格式校验不正确', validator: isJson }, | |
15227 | + ]) | |
15228 | + if (validate.begin()) { | |
15229 | + const replaceValue = currentNode.getAttribute(SWITCH_SEND_VALUE) | |
15230 | + flag = true | |
15231 | + value = jsonParse(value) | |
15232 | + value = replaceAttrPlaceholder(value, attr) | |
15233 | + } | |
15234 | + template = createCustomJSONParams() | |
15235 | + } | |
15236 | + } else { | |
15237 | + if (isTCP) { | |
15238 | + value = data[enumActionEl.SERVICE_TCP_COMMAND] | |
15239 | + const validate = new Validate([ | |
15240 | + { value, required: true, message: '下发值是必填项' }, | |
15241 | + ]) | |
15242 | + if (validate.begin()) flag = true | |
15243 | + } else { | |
15244 | + value = data | |
15245 | + const { flag: validateFlag, value: validateValue } = UseLayUi.validateThingsModelInputDataForm(Utils.stringToJSON(content.serviceOriginalConfiguration), value, true) | |
15246 | + if (validateFlag) { | |
15247 | + flag = true | |
15248 | + value = validateValue | |
15249 | + } | |
15250 | + } | |
15251 | + } | |
15252 | + | |
15253 | + return { flag, value } | |
15254 | + } | |
15255 | + | |
14902 | 15256 | const submitThrottle = this.throttle(submit) |
14903 | 15257 | async function submit(callback) { |
14904 | - const { value } = form.val(enumActionEl.ISSUED_WAY_FILTER) | |
14905 | - defaultHandler(value, callback) | |
15258 | + const value = form.val(enumActionEl.FORM_FILTER) | |
15259 | + const { flag, value: result } = validate(value) | |
15260 | + if (!flag) return | |
15261 | + defaultHandler(result, callback) | |
14906 | 15262 | } |
14907 | 15263 | |
14908 | 15264 | async function defaultHandler(value, callback) { |
14909 | 15265 | let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {} |
15266 | + console.log({ attr, value }) | |
14910 | 15267 | |
14911 | 15268 | /** |
14912 | 15269 | * @type {command: string , commandType: string, service: string, wary: string, tcpCommand: string} |
14913 | 15270 | */ |
14914 | 15271 | let { command, way, tcpCommand } = content |
14915 | - const validate = new Validate([ | |
14916 | - // { value, required: true, message: '下发值是必填项' }, | |
14917 | - // { value: deviceId, required: true, message: '未绑定设备' }, | |
14918 | - // { value: way, required: true, message: '未绑定指令下发方式(单向/双向)' }, | |
14919 | - // { value: command, required: true, message: '未设置下发命令' }, | |
14920 | - // { value: attr, required: true, message: '未绑定设备属性' }, | |
14921 | - ]) | |
14922 | - | |
14923 | - if (!validate.begin()) return | |
14924 | - if (typeof command === 'string') command = jsonParse(command) | |
14925 | - let data = replaceAttrPlaceholder(command, attr, value) | |
14926 | - if (tcpCommand) { | |
14927 | - data = tcpCommand | |
14928 | - } | |
15272 | + | |
14929 | 15273 | const instructionData = { |
14930 | 15274 | method: "methodThingskit", |
14931 | 15275 | additionalInfo: { cmdType: 'API' }, |
14932 | 15276 | persistent: true, |
14933 | - params: data, | |
15277 | + params: value, | |
14934 | 15278 | } |
14935 | 15279 | |
14936 | 15280 | const [err, res = []] = way === 'twoway' ? await to(ConfigurationNodeApi.deviceIsOnLine(deviceId)) : [null, [{ value: true }]] |
... | ... | @@ -14941,13 +15285,15 @@ class HandleDataInteraction { |
14941 | 15285 | UseLayUi.topSuccessMsg('操作成功') |
14942 | 15286 | callback && typeof callback === 'function' && callback() |
14943 | 15287 | } |
15288 | + if (err) { | |
15289 | + UseLayUi.topErrorMsg(err?.response?.data || err) | |
15290 | + } | |
14944 | 15291 | } else { |
14945 | 15292 | UseLayUi.topErrorMsg('设备不在线!') |
14946 | 15293 | } |
14947 | 15294 | } |
14948 | 15295 | |
14949 | 15296 | function createLayer() { |
14950 | - | |
14951 | 15297 | layer.open({ |
14952 | 15298 | title: '参数设置', |
14953 | 15299 | content: createContent(), |
... | ... | @@ -14961,7 +15307,9 @@ class HandleDataInteraction { |
14961 | 15307 | but2(index, layero) { |
14962 | 15308 | |
14963 | 15309 | }, |
14964 | - async success(layero, index) { | |
15310 | + success(layero, index) { | |
15311 | + createEditor() | |
15312 | + echoPresetValue() | |
14965 | 15313 | $('.layui-layer-setwin a').removeAttr('href') |
14966 | 15314 | form.render() |
14967 | 15315 | }, |
... | ... | @@ -14977,10 +15325,9 @@ class HandleDataInteraction { |
14977 | 15325 | } |
14978 | 15326 | |
14979 | 15327 | try { |
14980 | - // handle[componentType]() | |
14981 | - handleSwitchComponent() | |
15328 | + handle[componentType]() | |
14982 | 15329 | } catch (error) { |
14983 | - | |
15330 | + throw error | |
14984 | 15331 | } |
14985 | 15332 | } |
14986 | 15333 | startProcess() |
... | ... | @@ -15742,6 +16089,10 @@ class Validate { |
15742 | 16089 | this.list = ruleList |
15743 | 16090 | } |
15744 | 16091 | |
16092 | + static isFunction(value) { | |
16093 | + return Object.prototype.toString.call(value) === '[object Function]' | |
16094 | + } | |
16095 | + | |
15745 | 16096 | /** |
15746 | 16097 | * @description 设置规则 |
15747 | 16098 | * @param {{value: any, message: string, required?: boolean, validator?: any}} rule |
... | ... | @@ -15757,6 +16108,12 @@ class Validate { |
15757 | 16108 | UseLayUi.topErrorMsg(message) |
15758 | 16109 | return false |
15759 | 16110 | } |
16111 | + | |
16112 | + if (validator && Validate.isFunction(validator) && !validator(value)) { | |
16113 | + UseLayUi.topErrorMsg(message) | |
16114 | + return false | |
16115 | + } | |
16116 | + | |
15760 | 16117 | } |
15761 | 16118 | return true |
15762 | 16119 | } | ... | ... |