Bläddra i källkod

feature:增加扫码跳转小程序功能

liuzhenlin 1 månad sedan
förälder
incheckning
f42af07218

+ 2 - 1
.gitignore

@@ -23,4 +23,5 @@ dist-ssr
 *.sln
 *.sw?
 .history/
-*.orig
+*.orig
+*.zip

+ 1 - 0
package.json

@@ -29,6 +29,7 @@
     "postcss-px-to-viewport": "^1.1.1",
     "sm-crypto": "^0.3.13",
     "vant": "4.9.17",
+    "vconsole": "^3.15.1",
     "vue": "^3.5.21",
     "weixin-js-sdk": "^1.6.5"
   },

+ 35 - 0
pnpm-lock.yaml

@@ -68,6 +68,9 @@ importers:
       vant:
         specifier: 4.9.17
         version: 4.9.17(vue@3.5.22(typescript@4.9.5))
+      vconsole:
+        specifier: ^3.15.1
+        version: 3.15.1
       vue:
         specifier: ^3.5.21
         version: 3.5.22(typescript@4.9.5)
@@ -121,6 +124,10 @@ packages:
     engines: {node: '>=6.0.0'}
     hasBin: true
 
+  '@babel/runtime@7.28.4':
+    resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
+    engines: {node: '>=6.9.0'}
+
   '@babel/types@7.28.5':
     resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
     engines: {node: '>=6.9.0'}
@@ -576,6 +583,13 @@ packages:
     resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
     engines: {node: '>=18'}
 
+  copy-text-to-clipboard@3.2.2:
+    resolution: {integrity: sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==}
+    engines: {node: '>=12'}
+
+  core-js@3.46.0:
+    resolution: {integrity: sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==}
+
   cropperjs@1.5.13:
     resolution: {integrity: sha512-by7jKAo73y5/Do0K6sxdTKHgndY0NMjG2bEdgeJxycbcmHuCiMXqw8sxy5C5Y5WTOTcDGmbT7Sr5CgKOXR06OA==}
 
@@ -792,6 +806,9 @@ packages:
   ms@2.1.3:
     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
 
+  mutation-observer@1.0.3:
+    resolution: {integrity: sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA==}
+
   nanoid@3.3.11:
     resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -939,6 +956,9 @@ packages:
     peerDependencies:
       vue: ^3.0.0
 
+  vconsole@3.15.1:
+    resolution: {integrity: sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==}
+
   vite@4.5.14:
     resolution: {integrity: sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==}
     engines: {node: ^14.18.0 || >=16.0.0}
@@ -1015,6 +1035,8 @@ snapshots:
     dependencies:
       '@babel/types': 7.28.5
 
+  '@babel/runtime@7.28.4': {}
+
   '@babel/types@7.28.5':
     dependencies:
       '@babel/helper-string-parser': 7.27.1
@@ -1420,6 +1442,10 @@ snapshots:
     dependencies:
       is-what: 5.5.0
 
+  copy-text-to-clipboard@3.2.2: {}
+
+  core-js@3.46.0: {}
+
   cropperjs@1.5.13: {}
 
   csstype@3.1.3: {}
@@ -1639,6 +1665,8 @@ snapshots:
 
   ms@2.1.3: {}
 
+  mutation-observer@1.0.3: {}
+
   nanoid@3.3.11: {}
 
   node-addon-api@7.1.1:
@@ -1769,6 +1797,13 @@ snapshots:
       '@vue/shared': 3.5.22
       vue: 3.5.22(typescript@4.9.5)
 
+  vconsole@3.15.1:
+    dependencies:
+      '@babel/runtime': 7.28.4
+      copy-text-to-clipboard: 3.2.2
+      core-js: 3.46.0
+      mutation-observer: 1.0.3
+
   vite@4.5.14(@types/node@18.19.130)(sass@1.93.3):
     dependencies:
       esbuild: 0.18.20

+ 2 - 2
src/components/select-inst.vue

@@ -9,7 +9,7 @@
 <template>
   <van-popup v-model:show="state.showPicker" round position="bottom" :style="{ height: '60%' }">
     <div class="flex">
