Pārlūkot izejas kodu

修改UI--补充样式优化

“shengjie.huang” 1 gadu atpakaļ
vecāks
revīzija
8583c11fd2

+ 1 - 0
pages.config.ts

@@ -33,6 +33,7 @@ export default defineUniPages({
         text: '首页',
       },
       {
+        // TODO: 使用自定义菜单栏 / midButton样式
         iconPath: 'static/tabbar/device.png',
         selectedIconPath: 'static/tabbar/deviceHL.png',
         pagePath: 'pages/assistant/index',

+ 75 - 70
src/pages/assistant/detail.vue

@@ -8,74 +8,68 @@
 </route>
 <template>
   <view class="page-form">
-    <wd-form ref="form" :model="formData">
-      <view class="form-title">
-        <view>详细信息</view>
-        <!-- <view class="opt-item" @click="customRecognize">
-          <wd-icon name="list" size="30rpx"></wd-icon>
-          <text>右侧图标</text>
-        </view> -->
+    <view v-if="type == 'add'"
+          class="video-contain">
+      <view class="title">
+        <i class="iconfont icon-combined"></i>
+        <text>快速教程</text>
       </view>
-      <wd-cell-group custom-class="form-group" border>
-        <wd-input
-          v-if="type == 'add'"
-          v-model="formData.hostname"
-          label="主机台"
-          label-width="100px"
-          prop="hostname"
-          placeholder="请输入"
-          clearable
-          suffix-icon="scan"
-          :readonly="type == 'view'"
-          :rules="[{ required: true, message: '请填写主机台' }]"
-          @clicksuffixicon="scanQRCode"
-        />
-        <wd-input
-          v-model="formData.asname"
-          label="设备名称"
-          label-width="100px"
-          prop="asname"
-          placeholder="请输入"
-          clearable
-          :readonly="type == 'view'"
-          :rules="[{ required: true, message: '请填写设备名称' }]"
-        />
-        <!-- <wd-select-picker
-          v-model="formData.addType"
-          label="添加方式"
-          label-width="100px"
-          prop="addType"
-          type="radio"
-          filterable
-          readonly
-          :columns="typeList"
-          :max="1"
-          :show-confirm="false"
-          :rules="[{ required: true, message: '请选择添加方式' }]"
-        /> -->
-        <wd-cell
-          v-if="type != 'add'"
-          title="设备状态"
-          title-width="100px"
-          :value="getLabel(formData.enabled, statusList)"
-        />
-        <wd-textarea
-          v-if="type != 'add'"
-          v-model="formData.remark"
-          label="备注"
-          label-width="100px"
-          prop="remark"
-          clearable
-          auto-height
-          :readonly="type == 'view'"
-          :placeholder="type == 'view' ? '' : '请输入'"
-        />
-      </wd-cell-group>
+      <view class="video">视频区</view>
+    </view>
+    <view class="form-contain">
+      <wd-form ref="form" :model="formData">
+        <view v-if="type != 'add'"
+              class="form-title">
+          <view>详细信息</view>
+        </view>
+        <wd-cell-group custom-class="form-group" border>
+          <wd-input
+            v-if="type == 'add'"
+            v-model="formData.hostname"
+            label="打印助手"
+            label-width="100px"
+            prop="hostname"
+            placeholder="请通过扫描二维码/手动输入打印助手"
+            clearable
+            suffix-icon="scan"
+            :readonly="type == 'view'"
+            :rules="[{ required: true, message: '打印助手不能为空' }]"
+            @clicksuffixicon="scanQRCode"
+          />
+          <wd-input
+            v-model="formData.asname"
+            label="助手名称"
+            label-width="100px"
+            prop="asname"
+            placeholder="请填写助手名称"
+            clearable
+            :readonly="type == 'view'"
+            :rules="[{ required: true, message: '助手名称不能为空' }]"
+          />
+          <wd-cell
+            v-if="type != 'add'"
+            title="助手状态"
+            title-width="100px"
+            :value="getLabel(formData.enabled, statusList)"
+          />
+          <wd-textarea
+            v-if="type != 'add'"
+            v-model="formData.remark"
+            label="备注"
+            label-width="100px"
+            prop="remark"
+            clearable
+            auto-height
+            :readonly="type == 'view'"
+            :placeholder="type == 'view' ? '' : '请输入'"
+          />
+        </wd-cell-group>
 
-      <view v-if="type != 'view'" class="form-footer">
-        <wd-button type="primary" size="large" @click="handleSubmit" block>提交</wd-button>
-      </view>
-    </wd-form>
+        <view v-if="type != 'view'" class="form-footer">
+          <wd-button type="primary" size="large" @click="handleSubmit" block>保存</wd-button>
+        </view>
+      </wd-form>
+    </view>
   </view>
 </template>
 
@@ -146,7 +140,7 @@ function handleSubmit() {
             uni.$emit('refreshData')
             message
               .alert({
-                msg: '设备保存成功',
+                msg: '助手保存成功',
                 closeOnClickModal: false,
               })
               .then(() => {
@@ -169,12 +163,12 @@ onLoad((option) => {
     if (option.scene.startsWith("share_")) {
       let id = option.scene.split('_')[1]
       getDetailById(id, () => {
-        toast.success("已填入设备信息")
+        toast.success("已填入助手信息")
       }, () => {
-        toast.error("查询设备信息失败, 请稍后重试")
+        toast.error("查询助手信息失败, 请稍后重试")
       })
     } else {
-      // 设备扫码添加
+      // 助手扫码添加
       formData.value.hostname = option.scene
     }
   }
@@ -183,6 +177,17 @@ onLoad((option) => {
 </script>
 
 <style lang="scss" scoped>
+.video-contain {
+  margin-bottom: 30rpx;
+}
+:deep(.form-contain) {
+  .wd-input__suffix {
+    .wd-input__icon {
+      color: var(--wot-color-theme) !important;
+    }
+  }
+}
+
 :deep(.wd-radio-group) {
   padding: 0 !important;
   .wd-radio {

+ 1 - 0
src/pages/assistant/index.vue

@@ -9,6 +9,7 @@
 <template>
   <view class="page-list">
     <!-- 添加猫耳助手 -->
+    <!-- TODO: 多边形样式 -->
     <view class="add-contain" @click="toDetail('add')">
       <view class="main-text">
         <view class="tips">添加猫耳打印助手</view>

+ 69 - 93
src/pages/connect/index.vue

@@ -23,15 +23,15 @@
         <view class="step-item">
           <view class="tag">step1</view>
           <view class="icon">
-            <i class="iconfont icon-shangchuanwenjian"></i>
+            <i class="iconfont icon-shoujiWiFi"></i>
           </view>
-          <view class="label">先连接"maoer-hub"开头的WIFI</view>
+          <view class="label">先连接"maoer-hub"开头的WiFi</view>
         </view>
         <view class="step-link">···</view>
         <view class="step-item">
           <view class="tag">step2</view>
           <view class="icon">
-            <i class="iconfont icon-dayinshezhi"></i>
+            <i class="iconfont icon-internet"></i>
           </view>
           <view class="label">开始配网</view>
         </view>
@@ -39,9 +39,9 @@
         <view class="step-item">
           <view class="tag">step3</view>
           <view class="icon">
-            <i class="iconfont icon-dayinwancheng"></i>
+            <i class="iconfont icon-online"></i>
           </view>
-          <view class="label">选择链接WIFI</view>
+          <view class="label">选择连接WiFi</view>
         </view>
       </view>
     </view>
@@ -49,34 +49,34 @@
     <view class="opt-contain">
       <view class="btn" @click="getConnectedWifi()">开始配网</view>
       <i class="iconfont icon-xiayibu icon-down"></i>
-      <view class="tips">配网成功后再选择WIFI</view>
+      <view class="tips">配网成功后再选择WiFi</view>
     </view>
 
     <view class="form-contain">
-      <wd-form ref="form" :model="formData">
+      <wd-form ref="form" :model="formData" custom-class="my-form">
         <wd-cell-group custom-class="form-group" border>
           <wd-select-picker
             v-model="formData.ssid"
-            label="无线名称"
+            label="WiFi名称"
             label-width="100px"
             prop="ssid"
             type="radio"
             filterable
-            placeholder="请选择家里的无线名称"
+            placeholder="请选择WiFi"
             :columns="wifiList"
             value-key="ssid"
             label-key="ssid"
             :loading="loading"
             :max="1"
             :show-confirm="false"
-            :rules="[{ required: true, message: '请选择家里的无线名称' }]"
+            :rules="[{ required: true, message: '请选择WiFi' }]"
           />
           <wd-input
             v-model="formData.pwd"
-            label="无线密码"
+            label="WiFi密码"
             label-width="100px"
             prop="pwd"
-            placeholder="请输入家里的无线密码"
+            placeholder="请输入WiFi密码"
             clearable
             show-password
             :rules="[{ required: true, pattern: /^.{8,}$/, message: '请输入不少于8位无线密码' }]"
@@ -84,75 +84,40 @@
         </wd-cell-group>
 
         <view class="form-footer">
-          <wd-button type="primary" size="large" :disabled="loading" @click="handleSubmit()" block>提交</wd-button>
+          <wd-button type="primary" size="large" block :disabled="loading" @click="handleSubmit()">确认</wd-button>
         </view>
       </wd-form>
     </view>
 
-    <!-- <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>
-        <view v-if="currentWifi" class="check-result">{{ `设备当前连接WiFi: ${currentWifi}` }}</view>
-        <wd-button @click="getConnectedWifi()">重新检查</wd-button>
+    <wd-message-box selector="wd-message-box-slot">
+      <view class="message-contain">
+        <template v-if="connectFlag">
+          <i class="iconfont icon-online"></i>
+          <view class="result color-success">WiFi已经连接</view>
+          <view class="tips">助手已经连接到网络,你可以去打印了。</view>
+        </template>
+        <template v-else>
+          <i class="iconfont icon-offline"></i>
+          <view class="result color-danger">WiFi连接失败</view>
+        </template>
       </view>
-      <view v-if="!checkWiFiFlag">{{ `请先连接以 "${targetWifi}" 开头的WiFi` }}</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"
-          value-key="ssid"
-          label-key="ssid"
-          :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
-          show-password
-          :rules="[{ required: true, pattern: /^.{8,}$/, message: '请输入不少于8位无线密码' }]"
-        />
-      </wd-cell-group>
-
-      <view class="form-footer">
-        <wd-button type="primary" size="large" :disabled="loading" @click="handleSubmit()" block>提交</wd-button>
-      </view>
-    </wd-form> -->
+    </wd-message-box>
   </view>
 </template>
 
 <script lang="ts" setup>
 import { testConnect, getWifiStatus, getWifis, connectWifi } from '@/service/api/index'
-import { useToast } from 'wot-design-uni'
+import { useToast, useMessage } from 'wot-design-uni'
+
+defineOptions({
+  name: 'Connect',
+  styleIsolation: 'shared'
+})
 
 const loading = ref(false)
-const deviceImg = ref('/static/images/device.png')
 const toast = useToast()
+const message = useMessage()
+const messageSlot = useMessage("wd-message-box-slot")
 const targetWifi = "maoer-hub"
 const checkWiFiFlag = ref(false)
 const checkIPFlag = ref(false)
@@ -167,18 +132,14 @@ const formData: any = ref({
   pwd: "",
 })
 const wifiList: any = ref([])
-// 检查结果
-const checkResult = computed(() => {
-  return checkWiFiFlag.value ? (checkIPFlag.value ? "已检测到设备" : "未检测到设备") : "未连接指定WiFi"
-})
+const connectFlag = ref(false)
 
 // 检查手机wifi连接是否正确, 匹配前缀
 function checkWifi() {
   if (wifiInfo.value.SSID.startsWith(targetWifi)) {
     checkWiFiFlag.value = true
-    toast.success('您已连接指定WiFi!')
   } else {
-    toast.warning(`请先连接以 "${targetWifi}" 开头的WiFi`)
+    message.alert(`请先连接以 "${targetWifi}" 开头的WiFi`)
   }
 }
 
@@ -194,11 +155,19 @@ function getConnectedWifi(isFirst = false) {
           if (checkWiFiFlag.value) checkIP(isFirst)
         },
         fail: (err) => {
-          toast.error('获取WiFi信息失败')
+          message.alert(`获取WiFi信息失败,请先已开启手机WLAN,并连接以 "${targetWifi}" 开头的WiFi`)
         }
       })
     }, 1000)
-  }).catch((err)=> {})
+  }).catch((err)=> {
+    let tips = "初始化wifi模块失败, 请重试"
+    switch (err.errMsg) {
+      case "startWifi:fail 开发者工具暂时不支持此 API 调试,请使用真机进行开发":
+        tips = "开发者工具暂时不支持此 API 调试,请使用真机进行开发"
+        break;
+    }
+    message.alert(tips)
+  })
 }
 
 // 局域网通信: 检查IP地址是否请求成功
@@ -208,10 +177,11 @@ function checkIP(isFirst: boolean = false) {
     checkIPFlag.value = true
     getDeviceWifiStatus()
     if (isFirst) getWifiList()
+    message.alert("已检测到设备,请选择连接WiFi以及输入密码")
   }).catch((err)=> {
     checkIPFlag.value = false
     wifiList.value = []
-    toast.warning('未检测到设备')
+    message.alert("已连接指定WiFi,但未检测到设备,请稍后重试")
   })
 }
 
