params.wxml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <navigation-bar background="{{themeMode === 'dark' ? '#111827' : '#FFF'}}"></navigation-bar>
  2. <view wx:if="{{toastText}}" class="page-toast page-toast--{{toastType}} {{themeClass}}">
  3. {{toastText}}
  4. </view>
  5. <view class="subpage-fixed-header subpage-fixed-header--generic {{themeClass}}">
  6. <view class="subpage-page-header">
  7. <view wx:if="{{activeParamView == 'parameterGroups'}}" class="panel-actions subpage-actions generic-protocol-actions">
  8. <view class="panel-action-button {{isStorageAccessProtocol && !connectedDevice ? 'is-disabled' : ''}}" bindtap="syncParameterGroups">同步</view>
  9. <view class="panel-action-button {{isStorageAccessProtocol && !connectedDevice ? 'is-disabled' : ''}} {{parameterAutoPollEnabled ? 'is-active' : ''}}" bindtap="toggleParameterPolling">轮询</view>
  10. <view class="panel-action-button" bindtap="saveParameterGroupsJson">保存</view>
  11. <view class="panel-action-button" bindtap="importParameterGroupsJson">加载</view>
  12. <view wx:if="{{isStorageAccessProtocol}}" class="panel-action-button" bindtap="completeParameterStructs">结构</view>
  13. <view wx:if="{{isModbusProtocol}}" class="panel-action-button panel-action-button--icon" bindtap="openParameterDraft">+</view>
  14. </view>
  15. <view wx:elif="{{activeParamView == 'parameterGroup' && isModbusProtocol}}" class="panel-actions subpage-actions">
  16. <view
  17. class="panel-action-button {{connectedDevice && !activeParameterGroup.addressOverflow ? '' : 'is-disabled'}}"
  18. data-group-id="{{activeParameterGroup.id}}"
  19. bindtap="readParameterGroup"
  20. >读取</view>
  21. <view
  22. wx:if="{{activeParameterGroup.writable}}"
  23. class="panel-action-button {{connectedDevice && !activeParameterGroup.addressOverflow ? '' : 'is-disabled'}}"
  24. data-group-id="{{activeParameterGroup.id}}"
  25. bindtap="writeParameterGroup"
  26. >写入</view>
  27. <view class="panel-action-button" bindtap="backToParamsHome">返回</view>
  28. </view>
  29. </view>
  30. </view>
  31. <scroll-view class="scrollarea {{themeClass}} scrollarea--subpage scrollarea--generic" scroll-y type="list">
  32. <view class="page-shell">
  33. <block wx:if="{{activeParamView == 'parameterGroups'}}">
  34. <view wx:if="{{isStorageAccessProtocol}}" class="panel storage-code-info-card">
  35. <view class="storage-code-info-top">
  36. <text class="storage-code-info-model">{{storageCodeInfoCard.model}}</text>
  37. </view>
  38. <view class="storage-code-info-bottom">
  39. <text class="storage-code-info-chip">{{storageCodeInfoCard.chipModel}}</text>
  40. <view class="storage-code-info-metrics">
  41. <view wx:for="{{storageCodeInfoCard.metricItems}}" wx:for-item="item" wx:key="text" class="storage-code-info-metric">{{item.text}}</view>
  42. </view>
  43. </view>
  44. </view>
  45. <view
  46. wx:for="{{parameterGroups}}"
  47. wx:for-item="group"
  48. wx:key="id"
  49. class="generic-group-shell {{group.deleteVisible ? 'is-delete-visible' : ''}}"
  50. >
  51. <view
  52. wx:if="{{!group.expanded && group.deleteVisible}}"
  53. class="generic-delete-action"
  54. data-group-id="{{group.id}}"
  55. bindtap="deleteParameterGroup"
  56. >
  57. -
  58. </view>
  59. <view
  60. class="panel generic-group-panel {{group.expanded ? '' : 'panel--collapsed'}}"
  61. data-group-id="{{group.id}}"
  62. bindtouchstart="onParameterGroupTouchStart"
  63. bindtouchend="onParameterGroupTouchEnd"
  64. >
  65. <view class="panel-header panel-header--with-actions">
  66. <view
  67. class="panel-heading-toggle"
  68. data-group-id="{{group.id}}"
  69. bindtap="openParameterGroup"
  70. >
  71. <view class="panel-icon icon-terminal">
  72. <image class="panel-icon-image" src="/assets/icons/terminal-white.png" mode="aspectFit" />
  73. </view>
  74. <view class="generic-group-title-wrap">
  75. <view class="panel-title" data-group-id="{{group.id}}" catchlongpress="openParameterGroupEdit">{{group.displayName || group.name}}</view>
  76. <view class="param-meta generic-group-meta">{{group.listMetaText || group.addressRangeText}}</view>
  77. </view>
  78. </view>
  79. <view wx:if="{{isModbusProtocol}}" class="panel-actions generic-group-actions">
  80. <view
  81. class="panel-action-button {{connectedDevice && !group.addressOverflow ? '' : 'is-disabled'}}"
  82. data-group-id="{{group.id}}"
  83. bindtap="readParameterGroup"
  84. >
  85. 读取
  86. </view>
  87. <view
  88. wx:if="{{group.writable}}"
  89. class="panel-action-button {{connectedDevice && !group.addressOverflow ? '' : 'is-disabled'}}"
  90. data-group-id="{{group.id}}"
  91. bindtap="writeParameterGroup"
  92. >
  93. 写入
  94. </view>
  95. <view class="entry-chevron"></view>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. </block>
  101. <block wx:elif="{{activeParamView == 'parameterGroup'}}">
  102. <view wx:if="{{activeParameterGroup}}" class="panel generic-group-detail-panel">
  103. <view class="generic-group-detail-header">
  104. <view class="panel-title">{{activeParameterGroup.detailTitleText || activeParameterGroup.displayName || activeParameterGroup.name}}</view>
  105. </view>
  106. <view class="generic-group-detail-meta">
  107. {{activeParameterGroup.detailMetaText || activeParameterGroup.addressRangeText}}
  108. </view>
  109. <view
  110. wx:for="{{activeParameterRegisterRows.length ? activeParameterRegisterRows : activeParameterGroup.registers}}"
  111. wx:for-item="register"
  112. wx:for-index="registerIndex"
  113. wx:key="id"
  114. class="generic-register-row {{register.dragClass}}"
  115. style="{{register.dragStyle}}"
  116. >
  117. <view
  118. wx:if="{{!activeParameterGroup.isStructLayout}}"
  119. class="generic-register-drag-handle {{register.dragHandleClass}}"
  120. data-group-id="{{activeParameterGroup.id}}"
  121. data-index="{{register.sourceIndex !== undefined ? register.sourceIndex : registerIndex}}"
  122. catchtouchstart="onParameterRegisterDragStart"
  123. catchtouchmove="onParameterRegisterDragMove"
  124. catchtouchend="onParameterRegisterDragEnd"
  125. catchtouchcancel="onParameterRegisterDragCancel"
  126. >
  127. <view class="generic-register-drag-bar"></view>
  128. <view class="generic-register-drag-bar"></view>
  129. <view class="generic-register-drag-bar"></view>
  130. </view>
  131. <view wx:else class="generic-register-layout-spacer"></view>
  132. <view class="generic-register-main">
  133. <view
  134. class="generic-register-name"
  135. data-group-id="{{activeParameterGroup.id}}"
  136. data-index="{{register.sourceIndex !== undefined ? register.sourceIndex : registerIndex}}"
  137. bindtap="openParameterRegisterInfo"
  138. catchlongpress="openParameterRegisterEdit"
  139. >
  140. {{register.name}}
  141. </view>
  142. <view class="generic-register-meta">
  143. <text>{{register.metaText || (register.addressText + ' ' + register.rawValueText)}}</text>
  144. </view>
  145. </view>
  146. <view class="generic-register-input-wrap {{register.showUnit && register.unit ? 'generic-register-input-wrap--unit' : ''}}">
  147. <block wx:if="{{activeParameterGroup.writable}}">
  148. <block wx:if="{{register.conversionFormula}}">
  149. <view class="param-value generic-readonly-value">{{register.displayValue || '--'}}{{register.showUnit && register.unit ? ' ' + register.unit : ''}}</view>
  150. </block>
  151. <block wx:else>
  152. <input
  153. class="value-input generic-register-value {{register.isDirty ? 'value-input--dirty' : ''}}"
  154. placeholder="--"
  155. data-group-id="{{activeParameterGroup.id}}"
  156. data-index="{{register.sourceIndex !== undefined ? register.sourceIndex : registerIndex}}"
  157. value="{{register.inputValue}}"
  158. bindinput="onParameterRegisterValueInput"
  159. bindblur="onParameterRegisterValueBlur"
  160. />
  161. <view wx:if="{{register.showUnit && register.unit}}" class="generic-register-unit">{{register.unit}}</view>
  162. </block>
  163. </block>
  164. <view wx:else class="param-value generic-readonly-value">{{register.displayValue || '--'}}{{register.showUnit && register.unit ? ' ' + register.unit : ''}}</view>
  165. <view wx:if="{{register.displayMetaText}}" class="generic-register-display-meta">{{register.displayMetaText}}</view>
  166. </view>
  167. </view>
  168. </view>
  169. </block>
  170. </view>
  171. </scroll-view>
  172. <view wx:if="{{parameterDialog.visible}}" class="generic-dialog-mask {{themeClass}}" bindtap="closeParameterDraft">
  173. <view class="generic-dialog" catchtap="noop">
  174. <view class="generic-dialog-header">
  175. <view class="generic-dialog-title">{{parameterDialog.title}}</view>
  176. <view class="generic-dialog-close" bindtap="closeParameterDraft">×</view>
  177. </view>
  178. <block wx:if="{{parameterDialog.mode == 'createGroup' || parameterDialog.mode == 'editGroup'}}">
  179. <view class="generic-dialog-body">
  180. <view class="generic-config-row">
  181. <view class="param-main">
  182. <view class="param-name">寄存器组名</view>
  183. <view class="param-meta">每组寄存器地址连续</view>
  184. </view>
  185. <input
  186. class="value-input generic-value-input"
  187. data-field="groupName"
  188. value="{{parameterDialog.groupName}}"
  189. bindinput="onParameterDraftInput"
  190. />
  191. </view>
  192. <view class="generic-config-row">
  193. <view class="param-main">
  194. <view class="param-name">寄存器类型</view>
  195. <view class="param-meta">决定读取功能码与是否可写</view>
  196. </view>
  197. <picker
  198. mode="selector"
  199. range="{{parameterRegisterTypeOptions}}"
  200. range-key="label"
  201. value="{{parameterDialog.registerTypeIndex}}"
  202. bindchange="onParameterDraftTypeChange"
  203. >
  204. <view class="generic-picker-value">{{parameterDialog.registerTypeText}}</view>
  205. </picker>
  206. </view>
  207. <view class="generic-config-row">
  208. <view class="param-main">
  209. <view class="param-name">寄存器起始地址</view>
  210. <view class="param-meta">16进制,例如 00A0</view>
  211. </view>
  212. <input
  213. class="value-input generic-value-input"
  214. data-field="startAddress"
  215. value="{{parameterDialog.startAddress}}"
  216. bindinput="onParameterDraftInput"
  217. />
  218. </view>
  219. <view class="generic-config-row">
  220. <view class="param-main">
  221. <view class="param-name">寄存器数量</view>
  222. <view class="param-meta">{{parameterDialog.structParsedSummary || '1 - 256'}}</view>
  223. </view>
  224. <input
  225. class="value-input generic-value-input"
  226. type="number"
  227. data-field="quantity"
  228. value="{{parameterDialog.quantity}}"
  229. bindinput="onParameterDraftInput"
  230. />
  231. </view>
  232. <view wx:if="{{parameterDialog.mode == 'createGroup'}}" class="generic-struct-section">
  233. <view class="generic-struct-header">
  234. <view class="param-main">
  235. <view class="param-name">结构体定义</view>
  236. <view class="param-meta">支持 typedef struct、typedef 别名与数组</view>
  237. </view>
  238. <view class="panel-action-button" bindtap="parseParameterStructDefinition">解析</view>
  239. </view>
  240. <textarea
  241. class="generic-struct-input"
  242. maxlength="-1"
  243. placeholder="粘贴 C 结构体定义"
  244. data-field="structDefinition"
  245. value="{{parameterDialog.structDefinition}}"
  246. bindinput="onParameterDraftInput"
  247. />
  248. </view>
  249. </view>
  250. </block>
  251. <block wx:elif="{{parameterDialog.mode == 'editRegister' || parameterDialog.mode == 'viewRegister'}}">
  252. <view class="generic-dialog-body">
  253. <view class="generic-info-stack">
  254. <view class="generic-info-row">
  255. <view class="generic-info-label">名称</view>
  256. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.name}}</view>
  257. <input wx:else class="value-input generic-value-input" data-field="name" value="{{parameterDialog.name}}" bindinput="onParameterDraftInput" />
  258. </view>
  259. <view class="generic-info-row">
  260. <view class="generic-info-label">地址</view>
  261. <view class="generic-info-value">{{parameterDialog.addressText}}</view>
  262. </view>
  263. <view wx:if="{{parameterDialog.sourceMetaText}}" class="generic-info-row">
  264. <view class="generic-info-label">来源</view>
  265. <view class="generic-info-value">{{parameterDialog.sourceMetaText}}</view>
  266. </view>
  267. <view wx:if="{{parameterDialog.showDataType}}" class="generic-info-row">
  268. <view class="generic-info-label">类型</view>
  269. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.dataTypeText}}</view>
  270. <picker wx:else mode="selector" range="{{parameterDataTypeOptions}}" range-key="label" value="{{parameterDialog.dataTypeIndex}}" bindchange="onParameterDialogDataTypeChange">
  271. <view class="generic-picker-value">{{parameterDialog.dataTypeText}}</view>
  272. </picker>
  273. </view>
  274. <view wx:if="{{parameterDialog.showTextLength}}" class="generic-info-row">
  275. <view class="generic-info-label">长度</view>
  276. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.textByteLength || '--'}}B</view>
  277. <input wx:else class="value-input generic-value-input" type="number" data-field="textByteLength" value="{{parameterDialog.textByteLength}}" bindinput="onParameterDraftInput" />
  278. </view>
  279. <view class="generic-info-row">
  280. <view class="generic-info-label">备注</view>
  281. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.remark || '--'}}</view>
  282. <input wx:else class="value-input generic-value-input" data-field="remark" value="{{parameterDialog.remark}}" bindinput="onParameterDraftInput" />
  283. </view>
  284. <view wx:if="{{parameterDialog.showUnit}}" class="generic-info-row">
  285. <view class="generic-info-label">单位</view>
  286. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.unit || '--'}}</view>
  287. <input wx:else class="value-input generic-value-input" data-field="unit" value="{{parameterDialog.unit}}" bindinput="onParameterDraftInput" />
  288. </view>
  289. <view wx:if="{{parameterDialog.showDataType}}" class="generic-info-row">
  290. <view class="generic-info-label">公式</view>
  291. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.conversionFormula || '--'}}</view>
  292. <input wx:else class="value-input generic-value-input" data-field="conversionFormula" value="{{parameterDialog.conversionFormula}}" placeholder="x" bindinput="onParameterDraftInput" />
  293. </view>
  294. <view wx:if="{{parameterDialog.conversionFormulaErrorText}}" class="generic-info-row">
  295. <view class="generic-info-label">公式</view>
  296. <view class="generic-info-value">{{parameterDialog.conversionFormulaErrorText}}</view>
  297. </view>
  298. <view wx:if="{{parameterDialog.mode == 'viewRegister' || parameterDialog.showRange}}" class="generic-info-row">
  299. <view class="generic-info-label">最小值</view>
  300. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.minValue || '--'}}</view>
  301. <input wx:else class="value-input generic-value-input" data-field="minValue" value="{{parameterDialog.minValue}}" bindinput="onParameterDraftInput" />
  302. </view>
  303. <view wx:if="{{parameterDialog.mode == 'viewRegister' || parameterDialog.showRange}}" class="generic-info-row">
  304. <view class="generic-info-label">最大值</view>
  305. <view wx:if="{{parameterDialog.mode == 'viewRegister'}}" class="generic-info-value">{{parameterDialog.maxValue || '--'}}</view>
  306. <input wx:else class="value-input generic-value-input" data-field="maxValue" value="{{parameterDialog.maxValue}}" bindinput="onParameterDraftInput" />
  307. </view>
  308. </view>
  309. </view>
  310. </block>
  311. <view class="generic-draft-actions">
  312. <view class="panel-action-button" bindtap="closeParameterDraft">{{parameterDialog.cancelText}}</view>
  313. <view wx:if="{{parameterDialog.confirmText}}" class="panel-action-button is-active" bindtap="confirmParameterDialog">{{parameterDialog.confirmText}}</view>
  314. </view>
  315. </view>
  316. </view>