UniApp学习笔记
大约 6 分钟
自定义导航栏高度
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
,"navigationStyle": "custom"
}
}
],
<!--<view class="header" :style="{height:statusHeight+'px'}"></view>-->
<!--<view class="header-content" :style="{height:headerHeight+'px'}">首页</view>-->
<view class="htop" :style="{height:totalHeaght+'px'}"></view>
const statusHeight = ref(0)
const headerHeight = ref(0)
const totalHeaght = ref(0);
onMounted(() => {
uni.getSystemInfoAsync({
success(e) {
statusHeight.value = e.statusBarHeight // 状态栏高度
let custom = uni.getMenuButtonBoundingClientRect();
statusHeight.value -= custom.height/2;
headerHeight.value = custom.height + (custom.top - e.statusBarHeight)*2;
totalHeaght.value = e.statusBarHeight + custom.height + 10;
}
})
})
.htop{
width: 100%;
background: linear-gradient(to bottom right,#4e73df, #224abe); // 渐变背景
}
.header{
background-color: lavender;
color: wheat;
font-weight: 600;
text-align: center;
font-size: 20px;
padding-bottom: 20px;
}
.header-content{
width: 100%;
position: fixed;
display: flex;
justify-content: center;
align-items: center;
}
iconfont使用
1、将下载的文件放入到 status
目录
2、修改iconfont的文件路径iconfont.css
@font-face {
font-family: "iconfont"; /* 修改为你iconfont的文件路径 */
src: url('/static/iconfont/iconfont.woff2?t=1745734768803') format('woff2'),
url('/static/iconfont/iconfont.woff?t=1745734768803') format('woff'),
url('/static/iconfont/iconfont.ttf?t=1745734768803') format('truetype');
}
3、在 App.vue
中加载样式
<style lang="scss">
@import "./static/iconfont/iconfont.css"
</style>
4、使用
<text class="iconfont icon-fenxiang"></text>
小程序登录
1、uniapp获取到code
uni.login({
provider: 'weixin',
success:(res)=>{
console.log(res.code)
}
})
2、将code传递给后端,后端通过接口得到用户的openid,之后就可以自定义登录逻辑了。
<button open-type="getPhoneNumber" type="primary" @getphonenumber="login">登录</button>
const login = (res) => {
uni.login({
provider: 'weixin',
success(loginInfo) {
uni.request({
method: 'POST',
url: "http://127.0.0.1:8000/api/register",
data: {
code: loginInfo.code,
encryptedData: res.target.encryptedData,
iv: res.target.iv
},
success(res) {
console.log(res.data)
uni.showModal({
content: res.data.msg
})
}
})
}
})
}
3、调用用户信息更新用户资料
uni.getUserInfo({
provider: "weixin",
success(info)=>{
console.log(info.userInfo)
}
})
小程序注册
1、获取到用户的手机号
2、查询用户的手机号是否存在,如果存在就直接返回,或者获取用户的openid进行查询
3、返回登录信息
<button open-type="getPhoneNumber" type="primary" @getphonenumber="login">登录</button>
<script setup>
import { ref ,onMounted} from 'vue'
const user = ref({
id: 0,
name: "ornagbus",
phone: "18388112501",
openid: "123456"
})
const login = (res) => {
uni.login({
provider: 'weixin',
success(loginInfo) {
console.log({
code: loginInfo.code,
encryptedData: res.target.encryptedData,
iv: res.target.iv
})
uni.request({
method: 'POST',
url: "http://127.0.0.1:8000/api/register",
dataType: JSON,
data: {
code: loginInfo.code,
encryptedData: res.target.encryptedData,
iv: res.target.iv
},
success(res) {
let d = JSON.parse(res.data)
update(d.data.openid)
uni.showModal({
content: d.msg
})
}
})
}
})
}
const update = (openid) => {
uni.getUserInfo({
provider: 'weixin',
success(u) {
uni.request({
method: 'POST',
url: "http://127.0.0.1:8000/api/user/update",
dataType: JSON,
data: {
openid: openid,
name: u.userInfo.nickName,
avatar: u.userInfo.avatarUrl
},
success(res) {
let data = JSON.parse(res.data)
user.value = data.data;
}
})
}
})
}
</script>
public function register()
{
$code = request("code");
$encryptedData = request("encryptedData");
$iv = request("iv");
AssertUtils::isEmpty($code,"参数错误");
$setting = AccountSetting::first();
AssertUtils::isNull($setting,"请先配置账号信息");
$app = $this->NewMiniApp($setting);
$utils = $app->getUtils();
$response = $utils->codeToSession($code);
$openid = $response["openid"];
$user = User::where("openid", $openid)->first();
if (is_null($user)) {
$data = $utils->decryptSession($response["session_key"],$iv,$encryptedData);
$user = User::create([
"openid" => $openid,
"phone" => $data["phoneNumber"],
"name" =>$data["phoneNumber"],
"password" => "123456"
]);
}
return $this->success("登录成功",$user);
}
直接拨号
callPhone(phone){
//#ifdef H5||MP-WEIXIN
let _this = this;
uni.makePhoneCall({
phoneNumber: phone,
success(){
// 拨号成功
},
fail(){
uni.showModal({
content: "拨号失败!"
})
return false;
}
});
//#endif
//#ifdef APP-PLUS
plus.device.dial(phone,false);
//#endif
return true;
},
获取app的通话记录
getCalllog(){
var CallLog = plus.android.importClass('android.provider.CallLog');
var Activity = plus.android.runtimeMainActivity();
var ContentResolver = plus.android.importClass('android.content.ContentResolver');
var resolver = Activity.getContentResolver();
plus.android.importClass(resolver);
var String = plus.android.importClass("java.lang.String");
var cs = resolver.query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DEFAULT_SORT_ORDER);
var talist = [];
uni.showLoading({
title: "匹配通话记录中.."
});
var count = 0; // 记录多少条 用于处理循环跳出
while (plus.android.invoke(cs, "moveToNext")) {
count++;
talist.push({
xm: plus.android.invoke(cs, "getString", plus.android.invoke(cs, "getColumnIndex", CallLog.Calls.CACHED_NAME)),
telphone: plus.android.invoke(cs, "getString", plus.android.invoke(cs, "getColumnIndex", CallLog.Calls.NUMBER)),
duration: plus.android.invoke(cs, "getString", plus.android.invoke(cs, "getColumnIndex", CallLog.Calls.DURATION)),
date: plus.android.invoke(cs, "getString", plus.android.invoke(cs, "getColumnIndex", CallLog.Calls.DATE)),
type: plus.android.invoke(cs, "getString", plus.android.invoke(cs, "getColumnIndex", CallLog.Calls.TYPE))
});
if(count > 50){
break;
}
}
uni.hideLoading();
console.info("talist",talist);
},
// 获取通话记录
var CallLog = plus.android.importClass("android.provider.CallLog");
var main = plus.android.runtimeMainActivity();
var obj = main.getContentResolver();
plus.android.importClass(obj);
//查询
var cursor = obj.query(
CallLog.Calls.CONTENT_URI,
null,
null,
null,
null
);
plus.android.importClass(cursor);
var content = []; // 用来存储数据
var count = 0; // 记录多少条
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
count++;
//号码
var number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
//呼叫类型
var type;
switch (
parseInt(cursor.getString(cursor.getColumnIndex(CallLog.Calls.TYPE))))
// 判断通话类型
{
case CallLog.Calls.INCOMING_TYPE:
type = "呼入";
break;
case CallLog.Calls.OUTGOING_TYPE:
type = "呼出";
break;
case CallLog.Calls.MISSED_TYPE:
type = "未接";
break;
default:
type = "挂断"; //应该是挂断.根据我手机类型判断出的
break;
}
// 获取时间
var date = new Date(parseInt(
cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.DATE))));
// 联系人
var Name_Col = cursor.getColumnIndexOrThrow(CallLog.Calls.CACHED_NAME);
var name = cursor.getString(Name_Col);
// 号码归属地 返回:北京 联通
var numberLocation = cursor.getString(
cursor.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)
);
//通话时间,单位:s
var Duration_Col = cursor.getColumnIndexOrThrow(CallLog.Calls.DURATION);
var duration = cursor.getString(Duration_Col);
// 存入数组
content.push({
name: name, // 联系人的姓名
mobile: number, // 联系人电话
numberLocation: numberLocation, // 号码的归属地
callTime: new Date().getTime(date), // 呼入或呼出时间
talkTime: duration, // 通话时长
type: type
});
// 查询50条 就跳出
if (count > 50) {
break;
}
}
}
console.log(JSON.stringify(content));
uni-app获取通话记录 自定义基座打包能成功获取
// 获取通话记录
var CallLog = plus.android.importClass("android.provider.CallLog");
var main = plus.android.runtimeMainActivity();
var obj = main.getContentResolver();
plus.android.importClass(obj);
//查询
var cursor = obj.query(
CallLog.Calls.CONTENT_URI,
null,
null,
null,
null
);
plus.android.importClass(cursor);
var content = []; // 用来存储数据
var count = 0; // 记录多少条
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
count++;
//号码
var number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
//呼叫类型
var type;
switch (
parseInt(cursor.getString(cursor.getColumnIndex(CallLog.Calls.TYPE))))
// 判断通话类型
{
case CallLog.Calls.INCOMING_TYPE:
type = "呼入";
break;
case CallLog.Calls.OUTGOING_TYPE:
type = "呼出";
break;
case CallLog.Calls.MISSED_TYPE:
type = "未接";
break;
default:
type = "挂断"; //应该是挂断.根据我手机类型判断出的
break;
}
// 获取时间
var date = new Date(parseInt(
cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.DATE))));
// 联系人
var Name_Col = cursor.getColumnIndexOrThrow(CallLog.Calls.CACHED_NAME);
var name = cursor.getString(Name_Col);
// 号码归属地 返回:北京 联通
var numberLocation = cursor.getString(
cursor.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)
);
//通话时间,单位:s
var Duration_Col = cursor.getColumnIndexOrThrow(CallLog.Calls.DURATION);
var duration = cursor.getString(Duration_Col);
// 存入数组
content.push({
name: name, // 联系人的姓名
mobile: number, // 联系人电话
numberLocation: numberLocation, // 号码的归属地
callTime: new Date().getTime(date), // 呼入或呼出时间
talkTime: duration, // 通话时长
type: type
});
// 查询50条 就跳出
if (count > 50) {
break;
}
}
}
console.log(JSON.stringify(content));
打电话录音功能
const recorderManager = uni.getRecorderManager();
onLoad(option) {
let self = this;
recorderManager.onStop(function (res) {
console.log("res",res)
self.end_time = Math.round(new Date().getTime() / 1000);
let voicePath = res.tempFilePath;
self.voicePath = voicePath;
self.closeTimeOut();
uni.showToast({
icon: 'loading',
title: "请稍后...",
duration: 0
});
uni.uploadFile({
url: self.upload_url,
filePath: voicePath,
name: "file",
formData: {
id: self.phoneInfo.id,
start_time: self.start_time,
end_time: self.end_time,
phone: self.phoneNumber
},
header: {
Authorization: "Bearer " + uni.getStorageSync(EnumData.token)
},
success: (res) => {
// console.log("文件上传成功")
console.log(res.data);
},
fail(err) {
console.log("文件上传失败")
console.log(err);
},
complete() {
self.start_time = 0;
self.end_time = 0;
uni.hideToast();
}
})
});
this.getCallStatus();
}
getCallStatus() {
let that = this;
let maintest = plus.android.runtimeMainActivity();
let Contexttest = plus.android.importClass("android.content.Context");
let telephonyManager = plus.android.importClass("android.telephony.TelephonyManager");
let telManager = plus.android.runtimeMainActivity().getSystemService(Contexttest.TELEPHONY_SERVICE);
let receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
onReceive: function (Contexttest, intent) {
plus.android.importClass(intent);
let phoneStatus = telManager.getCallState();
that.callStatus = phoneStatus; //电话状态 0->空闲状态 1->振铃状态 2->通话存在
switch (phoneStatus) {
case 0:
console.log("3、电话挂断,上传录音")
// 结束录音
recorderManager.stop();
break;
case 1:
// console.log('1、振铃状态');
break;
case 2:
console.log('2、通话存在')
// 延迟录音
that.start_time = Math.round(new Date().getTime() / 1000);
recorderManager.start({
duration: EnumData.audioDuration, // 时长 10分钟
sampleRate: EnumData.audioSampleRate, // 码率
});
break;
}
}
});
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
let filter = new IntentFilter();
filter.addAction(telephonyManager.ACTION_PHONE_STATE_CHANGED);
maintest.registerReceiver(receiver, filter);
},
微信支付
import Message from "@/utils/Message";
import {payParam} from "@/api/pay";
export default {
data() {
return {
provider: '',
cb: '',
orderId: '',
};
},
methods: {
async pay(params) {
uni.showLoading({ title: '支付中', mask: true });
payParam({
order_id: params.order_id, // 订单id
order_type: params.order_type // 订单类型
}).then(res=>{
if (res.code === 200){
console.log("支付订单")
console.log(res)
const provider = this.getProvider();
uni.requestPayment({
provider, // 固定参数
service: 5, // 固定值:5(拉起小程序收银台)
...res.data, // 支付信息
success: (res) => {
console.log(res)
// 用户在手机端支付成功后的页面回调 = 用户真实付了钱
},
fail: (err) => {
console.log(err)
// 用户唤起了支付,但是没有支付前直接返回
// this.orderFail();
},
});
}else{
Message.error(res.msg);
}
});
// const orderInfo = await this.$api.getOrderInfo({
// order_id: this.orderId,
// });
// this.requestPayMent(orderInfo.data);
},
async requestPayMent(orderInfo) {
const provider = await this.getProvider();
uni.requestPayment({
provider,
service: 5,
...orderInfo,
timeStamp: orderInfo.timestamp,
success: (res) => {
console.log(res);
this.orderSuccess();
},
fail: (err) => {
console.log(err);
this.orderFail();
},
});
},
getProvider() {
return new Promise((resolve, reject) => {
uni.getProvider({
service: 'payment',
success: (res) => {
console.log(res);
resolve(res.provider);
},
fail: (err) => {
console.log(err);
reject(err);
},
});
});
},
orderSuccess() {
uni.hideLoading();
uni.showToast({ title: '支付成功', mask: true });
if (this.cb) {
this.cb();
}
this.message();
setTimeout(() => {
this.$redTo('/pages/order/views/success/index', {
id: this.orderId,
});
}, 1500);
},
orderFail() {
uni.hideLoading();
uni.showToast({ title: '支付失败', icon: 'none', mask: true });
setTimeout(() => {
this.$redTo('/pages/order/views/detail/index', {
id: this.orderId,
});
}, 500);
}
},
};