“shengjie.huang” преди 1 година
родител
ревизия
4e205e54b8

+ 7 - 0
src/pages.json

@@ -60,6 +60,13 @@
         "navigationBarTitleText": "打印助手列表"
       }
     },
+    {
+      "path": "pages/connect/index",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "配网向导"
+      }
+    },
     {
       "path": "pages/login/index",
       "type": "page",

+ 181 - 0
src/pages/connect/index.vue

@@ -0,0 +1,181 @@
+<!-- 使用 type="home" 属性设置首页,其他页面不需要设置,默认为page;推荐使用json5,更强大,且允许注释 -->
+<route lang="json5" type="page">
+{
+  style: {
+    navigationBarTitleText: '配网向导',
+  },
+}
+</route>
+
+<template>
+  <view class="page-form">
+    <view class="form-title">
+      <view>配网步骤</view>
+    </view>
+    <view class="tips-box">
+      <wd-img :src="deviceImg" width="100" mode="widthFix"></wd-img>
+      <view class="check-box">
+        <view class="check-result">{{ checkResult }}</view>
+        <wd-button @click="getConnectedWifi()">重新检查</wd-button>
+      </view>
+      <view v-if="!checkWiFiFlag">{{ `请先连接WiFi:${targetWifi}` }}</view>
+    </view>
+
+    <view class="form-title">
+      <view>家庭路由器信息</view>
+      <view class="opt-item" @click="getWifiList()">
+        <wd-icon name="refresh" size="30rpx"></wd-icon>
+        <text>刷新无线列表</text>
+      </view>
+    </view>
+    <wd-form ref="form" :model="formData">
+      <wd-cell-group custom-class="form-group" border>
+        <wd-select-picker
+          v-model="formData.ssid"
+          label="无线名称"
+          label-width="100px"
+          prop="ssid"
+          type="radio"
+          filterable
+          placeholder="请选择家里的无线名称"
+          :columns="wifiList"
+          :loading="loading"
+          :max="1"
+          :show-confirm="false"
+          :rules="[{ required: true, message: '请选择家里的无线名称' }]"
+        />
+        <wd-input
+          v-model="formData.pwd"
+          label="无线密码"
+          label-width="100px"
+          prop="pwd"
+          placeholder="请输入家里的无线密码"
+          clearable
+          :rules="[{ required: true, message: '请输入家里的无线密码' }]"
+        />
+      </wd-cell-group>
+
+      <view class="form-footer">
+        <wd-button type="primary" size="large" :disabled="loading" @click="handleSubmit()" block>提交</wd-button>
+      </view>
+    </wd-form>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { getWifiStatus, getWifis, connectWifi } from '@/service/api/index'
+import { useToast } from 'wot-design-uni'
+
+const loading = ref(false)
+const deviceImg = ref('/static/images/device.png')
+const toast = useToast()
+// const targetWifi = "maoer-printer-hub"
+const targetWifi = "ZBA_1813"
+const checkWiFiFlag = ref(false)
+const checkIPFlag = ref(false)
+// 已连接的wifi信息
+const wifiInfo: any = ref({})
+// 表单信息
+const form = ref()
+const formData: any = ref({
+  ssid: "",
+  pwd: "",
+})
+const wifiList: any = ref([])
+// 检查结果
+const checkResult = computed(() => {
+  return checkWiFiFlag.value ? (checkIPFlag.value ? "已检测到设备" : "未检测到设备") : "未连接指定WiFi"
+})
+
+// 检查wifi连接是否正确, 匹配前缀
+function checkWifi() {
+  if (wifiInfo.value.SSID.startsWith(targetWifi)) {
+    checkWiFiFlag.value = true
+    toast.success('您已连接指定WiFi!')
+  }
+}
+
+// 获取已连接中的 Wi-Fi 信息。
+function getConnectedWifi() {
+  uni.startWifi().then(() => {
+    setTimeout(() => {
+      uni.getConnectedWifi({
+        success: (res) => {
+          // 示例
+          // {
+          //   BSSID: "08:9b:4b:11:ce:b6"
+          //   SSID: "ZBA_1813"
+          //   frequency: 5785
+          //   signalStrength: 99
+          // }
+          wifiInfo.value = res.wifi || {}
+          console.log('res.wifi: ', res.wifi);
+          checkWifi()
+          if (checkWiFiFlag.value) checkIP()
+        },
+        fail: (err) => {
+          console.log('err: ', err);
+          toast.error('获取WiFi信息失败')
+        }
+      })
+    }, 1000)
+  }).catch((err)=> {})
+}
+
+// 局域网通信: 检查IP地址是否请求成功
+function checkIP() {
+  getWifiStatus().then((res: any) => {
+    console.log('当前连接WiFi: ', res);
+    checkIPFlag.value = true
+    getWifiList()
+  }).catch((err)=> {})
+}
+
+// 局域网通信: 获取可连接wifi列表
+function getWifiList() {
+  loading.value = true
+  getWifis().then((res: any) => {
+    console.log('wifi列表: ', res);
+    // wifiList.value = res || []
+  }).catch((err)=> {})
+  .finally(() => {
+    loading.value = false
+  })
+}
+
+// 局域网通信: 设置打印助手的WiFi连接信息
+function handleSubmit() {
+  form.value.validate().then(({ valid, errors }) => {
+    if (valid) {
+      loading.value = true
+      connectWifi(formData.value).then((res: any) => {
+        toast.success('连接成功')
+      }).catch((err) => {})
+      .finally(() => {
+        loading.value = false
+      })
+    }
+  })
+}
+
+onLoad(() => {
+  getConnectedWifi()
+})
+</script>
+
+<style lang="scss" scoped>
+.tips-box {
+  width: calc(100% - 60rpx);
+  padding: 40rpx 30rpx;
+  text-align: center;
+  background-color: #fff;
+  border-radius: 16rpx;
+}
+.check-box {
+  margin: 40rpx 0;
+  .check-result {
+    margin-bottom: 20rpx;
+  }
+}
+</style>
+

+ 42 - 25
src/pages/index/index.vue

@@ -34,7 +34,7 @@
           <view class="item-desc">我的打印助手</view>
         </view>
         <view class="guide-item" @click="toPrint()">
-          <wd-img :src="picImgSrc" width="100" mode="widthFix"></wd-img>
+          <wd-img :src="fileImgSrc" width="100" mode="widthFix"></wd-img>
           <view class="item-title">远程打印</view>
           <view class="item-desc">无需驱动 隔空打印</view>
         </view>
@@ -42,34 +42,37 @@
       <!-- 补充入口 -->
       <view class="content">
         <view class="section">
-          <view class="item">
+          <view class="item" @click="toConnect()">
             <view class="title">
-              <image :src="settingSrc"></image>
-              <view>设备配网</view>
+              <wd-img :src="connectSrc" width="40" mode="widthFix"></wd-img>
+              <view class="title-text">设备配网</view>
             </view>
-            <view class="tips"></view>
           </view>
           <view class="item">
             <view class="title">
-              <image :src="settingSrc"></image>
-              <view>预留入口</view>
+              <wd-img :src="pictureSrc" width="40" mode="widthFix"></wd-img>
+              <view class="title-text">相册图片</view>
             </view>
-            <view class="tips">描述信息</view>
           </view>
           <view class="item">
             <view class="title">
-              <image :src="settingSrc"></image>
-              <view>预留入口</view>
+              <wd-img :src="wechatFileSrc" width="40" mode="widthFix"></wd-img>
+              <view class="title-text">微信图片</view>
             </view>
-            <view class="tips">描述信息</view>
           </view>
           <view class="item">
+            <view class="title">
+              <wd-img :src="wechatInvoiceSrc" width="40" mode="widthFix"></wd-img>
+              <view class="title-text">微信发票</view>
+            </view>
+          </view>
+          <!-- <view class="item">
             <view class="title">
               <image :src="settingSrc"></image>
-              <view>预留入口</view>
+              <view class="title-text">预留入口</view>
             </view>
             <view class="tips">描述信息</view>
-          </view>
+          </view> -->
         </view>
       </view>
     </view>
@@ -77,12 +80,15 @@
 </template>
 
 <script lang="ts" setup>
+import { useUserStore } from '@/store'
+import { useToast } from 'wot-design-uni'
+
 defineOptions({
   name: 'Home',
 })
 
-// 获取屏幕边界到安全区域距离
-// const { safeAreaInsets } = uni.getSystemInfoSync()
+const toast = useToast()
+const isLogined = computed(() => !!useUserStore().token)
 const nvRef: any = ref()
 const nvConfig = ref({
   title: '首页',
@@ -98,9 +104,12 @@ const nvConfig = ref({
   },
 })
 const logoSrc = ref('/static/images/logo_temp.png')
-const picImgSrc = ref('/static/images/picture.jpg')
-const deviceImgSrc = ref('/static/images/device.jpg')
-const settingSrc = ref('/static/images/setting.png')
+const deviceImgSrc = ref('/static/images/device.png')
+const fileImgSrc = ref('/static/images/file.png')
+const connectSrc = ref('/static/images/connect.png')
+const pictureSrc = ref('/static/images/picture.png')
+const wechatFileSrc = ref('/static/images/wechat_file.png')
+const wechatInvoiceSrc = ref('/static/images/wechat_invoice.png')
 const swiperList = ref([])
 const current = ref(0)
 
@@ -122,15 +131,25 @@ function initSwiperList() {
 // })
 
 function toUserHub() {
-  uni.navigateTo({
-    url: `/pages/assistant/index`,
-  })
+  if (isLogined.value) {
+    uni.navigateTo({
+      url: `/pages/assistant/index`,
+    })
+  } else {
+    toast.warning('请先前往登录')
+  }
 }
 
 function toPrint() {
 
 }
 
+function toConnect() {
+  uni.navigateTo({
+    url: `/pages/connect/index`,
+  })
+}
+
 onLoad((option: any) => {
   initSwiperList()
 })
@@ -217,10 +236,8 @@ onPageScroll((e) => {
         justify-content: center;
         font-size: $uni-font-size-lg;
         
-        image {
-          width: 40rpx;
-          height: 40rpx;
-          margin-right: 10rpx;
+        .title-text {
+          margin-left: 20rpx;
         }
       }
       

+ 6 - 2
src/pages/login/index.vue

@@ -16,6 +16,7 @@
         <view class="login-password">
           <login-input key="password" v-model="password" password clearable placeholder="密码" :maxlength="20"></login-input>
         </view> -->
+        <wd-button v-if="isLogout && !token" size="large" block type="primary" @click="init()">微信登录</wd-button>
         <wd-button v-if="token" size="large" block type="primary" open-type="getPhoneNumber" :phone-number-no-quota-toast="false" @getphonenumber="onGetPhoneNumber">手机号快捷登录</wd-button>
       </view>
     </view>
@@ -33,6 +34,7 @@ import { loginByCode, bingPhoneByCode } from '@/service/api/index'
 import { getLoginCode } from '@/utils'
 // import LoginInput from './components/LoginInput.vue'
 const toast = useToast()
+const isLogout = ref(false)
 
 const username = ref<string>('') // 用户名
 const password = ref<string>('') // 密码
@@ -49,6 +51,7 @@ async function init() {
           break;
         case "1":
           token.value = res.body.token || ""
+          toast.warning("请选择手机号快捷登录")
           break;
         default:
           toast.error({ msg: '获取token异常', duration: 4000 })
@@ -123,8 +126,9 @@ function handlePhoneNumberLogin(code) {
   })
 }
 
-onLoad(() => {
-  init()
+onLoad((option: any) => {
+  isLogout.value = option.isLogout == "1"
+  if(!isLogout.value) init()
 })
 </script>
 

+ 19 - 56
src/pages/personal/index.vue

@@ -10,22 +10,6 @@
 <template>
   <view class="main overflow-hidden pt-2 px4" :style="{ marginTop: safeAreaInsets?.top + 'px' }">
     <view class="head">
-      <!-- <wd-upload
-        accept="image"
-        :file-list="fileList"
-        :max-count="1"
-        :upload-method="uploadImage"
-        @change="handleChange"
-      >
-        <wd-img
-          v-if="userInfo.avatar"
-          custom-class="img-btn"
-          :width="40"
-          :height="40"
-          :src="userInfo.avatar"
-        />
-        <wd-button v-else custom-class="gray-btn" type="icon" icon="photo"></wd-button>
-      </wd-upload> -->
       <wd-img
         v-if="userInfo.avatar"
         custom-class="img-btn"
@@ -40,64 +24,40 @@
         <view>添加打印助手</view>
         <wd-icon name="arrow-right" size="20px" color="#808080"></wd-icon>
       </view>
-      <view class="content-item" @click="handleLogout">
+      <view v-if="isLogined" class="content-item" @click="handleLogout">
         <view>退出登录</view>
         <wd-icon name="arrow-right" size="20px" color="#808080"></wd-icon>
       </view>
+      <view v-else class="content-item" @click="toLogin">
+        <view>前往登录</view>
+        <wd-icon name="arrow-right" size="20px" color="#808080"></wd-icon>
+      </view>
     </view>
   </view>
 </template>
 
 <script lang="ts" setup>
-import { getEnvBaseUrl } from '@/utils'
 import { logout } from '@/service/api/index'
 import { useUserStore } from '@/store'
 import { useToast } from 'wot-design-uni'
-import type { UploadMethod, UploadFile } from 'wot-design-uni/components/wd-upload/types'
 
-// 请求基准地址
-const baseUrl = getEnvBaseUrl()
-
-const toast = useToast()
 // 获取屏幕边界到安全区域距离
 const { safeAreaInsets } = uni.getSystemInfoSync()
 const userInfo = reactive({
   avatar: '',
   name: '',
 })
-const fileList = ref([])
-
-const uploadImage: UploadMethod = (file, formData, options) => {
-  uni.uploadFile({
-    url: `${baseUrl}/sys/user/avatar`,
-    filePath: file.url,
-    name: 'file', // 这里根据后端需要的字段来定义
-    fileType: options.fileType,
-    formData, // 如果需要额外的 formData
-    success: async (res) => {
-      if (res.statusCode === options.statusCode) {
-        toast.success('头像上传成功')
-        await useUserStore().initUserInfo()
-        initFn()
-      } else {
-        const dataObj: any = JSON.parse(res.data)
-        toast.error({ msg: dataObj.message || '头像上传失败', duration: 4000 })
-      }
-    },
-    fail: (error) => {
-      console.error('上传失败', error)
-    },
-  })
-}
-
-function handleChange({ fileList }) {
-  fileList.value = fileList
-}
+const toast = useToast()
+const isLogined = computed(() => !!useUserStore().token)
 
 function toAddUserHub() {
-  uni.navigateTo({
-    url: `/pages/assistant/detail?type=add`,
-  })
+  if (isLogined.value) {
+    uni.navigateTo({
+      url: `/pages/assistant/detail?type=add`,
+    })
+  } else {
+    toast.warning('请先前往登录')
+  }
 }
 
 function handleLogout() {
@@ -110,11 +70,14 @@ function handleLogout() {
   //     toLogin()
   //   }
   // })
-
   useUserStore().clearUserInfo()
   toast.success('退出登录成功')
+  toLogin()
+}
+
+function toLogin() {
   uni.reLaunch({
-    url: `/pages/login/index`
+    url: `/pages/login/index?isLogout=1`,
   })
 }
 

+ 27 - 0
src/service/api/index.ts

@@ -94,4 +94,31 @@ export const updateUserHub = (data: any) => {
     method: 'POST',
     data: data,
   })
+}
+
+// ---------------------- 设备配网相关 需要引导连接WiFi ----------------------
+/** 名称: maoer-printer-hub
+ *  密码: 0123456789
+ *  IP:   192.168.90.1 */
+
+export const getWifiStatus = () => {
+  return http<any>({
+    url: "http://192.168.90.1/api/wifi-status",
+    method: "GET",
+  })
+}
+
+export const getWifis = () => {
+  return http<any>({
+    url: "http://192.168.90.1/api/wifis",
+    method: "GET",
+  })
+}
+
+export const connectWifi = (data: any) => {
+  return http<any>({
+    url: "http://192.168.90.1/api/wifi-conntion",
+    method: "POST",
+    data: data,
+  })
 }

BIN
src/static/images/connect.png


BIN
src/static/images/device.png


BIN
src/static/images/file.png


BIN
src/static/images/picture.png


BIN
src/static/images/wechat_file.png


BIN
src/static/images/wechat_invoice.png


+ 1 - 1
src/store/user.ts

@@ -30,7 +30,7 @@ export const useUserStore = defineStore(
     const reset = () => {
       userInfo.value = { ...initState }
     }
-    const isLogined = computed(() => !!token)
+    const isLogined = computed(() => !!token.value)
 
     async function initUserInfo() {
       // 查询个人信息

+ 1 - 0
src/types/uni-pages.d.ts

@@ -7,6 +7,7 @@ interface NavigateToOptions {
   url: "/pages/index/index" |
        "/pages/assistant/detail" |
        "/pages/assistant/index" |
+       "/pages/connect/index" |
        "/pages/login/index" |
        "/pages/personal/index" |
        "/pages/webview/index";

+ 1 - 1
src/utils/http.ts

@@ -19,7 +19,7 @@ export const http = <T>(options: CustomRequestOptions) => {
         } else if (res.statusCode === 401) {
           // 401错误  -> 清理用户信息,跳转到登录页
           useUserStore().clearUserInfo()
-          uni.reLaunch({ url: '/pages/login/index' })
+          uni.reLaunch({ url: '/pages/login/index?isLogout=1' })
           reject(res)
         } else {
           // 其他错误 -> 根据后端错误信息轻提示