Commit 299f75340db37e3a7915322c6941e6e0a604ccea

Authored by ww
1 parent 278df047

fix: DEFECT-1118 修复命令下发,tcp设备命令下发为字符串,其他设备从物模型服务中取命令

@@ -209,4 +209,22 @@ class ConfigurationNodeApi { @@ -209,4 +209,22 @@ class ConfigurationNodeApi {
209 static getDictionaryValue(dictCode) { 209 static getDictionaryValue(dictCode) {
210 return defHttp.post('/yt/dict_item/find', {dictCode}) 210 return defHttp.post('/yt/dict_item/find', {dictCode})
211 } 211 }
  212 +
  213 + /**
  214 + * @description 获取设备配置详情通过id
  215 + * @param {string} id
  216 + * @returns
  217 + */
  218 + static getDeviceProfileDetailById(id) {
  219 + return defHttp.get('/yt/device_profile/' + id)
  220 + }
  221 +
  222 + /**
  223 + * @description 获取产品服务通过设备配置id
  224 + * @param {string} id
  225 + * @returns
  226 + */
  227 + static getThingsModelServiceByDeviceProfileId(id) {
  228 + return defHttp.get('/yt/things_model/get_services/' + id)
  229 + }
212 } 230 }
@@ -6890,6 +6890,26 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6890,6 +6890,26 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6890 COMMAND: 'command', 6890 COMMAND: 'command',
6891 6891
6892 /** 6892 /**
  6893 + * @description TCP命令
  6894 + */
  6895 + TCP_COMMAND: 'tcpCommand',
  6896 +
  6897 + /**
  6898 + * @description 命令下发方式
  6899 + */
  6900 + COMMAND_TYPE: 'commandType',
  6901 +
  6902 + /**
  6903 + * @description 服务
  6904 + */
  6905 + SERVICE: 'service',
  6906 +
  6907 + /**
  6908 + * @description 传输协议
  6909 + */
  6910 + TRANSPORTTYPE: 'transportType',
  6911 +
  6912 + /**
6893 * @description 属性占位符 6913 * @description 属性占位符
6894 */ 6914 */
6895 ATTR_PLACEHOLDER: 'attrPlaceholder', 6915 ATTR_PLACEHOLDER: 'attrPlaceholder',
@@ -6919,6 +6939,11 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6919,6 +6939,11 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6919 FORM_FILTER: 'formModelFilter', 6939 FORM_FILTER: 'formModelFilter',
6920 6940
6921 /** 6941 /**
  6942 + * @description 表单
  6943 + */
  6944 + FORM_EL: 'formModelEl',
  6945 +
  6946 + /**
6922 * @description 动作 lay-filter 6947 * @description 动作 lay-filter
6923 */ 6948 */
6924 ACTION_SELECT_FILTER: 'actionSelectFilter', 6949 ACTION_SELECT_FILTER: 'actionSelectFilter',
@@ -6948,7 +6973,47 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6948,7 +6973,47 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6948 */ 6973 */
6949 EDITOR: 'EDITOR', 6974 EDITOR: 'EDITOR',
6950 6975
6951 - WAY_SELECT: 'dynamicWaySelectEl' 6976 + /**
  6977 + * @description 命令类型选择器
  6978 + */
  6979 + COMMAND_TYPE_EL: 'commandTypeEl',
  6980 +
  6981 + /**
  6982 + * @description 服务选择器
  6983 + */
  6984 + SERVICE_EL: 'serviceEl',
  6985 +
  6986 + /**
  6987 + * @description 命令下发输入框
  6988 + */
  6989 + COMMAND_INPUT: 'commandInput',
  6990 +
  6991 + /**
  6992 + * @description TCP 命令下发输入框
  6993 + */
  6994 + TCP_COMMAND_INPUT: 'tcpCommandInput',
  6995 +
  6996 + /**
  6997 + * @description 输入参数表单
  6998 + */
  6999 + INPUT_DATA_FORM: 'inputDataForm',
  7000 +
  7001 + /**
  7002 + * @description 服务命令
  7003 + */
  7004 + SERVICE_COMMAND: 'serviceCommand',
  7005 +
  7006 + WAY_SELECT: 'dynamicWaySelectEl',
  7007 +
  7008 + /**
  7009 + * @description 输入参数表单控件
  7010 + */
  7011 + INPUT_DATA_FORM_FILTER: 'inputDataFilter'
  7012 + }
  7013 +
  7014 + const COMMAND_TYPE_ENUM = {
  7015 + CUSTOM: '0',
  7016 + SERVICE: '1'
6952 } 7017 }
6953 7018
6954 /** 7019 /**
@@ -6966,9 +7031,23 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6966,9 +7031,23 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6966 const val = { 7031 const val = {
6967 [enumConst.ACTION]: content.type, 7032 [enumConst.ACTION]: content.type,
6968 [enumGetValue[content.type]]: content.value, 7033 [enumGetValue[content.type]]: content.value,
6969 - [enumConst.WAY]: content[enumConst.WAY] 7034 + [enumConst.WAY]: content[enumConst.WAY],
  7035 + [enumConst.COMMAND_TYPE]: content[enumConst.COMMAND_TYPE],
  7036 + [enumConst.SERVICE]: content[enumConst.SERVICE],
  7037 + [enumConst.COMMAND]: content[enumConst.COMMAND],
  7038 + [enumConst.TCP_COMMAND]: content[enumConst.TCP_COMMAND],
  7039 + }
  7040 +
  7041 +
  7042 + const isTCPTransportType = !!content[enumConst.TCP_COMMAND]
  7043 + const isCustom = content[enumConst.COMMAND_TYPE] === COMMAND_TYPE_ENUM.CUSTOM
  7044 +
  7045 + if (content[enumConst.SERVICE] && !isCustom) {
  7046 + form.val(enumActionEl.INPUT_DATA_FORM_FILTER, content[enumConst.COMMAND])
6970 } 7047 }
6971 - controlFormDisplay(content.type) 7048 +
  7049 + controlFormDisplay(content.type, isTCPTransportType, isCustom)
  7050 +
6972 form.val(enumActionEl.FORM_FILTER, val) 7051 form.val(enumActionEl.FORM_FILTER, val)
6973 } 7052 }
6974 7053
@@ -6976,22 +7055,40 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -6976,22 +7055,40 @@ DataFormatPanel.prototype.addDataFont = function (container) {
6976 * @description 控制form 7055 * @description 控制form
6977 * @param {enumActionType} value 7056 * @param {enumActionType} value
6978 */ 7057 */
6979 - function controlFormDisplay(value) { 7058 + async function controlFormDisplay(value, isTCP, isCustom) {
6980 if (value === enumActionType.PAGE) { 7059 if (value === enumActionType.PAGE) {
6981 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' }) 7060 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' })
6982 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'block' }) 7061 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'block' })
6983 $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' }) 7062 $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' })
6984 $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'none' }) 7063 $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'none' })
  7064 + $(`#${enumActionEl.COMMAND_TYPE_EL}`).css({ display: 'none' })
  7065 +
  7066 + $(`#${enumActionEl.INPUT_DATA_FORM}`).css({ display: 'none' })
  7067 + $(`#${enumActionEl.SERVICE_EL}`).css({ display: 'none' })
  7068 + $(`#${enumActionEl.TCP_COMMAND_INPUT}`).css({ display: 'none' })
  7069 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' })
