Kaynağa Gözat

志愿者身份证正反面--二维码生成

jiayubo 1 gün önce
ebeveyn
işleme
88dcff05a2

+ 20 - 0
api/qrcode.js

@@ -0,0 +1,20 @@
+import request from '@/utils/request'
+
+// 获取不限制的小程序码
+export function getUnlimitedQRCode(data) {
+  return request({
+    url: '/wx/qrcode/unlimited',
+    method: 'post',
+    data: {
+      scene: data.scene, // 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符
+      page: data.page, // 默认是主页,页面 page,例如 pages/index/index
+      check_path: data.check_path || true, // 默认是true,检查page 是否存在
+      env_version: data.env_version || 'release', // 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"
+      width: data.width || 430, // 二维码的宽度,单位 px,最小 280px,最大 1280px
+      auto_color: data.auto_color || false, // 自动配置线条颜色
+      line_color: data.line_color || { r: 0, g: 0, b: 0 }, // 使用 rgb 设置颜色
+      is_hyaline: data.is_hyaline || false // 是否需要透明底色
+    },
+    responseType: 'arraybuffer' // 设置响应类型为arraybuffer,因为返回的是图片二进制内容
+  })
+} 

+ 4 - 4
components/Client/new_file.vue

@@ -207,7 +207,7 @@
 	const handleGridClick = async (service) => {
 		// 用户
 		if (userType == 1) {
-
+			uni.setNavigationBarTitle({ title: service.name }); // 动态设置顶部胶囊标题
 			// 动态获取 parentId
 			const params = {
 				parentId: service.key,
@@ -215,9 +215,9 @@
 			const res = await volunteerSeachgetTreeList(params)
 
 			// 只有第一条、第二条、临时帮手和家庭保洁可以跳转
-			if (service.key === 1 || service.key === 2 || service.key === 3 || service.key === 4) {
+			if (service.key === 1 || service.key === 2 || service.key === 3 || service.key === 4 || service.key === 5 || service.key === 6) {
 				uni.navigateTo({
-					url: `/pages_home/pages/client/details?dataList=${encodeURIComponent(JSON.stringify(res.data))}&serviceCategory=${service.key}`
+					url: `/pages_home/pages/client/details?title=${encodeURIComponent(service.name)}&dataList=${encodeURIComponent(JSON.stringify(res.data))}&serviceCategory=${service.key}`
 				});
 			} else {
 				// 其他条目提示"敬请期待"
@@ -255,7 +255,7 @@
 						url: `/pages_home/pages/register/index?data=${encodeURIComponent(JSON.stringify(service))}`
 					})
 				} else {
-					// 其他条目提示“敬请期待”
+					// 其他条目提示"敬请期待"
 					uni.showToast({
 						title: '敬请期待',
 						icon: 'none'

+ 111 - 0
components/QRCode/index.vue

@@ -0,0 +1,111 @@
+<template>
+  <view class="qrcode-container">
+    <view class="qrcode-box" v-if="qrCodeUrl">
+      <image :src="qrCodeUrl" mode="aspectFit" class="qrcode-image" @longpress="handleLongPress"></image>
+      <text class="qrcode-tip">长按保存二维码</text>
+    </view>
+    <view class="qrcode-loading" v-else>
+      <up-loading-icon vertical text="生成中..."></up-loading-icon>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+import { getUnlimitedQRCode } from '@/api/qrcode'
+import { arrayBufferToBase64, saveQRCodeToLocal } from '@/utils/qrcode'
+
+const props = defineProps({
+  scene: {
+    type: String,
+    required: true
+  },
+  page: {
+    type: String,
+    default: 'pages/index/index'
+  },
+  width: {
+    type: Number,
+    default: 430
+  },
+  autoColor: {
+    type: Boolean,
+    default: false
+  },
+  lineColor: {
+    type: Object,
+    default: () => ({ r: 0, g: 0, b: 0 })
+  },
+  isHyaline: {
+    type: Boolean,
+    default: false
+  }
+})
+
+const qrCodeUrl = ref('')
+
+const generateQRCode = async () => {
+  try {
+    const response = await getUnlimitedQRCode({
+      scene: props.scene,
+      page: props.page,
+      width: props.width,
+      auto_color: props.autoColor,
+      line_color: props.lineColor,
+      is_hyaline: props.isHyaline
+    })
+    
+    // 将ArrayBuffer转换为Base64图片
+    qrCodeUrl.value = arrayBufferToBase64(response)
+  } catch (error) {
+    console.error('生成二维码失败:', error)
+    uni.showToast({
+      title: '生成二维码失败',
+      icon: 'error'
+    })
+  }
+}
+
+const handleLongPress = async () => {
+  try {
+    await saveQRCodeToLocal(qrCodeUrl.value)
+  } catch (error) {
+    console.error('保存二维码失败:', error)
+  }
+}
+
+onMounted(() => {
+  generateQRCode()
+})
+</script>
+
+<style lang="scss" scoped>
+.qrcode-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 20rpx;
+  
+  .qrcode-box {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    
+    .qrcode-image {
+      width: 400rpx;
+      height: 400rpx;
+    }
+    
+    .qrcode-tip {
+      margin-top: 20rpx;
+      font-size: 24rpx;
+      color: #999;
+    }
+  }
+  
+  .qrcode-loading {
+    padding: 40rpx;
+  }
+}
+</style> 

+ 1 - 1
config.js

@@ -2,7 +2,7 @@
 const config = {
 	// baseUrl: 'https://vue.ruoyi.vip/prod-api',
 	//cloud后台网关地址
-	baseUrl: 'http://192.168.100.95:9527',//嵘哥
+	baseUrl: 'http://192.168.100.139:9527',//嵘哥
 	// baseUrl: 'http://192.168.100.101:9527',//龙哥
 	// baseUrl: 'https://zybooks.tech/prod-api',
 	mapKey:'KFEBZ-P2GKZ-A5PX4-7Q6Y7-KXOBF-XCB4C',

+ 2 - 2
pages.json

@@ -76,7 +76,7 @@
 				{
 					"path": "pages/client/details",
 					"style": {
-						"navigationBarTitleText": "孩子陪护"
+						// "navigationBarTitleText": "孩子陪护"
 					}
 				},
 				{
@@ -399,7 +399,7 @@
 	},
 	"globalStyle": {
 		"navigationBarTextStyle": "black",
-		"navigationBarTitleText": "RuoYi",
+		// "navigationBarTitleText": "RuoYi",
 		"navigationBarBackgroundColor": "#FFFFFF"
 	},
 	"plugins": {

+ 1 - 1
pages/common/orderList/index.vue

@@ -18,7 +18,7 @@
 <script setup>
 import ListItem from './listItem.vue';
 import UserItem from './userItem.vue';
-import { ref, defineExpose, defineProps, defineEmits } from 'vue';
+import { ref } from 'vue';
 
 const props = defineProps({
     data: {

+ 5 - 5
pages/index.vue

@@ -12,7 +12,7 @@
     </view>
     <view class="home-box" :style="`margin-top: ${globalData.navBarHeight}px `">
       <view class="home-main">
-        <view class="custom-swiper">
+        <view class="custom-swiper" v-if="list3.length > 0">
           <up-swiper
             :list="list3"
             indicator
@@ -45,7 +45,7 @@
           <view class="serve-title hot-box-title" v-if="userType === 1"
             >超值专区</view
           >
-          <view class="hot-swiper">
+          <view class="hot-swiper" v-if="ValueZone.length > 0">
             <up-swiper
               :list="ValueZone"
               :indicator="false"
@@ -97,12 +97,12 @@ import { getToken } from '@/utils/auth'
 
 const rightList = ref([])
 const leftList = ref([])
-const list3 = ref([])
-const ValueZone = ref([])
+const list3 = ref([''])  // Initialize with at least one empty item
+const ValueZone = ref([''])  // Initialize with at least one empty item
 const hotList = ref([])
 const userType = uni.getStorageSync('userType') //读取本地存储
 const text1 = ref(
-  '热烈祝贺:于5月20日上午9:00点钟召开“金邻助家”平台项目的首次发布会!'
+  '热烈祝贺:于5月20日上午9:00点钟召开"金邻助家"平台项目的首次发布会!'
 )
 const globalData = ref({
   statusBarHeight: 47,

+ 5 - 0
pages/mine.vue

@@ -79,6 +79,8 @@
 				</view>
 		</view>
 		<CustomTabBar page="mine" />
+
+    <QRCode scene="123" page="/pages/index/index" width="430" auto-color line-color="#000000" is-hyaline></QRCode>
 	</view>
 </template>
 
@@ -91,8 +93,11 @@ import {
 import store from "@/store"
 import { getVolunteerAccountInfo, volunteerOrderStatistics } from "@/api/mine";
 import CustomTabBar from '@/components/CustomTabBar/index.vue'
+import QRCode from '@/components/QRCode/index.vue'
+
 import { getToken } from '@/utils/auth'
 import { showConfirm } from '@/utils/common'
+
 const userInfo = ref({
 	avatar: '/static/serverImg/mine/user.png',
 	nickName: '登陆/注册'

+ 5 - 0
pages_home/pages/client/details.vue

@@ -160,6 +160,11 @@
 		serviceCategory.value = options.serviceCategory
 		list1.value = dataList
 		list2.value = dataList[0].children
+
+		// 新增:动态设置顶部标题
+		if (options.title) {
+			uni.setNavigationBarTitle({ title: decodeURIComponent(options.title) });
+		}
 	})
 
 	// 分页

+ 14 - 4
pages_home/pages/register/index.vue

@@ -150,10 +150,19 @@ const updata_list = [
 		required: true
 	},
 	{
-		title: '个人身份证',
-		text: '上传您的个人身份证',
+		title: '身份证正面',
+		text: '上传您的身份证正面',
 		img: '/static/img/updata-user-img.png',
-		key: 'idCardPicture',
+		key: 'idCardPictureFront',
+		ref: zsImg,
+		// permission: [1, 2],
+		required: true
+	},
+	{
+		title: '身份证反面',
+		text: '上传您的身份证反面',
+		img: '/static/img/updata-user-img.png',
+		key: 'idCardPictureBack',
 		ref: zsImg,
 		// permission: [1, 2],
 		required: true
@@ -527,7 +536,8 @@ async function getRegister() {
 			cust_form_ref.value.setData(details.value);
 			Object.assign(file_url, {
 				volunteerPicture: res.data.volunteerPicture,
-				idCardPicture: res.data.idCardPicture,
+				idCardPictureFront: res.data.idCardPictureFront,
+				idCardPictureBack: res.data.idCardPictureBack,
 				certificationPicture: res.data.certificationPicture
 			})
 			servesInit(data)

+ 40 - 0
utils/qrcode.js

@@ -0,0 +1,40 @@
+/**
+ * 将 ArrayBuffer 转换为 Base64 图片
+ * @param {ArrayBuffer} buffer - 图片的 ArrayBuffer 数据
+ * @returns {string} Base64 图片字符串
+ */
+export const arrayBufferToBase64 = (buffer) => {
+  // 使用 uni-app 的 API 将 ArrayBuffer 转换为 Base64
+  return uni.arrayBufferToBase64(buffer);
+}
+
+/**
+ * 保存二维码到本地
+ * @param {string} base64 - Base64 图片字符串
+ */
+export const saveQRCodeToLocal = async (base64) => {
+  try {
+    // 将 Base64 转换为临时文件路径
+    const fsm = uni.getFileSystemManager();
+    const filePath = `${uni.env.USER_DATA_PATH}/qrcode_${Date.now()}.png`;
+    
+    // 写入文件
+    fsm.writeFileSync(filePath, base64, 'base64');
+    
+    // 保存到相册
+    await uni.saveImageToPhotosAlbum({
+      filePath: filePath
+    });
+    
+    uni.showToast({
+      title: '保存成功',
+      icon: 'success'
+    });
+  } catch (error) {
+    console.error('保存二维码失败:', error);
+    uni.showToast({
+      title: '保存失败',
+      icon: 'error'
+    });
+  }
+}