-      <van-search class="search-input" v-model="state.params.searchText" placeholder="请输入仪器名称" shape="round" @search="getDataList" />
+      <van-search class="search-input" v-model="state.params.instName" placeholder="请输入仪器名称" shape="round" @search="getDataList" />
       <van-button style="" class="search-btn" type="success" size="small" round @click="getDataList">搜索</van-button>
     </div>
     <van-picker
@@ -41,7 +41,7 @@
       instStatus: '10',
       pageNum: 1,
       pageSize: 9999,
-      searchText: ''
+      instName: ''
     }
   })
 

+ 10 - 1
src/constants/pageConstants.ts

@@ -206,4 +206,13 @@ export enum HttpStatus {
   INTERNAL_ERROR = 500,
 }
 
-export const SUPPORT_FILE_UPLOAD_TYPE_MAX=".jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.pptx,.pdf,.txt,.zip,.rar"
+export const SUPPORT_FILE_UPLOAD_TYPE_MAX = ".jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.pptx,.pdf,.txt,.zip,.rar"
+
+// 扫码跳转微信方法
+
+const APPID = 'wx979e7a671a498586'
+
+const PATH = 'pages/appointList/user'
+export const scanCodeWxUrl = (query: string) => {
+  return `weixin://dl/business/?appid=${APPID}&path=${PATH}&query=scene=${query}`
+}

+ 83 - 71
src/layout/index.vue

@@ -11,99 +11,111 @@
   <van-tabbar route :placeholder="true">
     <van-tabbar-item replace to="/home" icon="wap-home-o">首页</van-tabbar-item>
     <van-tabbar-item replace to="/todo" icon="cluster-o">待办</van-tabbar-item>
-    <van-tabbar-item replace class="center-icon" @click="scan">
+    <!-- <van-tabbar-item replace class="center-icon" @click="scan">
       <template #icon>
         <van-icon name="scan" :size="50" color="#fff" />
-      </template>
-    </van-tabbar-item>
+      </template> -->
+    <!-- </van-tabbar-item> -->
     <van-tabbar-item replace to="/notice" icon="todo-list-o">通知</van-tabbar-item>
     <van-tabbar-item replace to="/user" icon="user-o">我的</van-tabbar-item>
   </van-tabbar>
-  
+
 </template>
 
 <script lang="ts" setup>
-  import { useRouter, useRoute } from 'vue-router'
-  import { useUserInfo } from '/@/stores/userInfo'
+import { useRouter, useRoute } from 'vue-router'
+import { useUserInfo } from '/@/stores/userInfo'
 
-  const router = useRouter()
-  const route = useRoute()
+const router = useRouter()
+const route = useRoute()
 