6985 } else if (value === enumActionType.LINK) { 7070 } else if (value === enumActionType.LINK) {
6986 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' }) 7071 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' })
6987 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'block' }) 7072 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'block' })
6988 $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' }) 7073 $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' })
6989 $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'none' }) 7074 $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'none' })
  7075 + $(`#${enumActionEl.COMMAND_TYPE_EL}`).css({ display: 'none' })
  7076 +
  7077 + $(`#${enumActionEl.INPUT_DATA_FORM}`).css({ display: 'none' })
  7078 + $(`#${enumActionEl.SERVICE_EL}`).css({ display: 'none' })
  7079 + $(`#${enumActionEl.TCP_COMMAND_INPUT}`).css({ display: 'none' })
  7080 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'none' })
6990 } else if (value === enumActionType.PARAMS_SETTING) { 7081 } else if (value === enumActionType.PARAMS_SETTING) {
6991 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' }) 7082 $(`#${enumActionEl.LINK_EL_ID}`).css({ display: 'none' })
6992 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' }) 7083 $(`#${enumActionEl.PAGE_EL_ID}`).css({ display: 'none' })
6993 - $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'flex' }) 7084 + // $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: 'flex' })
6994 $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'block' }) 7085 $(`#${enumActionEl.WAY_SELECT}`).css({ display: 'block' })
  7086 + $(`#${enumActionEl.COMMAND_TYPE_EL}`).css({ display: 'block' })
  7087 +
  7088 + $(`#${enumActionEl.INPUT_DATA_FORM}`).css({ display: isCustom ? 'none' : 'block' })
  7089 + $(`#${enumActionEl.SERVICE_EL}`).css({ display: isCustom ? 'none' : 'block' })
  7090 + $(`#${enumActionEl.TCP_COMMAND_INPUT}`).css({ display: isTCP && isCustom ? 'block' : 'none' })
  7091 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: !isTCP && isCustom ? 'flex' : 'none' })
