高敬炎 před 2 roky
rodič
revize
eff13a0bce

+ 3 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/ICertificateManagementInfoService.java

@@ -50,6 +50,9 @@ public interface ICertificateManagementInfoService{
 	@HttpMethod(description = "识别银行卡",  permissionName = "证件管理管理")
 	public DistinguishView bankShibie(@HttpParam(name = "certificateImage", type = HttpParamType.COMMON, description = "证件图") String certificateImage)throws ServiceException;
 
+	@HttpMethod(description = "语音识别",  permissionName = "证件管理管理")
+	public DistinguishView speechRecognition(@HttpParam(name = "voiceMessage", type = HttpParamType.COMMON, description = "语音") String voiceMessage)throws ServiceException;
+
 	@HttpMethod(description = "导出excl表", permissionName = "证件管理管理")
 	public String export(
 								@HttpParam(name = "commonId", type = HttpParamType.COMMON, description = "个人id") Long commonId,

+ 38 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/impl/CertificateManagementInfoServiceImpl.java

@@ -263,5 +263,43 @@ public class CertificateManagementInfoServiceImpl implements ICertificateManagem
 		}
 		return null;
 	}
+
+	@Override
+	public DistinguishView speechRecognition(String voiceMessage) throws ServiceException {
+		String host = "https://audio.market.alicloudapi.com";
+		String path = "/audioshort";
+		String method = "POST";
+		String appcode = "2d59bfa794994f5f94d1d98b7b5bd102";
+		Map<String, String> headers = new HashMap<String, String>();
+		//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
+		headers.put("Authorization", "APPCODE " + appcode);
+		//根据API的要求,定义相对应的Content-Type
+		headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+		Map<String, String> querys = new HashMap<String, String>();
+		Map<String, String> bodys = new HashMap<String, String>();
+		bodys.put("format", "m4a");
+		bodys.put("src", voiceMessage);
+		bodys.put("type", "zh-fast");
+		try {
+			HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
+			String body = EntityUtils.toString(response.getEntity());
+			System.out.println(body);
+			JSONObject jsonObject = JSONObject.parseObject(body);
+			JSONArray jsonArray = jsonObject.getJSONArray("msg");
+			DistinguishView distinguishView = new DistinguishView();
+			if(jsonArray!= null && jsonArray.size() >0){
+				String text = jsonArray.getString(0).replace("。","");
+				distinguishView.setText(text);
+				System.out.println(text);
+			}
+			else{
+				distinguishView.setText("未识别成功!");
+			}
+			return distinguishView;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
 }
 

+ 3 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/domain/CardHolderInfo.java

@@ -116,6 +116,9 @@ public class CardHolderInfo extends SuperDO {
     /** 当前模板 */
     @TableField(exist = false)
     private String cuttentTemplate;
+    /** 头像 */
+    @TableField(exist = false)
+    private String headSculpture;
 
     @Override
     public String toString() {

+ 3 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/domain/CertificateManagementInfo.java

@@ -68,6 +68,9 @@ public class CertificateManagementInfo extends SuperDO {
     @TableField("delete_flag")
     private Long deleteFlag;
 
+    /** 语音 */
+    @TableField(exist = false)
+    private String voiceMessage;
 
     @Override
     public String toString() {

+ 2 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/dto/DistinguishView.java

@@ -9,4 +9,6 @@ public class DistinguishView extends SuperDTO{
     private String recPersonNo;
 
     private String bankNo;
+
+    private String text;
 }

+ 1 - 0
unimall-data/src/main/resources/com/iotechn/unimall/data/mapper/CardHolderInfoMapper.xml

@@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         chi.remark,
         chi.classify,
         cmi.common_id as cardCommonId,
+        cmi.head_sculpture as headSculpture,
         cmi.name AS name,
         cmi.post AS post,
         cmi.company_name as companyName,

+ 338 - 101
xiaochengxu/pages/cardHolder/cardHolder.vue

@@ -1,94 +1,197 @@
 <template>
 	<view class="content">
-		<u-navbar title="电子名片" placeholder>
+		<u-navbar title="电子名片" placeholder bgColor="#112253" titleStyle="color:#fff">
 			<view class="u-nav-slot relative" slot="left">
-				<u-icon name="bell" size="26" @click="toNotice"></u-icon>
+				<u-icon name="bell" size="26" @click="toNotice" color="#fff"></u-icon>
 				<u-badge :isDot="unread>0?true:false" type="error" class="point"></u-badge>
 			</view>
 		</u-navbar>
 		<view class="content1 flex-row-center">
-			<view class="col flex">
-				<uni-icons type="scan" size="30" @click="scan"></uni-icons>
-			</view>
 			<view class="search flex flex-between" @click="search">
 				<view class="left flex">
-					<uni-icons type="search" size="24"></uni-icons>
+					<uni-icons type="search" size="24" color="#9199af"></uni-icons>
 					<text class="search-val"> {{searchVal?searchVal:'搜索名片'}}</text>
 					<uni-icons type="closeempty" size="24" @click.native.stop="delSearchVal"
 						v-if="searchVal"></uni-icons>
 				</view>
 				<view class="right">
-					<uni-icons type="mic" size="24" @click.stop="micOpen"></uni-icons>
+					<uni-icons type="mic" size="24" @click.native.stop="micOpen" color="#9199af"></uni-icons>
 				</view>
 			</view>
+			<view class="col flex">
+				<uni-icons type="scan" size="30" @click="scan" color="#fff"></uni-icons>
+			</view>
 		</view>
 
 		<view class="content2">
 			<view class="all-type flex" @click="selectType">
 				<text>{{typeName?typeName:'全部分类'}}</text>
-				<uni-icons type="bottom" size="20"></uni-icons>
+				<uni-icons type="bottom" size="18" color="#fff"></uni-icons>
 			</view>
 		</view>
-		<!-- <u-skeleton
-		:animate="true"
-			    rows="3"
-			    title
-				:loading='loading'
-			></u-skeleton> -->
-		<view v-if='islongPress'>
-			<view @click="del">删除</view>
-			<view @click='islongPress=false'>取消</view>
-			<u-checkbox-group placement="column" @change="checkboxChange($event,'')">
-				<u-checkbox :checked='checked' name='全部' :customStyle="{marginBottom: '8px'}">
-				</u-checkbox>
-			</u-checkbox-group>
-		</view>
+		<view class="content3">
 
-		<mescroll-body v-if='cardHolderList' :up="upOption" ref="mescrollRef" @init="mescrollInit" @up="upCallback"
-			@down="downCallback">
-			<view v-for='(item,index) in cardHolderList' @longpress="longpress" class="content3 flex">
-				<view class="left">
-					<view class="top flex-row-center">
-						<image :src="item.headSculpture" mode="widthFix" class="img"></image>
-					</view>
-					<view class="bottom flex flex-evenly">
-						<uni-icons @click="toHome(item)" type="home" size="20"></uni-icons>
-						<text @click='switchType(item)'>{{item.classify?item.classifyName:'默'}}</text>
-						<uni-icons @click='share(item)' type="redo" size="20" color=''></uni-icons>
-					</view>
-				</view>
-				<view class="right">
-					<view class="row1 flex">
-						<text>{{item.name}}</text>
-						<text class="line"></text>
-						<text>{{item.post}}</text>
-						<u-checkbox-group v-if='islongPress' placement="column" @change="checkboxChange($event,index)">
-							<u-checkbox :name='index+1' :checked='item.checked' :customStyle="{marginBottom: '8px'}">
-							</u-checkbox>
-						</u-checkbox-group>
-					</view>
-					<view class="row2">
-						{{item.companyName}}
-					</view>
-					<view class="row3" @click="toMap(item)">
-						<uni-icons type="redo" size="20"></uni-icons>
-						<text>{{item.province}}{{item.city}}{{item.area}}{{item.detailedAddress}}</text>
-					</view>
-					<view class="row3">
-						<uni-icons type="redo" size="20"></uni-icons>
-						<text>{{item.phone}}</text>
+			<mescroll-body v-if='cardHolderList' :up="upOption" ref="mescrollRef" @init="mescrollInit" @up="upCallback"
+				@down="downCallback">
+				<view v-for='(item,index) in cardHolderList' @longpress="longpress" class="item flex">
+					<!-- <view class="card-list-item" style="background:red"> -->
+					<view class="card-list-item" :style="'background:url('+item.currentBackground+');background-size:100% 100%'">
+						<view class="card-content style1" v-if="item.cuttentTemplate==0">
+							<view class="left">
+								<u--image :showLoading="true" :src="item.headSculpture" width="66px" height="66px" shape="circle"></u--image>
+							</view>
+							<view class="right">
+								<view class="row1">
+									<text class="name">{{item.name}}</text>
+									<text class="post">{{item.post}}</text>
+								</view>
+								<view class="row2">
+									{{item.companyName}}
+								</view>
+								<view class="row3 flex">
+									<uni-icons type="map-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.province }}{{ item.city }}{{ item.area }}
+								</view>
+								<view class="row4 flex">
+									<uni-icons type="phone-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.phone }}
+								</view>
+								<!-- <view class="">
+									备注
+								</view> -->
+							</view>
+						</view>
+						<view class="card-content style1 flex-between" v-if="item.cuttentTemplate==1">
+							<view class="right">
+								<view class="row1">
+									<text class="name">{{item.name}}</text>
+									<text class="post">{{item.post}}</text>
+								</view>
+								<view class="row2">
+									{{item.companyName}}
+								</view>
+								<view class="row3 flex">
+									<uni-icons type="map-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.province }}{{ item.city }}{{ item.area }}
+								</view>
+								<view class="row4 flex">
+									<uni-icons type="phone-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.phone }}
+								</view>
+								<!-- <view class="">
+									备注
+								</view> -->
+							</view>
+							<view class="left">
+								<u--image :showLoading="true" :src="item.headSculpture" width="66px" height="66px" shape="circle" v-if="item.headSculpture"></u--image>
+								<u--image :showLoading="true" src="/./../static/imgs/card/defaulthead.png" width="66px" height="66px" shape="circle" v-else></u--image>
+							</view>
+						</view>
+						<view class="card-content style2" v-if="item.cuttentTemplate==2">
+								<view class="top">
+									<u--image :showLoading="true" :src="item.headSculpture" width="66px" height="66px" shape="circle" v-if="item.headSculpture"></u--image>
+									<u--image :showLoading="true" src="/./../static/imgs/card/defaulthead.png" width="66px" height="66px" shape="circle" v-else></u--image>
+								</view>
+								<view class="bottom flex">
+									<view class="left">
+										<view class="row1">
+											<text class="name">{{item.name}}</text>
+											<text class="post">{{item.post}}</text>
+										</view>
+										<view class="row2">
+											{{item.companyName}}
+										</view>
+									</view>
+									<view class="right">
+										<view class="row1 flex">
+											<uni-icons type="map-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.province }}{{ item.city }}{{ item.area }}
+										</view>
+										<view class="row2 flex">
+											<uni-icons type="phone-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.phone }}
+										</view>
+									</view>
+								</view>
+						</view>
+						<view class="card-content style2" v-if="item.cuttentTemplate==3">
+								<view class="top">
+									<view class="row1">
+										<text class="name">{{item.name}}</text>
+										<text class="post">{{item.post}}</text>
+									</view>
+									<view class="row2">
+										{{item.companyName}}
+									</view>
+									
+								</view>
+								<view class="bottom flex">
+									<view class="left">
+									<u--image :showLoading="true" :src="item.headSculpture" width="66px" height="66px" shape="circle" v-if="item.headSculpture"></u--image>
+									<u--image :showLoading="true" src="/./../static/imgs/card/defaulthead.png" width="66px" height="66px" shape="circle" v-else></u--image>
+									</view>
+									<view class="right">
+										<view class="row1 flex">
+											<uni-icons type="map-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.province }}{{ item.city }}{{ item.area }}
+										</view>
+										<view class="row2 flex">
+											<uni-icons type="phone-filled" size="20" style="margin-right: 20rpx;" color="#5e6d82"></uni-icons>{{ item.phone }}
+										</view>
+									</view>
+								</view>
+						</view>
+						<view class="car-bottom flex">
+							<view class="left">
+								<image src="../../static/imgs/card/home.png" mode="widthFix" style="width: 32rpx;" @click="toHome(item)"></image>
+								<text @click='switchType(item)' style="color: #fff;">{{item.classify?item.classifyName:'默'}}</text>
+								<image src="../../static/imgs/card/share.png" mode="widthFix" style="width: 35rpx;" @click="share(item)"></image>
+							</view>
+							<view class="right">
+								
+							</view>
+						</view>
 					</view>
-					<view @click='remarkEdit(item)' class="row3">
-						<uni-icons type="redo" size="20"></uni-icons>
-						<text>{{item.remark?item.remark:'单击添加备注'}}</text>
+					
+					
+					
+					<!-- <view class="left">
+						<view class="top flex-row-center">
+							<image :src="item.headSculpture" mode="widthFix" class="img"></image>
+						</view>
+						<view class="bottom flex flex-evenly">
+							<uni-icons @click="toHome(item)" type="home" size="20"></uni-icons>
+							<text @click='switchType(item)'>{{item.classify?item.classifyName:'默'}}</text>
+							<uni-icons @click='share(item)' type="redo" size="20" color=''></uni-icons>
+						</view>
 					</view>
+					<view class="right">
+						<view class="row1 flex">
+							<text>{{item.name}}</text>
+							<text class="line"></text>
+							<text>{{item.post}}</text>
+							<u-checkbox-group v-if='islongPress' placement="column"
+								@change="checkboxChange($event,index)">
+								<u-checkbox :name='index+1' :checked='item.checked'
+									:customStyle="{marginBottom: '8px'}">
+								</u-checkbox>
+							</u-checkbox-group>
+						</view>
+						<view class="row2">
+							{{item.companyName}}
+						</view>
+						<view class="row3" @click="toMap(item)">
+							<uni-icons type="redo" size="20"></uni-icons>
+							<text>{{item.province}}{{item.city}}{{item.area}}{{item.detailedAddress}}</text>
+						</view>
+						<view class="row3">
+							<uni-icons type="redo" size="20"></uni-icons>
+							<text>{{item.phone}}</text>
+						</view>
+						<view @click='remarkEdit(item)' class="row3">
+							<uni-icons type="redo" size="20"></uni-icons>
+							<text>{{item.remark?item.remark:'单击添加备注'}}</text>
+						</view>
+					</view> -->
 				</view>
-			</view>
-		</mescroll-body>
+			</mescroll-body>
+		</view>
+
 		<u-picker :show="isShowType" :columns="typeColumns" keyName="circleName" title="选择分类" @close="isShowType=false"
 			@cancel="isShowType=false" closeOnClickOverlay @confirm="typeConfirm"></u-picker>
-		<lyuan-tx-asr ref="asr" :uploadMethod="uploadFile" @change="asrChange" @fileChange="fileChange" appId=""
-			secretId="" secretKey=""></lyuan-tx-asr>
 		<u-toast ref="uToast"></u-toast>
 		<u-modal :show="delShow" title="提示" showCancelButton='true' @cancel="delShow=false" @confirm="delConfirm"
 			:content='"已选中"+this.checkedList.length+"张名片,确定删除?"'></u-modal>
@@ -132,9 +235,14 @@
 		</u-popup>
 		<!-- <image :src="poster" style="width: 750rpx;height: 1334rpx;"></image> -->
 		<!-- 生成图片 -->
+<<<<<<< HEAD
 		<poster :list="canvasData" background-color="#FFF"
 		:width='750' :height='420'
 			@on-success="posterSuccess" ref="poster" @on-error="posterError"></poster>
+=======
+		<poster :list="canvasData" background-color="#FFF" @on-success="posterSuccess" ref="poster"
+			@on-error="posterError"></poster>
+>>>>>>> 53f9a4ae889bb3cdfdec083420d802cd24b01892
 	</view>
 </template>
 
@@ -180,7 +288,7 @@
 			this.searchVal = uni.getStorageSync("search_val") ? uni.getStorageSync("search_val") : ''
 		},
 		mounted() {
-			
+
 		},
 		onLoad: function() {
 			wx.showShareMenu({
@@ -193,7 +301,7 @@
 			let that = this;
 			//生成名片图片
 			let imageUrl = this.poster
-			console.log("imageUrl",imageUrl)
+			console.log("imageUrl", imageUrl)
 			if (res.from === 'button') {
 				let path = `/pages/cardHolder/scanCodeAddCard?id=${that.currectData.id}`
 				return {
@@ -223,15 +331,15 @@
 				this.popupshow=false
 			},
 			posterError(err) {
-			                console.log(err)
-			            },
-			            posterSuccess(url) {
-							console.log("hahahah",url)
-			                // 生成成功,会把临时路径在这里返回
-			                this.poster = url;
-							this.popupshow=true
-			                console.log(url)
-			            },
+			    console.log(err)
+			},
+			posterSuccess(url) {
+				console.log("hahahah",url)
+			    // 生成成功,会把临时路径在这里返回
+			    this.poster = url;
+				this.popupshow=true
+			    console.log(url)
+			},
 			toHome(item) {
 				uni.navigateTo({
 					url: "/pages/mySet/myHome?id=" + item.personalHomeId
@@ -401,6 +509,7 @@
 						width: 33,
 						height: 28
 					},
+
 				]
 				// this.popupshow = true
 			},
@@ -691,16 +800,9 @@
 				})
 			},
 			micOpen: function() {
-				this.$refs.asr.show();
-			},
-			asrChange: function(res) {
-				console.log('语音识别确认结果:' + res);
-			},
-			fileChange: function({
-				file,
-				content
-			}) {
-				console.log('录音文件', file);
+				uni.navigateTo({
+					url: "/pages/cardHolder/search?mic=1"
+				})
 			},
 			uploadFile: function(tempFilePath) {
 				return new Promise((resolve, reject) => {
@@ -780,7 +882,7 @@
 
 <style lang="scss" scoped>
 	.content {
-		padding: 0 20rpx;
+		// padding: 0 20rpx;
 	}
 
 	.u-nav-slot {
@@ -792,49 +894,182 @@
 	}
 
 	.content1 {
-		margin-top: 20rpx;
+		padding: 20rpx;
+		background-color: #112253;
 
 		.search {
-			margin-left: 20rpx;
-			border: 1px solid #ccc;
+			color: #9199af;
+			background: #22325f;
 			border-radius: 50rpx;
 			width: 100%;
 			padding: 10rpx 30rpx;
 			box-sizing: border-box;
-
-			.left {
-				.search-val {
-					margin-left: 30rpx;
-				}
-			}
+			margin-right: 20rpx;
 		}
 	}
 
 	.content2 {
-		.all-type {}
+		background: #112253;
+		color: #fff;
+		padding: 20rpx 20rpx 200rpx 20rpx;
+		border-radius: 0px 0px 20px 20px;
+
 	}
 
 	.content3 {
-		border: 1px solid #ccc;
+		// padding:0 20rpx;
+		position: relative;
+		top: -170rpx;
+		.style1{
+			display: flex;
+			padding: 20rpx 30rpx;
+			width: 85%;
+			margin-bottom: 90rpx;
+			.left{
+				width: 132rpx;
+				height: 132rpx;
+				border-radius: 50%;
+			}
+			.right{
+				margin-left: 40rpx;
+				.row1{
+					.name{
+						font-size: 38rpx;
+						font-weight: bold;
+						color: #040000;
+						margin-right: 20rpx;
+					}
+					.post{
+						font-size: 26rpx;
+						font-weight: 500;
+						color: #666666;
+					}
+				}
+				.row2{
+					margin-top: 20rpx;
+					font-size: 24rpx;
+					font-weight: bold;
+					color: #323333;
+				}
+				.row3{
+					margin-top: 30rpx;
+					font-size: 24rpx;
+					font-weight: 500;
+					color: #323333;
+					
+				}
+			}
+		}
+		.style2{
+				padding:30rpx;
+				margin-bottom: 100rpx;
+				.top{
+					.row1{
+						.name{
+							font-size: 38rpx;
+							font-weight: bold;
+							color: #040000;
+							margin-right: 20rpx;
+						}
+						.post{
+							font-size: 26rpx;
+							font-weight: 500;
+							color: #666666;
+						}
+					}
+					.row2{
+						margin-top: 20rpx;
+						font-size: 24rpx;
+						font-weight: bold;
+						color: #323333;
+					}
+				}
+				.bottom{
+					margin-top: 48rpx;
+					.left{
+						margin-right: 40rpx;
+						.row1{
+							.name{
+								font-size: 38rpx;
+								font-weight: bold;
+								color: #040000;
+								margin-right: 20rpx;
+							}
+							.post{
+								font-size: 26rpx;
+								font-weight: 500;
+								color: #666666;
+							}
+						}
+						.row2{
+							margin-top: 20rpx;
+							font-size: 24rpx;
+							font-weight: bold;
+							color: #323333;
+						}
+					}
+					.right{
+						.row1,.row2{
+							font-size: 24rpx;
+							font-weight: 500;
+							color: #323333;
+						}
+						.row2{
+							margin-top: 20rpx;
+						}
+					}
+				}
+				
+		}
+	.card-list-item {
+		width: calc(100%);
+		// left:-20rpx;
+		position: relative;
 		border-radius: 30rpx;
 		padding: 40rpx;
 		box-sizing: border-box;
-
+		.car-bottom{
+			position: absolute;
+			bottom: 63rpx;
+			left:20rpx;
+			// width: calc(100% - 40rpx);
+			.left{
+				// top: -40rpx;
+				position: absolute;
+				padding: 20rpx 0;
+				width: 70vw;
+				height: 80rpx;
+				box-sizing: border-box;
+				display: flex;
+				align-items: center;
+				justify-content: space-evenly;
+				background: url("../../static/imgs/card/bgc1.png") no-repeat center;
+				background-size: 100% 100%;
+			}
+			.right{
+				position: absolute;
+				left: 65vw;
+				height: 80rpx;
+				width: 30vw;
+				background: url("../../static/imgs/card/right-bgc.png") no-repeat center;
+				background-size: 100% 100%;
+			}
+		}
 		.left {
 			width: 30%;
-
+	
 			.top {
-
+	
 				margin-bottom: 20rpx;
 			}
-
+	
 			.img {
 				width: 80%;
 			}
-
+	
 			.bottom {}
 		}
-
+	
 		.right {
 			.row1 {
 				.line {
@@ -846,6 +1081,8 @@
 			}
 		}
 	}
+		
+	}
 
 	.slot-content {
 		width: 100%;

+ 336 - 7
xiaochengxu/pages/cardHolder/search.vue

@@ -1,38 +1,367 @@
 <template>
 	<view>
-		<d-search-log :placeholder="'搜索名片'" :color_border="color_border" :color_text="color_border" :search_list_old_man_num='15' :search_list_hot="search_list_hot"
-			:store_key="store_key" @onClickDelAllApi="onClickDelAll" @onSearchNameApi="onSearchName"></d-search-log>
-
+		<d-search-log :placeholder="'搜索名片'" :color_border="color_border" :color_text="color_border"
+			:search_list_old_man_num='15' :search_list_hot="search_list_hot" :store_key="store_key"
+			@onClickDelAllApi="onClickDelAll" @onSearchNameApi="onSearchName"></d-search-log>
+		<u-popup :show="isRecorderManager" mode="bottom">
+			<view class="shqx" v-if="longPress == '2'">
+				上划取消
+			</view>
+			<view class="record-layer">
+				<view class="record-box">
+					<view class="record-btn-layer" v-if="tempFilePath == ''">
+						<view class="record-btn">
+							<image src="../../static/mic1.png" mode="widthFix" style="width:120rpx;"
+								@longpress="longpressBtn" @touchend="touchendBtn" @touchmove="handleTouchMove"></image>
+							<text class="text">{{longPress == '1' ? '按住说出姓名' : '松开自动识别'}}</text>
+						</view>
+					</view>
+					<!-- 语音音阶动画 -->
+					<view class="prompt-layer prompt-layer-1" v-if="longPress == '2'">
+						<view class="prompt-loader">
+							<view class="em" v-for="(item,index) in 15" :key="index"></view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</u-popup>
+		<u-toast ref="uToast"></u-toast>
 	</view>
 </template>
 
 <script>
 	import dSearchLog from '@/uni_modules/d-search-log/components/d-search-log/d-search-log.vue'
+	const recorderManager = uni.getRecorderManager();
+	const innerAudioContext = uni.createInnerAudioContext();
+	var init // 录制时长计时器
+	var timer // 播放 录制倒计时
 	export default {
 		components: {
 			"dSearchLog": dSearchLog
 		},
 		data() {
 			return {
+				duration: 60000, //录音最大值ms 60000/1分钟
+				tempFilePath: '', //音频路径
+				playStatus: 0, //录音播放状态 0:未播放 1:正在播放
+				longPress: '1',
+				tempFilePath: '',
 				color_border: "#00aaff",
 				search_list_hot: [],
 				store_key: 'search_list',
+				isRecorderManager: false,
+				is_clock: true,
+				startPoint: ""
 			};
 		},
+		onLoad(options) {
+			if (options.mic == 1) {
+				this.isRecorderManager = true
+			}
+		},
 		methods: {
-			onClickDelAll() {
+
+			handleTouchMove: function(e) {
+				console.log("滑动")
+				if (Math.abs(e.touches[e.touches.length - 1].clientY - this.startPoint.clientY) > 35) {
+
+					this.is_clock = false
+				} else {
+
+					this.is_clock = true
+				}
+			},
+			longpressBtn(e) {
+				this.longPress = '2';
+				this.is_clock = true,
+					console.log(e);
+				this.startPoint = e.touches[0],
+					recorderManager.onStop((res) => {
+						console.log("录音结束")
+						this.tempFilePath = res.tempFilePath;
+					})
+				const options = {
+					duration: this.duration, // 指定录音的时长,单位 ms
+					sampleRate: 16000, // 采样率
+					numberOfChannels: 1, // 录音通道数
+					encodeBitRate: 96000, // 编码码率
+					// format: 'mp3', // 音频格式,有效值 aac/mp3
+					frameSize: 10, // 指定帧大小,单位 KB
+				}
+				recorderManager.start(options);
+				// 监听音频开始事件
+				recorderManager.onStart((res) => {
+					console.log(res)
+				})
+			},
+			touchendBtn() {
+				console.log("录音结束")
+				let that = this
+				this.longPress = '1'; 
+				recorderManager.onStop((res) => {
+					this.tempFilePath = res.tempFilePath
+					let _file = ''
+					if (that.is_clock) {
+						_file = uni.getFileSystemManager().readFileSync(res.tempFilePath, "base64")
+						console.log(_file)
+						that.$request.baseRequest('admin.unimall.certificateManagementInfo', 'speechRecognition', {
+							voiceMessage: _file,
+						}, failres => {
+							console.log('res+++++', failres.errmsg)
+							this.$refs.uToast.show({
+								type: 'error',
+								message: failres.errmsg,
+							})
+						}).then(res => {
+							uni.hideLoading()
+							console.log(res)
+							uni.setStorageSync('search_val', res.data);
+							uni.switchTab({
+								url: "/pages/cardHolder/cardHolder"
+
+							})
+
+						})
+					}
+					recorderManager.stop()
+				})
 			},
+			onClickDelAll() {},
 			onSearchName(e) {
 				uni.setStorageSync('search_val', e);
 				uni.switchTab({
-					url:"/pages/cardHolder/cardHolder"
-					
+					url: "/pages/cardHolder/cardHolder"
+
 				})
 			}
 		}
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
+	.shqx {
+		position: absolute;
+		top: -100rpx;
+		left: 0;
+		right: 0;
+		margin: auto;
+		text-align: center;
+		color: rgba(221, 221, 221, 1);
+	}
+
+	.record-box {
+		width: 100%;
+		position: relative;
+		top: 80rpx;
+	}
+
+	.record-btn-layer {
+		width: 100%;
+		display: flex;
+		justify-content: center;
+	}
+
+	.record-btn-layer button::after {
+		border: none;
+	}
+
+	.record-btn-layer button {
+		font-size: 14px;
+		line-height: 38px;
+		width: 100%;
+		height: 38px;
+		border-radius: 8px;
+		text-align: center;
+		background: rgba(56, 86, 156, 1);
+	}
+
+	.record-btn-layer button image {
+		width: 16px;
+		height: 16px;
+		margin-right: 4px;
+		vertical-align: middle;
+	}
+
+	.record-btn-layer .record-btn-2 {
+		background: rgba(56, 86, 156, 1);
+	}
+
+	.prompt-layer {
+		border-radius: 8px;
+		background: rgba(56, 86, 156, 1);
+		padding: 8px 16px;
+		box-sizing: border-box;
+		position: absolute;
+		left: 50%;
+		transform: translateX(-50%);
+	}
+
+	.prompt-layer::after {
+		content: '';
+		display: block;
+		border: 6px solid rgba(0, 0, 0, 0);
+		border-top-color: rgba(56, 86, 156, 1);
+		position: absolute;
+		bottom: -10px;
+		left: 50%;
+		transform: translateX(-50%);
+	}
+
+	.prompt-layer-1 {
+		font-size: 12px;
+		width: 128px;
+		text-align: center;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		top: -240px;
+	}
+
+	.del {
+		position: absolute;
+		top: -200rpx;
+
+		.img {
+			width: 100rpx;
+		}
+	}
+
+	.prompt-layer-1 .p {
+		color: #000000;
+	}
+
+	.prompt-layer-1 .span {
+		color: #fff;
+	}
+
+	.prompt-loader .em {}
+
+	.prompt-loader {
+		width: 96px;
+		height: 20px;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		margin-bottom: 6px;
+	}
+
+	.prompt-loader .em {
+		display: block;
+		background: #fff;
+		width: 1px;
+		height: 10%;
+		margin-right: 2.5px;
+		float: left;
+	}
+
+	.prompt-loader .em:last-child {
+		margin-right: 0px;
+	}
+
+	.prompt-loader .em:nth-child(1) {
+		animation: load 2.5s 1.4s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(2) {
+		animation: load 2.5s 1.2s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(3) {
+		animation: load 2.5s 1s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(4) {
+		animation: load 2.5s 0.8s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(5) {
+		animation: load 2.5s 0.6s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(6) {
+		animation: load 2.5s 0.4s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(7) {
+		animation: load 2.5s 0.2s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(8) {
+		animation: load 2.5s 0s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(9) {
+		animation: load 2.5s 0.2s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(10) {
+		animation: load 2.5s 0.4s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(11) {
+		animation: load 2.5s 0.6s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(12) {
+		animation: load 2.5s 0.8s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(13) {
+		animation: load 2.5s 1s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(14) {
+		animation: load 2.5s 1.2s infinite linear;
+	}
+
+	.prompt-loader .em:nth-child(15) {
+		animation: load 2.5s 1.4s infinite linear;
+	}
+
+	@keyframes load {
+		0% {
+			height: 10%;
+		}
+
+		50% {
+			height: 100%;
+		}
+
+		100% {
+			height: 10%;
+		}
+	}
 
+	.prompt-layer-2 {
+		// top: -540px;
+	}
+
+	.prompt-layer-2 .text {
+		color: rgba(0, 0, 0, 1);
+		font-size: 12px;
+	}
+
+	.record-btn {
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+
+		.text {
+			margin-top: 20rpx;
+		}
+
+	}
+
+	/deep/.u-popup__content {
+		padding-bottom: 100rpx;
+		background: linear-gradient(180deg, rgba(204, 204, 204, 0.95) 0%, rgba(203, 203, 203, 0.01) 100%) !important;
+		border-radius: 50% 50% 0 0;
+	}
+
+	.record-layerP {
+		position: relative;
+		top: 50px;
+	}
 </style>

binární
xiaochengxu/static/imgs/card/right-bgc.png


binární
xiaochengxu/static/mic1.png


binární
xiaochengxu/static/mic2.png


binární
xiaochengxu/static/stop.png


binární
xiaochengxu/static/voice.png