@@ -250,12 +220,16 @@ function handleSubmit() {
         title: '正在提交...'
       });
       connectWifi(formData.value).then((res: any) => {
-        console.log('res: ', res);
-        toast.success('连接成功')
         currentWifi.value = res.body || ""
+        connectFlag.value = true
+        messageSlot.alert("").then(() => {
+          uni.reLaunch({
+            url: `/pages/index/index`,
+          })
+        })
       }).catch((err) => {
-        console.log('err: ', err);
-        toast.error('连接失败')
+        connectFlag.value = false
+        messageSlot.alert("")
         getDeviceWifiStatus()
       })
       .finally(() => {
@@ -276,7 +250,14 @@ onLoad(() => {
   background-color: #fff;
 }
 .guide-contain {
-  margin-top: 20rpx;
+  margin-top: 30rpx;
+  .step-contain {
+    .step-item:first-of-type {
+      .label {
+        bottom: 30rpx;
+      }
+    }
+  }
 }
 .opt-contain {
   color: #666;
@@ -292,17 +273,12 @@ onLoad(() => {
     margin-top: 20rpx;
   }
 }
-// .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: 30rpx;
+// 写在公共样式中
+// :deep(.form-contain) {
+//   .wd-select-picker__cell,
+//   .wd-input,
+//   .wd-input__icon {
+//     background-color: rgba(15, 95, 254, 0.05) !important;
 //   }
 // }
 </style>

+ 2 - 0
src/pages/index/index.vue

@@ -79,6 +79,8 @@
     </view>
 
     <!-- TODO: showGuide 增加自定义confirm, 引导添加设备 -->
+    <!-- <wd-message-box selector="wd-message-box-slot">
+    </wd-message-box> -->
   </view>
 </template>
 

+ 53 - 1
src/pages/personal/index.vue

@@ -21,7 +21,7 @@
       <view class="main-text">
         <view v-if="isLogined">
           <view class="tips">{{ userInfo.name }}</view>
-          <view class="count">{{ `猫耳打印陪伴您1年了` }}</view>
+          <view class="count">{{ `猫耳打印陪伴您${getTimeInterval(userInfo.createTime)}了` }}</view>
         </view>
         <view v-else class="tips" @click="toLogin()">
           请点击登录
@@ -63,6 +63,7 @@ const { safeAreaInsets } = uni.getSystemInfoSync()
 const userInfo = reactive({
   avatar: '',
   name: '',
+  createTime: ''
 })
 const toast = useToast()
 const isLogined = computed(() => !!useUserStore().token)
@@ -99,6 +100,57 @@ function initFn() {
   userInfo.name = useUserStore().userInfo?.name || "微信用户"
   userInfo.avatar = "/static/images/avatar.png"
   // userInfo.avatar = useUserStore().userInfo.avatar
+  userInfo.createTime = useUserStore().userInfo?.createTime
+}
+
+function getTimeInterval(targetDate) {
+  const isoString = targetDate.replace(' ', 'T');
+  // 确保传入的是有效的日期对象
+  const target = new Date(isoString);
+  if (isNaN(target.getTime())) {
+    return '-';
+  }
+
+  const now = new Date();
+  
+  // 计算总月份差
+  let months = (now.getFullYear() - target.getFullYear()) * 12;
+  months += now.getMonth() - target.getMonth();
+  
+  // 计算天数差
+  let days = now.getDate() - target.getDate();
+  if (days < 0) {
+    months--;
+    // 获取上个月的天数
+    const lastDayOfMonth = new Date(
+      now.getFullYear(),
+      now.getMonth(),
+      0
+    ).getDate();
+    days += lastDayOfMonth;
+  }
+  
+  // 计算年数和剩余月数
+  const years = Math.floor(months / 12);
+  const remainingMonths = months % 12;
+  
+  // 构建结果字符串
+  // let result = [];
+  // if (years > 0) result.push(`${years}年`);
+  // if (remainingMonths > 0) result.push(`${remainingMonths}月`);
+  // if (days > 0) result.push(`${days}日`);
+  // return result.join('') || '0日'; // 如果所有值都是0,返回"0日"
+
+  // 结果只返回 年or月or日
+  let resStr = "-"
+  if (years > 0) {
+    resStr = `${years}年`
+  } else if (remainingMonths > 0) {
+    resStr = `${remainingMonths}月`
+  } else if (days > 0) {
+    resStr = `${days}日`
+  }  
+  return resStr
 }
 
 onLoad(() => {

+ 1 - 1
src/pages/print/jobDetail.vue

@@ -7,7 +7,7 @@
 }
 </route>
 <template>
-  <view class="page-form">
+  <view class="page-form form-contain">
     <wd-form ref="form" :model="formData">
       <view class="form-title">
         <view>详细信息</view>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 11 - 7
src/static/iconfont/iconfont.css


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
src/static/iconfont/iconfont.js


+ 14 - 7
src/static/iconfont/iconfont.json

@@ -5,6 +5,20 @@
   "css_prefix_text": "icon-",
   "description": "猫耳云打印小程序",
   "glyphs": [
+    {
+      "icon_id": "6239378",
+      "name": "online",
+      "font_class": "online",
+      "unicode": "e694",
+      "unicode_decimal": 59028
+    },
+    {
+      "icon_id": "6239381",
+      "name": "offline",
+      "font_class": "offline",
+      "unicode": "e695",
+      "unicode_decimal": 59029
+    },
     {
       "icon_id": "8288873",
       "name": "设置",
@@ -96,13 +110,6 @@
       "unicode": "e8b5",
       "unicode_decimal": 59573
     },
-    {
-      "icon_id": "20592561",
-      "name": "online",
-      "font_class": "online",
-      "unicode": "e602",
-      "unicode_decimal": 58882
-    },
     {
       "icon_id": "20912773",
       "name": "下一步",

BIN
src/static/iconfont/iconfont.ttf


BIN
src/static/iconfont/iconfont.woff


BIN
src/static/iconfont/iconfont.woff2


+ 47 - 4
src/style/index.scss

@@ -87,7 +87,7 @@ page {
 .page-form {
   min-height: calc(100vh - 168rpx);
   padding: 20rpx 20rpx 144rpx;
-  background-color: #f1f1f1;
+  // background-color: #f1f1f1;
 
   .form-title {
     display: flex;
@@ -364,6 +364,9 @@ page {
         transform: translateX(-50%);
         height: 40rpx;
         color: #000;
+        width: calc(100% - 20rpx);
+        text-align: center;
+        word-break: break-all;
       }
     }
     .step-link {
@@ -412,6 +415,7 @@ page {
     .iconfont {
       font-size: 32rpx;
       color: var(--wot-color-theme);
+      margin-right: 20rpx;
     }
   }
   .video {
@@ -427,8 +431,47 @@ page {
   }
 }
 
-:deep(.form-contain) {
-  .wd-cell-group {
-    background-color: rgba(15, 95, 254, 0.02) !important;
+.form-contain {
+  // .wd-cell-group__body > * {
+  //   background-color: rgba(15, 95, 254, 0.05) !important;
+  // }
+  .wd-select-picker__cell,
+  .wd-textarea,
+  .wd-textarea__value,
+  .wd-input,
+  .wd-input__icon,
+  .wd-input__suffix,
+  .wd-cell {
+    background-color: #F3F7FF !important;
+  }
+  .is-border::after {
+    width: calc(100% - 40rpx) !important;
+  }
+  .wd-cell.is-border {
+    .wd-cell__wrapper::after {
+      width: calc(100% - 20rpx) !important;
+    }
+  }
+}
+
+.message-contain {
+  .iconfont {
+    font-size: 120rpx;
+    line-height: 1.1;
+  }
+  .icon-online {
+    color: var(--wot-color-success);
+  }
+  .icon-offline {
+    color: var(--wot-color-danger);
+  }
+  .result {
+    margin-top: 20rpx;
+    font-size: 28rpx;
+  }
+  .tips {
+    margin-top: 20rpx;
+    font-size: 24rpx;
+    color: #666;
   }
 }