6995 } 7092 }
6996 } 7093 }
6997 7094
@@ -7012,9 +7109,42 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7012,9 +7109,42 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7012 } 7109 }
7013 7110
7014 if (isParamsSetting) { 7111 if (isParamsSetting) {
7015 - if (!isJson(formVal[enumConst.COMMAND])) {  
7016 - UseLayUi.topErrorMsg('命令配置存在错误')  
7017 - return 7112 + const isTCPTransportType = formVal[enumConst.TRANSPORTTYPE] === 'TCP'
  7113 + const isCustom = formVal[enumConst.COMMAND_TYPE] === COMMAND_TYPE_ENUM.CUSTOM
  7114 + const inputData = form.val(enumActionEl.INPUT_DATA_FORM_FILTER)
  7115 +
  7116 + const validateParamsSetting = () => {
  7117 + 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
  7125 + }
  7126 + } else {
  7127 + if (!formVal[enumConst.SERVICE]) {
  7128 + UseLayUi.topErrorMsg('请选择服务')
  7129 + return false
  7130 + }
  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 + }
  7140 + return true
  7141 + }
  7142 +
  7143 + if (!validateParamsSetting()) return
  7144 +
  7145 + // 选择服务的方式下发命令
  7146 + if (!isCustom && formVal[enumConst.SERVICE]) {
  7147 + formVal[enumConst.COMMAND] = inputData
7018 } 7148 }
7019 } 7149 }
7020 7150
@@ -7030,7 +7160,10 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7030,7 +7160,10 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7030 value: formVal[enumGetValue[formVal[enumConst.ACTION]]], 7160 value: formVal[enumGetValue[formVal[enumConst.ACTION]]],
7031 ...(isParamsSetting ? { 7161 ...(isParamsSetting ? {
7032 [enumConst.COMMAND]: formVal[enumConst.COMMAND], 7162 [enumConst.COMMAND]: formVal[enumConst.COMMAND],
7033 - [enumConst.WAY]: formVal[enumConst.WAY] 7163 + [enumConst.WAY]: formVal[enumConst.WAY],
  7164 + [enumConst.COMMAND_TYPE]: formVal[enumConst.COMMAND_TYPE],
  7165 + [enumConst.SERVICE]: formVal[enumConst.SERVICE],
  7166 + [enumConst.TCP_COMMAND]: formVal[enumConst.TCP_COMMAND],
7034 } : {}), 7167 } : {}),
7035 }, 7168 },
7036 } 7169 }
@@ -7057,6 +7190,18 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7057,6 +7190,18 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7057 } 7190 }
7058 7191
7059 /** 7192 /**
  7193 + * @description 生成命令类型选项
  7194 + * @returns
  7195 + */
  7196 + function generateCommandTypeOptions() {
  7197 + const options = [
  7198 + { name: '自定义', id: COMMAND_TYPE_ENUM.CUSTOM },
  7199 + { name: '服务', id: COMMAND_TYPE_ENUM.SERVICE },
  7200 + ]
  7201 + return UseLayUi.generateOptionTemplate({ dataSource: options, addPlaceholderOption: false })
  7202 + }
  7203 +
  7204 + /**
7060 * @description 生产页面选项 7205 * @description 生产页面选项
7061 */ 7206 */
7062 function generatorPageOptions() { 7207 function generatorPageOptions() {
@@ -7064,11 +7209,77 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7064,11 +7209,77 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7064 return UseLayUi.generateOptionTemplate({ dataSource: options, addPlaceholderOption: false }) 7209 return UseLayUi.generateOptionTemplate({ dataSource: options, addPlaceholderOption: false })
7065 } 7210 }
7066 7211
7067 - function generatorEventListen() { 7212 + async function generatorEventListen(data) {
  7213 + const info = getLayerBindInfo('event', event.data.type) || {}
  7214 + let originType = (info.content || {}).type
  7215 + const dataSource = getDataSourceBindValue()
  7216 + let transportType
  7217 + let deviceProfileServices = []
  7218 +
7068 form.on(`select(${enumActionEl.ACTION_SELECT_FILTER})`, (data) => { 7219 form.on(`select(${enumActionEl.ACTION_SELECT_FILTER})`, (data) => {
7069 const { value } = data 7220 const { value } = data
7070 - controlFormDisplay(value) 7221 + if (value === enumActionType.PARAMS_SETTING && !dataSource.deviceProfileId) {
  7222 + UseLayUi.topErrorMsg('请先绑定数据源!')
  7223 + form.val(enumActionEl.FORM_FILTER, { [enumConst.ACTION]: originType })
  7224 + return
  7225 + }
  7226 + originType = value
  7227 + const isCustom = form.val(enumActionEl.ACTION_SELECT_FILTER)[enumConst.COMMAND_TYPE] === COMMAND_TYPE_ENUM.CUSTOM
  7228 + controlFormDisplay(value, transportType, isCustom)
  7229 + })
  7230 +
  7231 + form.on(`select(${enumActionEl.COMMAND_TYPE_EL})`, (data) => {
  7232 + const { value } = data
  7233 + const flag = value === COMMAND_TYPE_ENUM.CUSTOM
  7234 + const isTCPTransportType = transportType === 'TCP'
  7235 + $(`#${enumActionEl.INPUT_DATA_FORM}`).css({ display: flag ? 'none' : 'block' })
  7236 + $(`#${enumActionEl.SERVICE_EL}`).css({ display: flag ? 'none' : 'block' })
  7237 + $(`#${enumActionEl.TCP_COMMAND_INPUT}`).css({ display: isTCPTransportType && flag ? 'block' : 'none' })
  7238 + $(`#${enumActionEl.EDITOR_CONTAINER}`).css({ display: !isTCPTransportType && flag ? 'flex' : 'none' })
  7239 + form.val(enumActionEl.FORM_FILTER, { [enumConst.TCP_COMMAND]: '', [enumConst.SERVICE]: '', [enumConst.COMMAND]: '' })
  7240 + })
  7241 +
  7242 + form.on(`select(${enumActionEl.SERVICE_EL})`, (data) => {
  7243 + const { value } = data
  7244 + const needRender = deviceProfileServices.find(item => item.identifier === value) || {}
  7245 + const isTCPTransportType = transportType === 'TCP'
  7246 +
  7247 + if (!isTCPTransportType) {
  7248 + const template = UseLayUi.genThingsModelInputDataForm(needRender.functionJson?.inputData || [], 120)
  7249 + $(`#${enumActionEl.INPUT_DATA_FORM}`).html(template)
  7250 + } 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))
  7254 + }
7071 }) 7255 })
  7256 +
  7257 + try {
  7258 + if (!dataSource.deviceProfileId) return
  7259 + const detail = await ConfigurationNodeApi.getDeviceProfileDetailById(dataSource.deviceProfileId)
  7260 + transportType = detail.transportType
  7261 + const { content = {} } = data
  7262 + form.val(enumActionEl.FORM_FILTER, { [enumConst.TRANSPORTTYPE]: transportType })
  7263 + const service = await ConfigurationNodeApi.getThingsModelServiceByDeviceProfileId(dataSource.deviceProfileId)
  7264 + deviceProfileServices = service || []
  7265 + const template = UseLayUi.generateOptionTemplate({ dataSource: deviceProfileServices, labelField: 'functionName', valueField: 'identifier' })
  7266 + $(`#${enumActionEl.SERVICE_EL} > .layui-input-block > select`).html(template)
  7267 + form.val(enumActionEl.FORM_FILTER, { [enumConst.SERVICE]: content[enumConst.SERVICE] })
  7268 +
  7269 + // 服务有值回显表单
  7270 + if (content[enumConst.SERVICE]) {
  7271 + const needRender = deviceProfileServices.find(item => item.identifier === content[enumConst.SERVICE]) || {}
  7272 + if (transportType !== 'TCP') {
  7273 + const template = UseLayUi.genThingsModelInputDataForm(needRender.functionJson?.inputData || [], 120)
  7274 + $(`#${enumActionEl.INPUT_DATA_FORM}`).html(template)
  7275 + form.val(enumActionEl.INPUT_DATA_FORM_FILTER, content[enumConst.COMMAND])
  7276 + }
  7277 + }
  7278 +
  7279 + form.render('select', enumActionEl.FORM_FILTER)
  7280 + } catch (error) {
  7281 + throw error
  7282 + }