-  const onRouterPush = (val: string) => {
-    router.push(val)
-  }
-  const scan = async () => {
-    const res = await useUserInfo().scanCode()
-    if (res) {
-      window.location.href = res as string
-    }
+const onRouterPush = (val: string) => {
+  router.push(val)
+}
+const scan = async () => {
+  const res = await useUserInfo().scanCode()
+  if (res) {
+    window.location.href = res as string
   }
+}
 </script>
 
 <style lang="scss" scoped>
-  .footer-nav {
+.footer-nav {
+  height: 60px;
+
+  ul {
     height: 60px;
-    ul {
-      height: 60px;
+    display: flex;
+
+    li {
+      flex: 1;
       display: flex;
-      li {
-        flex: 1;
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        font-size: 12px;
-        &.active {
-          color: #1989fa;
-        }
-        &.center-icon {
-          height: 60px;
-          flex: 0 0 60px;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      font-size: 12px;
+
+      &.active {
+        color: #1989fa;
+      }
+
+      &.center-icon {
+        height: 60px;
+        flex: 0 0 60px;
+        padding: 10px;
+        align-self: flex-end;
+
+        i {
           padding: 10px;
-          align-self: flex-end;
-          i {
-            padding: 10px;
-            background: #1d66dc;
-            border-radius: 50%;
-          }
-        }
-        img {
-          height: 20px;
-          width: 20px;
-        }
-        .img-container {
-          height: 28px;
-          width: 28px;
-          background-color: #419fe5;
+          background: #1d66dc;
           border-radius: 50%;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          margin-bottom: 4px;
-        }
-        &.service .img-container {
-          background-color: #f59969;
-        }
-        &.todo .img-container {
-          background-color: #20b5ae;
-        }
-        &.user .img-container {
-          background-color: #595cac;
         }
       }
+
+      img {
+        height: 20px;
+        width: 20px;
+      }
+
+      .img-container {
+        height: 28px;
+        width: 28px;
+        background-color: #419fe5;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-bottom: 4px;
+      }
+
+      &.service .img-container {
+        background-color: #f59969;
+      }
+
+      &.todo .img-container {
+        background-color: #20b5ae;
+      }
+
+      &.user .img-container {
+        background-color: #595cac;
+      }
     }
   }
-  .center-icon {
-    height: 60px;
-    flex: 0 0 60px;
+}
+
+.center-icon {
+  height: 60px;
+  flex: 0 0 60px;
+  padding: 10px;
+  align-self: flex-end;
+  position: relative;
+  z-index: 99999;
+
+  i {
     padding: 10px;
-    align-self: flex-end;
-    position: relative;
-    z-index: 99999;
-    i {
-      padding: 10px;
-      background: #1d66dc;
-      border-radius: 50%;
-    }
+    background: #1d66dc;
+    border-radius: 50%;
   }
+}
 </style>

+ 200 - 190
src/view/instr/appointList/soonGeton/index.vue

@@ -10,7 +10,8 @@
   <div class="panel-wrap">
     <!-- <van-pull-refresh v-model="refreshing" @refresh="onRefresh"> -->
     <van-empty v-if="appointList.length == 0" mode="list" description="暂无即将上机"></van-empty>
-    <van-list v-else v-model:loading="listloading" class="data-list" :finished="finished" finished-text="没有更多了" @load="onLoad">
+    <van-list v-else v-model:loading="listloading" class="data-list" :finished="finished" finished-text="没有更多了"
+      @load="onLoad">
       <div class="inst-item mb40" v-for="(v, index) in appointList" :key="index">
         <div class="flex flex-between mb20">
           <div>
@@ -19,25 +20,13 @@
             </div>
           </div>
           <div class="flex">
-            <van-button
-              style="width: 80px; height: 30px; margin: 0; font-size: 14px"
-              class="scan-txt"
-              type="primary"
-              size="small"
-              :disabled="loading"
-              v-if="['10', '20', '30', '50'].includes(v.controlMode)"
-              @click="handleGetOn(v)"
-            >
+            <van-button style="width: 80px; height: 30px; margin: 0; font-size: 14px" class="scan-txt" type="primary"
+              size="small" :disabled="loading" v-if="['10', '20', '30', '50'].includes(v.controlMode)"
+              @click="handleGetOn(v)">
               {{ v.controlMode == '10' ? '上机' : '扫码上机' }}
             </van-button>
-            <van-button
-              style="width: 60px; height: 30px; margin: 0 0 0 10px; font-size: 14px"
-              class="scan-txt"
-              type="warning"
-              size="small"
-              :disabled="loading"
-              @click="handleCancelAppoint(v)"
-            >
+            <van-button style="width: 60px; height: 30px; margin: 0 0 0 10px; font-size: 14px" class="scan-txt"
+              type="warning" size="small" :disabled="loading" @click="handleCancelAppoint(v)">
               取消
             </van-button>
           </div>
@@ -93,195 +82,216 @@
 </template>
 
 <script>
-  // import BlueTooth from '../../../components/BlueTooth'
-  // import { formatDate } from '/@/utils/formatTime'
-  import { useUserInfo } from '/@/stores/userInfo'
-  import { useMyAppointApi } from '/@/api/appoint'
-  const myAppointApi = useMyAppointApi()
-  import { useInstrApi } from '/@/api/instr'
-  const instApi = useInstrApi()
-  import instAppointApi from '/@/api/instr/instAppoint'
-  import to from 'await-to-js'
-  import { showConfirmDialog, showNotify } from 'vant'
-  export default {
-    // components: { BlueTooth },
-    data() {
-      return {
-        loading: false,
-        curAppointInfo: {},
-        appointList: [],
-        queryForm: {
-          pageNum: 1,
-          pageSize: 10
-        },
-        total: 0,
-        listloading: false,
-        finished: false
-      }
-    },
-    mounted() {
-      this.queryForm.pageNum = 1
+// import BlueTooth from '../../../components/BlueTooth'
+// import { formatDate } from '/@/utils/formatTime'
+import { useUserInfo } from '/@/stores/userInfo'
+import { useMyAppointApi } from '/@/api/appoint'
+const myAppointApi = useMyAppointApi()
+import { useInstrApi } from '/@/api/instr'
+const instApi = useInstrApi()
+import instAppointApi from '/@/api/instr/instAppoint'
+import to from 'await-to-js'
+import { showConfirmDialog, showNotify } from 'vant'
+import { scanCodeWxUrl } from '/@/constants/pageConstants'
+export default {
+  // components: { BlueTooth },
+  data() {
+    return {
+      loading: false,
+      curAppointInfo: {},
+      appointList: [],
+      queryForm: {
+        pageNum: 1,
+        pageSize: 10
+      },
+      total: 0,
+      listloading: false,
+      finished: false
+    }
+  },
+  mounted() {
+    this.queryForm.pageNum = 1
+    this.getInstList()
+  },
+  methods: {
+    // 重新加载
+    onLoad() {
+      this.queryForm.pageNum++
       this.getInstList()
     },
-    methods: {
-      // 重新加载
-      onLoad() {
-        this.queryForm.pageNum++
-        this.getInstList()
-      },
-      // 查询列表
-      async getInstList() {
-        this.listloading = true
-        const [err, res] = await to(myAppointApi.toGetonList(this.queryForm))
-        this.listloading = false
-        if (err) return
-        if (res?.code === 200) {
-          this.appointList = this.queryForm.pageNum == 1 ? [...(res?.data?.list || [])] : [...this.appointList, ...(res?.data?.list || [])]
-          this.total = res?.data?.total
-          if (this.queryForm.pageNum * this.queryForm.pageSize >= res.data.total) {
-            this.finished = true
-          }
+    // 查询列表
+    async getInstList() {
+      this.listloading = true
+      const [err, res] = await to(myAppointApi.toGetonList(this.queryForm))
+      this.listloading = false
+      if (err) return
+      if (res?.code === 200) {
+        this.appointList = this.queryForm.pageNum == 1 ? [...(res?.data?.list || [])] : [...this.appointList, ...(res?.data?.list || [])]
+        this.total = res?.data?.total
+        if (this.queryForm.pageNum * this.queryForm.pageSize >= res.data.total) {
+          this.finished = true
         }
-      },
-      /**
-       * 触发上机之前的订阅
-       *
-       * */
-      handleGetOn(row) {
-        this.handleScanCode(row)
-      },
-      /**
-       * 调起二维码扫码
-       * controlMode (10 不控制 20 电源控制(wifi) 30 电源控制(蓝牙) 50 电脑控制)
-       */
-      async handleScanCode(row) {
-        this.curAppointInfo = row
-        // 直接上机
-        if (row.controlMode == '10') {
-          showConfirmDialog({
-            title: '提示',
-            message: '确认上机?'
+      }
+    },
+    /**
+     * 触发上机之前的订阅
+     *
+     * */
+    handleGetOn(row) {
+      this.handleScanCode(row)
+    },
+    /**
+     * 调起二维码扫码
+     * controlMode (10 不控制 20 电源控制(wifi) 30 电源控制(蓝牙) 50 电脑控制)
+     */
+    async handleScanCode(row) {
+      this.curAppointInfo = row
+      // 直接上机
+      if (row.controlMode == '10') {
+        showConfirmDialog({
+          title: '提示',
+          message: '确认上机?'
+        })
+          .then(() => {
+            if (this.loading) return
+            this.loading = true
+            this.handleGetOnByAppointId(this.curAppointInfo.id)
           })
-            .then(() => {
-              if (this.loading) return
-              this.loading = true
-              this.handleGetOnByAppointId(this.curAppointInfo.id)
-            })
-            .catch(() => {})
-        } else if (row.controlMode == '20' || row.controlMode == '50') {
-          // wifi控制 和 电脑控制
-          const that = this
-          // 调起条码扫描
-          const res = await useUserInfo().scanCode()
-          that.handleDeCode(res, row)
-        } else if (row.controlMode == '30') {
-          // 蓝牙
-          // this.$refs.bluetoothRef.initBlue('open', row)
-          await useUserInfo().scanCode(0)
-        }
-      },
-      /**
-       *  解码
-       *  code 二维码内容
-       *  row 当前预约信息
-       * */
-      async handleDeCode(code, row) {
-        if (this.loading) return
-        this.loading = true
-        const params = { content: code }
-        const [err, res] = await to(instApi.decode({ ...params }))
-        if (err) return (this.loading = false)
-        if (res.code == 200) {
-          this.handleCodeInfo(res.data.content, row)
+          .catch(() => { })
+      } else if (row.controlMode == '20' || row.controlMode == '50') {
+        // wifi控制 和 电脑控制
+        const that = this
+        // 调起条码扫描
+        const res = await useUserInfo().scanCode()
+        that.handleDeCode(res, row, that.handleCodeInfo)
+      } else if (row.controlMode == '30') {
+        // 蓝牙
+        // this.$refs.bluetoothRef.initBlue('open', row)
+        // await useUserInfo().scanCode(0)
+        const that = this
+        const res = await useUserInfo().scanCode()
+        that.handleDeCode(res, row, that.handleBluetoothDeCode)
+      }
+    },
+    /**
+     *  解码
+     *  code 二维码内容
+     *  row 当前预约信息
+     * func 解码后的操作函数
+     * */
+    async handleDeCode(code, row, func) {
+      if (this.loading) return
+      this.loading = true
+      const params = { content: code }
+      const [err, res] = await to(instApi.decode({ ...params }))
+      if (err) {
+        this.loading = false
+        showNotify({ type: 'danger', message: '解码失败,请重试' })
+        return
+      }
+      if (res?.code == 200 && res?.data?.content) {
+        func(res.data.content, row)
+      } else {
+        this.loading = false
+        showNotify({ type: 'danger', message: res?.message || '解码失败' })
+      }
+    },
+    /**
+     * 解码后的信息判断扫码仪器是否是当前预约仪器
+     * content 解码后的内容 两种 带id(仪器id)和不带id
+     * appointRow 当前预约信息
+     */
+    async handleCodeInfo(content, appointRow) {
+      if (content.includes('id')) {
+        if (JSON.parse(content).id == appointRow.instId) {
+          this.handleGetOnByAppointId(appointRow.id)
         } else {
           this.loading = false
+          showNotify({ type: 'warning', message: '扫码机器不是预约机器' })
         }
-      },
-      /**
-       * 解码后的信息判断扫码仪器是否是当前预约仪器
-       * content 解码后的内容 两种 带id(仪器id)和不带id
-       * appointRow 当前预约信息
-       */
-      async handleCodeInfo(content, appointRow) {
-        if (content.includes('id')) {
-          if (JSON.parse(content).id == appointRow.instId) {
-            this.handleGetOnByAppointId(appointRow.id)
-          } else {
-            this.loading = false
-            showNotify({ type: 'warning', message: '扫码机器不是预约机器' })
-          }
+      } else {
+        // 拿到解码信息(仪器编码)获取仪器id
+        const [instErr, instRes] = await to(instApi.getIdByTerminal({ terminal: content }))
+        if (instErr) return
+        if (instRes.data.id == appointRow.instId) {
+          this.handleGetOnByAppointId(appointRow.id)
         } else {
-          // 拿到解码信息(仪器编码)获取仪器id
-          const [instErr, instRes] = await to(instApi.getIdByTerminal({ terminal: content }))
-          if (instErr) return
-          if (instRes.data.id == appointRow.instId) {
-            this.handleGetOnByAppointId(appointRow.id)
-          } else {
-            this.loading = false
-            showNotify({ type: 'warning', message: '扫码机器不是预约机器' })
-          }
+          this.loading = false
+          showNotify({ type: 'warning', message: '扫码机器不是预约机器' })
         }
-      },
+      }
+    },
 
-      // 上机
-      async handleGetOnByAppointId(id) {
-        const params = { appointId: id }
-        const [err, res] = await to(instAppointApi.getOn({ ...params }))
-        this.loading = false
-        if (err) return
-        if (res.code == 200) {
-          showNotify({ type: 'success', message: '上机成功' })
-          setTimeout(() => {
-            this.$router.push(`/onlineInfo?appointId=${id}`)
-          })
-        }
-      },
-      handleCancelAppoint(row) {
-        showConfirmDialog({
-          title: '提示',
-          message: '确认取消预约?'
+    //蓝牙 重新解码函数,获取解码内容之后 执行跳转操作
+    async handleBluetoothDeCode(content) {
+      if (content.includes('id')) {
+        const terminal = JSON.parse(content)?.terminal
+        const url = scanCodeWxUrl(terminal)
+        window.location.href = url
+      } else {
+        const url = scanCodeWxUrl(content)
+        window.location.href = url
+      }
+
+    },
+
+    // 上机
+    async handleGetOnByAppointId(id) {
+      const params = { appointId: id }
+      const [err, res] = await to(instAppointApi.getOn({ ...params }))
+      this.loading = false
+      if (err) return
+      if (res.code == 200) {
+        showNotify({ type: 'success', message: '上机成功' })
+        setTimeout(() => {
+          this.$router.push(`/onlineInfo?appointId=${id}`)
         })
-          .then((e) => {
-            console.log(e)
-            this.cancelAppoint(row.id)
-          })
-          .catch(() => {
-            console.log('ssss')
-          })
-      },
-      // 取消预约
-      async cancelAppoint(id) {
-        const params = { id }
-        const [err, res] = await to(instAppointApi.userCancelAppoint(params))
-        this.modalVisible = false
-        if (err) return
-        if (res?.code === 200) {
-          this.queryForm.pageNum = 1
-          this.appointList = []
-          this.getInstList()
-          showNotify({ type: 'success', message: '取消成功' })
-        }
+      }
+    },
+    handleCancelAppoint(row) {
+      showConfirmDialog({
+        title: '提示',
+        message: '确认取消预约?'
+      })
+        .then((e) => {
+          this.cancelAppoint(row.id)
+        })
+    },
+    // 取消预约
+    async cancelAppoint(id) {
+      const params = { id }
+      const [err, res] = await to(instAppointApi.userCancelAppoint(params))
+      if (err) return
+      if (res?.code === 200) {
+        this.queryForm.pageNum = 1
+        this.appointList = []
+        this.getInstList()
+        showNotify({ type: 'success', message: '取消成功' })
       }
     }
   }
+}
 </script>
 <style lang="scss" scoped>
-  * {
-    box-sizing: border-box;
-  }
-  .panel-wrap {
-    height: 100%;
-    .data-list {
-      .inst-item {
-        border-radius: 10px;
-        padding: 15px;
-        box-shadow: -2px 0px 9px rgba(0, 0, 0, 0.12);
-        margin-bottom: 20px;
-        background-color: #fff;
-        .equ-tit {
-          width: 74px;
-        }
+* {
+  box-sizing: border-box;
+}
+
+.panel-wrap {
+  height: 100%;
+
+  .data-list {
+    .inst-item {
+      border-radius: 10px;
+      padding: 15px;
+      box-shadow: -2px 0px 9px rgba(0, 0, 0, 0.12);
+      margin-bottom: 20px;
+      background-color: #fff;
+
+      .equ-tit {
+        width: 74px;
       }
     }
   }
+}
 </style>

+ 2 - 2
src/view/instr/list.vue

@@ -3,7 +3,7 @@
     <div class="search-wrap">
       <van-search
         placeholder="请输入仪器名称"
-        v-model="state.queryForm.searchText"
+        v-model="state.queryForm.instName"
         :clearabled="true"
         style="padding: 0"
       ></van-search>
@@ -286,7 +286,7 @@
       laboratoryName: '',
       pageNum: 1,
       pageSize: 10,
-      searchText: '',
+      instName: '',
     },
     popupShow: false,
     instDetail: {} as any,