LiLongLong 3 weeks ago
parent
commit
2f1c9a906f
  1. 6
      eslint.config.js
  2. 1
      package.json
  3. 3
      src/apis/system.ts
  4. 4
      src/app.vue
  5. 3
      src/assets/styles/variable.scss
  6. 2
      src/components/common/CascadingSelectModal/index.vue
  7. 32
      src/components/common/DatePicker/index.vue
  8. 8
      src/components/common/DigitalKeyboard/index.vue
  9. 12
      src/components/common/ErrorModal/index.vue
  10. 1
      src/components/common/FTTable/index.vue
  11. 3
      src/components/common/KeyboardPinyin/index.vue
  12. 10
      src/components/common/SelectModal/index.vue
  13. 13
      src/components/common/SoftKeyboard/index.vue
  14. 13
      src/components/common/SoftKeyboard/moveKeyboard.vue
  15. 17
      src/components/formula/FormulaConfig.vue
  16. 7
      src/components/formula/FormulaTable.vue
  17. 4
      src/components/home/Environment.vue
  18. 3
      src/components/home/HomeFormula.vue
  19. 5
      src/components/home/HomeLogLevel.vue
  20. 13
      src/components/home/HomeOperation.vue
  21. 9
      src/components/home/HomeSetting.vue
  22. 9
      src/components/home/config.vue
  23. 3
      src/components/liquid/LiquidLevel.vue
  24. 3
      src/components/seal/DashboardChart.vue
  25. 11
      src/components/setting/AddUser.vue
  26. 4
      src/components/setting/History.vue
  27. 11
      src/components/setting/ModifyPwd.vue
  28. 4
      src/components/setting/User.vue
  29. 3
      src/components/system/ErrorEventsModal.vue
  30. 3
      src/components/system/NetReconnection.vue
  31. 25
      src/layouts/default.vue
  32. 3
      src/libs/deviceComm.ts
  33. 3
      src/libs/http.ts
  34. 2
      src/libs/modalUtil.ts
  35. 1
      src/libs/socket.ts
  36. 9
      src/main.ts
  37. 6
      src/router/index.ts
  38. 2
      src/router/routes.ts
  39. 5
      src/stores/deviceStore.ts
  40. 3
      src/stores/formulaStore.ts
  41. 3
      src/stores/homeStore.ts
  42. 4
      src/stores/initHomeData.ts
  43. 2
      src/stores/settingStore.ts
  44. 3
      src/stores/systemStore.ts
  45. 12
      src/types/softKeyboard.d.ts
  46. 3
      src/views/audit/index.vue
  47. 6
      src/views/debug/index.vue
  48. 3
      src/views/formula/index.vue
  49. 7
      src/views/home/chart.vue
  50. 7
      src/views/home/index.vue
  51. 15
      src/views/liquid/index.vue
  52. 11
      src/views/login/index.vue
  53. 13
      src/views/seal/index.vue
  54. 7
      src/views/setting/index.vue

6
eslint.config.js