7072 } 7283 }
7073 7284
7074 function isJson(string) { 7285 function isJson(string) {
@@ -7123,49 +7334,75 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7123,49 +7334,75 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7123 function createLayerForm(type) { 7334 function createLayerForm(type) {
7124 7335
7125 const content = ` 7336 const content = `
7126 - <form class="layui-form" lay-filter="${enumActionEl.FORM_FILTER}"> 7337 + <form id="${enumActionEl.FORM_EL}" class="layui-form" lay-filter="${enumActionEl.FORM_FILTER}">
7127 <div style="width: 450px"> 7338 <div style="width: 450px">
7128 <div class="layui-form-item"> 7339 <div class="layui-form-item">
7129 - <label class="layui-form-label">事件</label>  
7130 - <div class="layui-input-block"> 7340 + <label class="layui-form-label" style="width: 120px;">事件</label>
  7341 + <div class="layui-input-block" style="margin-left: 150px;">
7131 <input type="text" name="${enumConst.EVENT}" disabled class="layui-input" value="${enumEventType[type]}"> 7342 <input type="text" name="${enumConst.EVENT}" disabled class="layui-input" value="${enumEventType[type]}">
7132 </div> 7343 </div>
7133 </div> 7344 </div>
7134 <div class="layui-form-item"> 7345 <div class="layui-form-item">
7135 - <label class="layui-form-label">动作</label>  
7136 - <div class="layui-input-block"> 7346 + <label class="layui-form-label" style="width: 120px;">动作</label>
  7347 + <div class="layui-input-block" style="margin-left: 150px;">
7137 <select name="${enumConst.ACTION}" lay-verType="tips" lay-verify="required" lay-filter="${enumActionEl.ACTION_SELECT_FILTER}"> 7348 <select name="${enumConst.ACTION}" lay-verType="tips" lay-verify="required" lay-filter="${enumActionEl.ACTION_SELECT_FILTER}">
7138 ${generatorActionOptions()} 7349 ${generatorActionOptions()}
7139 </select> 7350 </select>
7140 </div> 7351 </div>
7141 </div> 7352 </div>
7142 <div class="layui-form-item" id="${enumActionEl.LINK_EL_ID}"> 7353 <div class="layui-form-item" id="${enumActionEl.LINK_EL_ID}">
7143 - <label class="layui-form-label">链接</label>  
7144 - <div class="layui-input-block"> 7354 + <label class="layui-form-label" style="width: 120px;">链接</label>
  7355 + <div class="layui-input-block" style="margin-left: 150px;">
7145 <input type="text" lay-verType="tips" name="${enumConst.LINK_VALUE}" class="layui-input"> 7356 <input type="text" lay-verType="tips" name="${enumConst.LINK_VALUE}" class="layui-input">
7146 </div> 7357 </div>
7147 </div> 7358 </div>
7148 <div class="layui-form-item" id="${enumActionEl.PAGE_EL_ID}" style="display:none"> 7359 <div class="layui-form-item" id="${enumActionEl.PAGE_EL_ID}" style="display:none">
7149 - <label class="layui-form-label">页面</label>  
7150 - <div class="layui-input-block"> 7360 + <label class="layui-form-label" style="width: 120px;">页面</label>
  7361 + <div class="layui-input-block" style="margin-left: 150px;">
7151 <select name="${enumConst.PAGE_VALUE}" lay-verType="tips" id="pageSelect"> 7362 <select name="${enumConst.PAGE_VALUE}" lay-verType="tips" id="pageSelect">
7152 ${generatorPageOptions()} 7363 ${generatorPageOptions()}
7153 </select> 7364 </select>
7154 </div> 7365 </div>
7155 </div> 7366 </div>
7156 - <div class="layui-form-item" id="${enumActionEl.WAY_SELECT}" style="display:none">  
7157 - <label class="layui-form-label">单向/双向 ${createHelpMessage(`单向:服务器向网关设备、直连设备发送指令。发送指令后,设备不会返回任何信息。\n 7367 + <div class="layui-form-item" id="${enumActionEl.WAY_SELECT}" style="display:none;">
  7368 + <label class="layui-form-label" style="width: 120px;">单向/双向 ${createHelpMessage(`单向:服务器向网关设备、直连设备发送指令。发送指令后,设备不会返回任何信息。\n
7158 双向:服务器向网关设备、直连设备发送指令。发送指令后,设备返回响应信息。`, 'way')}</label> 7369 双向:服务器向网关设备、直连设备发送指令。发送指令后,设备返回响应信息。`, 'way')}</label>
7159 - <div class="layui-input-block"> 7370 + <div class="layui-input-block" style="margin-left: 150px;">
7160 <input type="radio" name="${enumConst.WAY}" value="${enumWayType.ONE_WAY}" title="单向" checked=""> 7371 <input type="radio" name="${enumConst.WAY}" value="${enumWayType.ONE_WAY}" title="单向" checked="">
7161 <input type="radio" name="${enumConst.WAY}" value="${enumWayType.TWO_WAY}" title="双向"> 7372 <input type="radio" name="${enumConst.WAY}" value="${enumWayType.TWO_WAY}" title="双向">
7162 </div> 7373 </div>
7163 </div> 7374 </div>
7164 - <div id="${enumActionEl.EDITOR_CONTAINER}" style="display: none;">  
7165 - <div style="width: 80px; text-align: right; padding: 9px 15px;flex: 0 0 80px;">命令 ${createHelpMessage('用户预览模式下,点击参数设置后。输入的变量值将作为"attrPlaceholder"的值,并以JSON格式下发给服务器。', 'command')}</div> 7375 + <div id="${enumActionEl.COMMAND_TYPE_EL}" class="layui-form-item" style="display: none;">
  7376 + <label class="layui-form-label" style="width: 120px;">命令下发方式</label>
  7377 + <div class="layui-input-block" style="margin-left: 150px;">
  7378 + <select name="${enumConst.COMMAND_TYPE}" lay-verType="tips" required lay-filter="${enumActionEl.COMMAND_TYPE_EL}">
  7379 + ${generateCommandTypeOptions()}
  7380 + </select>
  7381 + </div>
  7382 + </div>
  7383 + <div class="layui-form-item" id="${enumActionEl.SERVICE_EL}" style="display: none;">
  7384 + <label class="layui-form-label" style="width: 120px;">服务</label>
  7385 + <div class="layui-input-block" style="margin-left: 150px;">
  7386 + <select name="${enumConst.SERVICE}" lay-verType="tips" lay-filter="${enumActionEl.SERVICE_EL}">
  7387 + </select>
  7388 + </div>
  7389 + </div>
  7390 + <div id="${enumActionEl.EDITOR_CONTAINER}" style="display: none; margin-bottom: 15px;">
  7391 + <div style="width: 120px; text-align: right; padding: 9px 15px;flex: 0 0 120px;">命令 ${createHelpMessage('用户预览模式下,点击参数设置后。输入的变量值将作为"attrPlaceholder"的值,并以JSON格式下发给服务器。', 'command')}</div>
7166 <div id="${enumActionEl.EDITOR}" style="width: 100%; height: 100%;border: 2px solid #eee;"></div> 7392 <div id="${enumActionEl.EDITOR}" style="width: 100%; height: 100%;border: 2px solid #eee;"></div>
7167 <textarea name="${enumConst.COMMAND}" style="display: none;" /> 7393 <textarea name="${enumConst.COMMAND}" style="display: none;" />
7168 </div> 7394 </div>
  7395 + <div id="${enumActionEl.TCP_COMMAND_INPUT}" style="display: none;">
  7396 + <label class="layui-form-label" style="width: 120px;">命令 ${createHelpMessage('用户预览模式下,点击参数设置后。输入的变量值将作为"attrPlaceholder"的值,并以JSON格式下发给服务器。', 'command')}</label>
  7397 + <div class="layui-input-block" style="margin-left: 150px;">
  7398 + <input type="text" lay-verType="tips" name="${enumConst.TCP_COMMAND}" placeholder="请输入自定义下发命令" class="layui-input">
  7399 + </div>
  7400 + </div>
  7401 + <div style="display: none;">
  7402 + <input type="text" lay-verType="tips" name="${enumConst.TRANSPORTTYPE}" placeholder="请输入自定义下发命令" class="layui-input">
  7403 + </div>
  7404 + <div id="${enumActionEl.INPUT_DATA_FORM}" class="layui-form" lay-filter="${enumActionEl.INPUT_DATA_FORM_FILTER}">
  7405 + </div>
7169 </div> 7406 </div>
7170 </form> 7407 </form>
7171 ` 7408 `
@@ -7173,7 +7410,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7173,7 +7410,7 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7173 layer.open({ 7410 layer.open({
7174 title: "创建交互", 7411 title: "创建交互",
7175 content, 7412 content,
7176 - area: ["800px", "500px"], 7413 + area: ["800px", "650px"],
7177 btn: ["保存", "取消"], 7414 btn: ["保存", "取消"],
7178 yes(index) { 7415 yes(index) {
7179 form.on(`submit(${enumActionEl.LAYER_SUBMIT_FILTER})`, data => { 7416 form.on(`submit(${enumActionEl.LAYER_SUBMIT_FILTER})`, data => {
@@ -7191,8 +7428,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7191,8 +7428,8 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7191 'lay-submit': '', 7428 'lay-submit': '',
7192 'lay-filter': enumActionEl.LAYER_SUBMIT_FILTER, 7429 'lay-filter': enumActionEl.LAYER_SUBMIT_FILTER,
7193 }) 7430 })
7194 - generatorEventListen()  
7195 const info = getLayerBindInfo('event', type) 7431 const info = getLayerBindInfo('event', type)
  7432 + generatorEventListen(info)
7196 Object.assign(recordData, { enabled: info.enabled }) 7433 Object.assign(recordData, { enabled: info.enabled })
7197 createEditor(info) 7434 createEditor(info)
7198 form.render(null, enumActionEl.FORM_FILTER) 7435 form.render(null, enumActionEl.FORM_FILTER)
@@ -7823,7 +8060,6 @@ DataFormatPanel.prototype.addDataFont = function (container) { @@ -7823,7 +8060,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
7823 [enumDataSourceConst.DEVICE_ID]: null, 8060 [enumDataSourceConst.DEVICE_ID]: null,
7824 [enumDataSourceConst.ATTR]: null, 8061 [enumDataSourceConst.ATTR]: null,
7825 [enumDataSourceConst.ATTR_NAME]: null, 8062 [enumDataSourceConst.ATTR_NAME]: null,
7826 - [enumDataSourceConst.ORG_ID]: null  
7827 }) 8063 })
7828 8064
7829 currentDataSource[enumDataSourceConst.DEVICE_TYPE] = value 8065 currentDataSource[enumDataSourceConst.DEVICE_TYPE] = value
@@ -12251,6 +12487,57 @@ class UseLayUi { @@ -12251,6 +12487,57 @@ class UseLayUi {
12251 static dynamicAttr = (attr, value) => value ? `${attr}="${value}"` : '' 12487 static dynamicAttr = (attr, value) => value ? `${attr}="${value}"` : ''
12252 12488
12253 /** 12489 /**
  12490 + * @description 生成输入框控件
  12491 + * @param {{label: string, value: string, labelWidth: number, numberInput: boolean}} params
  12492 + * @returns
  12493 + */
  12494 + static createInputTemplate({ label, value, labelWidth = 80, required = false, type = 'TEXT' }) {
  12495 + return `
  12496 + <div class="layui-form-item" >
  12497 + <label class="layui-form-label" style="width: ${labelWidth}px">${label}</label>
  12498 + <div class="layui-input-block" style="margin-left: ${labelWidth + 30}px">
  12499 + <input type="text" name="${value}" value-type="${type}" ${required && 'required'} lay-verType="tips" lay-verify="${required && 'required'}" placeholder="请输入${label}" autocomplete="off" class="layui-input">
  12500 + </div>
  12501 + </div>
  12502 + `
  12503 + }
  12504 +
  12505 + static createJSONTemplate() {
  12506 +
  12507 + }
  12508 +
  12509 + /**
  12510 + *
  12511 + * @param {{
  12512 + * accessMode: 'r' | 'w',
  12513 + * functionName: string,
  12514 + * id: string,
  12515 + * identifier: string,
  12516 + * dataType: {
  12517 + * type: 'TEXT' | 'INT' | 'DOUBLE' | 'STRUCT',
  12518 + * specs: { unit: {value: string, label: string},
  12519 + * unitName: string,
  12520 + * valueRange: {min: number, max: number},
  12521 + * length: number
  12522 + * }}}[]} inputData
  12523 + * @param {number} labelWidth = 80
  12524 + * @param {}
  12525 + */
  12526 + static genThingsModelInputDataForm(inputData, labelWidth = 80, formFilter = 'inputDataFilter') {
  12527 + const list = []
  12528 + inputData.forEach(item => {
  12529 + const { identifier, functionName, dataType = {} } = item
  12530 + const { type } = dataType
  12531 + list.push(UseLayUi.createInputTemplate({ label: functionName, value: identifier, labelWidth, type }))
  12532 + })
  12533 + const template = `
  12534 + <form class="layui-form" action="" lay-filter="${formFilter}">
  12535 + ${list.join('')}
  12536 + </form>`
  12537 + return template
  12538 + }
  12539 +
  12540 + /**
12254 * @description format data source to tree structure 12541 * @description format data source to tree structure
12255 * @param {object[]} data - data source 12542 * @param {object[]} data - data source
12256 * @param {Function} [customSetValue = ((record) => ({ id: record.id, title: record.name }))] customSetValue - custom set value && need return value 12543 * @param {Function} [customSetValue = ((record) => ({ id: record.id, title: record.name }))] customSetValue - custom set value && need return value
@@ -14559,6 +14846,7 @@ class HandleDataInteraction { @@ -14559,6 +14846,7 @@ class HandleDataInteraction {
14559 } 14846 }
14560 14847
14561 function createContent() { 14848 function createContent() {
  14849 + const { command, tcpCommand, } = content
14562 return ` 14850 return `
14563 <div> 14851 <div>
14564 <div class="layui-form" lay-filter="${enumActionEl.ISSUED_WAY_FILTER}"> 14852 <div class="layui-form" lay-filter="${enumActionEl.ISSUED_WAY_FILTER}">
@@ -14619,17 +14907,25 @@ class HandleDataInteraction { @@ -14619,17 +14907,25 @@ class HandleDataInteraction {
14619 14907
14620 async function defaultHandler(value, callback) { 14908 async function defaultHandler(value, callback) {
14621 let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {} 14909 let { deviceId, attr } = contentData.dataSources.find(item => item.nodeId === nodeId) || {}
14622 - let { command, way } = content 14910 +
  14911 + /**
  14912 + * @type {command: string , commandType: string, service: string, wary: string, tcpCommand: string}
  14913 + */
  14914 + let { command, way, tcpCommand } = content
14623 const validate = new Validate([ 14915 const validate = new Validate([
14624 - { value, required: true, message: '下发值是必填项' },  
14625 - { value: deviceId, required: true, message: '未绑定设备' },  
14626 - { value: way, required: true, message: '未绑定指令下发方式(单向/双向)' },  
14627 - { value: command, required: true, message: '未设置下发命令' },  
14628 - { value: attr, required: true, message: '未绑定设备属性' }, 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: '未绑定设备属性' },
14629 ]) 14921 ])
  14922 +
14630 if (!validate.begin()) return 14923 if (!validate.begin()) return
14631 if (typeof command === 'string') command = jsonParse(command) 14924 if (typeof command === 'string') command = jsonParse(command)
14632 - const data = replaceAttrPlaceholder(command, attr, value) 14925 + let data = replaceAttrPlaceholder(command, attr, value)
  14926 + if (tcpCommand) {
  14927 + data = tcpCommand
  14928 + }
14633 const instructionData = { 14929 const instructionData = {
14634 method: "methodThingskit", 14930 method: "methodThingskit",
14635 additionalInfo: { cmdType: 'API' }, 14931 additionalInfo: { cmdType: 'API' },
@@ -14637,7 +14933,7 @@ class HandleDataInteraction { @@ -14637,7 +14933,7 @@ class HandleDataInteraction {
14637 params: data, 14933 params: data,
14638 } 14934 }
14639 14935
14640 - const [err, res = []] = await to(ConfigurationNodeApi.deviceIsOnLine(deviceId)) 14936 + const [err, res = []] = way === 'twoway' ? await to(ConfigurationNodeApi.deviceIsOnLine(deviceId)) : [null, [{ value: true }]]
14641 const { value: onlineFlag } = res[0] || {} 14937 const { value: onlineFlag } = res[0] || {}
14642 if (onlineFlag) { 14938 if (onlineFlag) {
14643 const [err, res] = await to(ConfigurationNodeApi.sendInstruction(way, deviceId, instructionData)) 14939 const [err, res] = await to(ConfigurationNodeApi.sendInstruction(way, deviceId, instructionData))
@@ -14681,7 +14977,8 @@ class HandleDataInteraction { @@ -14681,7 +14977,8 @@ class HandleDataInteraction {
14681 } 14977 }
14682 14978
14683 try { 14979 try {
14684 - handle[componentType]() 14980 + // handle[componentType]()
  14981 + handleSwitchComponent()
14685 } catch (error) { 14982 } catch (error) {
14686 14983
14687 } 14984 }