paramsSetInfo.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. <template>
  2. <div class="parameter-adjustment">
  3. <s-header :name="paramsTitle" :noback="false" />
  4. <div class="content-container">
  5. <!-- 设备信息卡片 -->
  6. <div class="device-card">
  7. <div class="device-header">
  8. <van-icon name="desktop-o" class="icon" />
  9. <h3 class="device-name">
  10. {{ equipmentName }}
  11. </h3>
  12. </div>
  13. </div>
  14. <!-- 参数配置区 -->
  15. <div class="parameter-container">
  16. <!-- 温湿度监控模式 -->
  17. <div v-if="type === '3'" class="monitoring-grid">
  18. <div
  19. v-for="item in monitoringParams"
  20. :key="item.key"
  21. class="parameter-card"
  22. >
  23. <van-icon :name="item.icon" class="param-icon" />
  24. <div class="param-info">
  25. <div class="param-label">{{ $t(item.label) }}</div>
  26. <div class="param-value">
  27. {{ deviceDetal[item.key] ?? $t("device.noData") }}
  28. <span v-if="deviceDetal[item.key] !== null">{{
  29. $t(item.unit)
  30. }}</span>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. <!-- 调试参数模式 -->
  36. <div v-if="type === '2'" class="debug-panel">
  37. <div class="parameter-card">
  38. <van-icon name="weapp-nav" class="param-icon" />
  39. <div class="param-info">
  40. <div class="param-label">
  41. {{ $t("device.humidityInCabinet") }}
  42. </div>
  43. <div class="param-value">
  44. {{ deviceDetal.cabinetHd ?? $t("device.noData") }}
  45. <span v-if="deviceDetal.cabinetHd !== null">{{
  46. $t("device.humidity")
  47. }}</span>
  48. </div>
  49. </div>
  50. </div>
  51. <div class="control-group">
  52. <van-field
  53. v-model="interval"
  54. :label="$t('device.increaseOrDecrease')"
  55. class="smart-field"
  56. >
  57. <template #button>
  58. <van-button
  59. size="small"
  60. type="primary"
  61. @click="updateInterval(0)"
  62. class="action-btn"
  63. >
  64. {{ $t("device.submitUpdates") }}
  65. </van-button>
  66. </template>
  67. </van-field>
  68. <div class="preset-buttons">
  69. <van-button
  70. v-for="preset in presets"
  71. :key="preset.type"
  72. type="primary"
  73. @click="updateInterval(preset.type)"
  74. class="preset-btn"
  75. >
  76. {{ $t(preset.label) }}
  77. </van-button>
  78. </div>
  79. </div>
  80. </div>
  81. <!-- 通用参数列表 -->
  82. <div class="parameter-list">
  83. <div
  84. v-for="(item, key) in paramsList"
  85. :key="key"
  86. class="parameter-item"
  87. >
  88. <van-field
  89. v-if="!checkBtn(item.name)"
  90. v-model="item.val"
  91. :label="paramName[key]"
  92. @update:model-value="onUpdateParameters(item, key, $event)"
  93. class="smart-field"
  94. >
  95. <template #button>
  96. <van-button
  97. size="small"
  98. type="primary"
  99. @click="updateParams(item, key)"
  100. class="action-btn"
  101. >
  102. {{ $t("device.submitUpdates") }}
  103. </van-button>
  104. </template>
  105. </van-field>
  106. <div v-else class="switch-control">
  107. <span class="switch-label">{{ paramName[key] }}</span>
  108. <van-switch
  109. :model-value="checked[key]"
  110. @update:model-value="onUpdateValue(item, key)"
  111. size="24px"
  112. class="custom-switch"
  113. />
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. </div>
  119. </div>
  120. </template>
  121. <script>
  122. import { onMounted, ref } from "vue";
  123. import sHeader from "@/components/SimpleHeader";
  124. import { useRoute, useRouter } from "vue-router";
  125. import {
  126. getDeviceDetal,
  127. getParameters,
  128. updateParameters,
  129. humidityParameters,
  130. } from "@/service/device";
  131. import {
  132. showFailToast,
  133. showSuccessToast,
  134. showConfirmDialog,
  135. showToast,
  136. } from "vant";
  137. import { useI18n } from "vue-i18n";
  138. import { styleUrl } from "../../../common/js/utils";
  139. export default {
  140. components: { sHeader },
  141. setup() {
  142. const { t } = useI18n();
  143. const route = useRoute();
  144. const router = useRouter();
  145. const deviceId = route.query.deviceId;
  146. const machineType = route.query.machineType;
  147. const deviceDetal = ref([]);
  148. const paramsTitle = ref("");
  149. const paramsList = ref([]);
  150. const comParams = ref([]);
  151. const paramName = ref([]);
  152. const checked = ref([]);
  153. const type = ref("");
  154. const isChange = ref(false);
  155. const howLong = ref([]);
  156. const interval = ref("");
  157. const equipmentName = route.query.name;
  158. const monitoringParams = ref([
  159. {
  160. key: "numberOne",
  161. label: "device.numberOneTm",
  162. unit: "device.degree",
  163. icon: "fire",
  164. },
  165. {
  166. key: "furnaceTm",
  167. label: "device.furnaceHeadTemperature",
  168. unit: "device.degree",
  169. icon: "fire",
  170. },
  171. {
  172. key: "candyGeneratorTm",
  173. label: "device.candyGeneratorTm",
  174. unit: "device.degree",
  175. icon: "fire",
  176. },
  177. {
  178. key: "cabinetTm",
  179. label: "device.temperatureInCabinet",
  180. unit: "device.degree",
  181. icon: "fire",
  182. },
  183. {
  184. key: "cabinetHd",
  185. label: "device.humidityInCabinet",
  186. unit: "device.humidity",
  187. icon: "weapp-nav",
  188. },
  189. {
  190. key: "outsideTm",
  191. label: "device.outsideTm",
  192. unit: "device.degree",
  193. icon: "fire",
  194. },
  195. {
  196. key: "outsideHd",
  197. label: "device.outsidehd",
  198. unit: "device.humidity",
  199. icon: "weapp-nav",
  200. },
  201. ]);
  202. const presets = ref([
  203. { type: 1, label: "device.winterParameters" },
  204. { type: 2, label: "device.summerParameters" },
  205. ]);
  206. // 初始化页面获取列表
  207. onMounted(async () => {
  208. // 加载样式
  209. styleUrl("paramsSet");
  210. type.value = route.query.type;
  211. if (route.query.type === "0") {
  212. paramsTitle.value = t("device.generalParameterConfiguration");
  213. }
  214. if (route.query.type === "1") {
  215. paramsTitle.value = t("device.advancedParameterConfiguration");
  216. }
  217. if (route.query.type === "2") {
  218. paramsTitle.value = t("device.debuggingParameterConfiguration");
  219. }
  220. if (route.query.type === "3") {
  221. paramsTitle.value = t("device.humidityParameterConfiguration");
  222. }
  223. getDeviceDetalFun();
  224. });
  225. // 判断是否为按钮
  226. const checkBtn = (name) => {
  227. return name.includes("M");
  228. };
  229. // 获取设备列表数据
  230. const getDeviceDetalFun = async () => {
  231. const { data } = await getDeviceDetal({ id: deviceId });
  232. if (data.code === "00000") {
  233. deviceDetal.value = data.data;
  234. if (route.query.type != "2") {
  235. getParametersFun();
  236. }
  237. } else {
  238. showFailToast(data.message);
  239. }
  240. };
  241. // 获取参数列表
  242. const getParametersFun = async () => {
  243. paramsList.value = [];
  244. const params = {
  245. id: deviceId,
  246. status: route.query.type,
  247. clientId: deviceDetal.value.clientId,
  248. };
  249. const { data } = await getParameters(params);
  250. if (data.code) {
  251. paramsList.value = data.data;
  252. paramsList.value.forEach((paramItem) => {
  253. comParams.value.push(paramItem.name);
  254. if (machineType == 0) {
  255. paramName.value.push(t("paramNames." + paramItem.name));
  256. }
  257. if (machineType == 1) {
  258. paramName.value.push(t("popParams." + paramItem.name));
  259. }
  260. if (paramItem.val === "1") {
  261. checked.value.push(true);
  262. } else {
  263. checked.value.push(false);
  264. }
  265. howLong.value.push(paramItem.val != null ? paramItem.val.length : 0);
  266. });
  267. } else {
  268. showToast(t("device.noParameterData"));
  269. }
  270. };
  271. const onUpdateParameters = (item, key, e) => {
  272. if (howLong.value[key] != e.length) {
  273. isChange.value = true;
  274. } else {
  275. isChange.value = false;
  276. }
  277. item.val = e;
  278. };
  279. // 更新参数值
  280. const updateParams = async (item, key) => {
  281. const params = {
  282. id: deviceId,
  283. name: item.name,
  284. val: item.val,
  285. };
  286. showConfirmDialog({
  287. title: t("device.tips"),
  288. message:
  289. t("device.isUpdate") +
  290. paramName.value[key] +
  291. t("device.to") +
  292. item.val +
  293. "?" +
  294. (isChange.value ? t("device.attention") : ""),
  295. })
  296. .then(async () => {
  297. const { data } = await updateParameters(params);
  298. if (data.code) {
  299. showSuccessToast(t("device.modificationSucceeded"));
  300. } else {
  301. showFailToast(data.message);
  302. }
  303. })
  304. .catch(() => {});
  305. };
  306. const onUpdateValue = (item, key) => {
  307. console.log(item);
  308. const params = {
  309. id: deviceId,
  310. name: item.name,
  311. val: item.val == "0" ? "1" : "0",
  312. };
  313. showConfirmDialog({
  314. title: t("device.tips"),
  315. message: t("device.content"),
  316. })
  317. .then(async () => {
  318. const { data } = await updateParameters(params);
  319. if (data.code) {
  320. checked.value[key] = !checked.value[key];
  321. showSuccessToast(t("device.modificationSucceeded"));
  322. setTimeout(() => {
  323. router.go(-1);
  324. }, 1000);
  325. } else {
  326. showFailToast(data.message);
  327. }
  328. })
  329. .catch(() => {
  330. // on cancel
  331. });
  332. };
  333. // 一键递增递减
  334. const updateInterval = (value) => {
  335. const params = {
  336. id: deviceId,
  337. name: "allUpdate",
  338. val: interval.value,
  339. };
  340. if (value === 0) {
  341. params.name = "allUpdate";
  342. params.val = interval.value;
  343. } else if (value === 1) {
  344. params.name = "winter";
  345. params.val = "winter";
  346. } else {
  347. params.name = "summer";
  348. params.val = "summer";
  349. }
  350. showConfirmDialog({
  351. title: t("device.tips"),
  352. message: t("device.isUpdate") + "?",
  353. })
  354. .then(async () => {
  355. const { data } = await humidityParameters(params);
  356. if (data.code) {
  357. showSuccessToast(t("device.modificationSucceeded"));
  358. } else {
  359. showFailToast(data.message);
  360. }
  361. })
  362. .catch(() => {});
  363. };
  364. return {
  365. deviceDetal,
  366. paramsTitle,
  367. paramsList,
  368. // getParamName,
  369. updateParams,
  370. paramName,
  371. checked,
  372. onUpdateValue,
  373. type,
  374. onUpdateParameters,
  375. interval,
  376. updateInterval,
  377. checkBtn,
  378. monitoringParams,
  379. presets,
  380. equipmentName,
  381. };
  382. },
  383. };
  384. </script>
  385. <style lang="less" scoped>
  386. @primary-color: #4d6add;
  387. @card-bg: #ffffff;
  388. @text-primary: #2d3436;
  389. @border-color: #e4e7ec;
  390. .parameter-adjustment {
  391. background: #f8fafb;
  392. min-height: 100vh;
  393. }
  394. .content-container {
  395. background: #f5f6fa;
  396. // padding: 16px;
  397. height: calc(100% - 50px);
  398. overflow: auto;
  399. overflow-x: hidden;
  400. }
  401. .device-card {
  402. background: @card-bg;
  403. border-radius: 12px;
  404. box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  405. margin: 10px;
  406. padding: 16px;
  407. .device-header {
  408. display: flex;
  409. align-items: center;
  410. .icon {
  411. font-size: 18px;
  412. color: @primary-color;
  413. margin-right: 10px;
  414. }
  415. .device-name {
  416. font-size: 15px;
  417. color: #404d74;
  418. margin: 0;
  419. overflow: hidden;
  420. text-overflow: ellipsis;
  421. white-space: nowrap;
  422. }
  423. }
  424. }
  425. .parameter-container {
  426. .monitoring-grid {
  427. display: grid;
  428. grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  429. gap: 12px;
  430. }
  431. .parameter-card {
  432. background: @card-bg;
  433. border-radius: 8px;
  434. margin: 0 10px;
  435. padding: 16px;
  436. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  437. display: flex;
  438. align-items: center;
  439. .param-icon {
  440. font-size: 24px;
  441. color: @primary-color;
  442. margin-right: 12px;
  443. }
  444. .param-label {
  445. font-size: 12px;
  446. color: #666;
  447. margin-bottom: 4px;
  448. }
  449. .param-value {
  450. font-size: 14px;
  451. color: @text-primary;
  452. font-weight: 500;
  453. span {
  454. color: #999;
  455. margin-left: 4px;
  456. }
  457. }
  458. }
  459. .control-group {
  460. background: @card-bg;
  461. border-radius: 12px;
  462. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  463. margin: 10px;
  464. .smart-field {
  465. // margin-bottom: 12px;
  466. :deep(.van-field__label) {
  467. color: @primary-color;
  468. font-weight: 500;
  469. }
  470. }
  471. .preset-buttons {
  472. display: grid;
  473. gap: 12px;
  474. // margin: 10px;
  475. padding: 15px;
  476. }
  477. .preset-btn {
  478. width: 100%;
  479. }
  480. }
  481. .parameter-list {
  482. .parameter-item {
  483. background: @card-bg;
  484. border-radius: 8px;
  485. margin: 10px;
  486. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  487. border: 1px solid #e4e7ec;
  488. transition: border-color 0.3s;
  489. &:focus-within {
  490. border-color: @primary-color;
  491. box-shadow: 0 0 0 2px rgba(77, 194, 148, 0.1);
  492. }
  493. :deep(.van-field__label) {
  494. font-weight: 500;
  495. }
  496. .switch-control {
  497. display: flex;
  498. align-items: center;
  499. justify-content: space-between;
  500. padding: 12px 25px;
  501. .switch-label {
  502. flex: 1;
  503. padding-right: 16px;
  504. color: @primary-color;
  505. }
  506. }
  507. }
  508. }
  509. }
  510. .action-btn {
  511. background: @primary-color;
  512. border: none;
  513. transition: transform 0.2s;
  514. &:active {
  515. transform: scale(0.95);
  516. }
  517. }
  518. .safe-area {
  519. height: 50px;
  520. }
  521. :deep(.van-field__control) {
  522. /* 输入框容器样式 */
  523. border: 1px solid #e4e7ec;
  524. border-radius: 8px;
  525. padding: 5px;
  526. transition: border-color 0.3s;
  527. }
  528. :deep(.van-field) {
  529. /* 输入框容器样式 */
  530. border-radius: 8px;
  531. transition: border-color 0.3s;
  532. /* label文本居中对齐 */
  533. .van-field__label {
  534. display: flex;
  535. align-items: center;
  536. justify-content: center;
  537. width: 120px;
  538. margin-right: 16px;
  539. color: @primary-color;
  540. font-weight: 500;
  541. /* 小屏幕适配 */
  542. @media (max-width: 480px) {
  543. width: 100px;
  544. font-size: 13px;
  545. }
  546. }
  547. /* 输入框内边距调整 */
  548. .van-field__body {
  549. padding: 8px 0;
  550. }
  551. /* 按钮样式微调 */
  552. .van-button {
  553. margin-left: 12px;
  554. }
  555. }
  556. @media (max-width: 480px) {
  557. .monitoring-grid {
  558. grid-template-columns: 1fr !important;
  559. }
  560. .parameter-card {
  561. padding: 12px !important;
  562. }
  563. }
  564. </style>