@ -4,13 +4,19 @@
// import vue_parser from 'vue-eslint-parser';
import lintConfig from '@antfu/eslint-config'
import simpleImportSort from 'eslint-plugin-simple-import-sort'
export default lintConfig({
vue: true,
markdown: true,
ignores: [],
plugins: {
'simple-import-sort': simpleImportSort, // 作为对象注册插件
},
rules: {
'simple-import-sort/imports': 'error',
'no-console': 0,
'perfectionist/sort-imports': 'off',
'antfu/top-level-function': 0,
'ts/no-use-before-define': 0,
'no-alert': 0,

1
package.json

@ -75,6 +75,7 @@
"eslint": "^9.21.0",
"eslint-config-prettier": "^10.0.2",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-vue": "^9.32.0",
"husky": "^9.1.7",
"lint-staged": "^15.4.3",

3
src/apis/system.ts

@ -1,7 +1,8 @@
import { useSystemStore } from '@/stores/systemStore'
import { createWebSocket } from 'libs/socket'
import { nanoid } from 'nanoid'
import { useSystemStore } from '@/stores/systemStore'
const wsClient = createWebSocket()
export async function sendCmd(resParams: System.SendCmdParams) {

4
src/app.vue

@ -1,9 +1,11 @@
<script setup lang='ts'>
import { sendCmd } from '@/apis/system'
import { useDeviceStore } from 'stores/deviceStore'
import { useHomeStore } from 'stores/homeStore'
import { useLiquidStore } from 'stores/liquidStore'
import { onBeforeMount, ref } from 'vue'
import { sendCmd } from '@/apis/system'
import { useFormulaStore } from './stores/formulaStore'
/**

3
src/assets/styles/variable.scss

@ -3,5 +3,6 @@ $success-color: #14A656;
$danger-color: #DF1515;
$warn-color: #EE8223;
$info-color: #909399;
$gradient-color: linear-gradient(185deg, rgb(175 216 255) -90%, #fff 24%);
//$gradient-color: linear-gradient(185deg, rgb(175 216 255) -90%, #fff 24%);
$gradient-color: #fff;
$main-container-height: calc(100vh - 17vh)

2
src/components/common/CascadingSelectModal/index.vue

@ -114,7 +114,7 @@ watchEffect(() => {
<div class="modal-header">
<h3>{{ placeholder }}</h3>
<button class="close-btn" @click="handleCancel">
<i class="fa fa-times"></i>
<i class="fa fa-times" />
</button>
</div>
<div class="modal-main">

32
src/components/common/DatePicker/index.vue

@ -291,33 +291,33 @@ onUnmounted(() => {
<div class="date-time-picker">
<div class="input-group">
<input
type="text"
v-model="dateText"
@click="toggleDropdown"
type="text"
readonly
placeholder="请选择日期时间"
class="form-input"
@click="toggleDropdown"
>
<span class="input-icon" @click="toggleDropdown">
<i class="fa fa-calendar"></i>
<i class="fa fa-calendar" />
</span>
</div>
<transition name="fade">
<div v-show="isDropdownVisible" class="dropdown-container">
<div class="calendar-header">
<button @click="prevYear" class="nav-btn">
<button class="nav-btn" @click="prevYear">
<el-icon><DArrowLeft /></el-icon>
</button>
<button @click="prevMonth" class="nav-btn">
<button class="nav-btn" @click="prevMonth">
<el-icon><ArrowLeft /></el-icon>
</button>
<span class="current-date">
{{ currentYear }} {{ currentMonth + 1 }}
</span>
<button @click="nextMonth" class="nav-btn">
<button class="nav-btn" @click="nextMonth">
<el-icon><ArrowRight /></el-icon>
</button>
<button @click="nextYear" class="nav-btn">
<button class="nav-btn" @click="nextYear">
<el-icon><DArrowRight /></el-icon>
</button>
</div>
@ -343,28 +343,34 @@ onUnmounted(() => {
</div>
</div>
<div class="time-selector">
<div class="time-label">时间:</div>
<el-select v-model="selectedHour" @change="updateTime" class="time-select" >
<div class="time-label">
时间:
</div>
<el-select v-model="selectedHour" class="time-select" @change="updateTime">
<el-option v-for="i in hoursOptions" :key="i" :value="i.toString().padStart(2, '0')" style="font-size: 20px;line-height: 2px;height: 5rem;display: flex; align-items: center;">
{{ i.toString().padStart(2, '0') }}
</el-option>
</el-select>
<span class="time-separator">:</span>
<el-select v-model="selectedMinute" @change="updateTime" class="time-select">
<el-select v-model="selectedMinute" class="time-select" @change="updateTime">
<el-option v-for="i in minuteOptions" :key="i" :value="i.toString().padStart(2, '0')" style="font-size: 20px;line-height: 2px;height: 5rem;display: flex; align-items: center;">
{{ i.toString().padStart(2, '0') }}
</el-option>
</el-select>
<span class="time-separator">:</span>
<el-select v-model="selectedSecond" @change="updateTime" class="time-select">
<el-select v-model="selectedSecond" class="time-select" @change="updateTime">
<el-option v-for="i in secondOptions" :key="i" :value="i.toString().padStart(2, '0')" style="font-size: 20px;line-height: 2px;height: 5rem;display: flex; align-items: center;">
{{ i.toString().padStart(2, '0') }}
</el-option>
</el-select>
</div>
<div class="calendar-footer">
<button @click="confirmSelection" class="confirm-btn">确定</button>
<button @click="cancelSelection" class="cancel-btn">取消</button>
<button class="confirm-btn" @click="confirmSelection">
确定
</button>
<button class="cancel-btn" @click="cancelSelection">
取消
</button>
</div>
</div>
</transition>

8
src/components/common/DigitalKeyboard/index.vue

@ -63,13 +63,13 @@ onMounted(() => {
<div
ref="keyboardRef"
class="keyboard-container"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
:style="{
transform: `translate(${x}px, ${y}px)`,
transition: isDragging ? 'none' : 'transform 0.3s ease',
}"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<!-- 输入显示框 -->
<div class="input-box">
@ -79,7 +79,7 @@ onMounted(() => {
placeholder="点击输入"
class="input-field"
@click.stop
/>
>
</div>
<!-- 数字按键区域 -->

12
src/components/common/ErrorModal/index.vue

@ -33,14 +33,20 @@ const close = () => {
<div v-if="visible" class="error-box-mask">
<div class="error-box-container">
<div class="error-box-header">
<div class="error-title">{{ title }}</div>
<button @click="close">X</button>
<div class="error-title">
{{ title }}
</div>
<button @click="close">
X
</button>
</div>
<div class="error-box-content">
<slot>{{ message }}</slot>
</div>
<div class="error-box-footer">
<button @click="close" class="error-box-btn">{{ confirmText }}</button>
<button class="error-box-btn" @click="close">
{{ confirmText }}
</button>
</div>
</div>
</div>

1
src/components/common/FTTable/index.vue

@ -1,6 +1,7 @@
<script setup lang="ts">
import type { VNode } from 'vue'
import { onMounted, reactive } from 'vue'
import Expand from './expand'
defineOptions({

3
src/components/common/KeyboardPinyin/index.vue

@ -1,7 +1,8 @@
<script lang="ts" setup>
import 'cnchar-poly'
import cnchar from 'cnchar'
import { onMounted, ref } from 'vue'
import 'cnchar-poly'
const props = defineProps<{
isVisible: boolean

10
src/components/common/SelectModal/index.vue

@ -69,7 +69,7 @@ const handleCancel = () => {
<div class="modal-header">
<h3>{{ placeholder }}</h3>
<button class="close-btn" @click="handleCancel">
<i class="fa fa-times"></i>
<i class="fa fa-times" />
</button>
</div>
<div ref="optionsList" class="modal-content" re>
@ -89,8 +89,12 @@ const handleCancel = () => {
</div>
</div>
<div class="modal-footer">
<button class="cancel-btn" @click="handleCancel">取消</button>
<button class="confirm-btn" @click="confirmSelection">确定</button>
<button class="cancel-btn" @click="handleCancel">
取消
</button>
<button class="confirm-btn" @click="confirmSelection">
确定
</button>
</div>
</div>
</div>

13
src/components/common/SoftKeyboard/index.vue

@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { Ref } from 'vue'
import pinyinDict from 'libs/pinyinDict.json'
import { useDeviceStore } from 'stores/deviceStore'
import type { Ref } from 'vue'
import { computed, defineEmits, defineProps, onMounted, ref, watch, watchEffect } from 'vue'
const props = defineProps<{
@ -189,15 +189,15 @@ const handleTouchEnd = () => {
<div
ref="keyboardRef"
class="keyboard-container keyboard-body"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
:style="{
transform: `translate(${x}px, ${y}px)`,
transition: isDragging ? 'none' : 'transform 0.3s ease',
width: keyboardType === 'number' ? '30vw' : '66vw',
height: keyboardType === 'number' ? '46vh' : '46vh',
}"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<div>
<div v-if="keyboardType === 'text'" class="pinyin-container">
@ -207,7 +207,8 @@ const handleTouchEnd = () => {
v-for="(cnName, cnIndex) in cnList"
:key="cnIndex"
class="cn-name"
@click="(e) => { e.stopPropagation(); handleKeyCn(cnName) }">
@click="(e) => { e.stopPropagation(); handleKeyCn(cnName) }"
>
{{ cnName }}
</div>
</div>
@ -284,7 +285,7 @@ const handleTouchEnd = () => {
width: 1rem;
position: relative;
gap:5px;
font-family: fangsong;
//font-family: fangsong;
.cn-name{
font-size: 2.5rem;
}

13
src/components/common/SoftKeyboard/moveKeyboard.vue

@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { Ref } from 'vue'
import pinyinDict from 'libs/pinyinDict.json'
import type { Ref } from 'vue'
import { computed, defineEmits, defineProps, nextTick, onMounted, ref, watch, watchEffect } from 'vue'
const props = defineProps<{
@ -206,15 +206,15 @@ const handleTouchEnd = () => {
<div
ref="keyboardRef"
class="keyboard-container keyboard-body"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
:style="{
transform: `translate(${x}px, ${y}px)`,
transition: isDragging ? 'none' : 'transform 0.3s ease',
width: keyboardType === 'number' ? '30vw' : '66vw',
height: keyboardType === 'number' ? '46vh' : '46vh',
}"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<div>
<div v-if="keyboardType === 'text'" class="pinyin-container">
@ -224,7 +224,8 @@ const handleTouchEnd = () => {
v-for="(cnName, cnIndex) in cnList"
:key="cnIndex"
class="cn-name"
@click="(e) => { e.stopPropagation(); handleKeyCn(cnName) }">
@click="(e) => { e.stopPropagation(); handleKeyCn(cnName) }"
>
{{ cnName }}
</div>
</div>
@ -285,7 +286,7 @@ const handleTouchEnd = () => {
width: 1rem;
position: relative;
gap:5px;
font-family: fangsong;
//font-family: fangsong;
.cn-name{
font-size: 2.5rem;
}

17
src/components/formula/FormulaConfig.vue

@ -1,7 +1,4 @@
<script lang="ts" setup>
import { FtMessage } from '@/libs/message'
import { compareJSON, convertValuesToInt, convertValuesToString } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
import { sendCmd, syncSendCmd } from 'apis/system'
import SelectModal from 'components/common/SelectModal/index.vue'
import SoftKeyboard from 'components/common/SoftKeyboard/index.vue'
@ -9,6 +6,10 @@ import { formulaNameMap } from 'libs/constant'
import { cloneDeep } from 'lodash'
import { inject, onMounted, ref, watch, watchEffect } from 'vue'
import { FtMessage } from '@/libs/message'
import { compareJSON, convertValuesToInt, convertValuesToString } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
/**
* 配方表单组件 - 用于配置和管理各种配方参数
* 支持三种模式主页模式(home)设置模式(setting)和配方管理模式(formula)
@ -85,6 +86,8 @@ const labelUnitMap: Record<string, any> = {
injection_pump_speed: 'g/min',
continued_gs: 'ppm',
stoped_gs: 'ppm',
max_humidity: '%RH',
pre_heat_time_s: '秒',
continued_humi: '%RH',
stoped_humi: '%RH',
continued_satur: '%RS',
@ -390,7 +393,9 @@ const openKeyboardType = (labelName: string) => {
:disabled="!item.is_visible_in_setting_page"
@focus="(e) => openKeyboard(e, item)"
>
<template v-if="labelUnitMap[item.setting_id]" #append>{{ labelUnitMap[item.setting_id] }}</template>
<template v-if="labelUnitMap[item.setting_id]" #append>
{{ labelUnitMap[item.setting_id] }}
</template>
</el-input>
</template>
<template v-else-if="item.val_type === 'enum'">
@ -402,7 +407,9 @@ const openKeyboardType = (labelName: string) => {
readonly
@focus="openModal"
>
<template #append>{{ labelUnitMap[item.setting_id] }}</template>
<template #append>
{{ labelUnitMap[item.setting_id] }}
</template>
</el-input>
</template>
<template v-else-if="item.val_type === 'boolean'">

7
src/components/formula/FormulaTable.vue

@ -1,11 +1,12 @@
<script lang="ts" setup>
import { syncSendCmd } from 'apis/system'
import { ElMessageBox } from 'element-plus'
import { onMounted, ref, watchEffect } from 'vue'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { convertValuesToInt } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
import { syncSendCmd } from 'apis/system'
import { ElMessageBox } from 'element-plus'
import { onMounted, ref, watchEffect } from 'vue'
const formulaStore = useFormulaStore()
const selectedIndex = ref<number | null>(null)

4
src/components/home/Environment.vue

@ -8,7 +8,7 @@ import { onMounted } from 'vue'
/**
* 环境参数展示组件
* @description 用于展示仓内或探头的环境数据温度湿度过氧化氢浓度等
* @props {Object} envParams - 环境参数对象
* @props {object} envParams - 环境参数对象
* @props {string} lineColor - 线条颜色默认值red
*/
defineProps({
@ -91,7 +91,7 @@ onMounted(() => {
<style lang="scss" scoped>
div{
font-family: 思源黑体;
//font-family: ;
font-size: 18px;
font-weight: normal;
line-height: normal;

3
src/components/home/HomeFormula.vue

@ -1,8 +1,9 @@
<script lang="ts" setup>
import { useFormulaStore } from '@/stores/formulaStore'
// import homeRound from 'assets/images/home/home-round.svg'
import { ref, watchEffect } from 'vue'
import { useFormulaStore } from '@/stores/formulaStore'
const formulaStore = useFormulaStore()
const formulaInfo = ref()
watchEffect(() => {

5
src/components/home/HomeLogLevel.vue

@ -1,8 +1,9 @@
<script lang="ts" setup>
import { useFormulaStore } from '@/stores/formulaStore'
import SelectModal from 'components/common/SelectModal/index.vue'
import { ref, watchEffect } from 'vue'
import { useFormulaStore } from '@/stores/formulaStore'
const formulaStore = useFormulaStore()
const options = ref(formulaStore.logLevelOptions)
const loglevel = ref(formulaStore.loglevel)
@ -68,7 +69,7 @@ $input-height: 3rem;
align-items: center;
justify-content: center;
margin-top: 24vh;
font-family: Source Han Sans;
//font-family: Source Han Sans;
font-size: 24px;
.input{
width: 14vw;

13
src/components/home/HomeOperation.vue

@ -1,10 +1,4 @@
<script lang="ts" setup>
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import { useSystemStore } from '@/stores/systemStore'
import { sendCmd, subscribeEvent } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg'
import homeStart from 'assets/images/home/home-start.svg'
@ -12,6 +6,13 @@ import { startTimer, stopTimer } from 'libs/countdownTimer'
import { deviceStateMap } from 'libs/utils'
import { computed, onMounted, ref, watchEffect } from 'vue'
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import { useSystemStore } from '@/stores/systemStore'
/**
* 消毒操作控制组件
* @description 负责处理消毒流程控制开始/结束状态监听及倒计时逻辑

9
src/components/home/HomeSetting.vue

@ -1,8 +1,4 @@
<script lang="ts" setup>
import { FtMessage } from '@/libs/message'
import { useDeviceStore } from '@/stores/deviceStore'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import { sendCmd, syncSendCmd } from 'apis/system'
// import homeChart from 'assets/images/home/home-chart.svg'
import BtButton from 'components/common/BTButton/index.vue'
@ -13,6 +9,11 @@ import { cloneDeep } from 'lodash'
import { computed, onMounted, provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'
import { FtMessage } from '@/libs/message'
import { useDeviceStore } from '@/stores/deviceStore'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
/**
* 主页操作控制组件
* @description 负责处理压力控制消毒设置图表导航等功能协调组件间通信

9
src/components/home/config.vue

@ -1,12 +1,13 @@
<script lang="ts" setup>
import { convertValuesToInt } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import SelectModal from 'components/common/SelectModal/index.vue'
import FormulaConfig from 'components/formula/FormulaConfig.vue'
import { FtMessage } from 'libs/message'
import { computed, onMounted, ref, watchEffect } from 'vue'
import { convertValuesToInt } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
/**
* 配方选择页面组件
* @description 负责处理配方选择逻辑设备状态判断及界面交互
@ -151,7 +152,7 @@ const onDefaultFormula = () => {
.main-content{
overflow: hidden;
height: $main-container-height;
background: $gradient-color;
//background: $gradient-color;
padding: 15px;
.formula-config{
display: grid;

3
src/components/liquid/LiquidLevel.vue

@ -1,10 +1,11 @@
<script lang="ts" setup>
import { useLiquidStore } from '@/stores/liquidStore'
import liquidLevelSvg from 'assets/images/liquid/liquid-container.svg'
import liquidScaleSvg from 'assets/images/liquid/liquid-scale.svg'
import { roundNumber } from 'libs/utils'
import { computed, ref, watchEffect } from 'vue'
import { useLiquidStore } from '@/stores/liquidStore'
const liquidStore = useLiquidStore()
const liquidStateData = ref(liquidStore.liquidStateData)
const liquidTotal = ref(liquidStore.liquidTotal)

3
src/components/seal/DashboardChart.vue

@ -1,8 +1,9 @@
<script lang="ts" setup>
import { useSealStore } from '@/stores/sealStore'
import * as echarts from 'echarts'
import { onUnmounted, ref, watchEffect } from 'vue'
import { useSealStore } from '@/stores/sealStore'
const sealStore = useSealStore()
const chartRef = ref<HTMLElement | null>(null)
const realTimePressure = ref(sealStore.sealInfo.pressure)

11
src/components/setting/AddUser.vue

@ -1,11 +1,12 @@
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { useSettingStore } from '@/stores/settingStore'
import { syncSendCmd } from 'apis/system'
import SoftKeyboard from 'components/common/SoftKeyboard/index.vue'
import type { FormInstance } from 'element-plus'
import { FtMessage } from 'libs/message'
import { ref, watchEffect } from 'vue'
import { useSettingStore } from '@/stores/settingStore'
const emits = defineEmits(['refresh'])
const settingStore = useSettingStore()
const visible = ref(settingStore.addUserVisible)
@ -129,7 +130,7 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'],
}]"
>
<el-input v-model="userForm.name" v-prevent-keyboard name="name" @focus="openKeyboard" placeholder="登录名" />
<el-input v-model="userForm.name" v-prevent-keyboard name="name" placeholder="登录名" @focus="openKeyboard" />
</el-form-item>
<div>
<el-form-item
@ -141,7 +142,7 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" @focus="openKeyboard" type="password" placeholder="密码" />
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" type="password" placeholder="密码" @focus="openKeyboard" />
</el-form-item>
<el-form-item
label="确认密码:"
@ -152,7 +153,7 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.confirmPasswd" v-prevent-keyboard name="confirmPasswd" @focus="openKeyboard" placeholder="确认密码" />
<el-input v-model="userForm.confirmPasswd" v-prevent-keyboard name="confirmPasswd" placeholder="确认密码" @focus="openKeyboard" />
</el-form-item>
</div>
<el-form-item

4
src/components/setting/History.vue

@ -1,9 +1,11 @@
<script lang="ts" setup>
// import { useSettingStore } from '@/stores/settingStore'
import { FtMessage } from '@/libs/message'
import { syncSendCmd } from 'apis/system'
import { ElMessageBox } from 'element-plus'
import { onMounted, ref } from 'vue'
import { FtMessage } from '@/libs/message'
import HistoryDetail from './HistoryDetail.vue'
// const settingStore = useSettingStore()

11
src/components/setting/ModifyPwd.vue

@ -1,11 +1,12 @@
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { useSettingStore } from '@/stores/settingStore'
import { syncSendCmd } from 'apis/system'
import SoftKeyboard from 'components/common/SoftKeyboard/index.vue'
import type { FormInstance } from 'element-plus'
import { FtMessage } from 'libs/message'
import { ref, watchEffect } from 'vue'
import { useSettingStore } from '@/stores/settingStore'
const emits = defineEmits(['refresh'])
const settingStore = useSettingStore()
const visible = ref(settingStore.modifyPwdVisible)
@ -104,7 +105,7 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" @focus="openKeyboard" type="password" placeholder="密码" />
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" type="password" placeholder="密码" @focus="openKeyboard" />
</el-form-item>
<el-form-item
label="新密码:"
@ -115,7 +116,7 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.newpasswd" v-prevent-keyboard name="newpasswd" @focus="openKeyboard" type="password" placeholder="密码" />
<el-input v-model="userForm.newpasswd" v-prevent-keyboard name="newpasswd" type="password" placeholder="密码" @focus="openKeyboard" />
</el-form-item>
<el-form-item
label="确认新密码:"
@ -126,7 +127,7 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.confirmNewPasswd" v-prevent-keyboard name="confirmNewPasswd" @focus="openKeyboard" type="password" placeholder="确认密码" />
<el-input v-model="userForm.confirmNewPasswd" v-prevent-keyboard name="confirmNewPasswd" type="password" placeholder="确认密码" @focus="openKeyboard" />
</el-form-item>
</div>
</el-form>

4
src/components/setting/User.vue

@ -1,9 +1,11 @@
<script lang="ts" setup>
import { useSettingStore } from '@/stores/settingStore'
import { syncSendCmd } from 'apis/system'
import { FtMessage } from 'libs/message'
import { FtMessageBox } from 'libs/messageBox'
import { onMounted, ref } from 'vue'
import { useSettingStore } from '@/stores/settingStore'
import AddUser from './AddUser.vue'
import ModifyPwd from './ModifyPwd.vue'

3
src/components/system/ErrorEventsModal.vue

@ -1,7 +1,8 @@
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import { syncSendCmd } from '@/apis/system'
import { useDeviceStore } from '@/stores/deviceStore'
import { ref, watchEffect } from 'vue'
const deviceStore = useDeviceStore()
const appEvents = ref<Record<string, any>[]>([])

3
src/components/system/NetReconnection.vue

@ -1,9 +1,10 @@
<script setup lang="ts">
import { useSystemStore } from '@/stores/systemStore'
import { startTimer, stopTimer } from 'libs/countdownTimer'
import { ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'
import { useSystemStore } from '@/stores/systemStore'
const systemStore = useSystemStore()
const router = useRouter()
const timer = ref()

25
src/layouts/default.vue

@ -1,10 +1,4 @@
<script setup lang="ts">
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessageBox } from '@/libs/messageBox'
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
import HomeAlarmSvg from 'assets/images/home/home-alarm.svg'
import WifiConnSvg from 'assets/images/wifi-conn.svg'
import WifiUnconnSvg from 'assets/images/wifi-unconn.svg'
@ -18,6 +12,13 @@ import { onMounted, onUnmounted, ref, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessageBox } from '@/libs/messageBox'
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
const { locale } = useI18n()
const router = useRouter()
const liquidStore = useLiquidStore()
@ -154,8 +155,8 @@ const toggleLanguage = () => {
</div>
<div class="user">
<span v-if="isLowCost">
<img v-if="websocketConnected" width="20" :src="WifiConnSvg" alt="" />
<img v-else :src="WifiUnconnSvg" width="20" alt="" />
<img v-if="websocketConnected" width="20" :src="WifiConnSvg" alt="">
<img v-else :src="WifiUnconnSvg" width="20" alt="">
</span>
<el-select v-model="languageType" class="select-language" :disabled="false" @change="toggleLanguage">
<el-option v-for="language in languages" :key="language.value" style="height: 2rem;" :value="language.value" :label="language.name">
@ -174,7 +175,9 @@ const toggleLanguage = () => {
<el-main>
<router-view v-slot="{ Component }" class="content">
<transition name="el-fade-in-linear">
<keep-alive include="seal"><component :is="Component" /></keep-alive>
<keep-alive include="seal">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
</el-main>
@ -185,7 +188,9 @@ const toggleLanguage = () => {
</div>
<div class="alarm-info">
<img :src="HomeAlarmSvg" width="20" alt="报警">
<div class="alarm-workState">{{ workStateName || '空闲' }}</div>
<div class="alarm-workState">
{{ workStateName || '空闲' }}
</div>
</div>
<div class="time">
{{ currentTime }}

3
src/libs/deviceComm.ts

@ -1,7 +1,8 @@
import { ref, watchEffect } from 'vue'
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { ref, watchEffect } from 'vue'
const homeStore = useHomeStore()
const liquidStore = useLiquidStore()

3
src/libs/http.ts

@ -1,8 +1,9 @@
import { HEADER_TOKEN_KEY } from '@/libs/constant'
import axios from 'axios'
import { FtMessage } from 'libs/message'
import { getToken } from 'libs/token'
import { HEADER_TOKEN_KEY } from '@/libs/constant'
const http = axios.create({
baseURL: import.meta.env.FT_API_BASE,
timeout: 1000 * 60,

2
src/libs/modalUtil.ts

@ -1,5 +1,5 @@
import type { App } from 'vue'
import ErrorBox from 'components/common/ErrorModal/index.vue'
import type { App } from 'vue'
import { createVNode, render } from 'vue'
interface ErrorBoxOptions {

1
src/libs/socket.ts

@ -1,5 +1,6 @@
import type { Ref } from 'vue'
import { ref, watch } from 'vue'
import { FtMessageBox } from './messageBox'
// WebSocket客户端类

9
src/main.ts

@ -1,21 +1,22 @@
import type { LocaleType } from './lang'
import 'element-plus/dist/index.css'
import 'assets/styles/main.scss'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import BTButton from 'components/common/BTButton/index.vue'
import FtButton from 'components/common/FTButton/index.vue'
import FtDialog from 'components/common/FTDialog/index.vue'
import FtTable from 'components/common/FTTable/index.vue'
import ElementPlus from 'element-plus'
import locale from 'element-plus/es/locale/lang/zh-cn'
import ErrorBox from 'libs/modalUtil'
import pinia from 'stores/index'
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import App from './app.vue'
import type { LocaleType } from './lang'
import { defaultLocale, messages } from './lang'
import router from './router'
import 'element-plus/dist/index.css'
import 'assets/styles/main.scss'
// 创建 i18n 实例
const i18n = createI18n<{

6
src/router/index.ts

@ -1,7 +1,9 @@
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
import { getToken } from '@/libs/token'
import { createWebSocket } from 'libs/socket'
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
import { createRouter, createWebHashHistory } from 'vue-router'
import { getToken } from '@/libs/token'
import routes from './routes'
const wsClient = createWebSocket()

2
src/router/routes.ts

@ -1,4 +1,3 @@
import type { RouteRecordRaw } from 'vue-router'
import n_audit from 'assets/images/menuIcon/n-audit.svg'
import n_debug from 'assets/images/menuIcon/n-debug.svg'
import n_disinfect from 'assets/images/menuIcon/n-disinfect.svg'
@ -15,6 +14,7 @@ import s_seal from 'assets/images/menuIcon/s-seal.svg'
import s_setting from 'assets/images/menuIcon/s-setting.svg'
import { useDeviceStore } from 'stores/deviceStore'
import { ref, watchEffect } from 'vue'
import type { RouteRecordRaw } from 'vue-router'
const authRoutes = ref<RouteRecordRaw[]>([
{

5
src/stores/deviceStore.ts

@ -1,8 +1,9 @@
import { subscribeEvent } from '@/apis/system'
import { DEVICE_STATES } from '@/libs/utils'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { subscribeEvent } from '@/apis/system'
import { DEVICE_STATES } from '@/libs/utils'
const initDeviceInfo = {
appVersion: '',
deviceId: '',

3
src/stores/formulaStore.ts

@ -1,9 +1,10 @@
import { FtMessage } from '@/libs/message'
import { sendCmd, syncSendCmd } from 'apis/system'
import { cloneDeep } from 'lodash'
import { defineStore } from 'pinia'
import { computed, ref, watch } from 'vue'
import { FtMessage } from '@/libs/message'
// 常量定义
const LOG_ITEMS = Array.from({ length: 12 }, (_, i) => ({
value: i + 1,

3
src/stores/homeStore.ts

@ -1,9 +1,10 @@
import { DEVICE_STATES } from '@/libs/utils'
import { syncSendCmd } from 'apis/system'
import { PARSSURE_DATA } from 'libs/constant'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { DEVICE_STATES } from '@/libs/utils'
// 传感器数据初始值
const h2O2Data: Home.DisplayrelyMgrParams[] = [{
type: 'inside',

4
src/stores/initHomeData.ts

@ -1,6 +1,8 @@
import { sendCmd } from '@/apis/system'
import { useHomeStore } from 'stores/homeStore'
import { useLiquidStore } from 'stores/liquidStore'
import { sendCmd } from '@/apis/system'
import { useDeviceStore } from './deviceStore'
const homeStore = useHomeStore()

2
src/stores/settingStore.ts

@ -11,7 +11,7 @@ export const useSettingStore = defineStore('setting', () => {
name: '消毒历史记录',
code: 'history',
}, {
name: '消毒参数配置',
name: '消毒默认配置',
code: 'defaultFormula',
}, {
name: '用户管理',

3
src/stores/systemStore.ts

@ -1,7 +1,8 @@
import { syncSendCmd } from '@/apis/system'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { syncSendCmd } from '@/apis/system'
export const useSystemStore = defineStore('system', () => {
const websocketConnected = ref(true)
const systemUser = ref({

12
src/types/softKeyboard.d.ts

@ -1,13 +1,13 @@
// types/softKeyboard.d.ts
declare module 'vue-soft-keyboard' {
import type { Component } from 'vue';
import type { Component } from 'vue'
export interface SoftKeyboardProps {
modelValue: string;
keyboardType?: 'number' | 'text';
isVisible?: boolean;
modelValue: string
keyboardType?: 'number' | 'text'
isVisible?: boolean
}
const SoftKeyboard: Component<SoftKeyboardProps>;
export default SoftKeyboard;
const SoftKeyboard: Component<SoftKeyboardProps>
export default SoftKeyboard
}

3
src/views/audit/index.vue

@ -1,8 +1,9 @@
<script lang="ts" setup>
import { FtMessage } from '@/libs/message'
import { sendCmd, syncSendCmd } from 'apis/system'
import { onMounted, ref } from 'vue'
import { FtMessage } from '@/libs/message'
/**
* 审计日志管理组件
* @description 展示审计日志列表支持分页和单条记录导出功能

6
src/views/debug/index.vue

@ -98,11 +98,11 @@ const onBottomState = () => {}
</div>
<div class="env-content-p">
<span>湿度</span>
<span class="debug-text">{{ roundNumber(item.rh, 2) }}</span>
<span class="debug-text">{{ roundNumber(item.rh, 2) }}</span>%RH
</div>
<div class="env-content-p">
<span>H202浓度</span>
<span class="debug-text">{{ roundNumber(item.h2o2, 2) }}</span>PPM
<span class="debug-text">{{ roundNumber(item.h2o2, 2) }}</span>ppm
</div>
</div>
</div>
@ -308,7 +308,7 @@ const onBottomState = () => {}
height: 10vh;
}
.debug-bw{
width: 8vw;
width: 13vw;
}
.debug-label{
width: 13vw;

3
src/views/formula/index.vue

@ -1,10 +1,11 @@
<script lang="ts" setup>
import { useFormulaStore } from '@/stores/formulaStore'
import { syncSendCmd } from 'apis/system'
import FormulaConfig from 'components/formula/FormulaConfig.vue'
import FormulaTable from 'components/formula/FormulaTable.vue'
import { FtMessage } from 'libs/message'
import { useFormulaStore } from '@/stores/formulaStore'
const formulaStore = useFormulaStore()
const onAddFormula = () => {
const params = {

7
src/views/home/chart.vue

@ -1,6 +1,4 @@
<script lang="ts" setup>
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import { syncSendCmd } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg'
import homeSettingSvg from 'assets/images/home/home-setting.svg'
@ -13,6 +11,9 @@ import { cloneDeep } from 'lodash'
import { provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
const configRef = ref()
provide<(methods: Home.GrandsonMethods) => void>('registerGrandsonMethods', (methods) => {
configRef.value = methods
@ -166,7 +167,7 @@ const onClose = () => {
/>
</div>
</div>
<ft-dialog v-model="disinfectFormulaVisible" width="80vw" :ok-handle="onSave" @cancel="onClose">
<ft-dialog v-model="disinfectFormulaVisible" title="消毒设置" width="80vw" :ok-handle="onSave" @cancel="onClose">
<div>
<Config ref="configRef" />
</div>

7
src/views/home/index.vue

@ -1,7 +1,4 @@
<script lang="ts" setup>
import { roundNumber } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
import { useSystemStore } from '@/stores/systemStore'
import homeLiquid from 'assets/images/home/home-liquid.svg'
import Environment from 'components/home/Environment.vue'
import HomeFormula from 'components/home/HomeFormula.vue'
@ -13,6 +10,10 @@ import { useLiquidStore } from 'stores/liquidStore'
import { computed, ref, watchEffect } from 'vue'
import { useRoute } from 'vue-router'
import { roundNumber } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
import { useSystemStore } from '@/stores/systemStore'
const route = useRoute()
const homeStore = useHomeStore()
const liquidStore = useLiquidStore()

15
src/views/liquid/index.vue

@ -1,11 +1,4 @@
<script lang="ts" setup>
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
import { subscribeEvent, syncSendCmd } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg'
import homeStart from 'assets/images/home/home-start.svg'
@ -15,6 +8,14 @@ import { ElMessage } from 'element-plus'
// import { roundNumber } from 'libs/utils'
import { onMounted, ref, watch, watchEffect } from 'vue'
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
const liquidStore = useLiquidStore()
const homeStore = useHomeStore()
const sealStore = useSealStore()

11
src/views/login/index.vue

@ -1,6 +1,4 @@
<script setup lang="ts">
import { FtMessage } from '@/libs/message'
import { setToken } from '@/libs/token'
import { syncSendCmd } from 'apis/system'
import { login } from 'apis/user'
import logo from 'assets/images/logo.svg'
@ -12,6 +10,9 @@ import { useSystemStore } from 'stores/systemStore'
import { ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'
import { FtMessage } from '@/libs/message'
import { setToken } from '@/libs/token'
const router = useRouter()
const sys = useSystemStore()
const formRef = ref()
@ -97,8 +98,8 @@ const loginHandle = async () => {
<div>
<img :src="logo" style="width:20vw" alt="">
</div>
<br/>
<el-form ref="formRef" class="input-username" :model="loginForm" :rules="rules" style="width: 100%" >
<br>
<el-form ref="formRef" class="input-username" :model="loginForm" :rules="rules" style="width: 100%">
<!-- <div class="input-title">
用户名
</div> -->
@ -147,8 +148,8 @@ const loginHandle = async () => {
</el-form>
<SoftKeyboard
ref="softKeyboardRef"
v-model="inputValue"
:key="keyboardKey"
v-model="inputValue"
:is-visible="keyboardVisible"
:keyboard-type="keyboardType"
@update-keyboard-visible="(visible: boolean) => keyboardVisible = visible"

13
src/views/seal/index.vue

@ -1,9 +1,4 @@
<script lang="ts" setup>
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
import { subscribeEvent, syncSendCmd } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg'
import homeStart from 'assets/images/home/home-start.svg'
@ -13,8 +8,14 @@ import DashboardChart from 'components/seal/DashboardChart.vue'
import { startPosityveTimer, stopPosityveTimer } from 'libs/timer'
import { computed, onMounted, ref, watch, watchEffect } from 'vue'
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore'
defineOptions({
name: 'seal',
name: 'Seal',
})
const sealStore = useSealStore()
const systemStore = useSystemStore()

7
src/views/setting/index.vue

@ -1,11 +1,12 @@
<script lang="ts" setup>
import History from 'components/setting/History.vue'
import { ref } from 'vue'
import FormulaConfig from '@/components/formula/FormulaConfig.vue'
import Device from '@/components/setting/Device.vue'
import SystemDate from '@/components/setting/SystemDate.vue'
import User from '@/components/setting/User.vue'
import { useSettingStore } from '@/stores/settingStore'
import History from 'components/setting/History.vue'
import { ref } from 'vue'
const settingStore = useSettingStore()
const settingMenus = settingStore.settingMenus
@ -35,7 +36,7 @@ const selectItem = (menuCode: string) => {
</div>
</div>
<div class="setting-right">
<History v-if="selectedMenuCode === 'history'"/>
<History v-if="selectedMenuCode === 'history'" />
<div v-if="selectedMenuCode === 'defaultFormula'">
<FormulaConfig type="setting" />
</div>

Loading…
Cancel
Save