Ver Fonte

fix: 增加了拍照功能,修复了不能同时选择多张照片问题

lvkun996 há 8 meses atrás
pai
commit
9a1210583a

+ 1 - 1
src/App.vue

@@ -28,7 +28,7 @@ const pushHomePage = () => {
 }
 
 onMounted(() => {
-  registerWxConfig()
+  // registerWxConfig()
 })
 
 </script>

+ 2 - 2
src/store/useTrainStore.js

@@ -34,10 +34,10 @@ export const useTrainStore = defineStore('useTrainStore', () => {
     }
   }
 
-  const finish = async (id) => {
+  const finish = async (id, photos, checkInCount) => {
     const { latitude, longitude } = await getLocation()
     const { status } = await finishTrain({
-      id, latitude, longitude
+      id, latitude, longitude, photos, checkInCount
     })
     if (status === 200) {
       // eslint-disable-next-line no-undef

+ 16 - 0
src/utils/tools.js

@@ -0,0 +1,16 @@
+export function getMobileOperatingSystem () {
+  var userAgent = navigator.userAgent || navigator.vendor || window.opera
+
+  // iOS 判断
+  if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
+    return 'iOS'
+  }
+
+  // Android 判断
+  if (/android/i.test(userAgent)) {
+    return 'Android'
+  }
+
+  // 其他设备
+  return 'unknown'
+}

+ 2 - 2
src/utils/wx.js

@@ -8,7 +8,7 @@ import axios from 'axios'
 
 export const WxLogin = (url = '/') => {
   const appid = 'wxe87236d542cd0f94'
-  const URL = 'https://luojigou.vip/training-test//#' + url
+  const URL = 'https://luojigou.vip/training/#' + url
   const redirect_uri = encodeURIComponent(URL)
   const state = 1
   window.location.replace(`https://open.weixin.qq.com/connect/oauth2/authorize?&appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`)
@@ -42,7 +42,7 @@ export function registerWxConfig () {
       timestamp: data.timestamp, // 必填,生成签名的时间戳
       nonceStr: data.nonceStr, // 必填,生成签名的随机串
       signature: data.signature, // 必填,签名
-      jsApiList: ['getLocation', 'chooseImage', 'uploadImage'] // 必填,需要使用的JS接口列表
+      jsApiList: ['getLocation', 'chooseImage', 'uploadImage', 'getLocalImgData'] // 必填,需要使用的JS接口列表
     })
     wx.ready(() => {
       resolve()

+ 34 - 14
src/views/create-train.vue

@@ -45,15 +45,10 @@
         <div class="check-in-item-title" >培训内容</div>
         <van-checkbox-group class="check-in-item-content"  v-model="formSate.contents" direction="horizontal" shape="square">
           <van-checkbox :name="item.name" style="margin-bottom: 12px"  v-for="item in contentList" :key="item.id" >{{item.name}}</van-checkbox>
-          <van-checkbox label-disabled :name="formSate.cusContent" style="margin-bottom: 12px"  >
-            <van-field  style="border: 1px solid #cdc8c8;height: 40px;" v-model="formSate.cusContent" label="" placeholder="自定义培训内容" />
+          <van-checkbox label-disabled name="cusContent" style="margin-bottom: 12px;display: flex;align-items: center;padding: 0;"  >
+            <van-field  style="border: 1px solid #cdc8c8;height: 34px;" v-model="formSate.cusContent" label="" placeholder="自定义培训内容" />
           </van-checkbox>
         </van-checkbox-group>
-        <!-- <div :class="['check-in-item-input',formRequireState.contentId ? 'check-in-item-input-warn' : '' ]" @click="openModal('content')">
-          <div class="placeholder" v-if="!formSate.content" >请选择</div>
-          <div :class="['check-in-item-value' ]" v-else >{{formSate.content}}</div>
-          <van-icon name="arrow-down" />
-        </div> -->
       </div>
       <div class="check-in-item" >
         <div class="check-in-item-title" >培训科目</div>
@@ -89,7 +84,7 @@
   </van-popup>
 
   <!-- 信息确认 -->
-  <van-popup v-model:show="infoSubmitShow" round  >
+  <van-popup v-model:show="infoSubmitShow" round  @closed="closePop" >
     <div class="info-modal" >
       <div class="title" >信息确认</div>
       <div class="info-modal-form" >
@@ -100,7 +95,7 @@
         <div class="info-modal-item" >  <div class="title"> 培训性质 </div> <div class="value"> {{formSate.nature}} </div></div>
         <div class="info-modal-item" >  <div class="title"> 培训形式 </div> <div class="value"> {{formSate.method}} </div></div>
         <div class="info-modal-item" >  <div class="title"> 培训形态 </div> <div class="value"> {{formSate.form}} </div></div>
-        <div class="info-modal-item" >  <div class="title"> 培训内容 </div> <div class="value"> {{formSate.contents.join('/')}} </div></div>
+        <div class="info-modal-item" >  <div class="title"> 培训内容 </div> <div class="value"> {{formSate.contents.join('/')}}  {{formSate.contents.length === 0 ? '' : '/'}} {{formSate.cusContent}} </div></div>
         <div class="info-modal-item" >  <div class="title"> 园所名称 </div> <div class="value"> {{formSate.schoolName}} </div></div>
         <div class="info-modal-item" >  <div class="title"> 代理商名称 </div> <div class="value"> {{formSate.agentName}} </div></div>
       </div>
@@ -194,12 +189,18 @@ const sheetAction = computed(() => {
 })
 
 watch(
-  () => formSate.value.content,
+  () => formSate.value.contents,
   () => {
-    console.log(formSate.value.content)
+    console.log(formSate.value.contents)
   }
 )
 
+const closePop = () => {
+  if (formSate.value.cusContent) {
+    formSate.value.contents.push('cusContent')
+  }
+}
+
 const submit = () => {
   // eslint-disable-next-line no-undef
   showLoadingToast({
@@ -207,6 +208,7 @@ const submit = () => {
     forbidClick: true
   })
   setTimeout(() => {
+    formSate.value.contents.push(formSate.value.cusContent)
     trainStore.add(formSate.value).then(() => {
       router.replace({
         path: '/sign-code'
@@ -231,8 +233,16 @@ const submitInfoModal = () => {
   } else {
     formRequireState.value.regions = false
   }
-  console.log('formRequireState:', formRequireState.value)
-  if (flag) { infoSubmitShow.value = true }
+  if (flag) {
+    if (!formSate.value.contents.includes('cusContent')) {
+      formSate.value.cusContent = ''
+    } else {
+      const index = formSate.value.contents.findIndex(item => item === 'cusContent')
+      formSate.value.contents.splice(index, 1)
+    }
+
+    infoSubmitShow.value = true
+  }
 }
 const openModal = (key) => {
   curSheetKey.value = key
@@ -357,7 +367,10 @@ onMounted(() => {
           font-weight: normal;
           margin-right: 12px;
         }
-        .value { }
+        .value {
+          width: 220px;
+          text-align: left;
+        }
       }
     }
     .submit-btn {
@@ -372,4 +385,11 @@ onMounted(() => {
       margin-top: 80px;
     }
   }
+
+  .van-checkbox__label .van-cell {
+    padding: 0;
+    display: flex;
+    align-items: center;
+    padding-left: 12px
+  }
 </style>

+ 3 - 3
src/views/record.vue

@@ -31,7 +31,7 @@
             </div>
             <div class="schoolName" >{{item.schoolName}}</div>
             <div class="duration"  >培训时长: <span :style="{color: item.state ===  1 ? 'green' :  item.state === 2 ? 'red' : '#000'}" >{{item.state === 1 ? '进行中' : item.state === 2 ? '未开始' : item.duration}}</span></div>
-            <div class="contentName" >培训内容: {{item.contentName}}</div>
+            <div class="contentName" >培训内容: {{item.contents.join('/')}}</div>
           </div>
         </div>
         <div class="record-null"   v-else  >
@@ -127,7 +127,7 @@ const changeSubject = (record) => {
     console.log(dateShow.value)
   } else {
     actionShow.value = true
-  }
+  }
 }
 
 const list = ref([])
@@ -193,7 +193,7 @@ const onConfirm = (key) => {
   }
   dateShow.value = false
   queryParamsState.value.page = 1
-  getRecordPage()
+  getRecordPage()
 }
 
 const onSelect = (record) => {

+ 26 - 12
src/views/sign-code.vue

@@ -33,7 +33,7 @@
       <div class="photo-container-item upload" >
         <div class="label" >参与人数</div>
         <div class="content" >
-          <van-field  style="border: 1px solid #d6cece;" v-model="checkInCount" label="" placeholder="请输入" />
+          <van-field type="number"  style="border: 1px solid #d6cece;" v-model="checkInCount" label="" placeholder="请输入" />
         </div>
       </div>
     </div>
@@ -52,7 +52,7 @@ import { storeToRefs } from 'pinia'
 import wx from 'weixin-js-sdk'
 import { qiniuUploadRequest } from '@/utils/qiniu.js'
 import { getServerIdByLocalId } from '@/utils/wx.js'
-
+import { getMobileOperatingSystem } from '@/utils/tools'
 const trainStore = useTrainStore()
 
 const { current } = storeToRefs(trainStore)
@@ -110,21 +110,34 @@ const delPhoto = (index) => {
 const chooseImage = () => {
   wx.chooseImage({
     count: maxUploadCount - photos.value.length,
+    // count: 1,
     sizeType: ['original', 'compressed'],
-    sourceType: ['album'],
-    success: function (res) {
-      res.localIds.forEach(localId => {
-        wx.getLocalImgData({
-          localId, // 图片的localID
-          success: function (res) {
-            var localData = res.localData // localData是图片的base64数据,可以用img标签显示
-            photos.value.push({ localId, localData })
-          }
+    sourceType: ['album', 'camera'],
+    success: async function (res) {
+      console.log('res:', res)
+      console.log(getMobileOperatingSystem())
+      if (getMobileOperatingSystem() === 'iOS') {
+        for (let index = 0; index < res.localIds.length; index++) {
+          await new Promise((resolve) => {
+            wx.getLocalImgData({
+              localId: res.localIds[index],
+              success: function (LocalImgData) {
+                var localData = LocalImgData.localData
+                photos.value.push({ localId: res.localIds[index], localData })
+                resolve()
+              }
+            })
+          })
+        }
+      } else {
+        res.localIds.forEach(function (localId) {
+          photos.value.push({ localId, localData: localId })
         })
-      })
+      }
     }
   })
 }
+
 onMounted(() => {
   byId(current.value.id)
 })
@@ -213,6 +226,7 @@ onMounted(() => {
             img {
               width: 100%;
               height: 100%;
+              object-fit: cover;
             }
           }
         }

+ 8 - 0
src/views/trained.vue

@@ -86,9 +86,16 @@ onMounted(() => {
   min-height: 100vh;
   overflow: hidden;
   background-color: #eff2f5;
+  padding-top: 40px;
   padding-bottom: 260px;
   box-sizing: border-box;
   .photo-cantainer {
+    width: 340px;
+    background-color: #fff;
+    padding: 24px;
+    border-radius: 10px;
+    margin: 0 auto;
+    box-sizing: border-box;
     .photos {
       display: flex;
       .photo {
@@ -104,6 +111,7 @@ onMounted(() => {
         img {
           width: 100%;
           height: 100%;
+          object-fit: cover;
         }
       }
     }

+ 26 - 13
src/views/training.vue

@@ -19,7 +19,7 @@
       <div class="photo-container-item upload" >
         <div class="label" >参与人数</div>
         <div class="content" >
-          <van-field  style="border: 1px solid #d6cece;" v-model="checkInCount" label="" placeholder="请输入" />
+          <van-field type="number" style="border: 1px solid #d6cece;" v-model="checkInCount" label="" placeholder="请输入" />
         </div>
       </div>
     </div>
@@ -65,6 +65,7 @@ import { useTrainStore } from '@/store'
 import { storeToRefs } from 'pinia'
 import wx from 'weixin-js-sdk'
 import { getServerIdByLocalId } from '@/utils/wx.js'
+import { getMobileOperatingSystem } from '@/utils/tools'
 
 const trainStore = useTrainStore()
 
@@ -120,18 +121,28 @@ const endTrain = () => {
 const chooseImage = () => {
   wx.chooseImage({
     count: maxUploadCount - photos.value.length,
+    // count: 1,
     sizeType: ['original', 'compressed'],
-    sourceType: ['album'],
-    success: function (res) {
-      res.localIds.forEach(localId => {
-        wx.getLocalImgData({
-          localId, // 图片的localID
-          success: function (res) {
-            var localData = res.localData // localData是图片的base64数据,可以用img标签显示
-            photos.value.push({ localId, localData })
-          }
+    sourceType: ['album', 'camera'],
+    success: async function (res) {
+      if (getMobileOperatingSystem() === 'iOS') {
+        for (let index = 0; index < res.localIds.length; index++) {
+          await new Promise((resolve) => {
+            wx.getLocalImgData({
+              localId: res.localIds[index],
+              success: function (LocalImgData) {
+                var localData = LocalImgData.localData
+                photos.value.push({ localId: res.localIds[index], localData })
+                resolve()
+              }
+            })
+          })
+        }
+      } else {
+        res.localIds.forEach(function (localId) {
+          photos.value.push({ localId, localData: localId })
         })
-      })
+      }
     }
   })
 }
@@ -145,7 +156,7 @@ const confirmEnd = async () => {
   for (let index = 0; index < photos.value.length; index++) {
     serverIds.push(await getServerIdByLocalId(photos.value[index].localId))
   }
-  finish(current.value.id, serverIds, checkInCount)
+  finish(current.value.id, serverIds, checkInCount.value)
 }
 
 const cancelEnd = () => {
@@ -157,7 +168,7 @@ const timeStampText = ref('加载中...')
 const timeId = ref()
 onMounted(() => {
   byId(current.value.id).then(() => {
-    createQrecode()
+    // createQrecode()
     timeId.value = setInterval(() => {
       const timeStamp = ((new Date().getTime() - current.value.startTimestamp) / 1000).toFixed(0)
       const h = Math.floor((timeStamp / 3600))
@@ -194,6 +205,7 @@ onUnmounted(() => {
         margin-right: 0.2em; /* 星号和文本之间的距离 */
       }
       .content {
+        display: flex;
         text-align: left;
         margin-top: 12px;
         margin-bottom: 12px;
@@ -212,6 +224,7 @@ onUnmounted(() => {
             img {
               width: 100%;
               height: 100%;
+              object-fit: cover;
             }
           }
         }