Compare commits
97
Commits
7ce2ad8d8e
..
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7dbbfda16 | ||
|
|
fd78b504a6 | ||
|
|
a26fc1a4a7 | ||
|
|
5d31c3658b | ||
|
|
5f9a346960 | ||
|
|
7180e176eb | ||
|
|
e3a852cb43 | ||
|
|
0a51901807 | ||
|
|
8a879df4b4 | ||
|
|
18c7f7386d | ||
|
|
b5cc11ddd3 | ||
|
|
4a22470f38 | ||
|
|
6cdd8b90db | ||
|
|
cbc427e41c | ||
|
|
45a9478790 | ||
|
|
c6ce198c31 | ||
|
|
f4fe516224 | ||
|
|
80772749b2 | ||
|
|
0fa310e422 | ||
|
|
761a8fdaa4 | ||
|
|
ca69dfbe4b | ||
|
|
4042df6762 | ||
|
|
4e3a30b863 | ||
|
|
2831de027c | ||
|
|
08e3ba22c5 | ||
|
|
40f5ddf4a5 | ||
|
|
1fa822ed72 | ||
|
|
89848ba321 | ||
|
|
7fb1200528 | ||
|
|
b833a00d65 | ||
|
|
e8e9c84cdf | ||
|
|
1e99b3a082 | ||
|
|
efcc7d9603 | ||
|
|
54f8132cee | ||
|
|
ddbfac11c3 | ||
|
|
1de18aa228 | ||
|
|
799471090f | ||
|
|
ae9a961a42 | ||
|
|
db9ca707ae | ||
|
|
a7b2a673a9 | ||
|
|
d06ee397cf | ||
|
|
034744959f | ||
|
|
cf6df28e8c | ||
|
|
00d0ec8a9b | ||
|
|
56c645a75c | ||
|
|
8025b2abab | ||
|
|
c86aa03f01 | ||
|
|
22104881f1 | ||
|
|
f4c8df1950 | ||
|
|
1785e9309e | ||
|
|
da3659412d | ||
|
|
51367c48c9 | ||
|
|
41079458dc | ||
|
|
60531b339e | ||
|
|
9788e723a2 | ||
|
|
91726b87c5 | ||
|
|
6b37f0899d | ||
|
|
f4b1ef932d | ||
|
|
76e619b85d | ||
|
|
2cfc225b55 | ||
|
|
2cfa4bdc53 | ||
|
|
9e0a5d2512 | ||
|
|
589092ec62 | ||
|
|
1255ce8aa5 | ||
|
|
4dca51b0a3 | ||
|
|
8d9ad1ca51 | ||
|
|
e7cebcb00c | ||
|
|
dcade02e47 | ||
|
|
f7d44b9c27 | ||
|
|
d1a4f610d3 | ||
|
|
6b238c2d33 | ||
|
|
7c46a3487a | ||
|
|
38d13d33ce | ||
|
|
5d2d8cc9ff | ||
|
|
5af6f8c906 | ||
|
|
1e134f236c | ||
|
|
4816054b96 | ||
|
|
ea320f4e54 | ||
|
|
d44cd1516a | ||
|
|
2a1f4a2405 | ||
|
|
2532aa055c | ||
|
|
b16601baa6 | ||
|
|
8b1e9bcb41 | ||
|
|
dd9b2984b2 | ||
|
|
65b2d269c5 | ||
|
|
570e47698c | ||
|
|
71136a03a6 | ||
|
|
053063dc88 | ||
|
|
4703b22d25 | ||
|
|
df4d95993a | ||
|
|
36cda41b14 | ||
|
|
9e78b974a2 | ||
|
|
bdd2ba278e | ||
|
|
70eeb19867 | ||
|
|
ae08b222af | ||
|
|
b884a8f6fc | ||
|
|
215b3298d0 |
@@ -0,0 +1,12 @@
|
||||
|
||||
changed 1 package, and audited 42 packages in 5s
|
||||
|
||||
7 packages are looking for funding
|
||||
run `npm fund` for details
|
||||
|
||||
3 high severity vulnerabilities
|
||||
|
||||
Some issues need review, and may require choosing
|
||||
a different dependency.
|
||||
|
||||
Run `npm audit` for details.
|
||||
@@ -1,53 +1,264 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
import version from '@/utils/version.js'
|
||||
export default {
|
||||
globalData: {
|
||||
plAd: true,
|
||||
dotNumber: {},
|
||||
apiHost: "https://dev-app.igandan.com/app",
|
||||
//BASE_URL='https://dev-app.igandan.com/app'
|
||||
},
|
||||
onLaunch(options) {
|
||||
//uni.setStorageSync('apiHost', 'value')
|
||||
console.log("打印options");
|
||||
console.log(options);
|
||||
if (
|
||||
options &&
|
||||
options.referrerInfo.extraData &&
|
||||
options.referrerInfo.extraData.token
|
||||
) {
|
||||
uni.setStorageSync(
|
||||
"AUTH_TOKEN_App",
|
||||
options.referrerInfo.extraData.token
|
||||
);
|
||||
uni.setStorageSync("userInfo", options.referrerInfo.extraData.userInfo);
|
||||
if(process.env.UNI_PLATFORM =="mp-weixin"){
|
||||
uni.setStorageSync("app_version",version);
|
||||
}else{
|
||||
let app_version=options.referrerInfo.extraData.app_version?options.referrerInfo.extraData.app_version:version;
|
||||
uni.setStorageSync("app_version",app_version);
|
||||
};
|
||||
|
||||
//getApp({allowDefault: true}).globalData.apiHost = options.referrerInfo.extraData.apiHost;
|
||||
}
|
||||
if (
|
||||
options &&
|
||||
options.referrerInfo.extraData &&
|
||||
options.referrerInfo.extraData.targetPath
|
||||
) {
|
||||
let src=options.referrerInfo.extraData.targetPath
|
||||
|
||||
if(src.indexOf('downLoadVideo') > -1 ){
|
||||
uni.navigateTo({
|
||||
url: src+'?from=mine',
|
||||
});
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url: src,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log("app传递登录信息onLaunch-------------------");
|
||||
try {
|
||||
// #ifdef APP
|
||||
uni.onNativeEventReceive((event, data) => {
|
||||
console.log("event", event);
|
||||
console.log("data", data);
|
||||
if (event.indexOf("clearToken") > -1) {
|
||||
uni.setStorageSync("AUTH_TOKEN_App", "");
|
||||
plus.runtime.quit();
|
||||
}
|
||||
if(event.indexOf("goPage") > -1){
|
||||
if(data.indexOf('downLoadVideo') > -1){
|
||||
uni.navigateTo({
|
||||
url: data+'?from=mine'
|
||||
});
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
if(event.indexOf('paySuccess') > -1){
|
||||
console.log('app.vue监听到成功支付');
|
||||
if(data.type=='GandanFile'){
|
||||
uni.$emit('paySuccess',{
|
||||
type:'GandanFile',
|
||||
});
|
||||
}else if(data.type=='BuyPoint'){
|
||||
uni.navigateBack();
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
} catch (error) {
|
||||
console.log("app传递登录信息error-------------------");
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
try {
|
||||
// #ifdef APP
|
||||
let checkTokenCallBackFlag = false;
|
||||
console.log("执行onshow");
|
||||
|
||||
uni.sendNativeEvent(
|
||||
"checkToken",
|
||||
{
|
||||
msg: "checkToken",
|
||||
},
|
||||
(ret) => {
|
||||
checkTokenCallBackFlag = true;
|
||||
console.log("check回调");
|
||||
console.log(ret);
|
||||
if (ret.code == 0) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
showCancel: false,
|
||||
content: "您已退出登录!",
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
uni.sendNativeEvent(
|
||||
"goTabbarPage",
|
||||
{
|
||||
msg: "home",
|
||||
},
|
||||
(ret) => {
|
||||
console.log(ret);
|
||||
}
|
||||
);
|
||||
plus.runtime.quit();
|
||||
} else if (res.cancel) {
|
||||
console.log("用户点击取消");
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// setTimeout(function(){
|
||||
// console.log("执行 setTimeout")
|
||||
// if(!checkTokenCallBackFlag){
|
||||
// uni.showModal({
|
||||
// title: '提示',
|
||||
// showCancel: false,
|
||||
// content: '您已退出登录',
|
||||
// success: function (res) {
|
||||
// if (res.confirm) {
|
||||
// uni.sendNativeEvent('goTabbarPage', {
|
||||
// msg: 'home'
|
||||
// }, ret => {
|
||||
// console.log(ret);
|
||||
// })
|
||||
// } else if (res.cancel) {
|
||||
// console.log('用户点击取消');
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }, 1000)
|
||||
|
||||
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
//为了防止快速点按返回键导致程序退出重写quit方法改为隐藏至后台
|
||||
plus.runtime.quit = function () {
|
||||
main.moveTaskToBack(false);
|
||||
};
|
||||
//重写toast方法如果内容为 ‘再按一次退出应用’ 就隐藏应用,其他正常toast
|
||||
plus.nativeUI.toast = function (str) {
|
||||
if (str == "再按一次退出应用") {
|
||||
main.moveTaskToBack(false);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: str,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// uni.onNativeEventReceive((event, data) => {
|
||||
// console.log("app传递登录信息onshow-------------------");
|
||||
// console.log("event", event);
|
||||
// console.log("data", data);
|
||||
// if (event == "loginInfo") {
|
||||
// uni.setStorageSync("DEV_AUTH_YX_TOKEN_App", data.token);
|
||||
// uni.setStorageSync("userInfo", data.userInfo);
|
||||
// }else if(event == "showRedDot"){
|
||||
// console.log("showRedDot");
|
||||
// console.log(data);
|
||||
// getApp().globalData.dotNumber=data;
|
||||
// }
|
||||
// });
|
||||
// #endif
|
||||
} catch (error) {
|
||||
console.log("error");
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
onHide() {},
|
||||
methods: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
/*每个页面公共css */
|
||||
@import '@/uni_modules/uni-scss/index.scss';
|
||||
/* #ifndef APP-NVUE */
|
||||
@import '@/static/customicons.css';
|
||||
// 设置整个项目的背景色
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
<template>
|
||||
<GlobalDialog />
|
||||
</template>
|
||||
|
||||
/* #endif */
|
||||
.uni-nav-bar-text{
|
||||
font-weight: bold;
|
||||
font-size: 34rpx!important;
|
||||
}
|
||||
.example-info {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
padding: 10px;
|
||||
}
|
||||
.twoline{
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oneline{
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.uni-navbar .uniui-left{
|
||||
font-weight: bold;
|
||||
font-size: 50rpx!important;
|
||||
}
|
||||
::-webkit-scrollbar { display: none; }
|
||||
</style>
|
||||
<style lang="scss">
|
||||
/*每个页面公共css */
|
||||
@import "@/uni_modules/uni-scss/index.scss";
|
||||
/* #ifndef APP-NVUE */
|
||||
@import "@/static/customicons.css";
|
||||
|
||||
// 设置整个项目的背景色
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.uni-navbar__header-btns-right {
|
||||
min-width: 120rpx;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.uni-nav-bar-text {
|
||||
|
||||
font-size: 40rpx !important;
|
||||
}
|
||||
|
||||
.example-info {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.twoline {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oneline {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.uni-navbar .uniui-left {
|
||||
font-weight: bold;
|
||||
font-size: 50rpx !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.status_bar {
|
||||
height: var(--status-bar-height);
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.navbox {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: calc(var(--status-bar-height) + 44px);
|
||||
z-index: 9999;
|
||||
}
|
||||
.share-content .share-item:last-child{
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"prompt" : "none"
|
||||
}
|
||||
+294
-2
@@ -1,4 +1,5 @@
|
||||
import {request} from '@/utils/request.js'
|
||||
|
||||
const api = {
|
||||
|
||||
expertWxLogin(jscode){
|
||||
@@ -119,11 +120,11 @@ const api = {
|
||||
},
|
||||
// 积分支付列表
|
||||
bonusPointsPayList(data) {
|
||||
return request('/expertAPI/bonusPointsPayList', data, 'post', false);
|
||||
return request('/expertAPI/bonusPointsPayList', data, 'post', true);
|
||||
},
|
||||
// 积分列表
|
||||
bonusPointsList(data) {
|
||||
return request('/expertAPI/bonusPointsList', data, 'post', false);
|
||||
return request('/expertAPI/bonusPointsList', data, 'post', true);
|
||||
},
|
||||
|
||||
getWelfarePage(data) {
|
||||
@@ -335,6 +336,9 @@ const api = {
|
||||
applyList(data){
|
||||
return request('/expertAPI/applyList', data, 'post', false);
|
||||
},
|
||||
patientListByGBKPage(data){
|
||||
return request('/expertAPI/patientListByGBKPage', data, 'post', false);
|
||||
},
|
||||
patientListByGBK(data){
|
||||
return request('/expertAPI/patientListByGBK', data, 'post', false);
|
||||
},
|
||||
@@ -411,6 +415,10 @@ const api = {
|
||||
bankCardList(data){
|
||||
return request('/expertPay/bankCardList', data, 'post', false);
|
||||
},
|
||||
|
||||
deleteBankCard(data){
|
||||
return request('/expertPay/deleteBankCard', data, 'post', false);
|
||||
},
|
||||
getIncomeTax(data){
|
||||
return request('/expertPay/getIncomeTax', data, 'post', false);
|
||||
},
|
||||
@@ -439,6 +447,290 @@ const api = {
|
||||
getOfficeList(data){
|
||||
return request('/expertAPI/officeList', data, 'post', false);
|
||||
},
|
||||
newConsultList(data){
|
||||
return request('/expertAPI/newConsultList', data, 'post', false);
|
||||
},
|
||||
consultListHis(data){
|
||||
return request('/expertAPI/consultListHis', data, 'post', false);
|
||||
},
|
||||
listNewInterrogation(data){
|
||||
return request('/expertAPI/listNewInterrogation', data, 'post', true);
|
||||
},
|
||||
listMyAnsweredInterrogation(data){
|
||||
return request('/expertAPI/listMyAnsweredInterrogation', data, 'post', true);
|
||||
},
|
||||
getInterrogation(data){
|
||||
return request('/expertAPI/getInterrogation', data, 'post', false);
|
||||
},
|
||||
interrogationPatientInfo(data){
|
||||
return request('/expertAPI/InterrogationPatientInfo', data, 'post', false);
|
||||
},
|
||||
updateInterrogationAnswer(data){
|
||||
return request('/expertAPI/updateInterrogationAnswerU', data, 'post', true);
|
||||
},
|
||||
addInterrogationAnswer(data){
|
||||
return request('/expertAPI/addInterrogationAnswerU', data, 'post', true);
|
||||
},
|
||||
videoDetail(data){
|
||||
return request('/expertAPI/videoDetail', data, 'post', false);
|
||||
},
|
||||
addVideoWatchRecord(data){
|
||||
return request('/expertAPI/addVideoWatchRecord', data, 'post', false);
|
||||
},
|
||||
videoCommentListV2(data){
|
||||
return request('/expertAPI/videoCommentListV2', data, 'post', false);
|
||||
},
|
||||
isVideoDownloadRecord(data){
|
||||
return request('/expertAPI/isVideoDownloadRecord', data, 'post', false);
|
||||
},
|
||||
getWelfareNum(data){
|
||||
return request('/expertAPI/getWelfareNum', data, 'post', false);
|
||||
},
|
||||
payVideoDownload(data){
|
||||
return request('/expertAPI/payVideoDownload', data, 'post', false);
|
||||
},
|
||||
addCommentV2(data){
|
||||
return request('/expertAPI/addCommentV2', data, 'post', false);
|
||||
},
|
||||
collection(data){
|
||||
return request('/expertAPI/collection', data, 'post', false);
|
||||
},
|
||||
discollection(data){
|
||||
return request('/expertAPI/discollection', data, 'post', false);
|
||||
},
|
||||
meetingV2Video(data){
|
||||
return request('/expertAPI/meetingV2Video', data, 'post', false);
|
||||
},
|
||||
listGroupSendMsg(data){
|
||||
return request('/expertAPI/listGroupSendMsg', data, 'post', false);
|
||||
},
|
||||
addGroupSendMsg4YunXin(data){
|
||||
return request('/expertAPI/addGroupSendMsg4YunXin', data, 'post', false);
|
||||
},
|
||||
quickReplyList(data){
|
||||
return request('/expertAPI/QuickReplyList', data, 'post', false);
|
||||
},
|
||||
addQuickReply(data){
|
||||
return request('/expertAPI/addQuickReply', data, 'post', false);
|
||||
},
|
||||
deleteQuickReply(data){
|
||||
return request('/expertAPI/deleteQuickReply', data, 'post', false);
|
||||
},
|
||||
listOutPatient(data){
|
||||
return request('/expertAPI/listOutPatient', data, 'post', false);
|
||||
},
|
||||
stopOutPatientList(data){
|
||||
return request('/expertAPI/stopOutPatientList', data, 'post', false);
|
||||
},
|
||||
listWorkPlace(data){
|
||||
return request('/expertAPI/listWorkPlace', data, 'post', false);
|
||||
},
|
||||
addOutPatient(data){
|
||||
return request('/expertAPI/addOutPatient', data, 'post', false);
|
||||
},
|
||||
updateOutPatient(data){
|
||||
return request('/expertAPI/updateOutPatientA', data, 'post', false);
|
||||
},
|
||||
deleteOutPatient(data){
|
||||
return request('/expertAPI/deleteOutPatient', data, 'post', false);
|
||||
},
|
||||
addWorkPlace(data){
|
||||
return request('/expertAPI/addWorkPlace', data, 'post', false);
|
||||
},
|
||||
updateWorkPlace(data){
|
||||
return request('/expertAPI/editWorkPlace', data, 'post', false);
|
||||
},
|
||||
deleteWorkPlace(data){
|
||||
return request('/expertAPI/deleteWorkPlace', data, 'post', false);
|
||||
},
|
||||
hospitalList(data){
|
||||
return request('/expertAPI/hospitalList', data, 'post', false);
|
||||
},
|
||||
addStopPatient(data){
|
||||
return request('/expertAPI/addStopOutPatient', data, 'post', false);
|
||||
},
|
||||
deleteStopPatient(data){
|
||||
return request('/expertAPI/deleteStopOutPatient', data, 'post', false);
|
||||
},
|
||||
addOutPatientA(data){
|
||||
return request('/expertAPI/addOutPatientA', data, 'post', false);
|
||||
},
|
||||
delGroupSendMsg(data){
|
||||
return request('/expertAPI/delGroupSendMsg', data, 'post', false);
|
||||
},
|
||||
patientDetail(data){
|
||||
return request('/expertAPI/patientDetail', data, 'post', false);
|
||||
},
|
||||
toAddNickname(data){
|
||||
return request('/expertAPI/toAddNickname', data, 'post', false);
|
||||
},
|
||||
caseDetail(data){
|
||||
return request('/expertAPI/caseDetail', data, 'post', false);
|
||||
},
|
||||
conditionRecordList(data){
|
||||
return request('/expertAPI/conditionRecordList', data, 'post', false);
|
||||
},
|
||||
addConditionRecord(data){
|
||||
return request('/expertAPI/addConditionRecord', data, 'post', false);
|
||||
},
|
||||
updateConditionRecord(data){
|
||||
return request('/expertAPI/upConditionRecord', data, 'post', false);
|
||||
},
|
||||
deleteConditionRecord(data){
|
||||
return request('/expertAPI/delConditionRecord', data, 'post', false);
|
||||
},
|
||||
consultDetail(data){
|
||||
return request('/expertAPI/consultDetail', data, 'post', false);
|
||||
},
|
||||
isConsultIng(data){
|
||||
return request('/expertAPI/isConsultIng', data, 'post', false);
|
||||
},
|
||||
resConsult(data){
|
||||
return request('/expertAPI/resConsult', data, 'post', false);
|
||||
},
|
||||
countConsult(data){
|
||||
return request('/expertAPI/countConsult', data, 'post', false);
|
||||
},
|
||||
closeConsult(data){
|
||||
return request('/expertAPI/closeConsult', data, 'post', false);
|
||||
},
|
||||
checkUser(data){
|
||||
return request('/expertAPI/checkUser', data, 'post', false);
|
||||
},
|
||||
ganDanFileDetials(data){
|
||||
return request('/expertAPI/ganDanFileDetials', data, 'post', false);
|
||||
},
|
||||
createGanDanFileOrder(data){
|
||||
return request('/expertPay/createGanDanFileOrder', data, 'post', false);
|
||||
},
|
||||
getOrderStatus(data){
|
||||
return request('/expertPay/getOrderStatus', data, 'post', false);
|
||||
},
|
||||
|
||||
getOrderStatus(data){
|
||||
return request('/expertPay/getOrderStatus', data, 'post', false);
|
||||
},
|
||||
getBalance(data){
|
||||
return request('/expertPay/getBalance', data, 'post', false);
|
||||
},
|
||||
payGanDanFile(data){
|
||||
return request('/expertPay/payGanDanFileOrder', data, 'post', false);
|
||||
},
|
||||
// discollection(data){
|
||||
// return request('/expert/discollection', data, 'post', false);
|
||||
// },
|
||||
// collection(data){
|
||||
// return request('/expert/collection', data, 'post', false);
|
||||
// },
|
||||
getTypeUuidByName(data){
|
||||
return request('/expertAPI/getTypeUuidByName', data, 'post', false);
|
||||
},
|
||||
videoByTypeNew(data){
|
||||
return request('/expertAPI/videoByTypeNew', data, 'post', false);
|
||||
},
|
||||
meetingHistoryList(data){
|
||||
return request('/expertAPI/meetingHistoryList', data, 'post', false);
|
||||
},
|
||||
|
||||
// 扫码登录相关API
|
||||
// 确认扫码登录
|
||||
confirmScanLogin(data){
|
||||
return request('/expertAPI/confirmScanLogin', data, 'post', false);
|
||||
},
|
||||
|
||||
// 取消扫码登录
|
||||
cancelScanLogin(data){
|
||||
return request('/expertAPI/cancelScanLogin', data, 'post', false);
|
||||
},
|
||||
|
||||
// 获取扫码登录状态
|
||||
getScanLoginStatus(data){
|
||||
return request('/expertAPI/getScanLoginStatus', data, 'post', false);
|
||||
},
|
||||
gethonorDetail(data){
|
||||
return request('/expertAPI/gethonorDetail', data, 'post', false);
|
||||
},
|
||||
checkVersion(data){
|
||||
return request('/expertAPI/checkVersion', data, 'post', false);
|
||||
},
|
||||
getIsAccount(data){
|
||||
return request('/expertAPI/getIsAccount', data, 'post', false);
|
||||
},
|
||||
patientVideoByJingHuaNew(data){
|
||||
return request('/expertAPI/patientVideoByJingHuaNew', data, 'post', false);
|
||||
},
|
||||
useWelfareNum(data){
|
||||
return request('/expertAPI/useWelfareNum', data, 'post', false);
|
||||
},
|
||||
deleteComment(data){
|
||||
return request('/expertAPI/deleteComment', data, 'post', false);
|
||||
},
|
||||
downloadGanDanFile(data){
|
||||
return request('/expertAPI/downloadGanDanFile', data, 'post', false,'application/json',{},'arraybuffer');
|
||||
},
|
||||
downloadGanDanFileV2(data){
|
||||
return request('/expertAPI/downloadGanDanFileV2', data, 'post', false);
|
||||
},
|
||||
feedBack(data){
|
||||
return request('/expertAPI/addFeedBack', data, 'post', false);
|
||||
},
|
||||
getPointUnitPrice(data){
|
||||
return request('/expertAPI/getPointUnitPrice', data, 'post', false);
|
||||
},
|
||||
welfareList(data){
|
||||
return request('/expertAPI/welfareList', data, 'post', false);
|
||||
},
|
||||
|
||||
getUGoods(data){
|
||||
return request('/expertAPI/getGoodsDetailU', data, 'post', false);
|
||||
},
|
||||
createGoodsOrder(data){
|
||||
return request('/expertAPI/createGoodsOrder', data, 'post', false);
|
||||
},
|
||||
useWelfareNum(data){
|
||||
return request('/expertAPI/useWelfareNum', data, 'post', false);
|
||||
},
|
||||
createBointsOrder(data){
|
||||
return request('/expertPay/createBointsOrder', data, 'post', false);
|
||||
},
|
||||
receiveWelfare(data){
|
||||
return request('/expertAPI/receiveWelfare', data, 'post', false);
|
||||
},
|
||||
getKePuCollection(data){
|
||||
return request('/expertAPI/getKePuCollection', data, 'post', false);
|
||||
},
|
||||
getRead(data){
|
||||
return request('/expertAPI/read', data, 'post', false);
|
||||
},
|
||||
getOutRead(data){
|
||||
return request('/expertAPI/outread', data, 'post', false);
|
||||
},
|
||||
getAgree(data){
|
||||
return request('/expertAPI/agree', data, 'post', false);
|
||||
},
|
||||
getDisagree(data){
|
||||
return request('/expertAPI/disagree', data, 'post', false);
|
||||
},
|
||||
getCollect(data){
|
||||
return request('/expertAPI/collection', data, 'post', false);
|
||||
},
|
||||
getDiscollect(data){
|
||||
return request('/expertAPI/discollection', data, 'post', false);
|
||||
},
|
||||
getGanDanFileOrder(data){
|
||||
return request('/expertPay/getGanDanFileOrder', data, 'post', false);
|
||||
},
|
||||
publishOutPatient(data){
|
||||
return request('/expertAPI/addGroupSendMsg4YunXin', data, 'post', false);
|
||||
},
|
||||
polularScienceArticleListIndexNew(data){
|
||||
return request('/expertAPI/polularScienceArticleListIndexNew', data, 'post', false);
|
||||
},
|
||||
getNewsDetail(data){
|
||||
return request('/expertAPI/newsDetial', data, 'post', false);
|
||||
},
|
||||
|
||||
//https://dev-app.igandan.com/app/expertPay/getGanDanFileOrder
|
||||
|
||||
}
|
||||
|
||||
|
||||
+16
-2
@@ -23,11 +23,25 @@ const goods_api = {
|
||||
createGoodsOrder(data) {
|
||||
return request('/expertAPI/createGoodsOrder', data, 'post', true);
|
||||
},
|
||||
|
||||
payGoodsOrder(data) {
|
||||
return request('/expertAPI/payGoodsOrder', data, 'post', true);
|
||||
},
|
||||
getGoodsOrderList(data) {
|
||||
return request('/expertAPI/goodsOrderList', data, 'post', true);
|
||||
},
|
||||
getUpanWelfareCount(data){
|
||||
return request('/expertAPI/getUpanWelfareCount', data, 'post', false);
|
||||
},
|
||||
getGoodsOrderDetail(data) {
|
||||
return request('/expertAPI/getGoodsOrder', data, 'post', true);
|
||||
},
|
||||
getOrderTrack(data) {
|
||||
return request('/expertAPI/getOrderTrack', data, 'post', true);
|
||||
},
|
||||
cancelGoodsOrder(data) {
|
||||
return request('/expertAPI/cancleGoodsOrder', data, 'post', true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default goods_api;
|
||||
@@ -0,0 +1,31 @@
|
||||
import {request} from '@/utils/request.js'
|
||||
const my_api = {
|
||||
isBoundWechat() {
|
||||
return request('/expertAPI/isBoundWechatByUuid', {}, 'post', true);
|
||||
},
|
||||
|
||||
unBindWechat(data) {
|
||||
return request('/expertAPI/delWechatExpert', data, 'post', true);
|
||||
},
|
||||
|
||||
bindWechat(data) {
|
||||
return request('/expertAPI/addWechatExpert', data, 'post', true);
|
||||
},
|
||||
|
||||
expertWxLogin(data,header) {
|
||||
return request('/expertAPI/wechatLogin', data, 'post', true,'application/json',header);
|
||||
},
|
||||
|
||||
checkVersion(data) {
|
||||
return request('/expertAPI/checkVersion', data, 'post', true);
|
||||
},
|
||||
|
||||
startpage() {
|
||||
return request('/expertAPI/startpage', {}, 'post', true);
|
||||
},
|
||||
addUniappCid(data) {
|
||||
return request('/expertAPI/addUniappCid', data, 'post', true);
|
||||
}
|
||||
}
|
||||
|
||||
export default my_api;
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<span
|
||||
class="appellation"
|
||||
:style="{ color: color, fontSize: fontSize + 'px' }"
|
||||
>{{ appellation }}</span
|
||||
>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { autorun } from 'mobx'
|
||||
import { onUnmounted, ref, withDefaults } from 'vue'
|
||||
|
||||
const appellation = ref('')
|
||||
|
||||
const { account, teamId, ignoreAlias, nickFromMsg } = withDefaults(
|
||||
defineProps<{
|
||||
account: string
|
||||
teamId?: string
|
||||
ignoreAlias?: boolean
|
||||
nickFromMsg?: string
|
||||
color?: string
|
||||
fontSize?: number
|
||||
}>(),
|
||||
{
|
||||
teamId: undefined,
|
||||
ignoreAlias: false,
|
||||
nickFromMsg: undefined,
|
||||
color: '#333',
|
||||
fontSize: 16,
|
||||
}
|
||||
)
|
||||
|
||||
const uninstallAppellationWatch = autorun(() => {
|
||||
appellation.value = uni.$UIKitStore.uiStore.getAppellation({
|
||||
account,
|
||||
teamId,
|
||||
ignoreAlias,
|
||||
nickFromMsg,
|
||||
})
|
||||
})
|
||||
onUnmounted(() => {
|
||||
uninstallAppellationWatch()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.appellation {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div
|
||||
class="avatar"
|
||||
:style="{ width: avatarSize + 'px', height: avatarSize + 'px' }"
|
||||
@click="handleAvatarClick"
|
||||
@longpress="longpress"
|
||||
@touchend="touchend"
|
||||
>
|
||||
|
||||
<!-- 使用遮罩层避免android长按头像会出现保存图片的弹窗 -->
|
||||
<div class="img-mask"></div>
|
||||
<image
|
||||
:lazy-load="true"
|
||||
class="avatar-img"
|
||||
v-if="avatarUrl"
|
||||
:src="docUrl+avatarUrl.replace('null','')"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<image
|
||||
:lazy-load="true"
|
||||
class="avatar-img"
|
||||
v-else-if="userInfo.uuid && account==userInfo.uuid.toLowerCase()"
|
||||
:src="docUrl+userInfo.photo"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<div class="avatar-name-wrapper" :style="{ backgroundColor: color }">
|
||||
<div class="avatar-name-text" :style="{ fontSize: fontSize + 'px' }">
|
||||
{{ appellation }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { customNavigateTo, customRedirectTo } from '@/utils/im/customNavigate'
|
||||
import { autorun } from 'mobx'
|
||||
import { ref, computed, onUnmounted, withDefaults } from 'vue'
|
||||
import docUrl from "@/utils/docUrl"
|
||||
import { onShow,onLoad,onReady } from "@dcloudio/uni-app";
|
||||
import { V2NIMUser } from 'nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK/V2NIMUserService'
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
account: string
|
||||
teamId?: string
|
||||
avatar?: string
|
||||
size?: string
|
||||
gotoUserCard?: boolean
|
||||
fontSize?: string
|
||||
isRedirect?: boolean
|
||||
}>(),
|
||||
{
|
||||
teamId: '',
|
||||
avatar: '',
|
||||
size: '',
|
||||
gotoUserCard: false,
|
||||
fontSize: '',
|
||||
isRedirect: false,
|
||||
}
|
||||
)
|
||||
const userInfo=ref({
|
||||
uuid:''
|
||||
})
|
||||
const $emit = defineEmits(['onLongpress'])
|
||||
|
||||
const avatarSize = props.size || 42
|
||||
const user = ref<V2NIMUser>()
|
||||
let isLongPress = false // uniapp 长按事件也会触发点击事件,此时需要处理
|
||||
|
||||
const appellation = ref<string>('')
|
||||
|
||||
const appellationWatch = autorun(() => {
|
||||
appellation.value = uni.$UIKitStore.uiStore
|
||||
.getAppellation({
|
||||
account: props.account,
|
||||
ignoreAlias: false,
|
||||
})
|
||||
?.slice(0, 2)
|
||||
})
|
||||
|
||||
const userInfoWatch = autorun(() => {
|
||||
uni.$UIKitStore?.userStore?.getUserActive(props.account).then((data) => {
|
||||
user.value = data
|
||||
})
|
||||
})
|
||||
|
||||
const avatarUrl = computed(() => {
|
||||
user.value = uni.$UIKitStore?.userStore?.users?.get(props.account)
|
||||
return props.avatar || user.value?.avatar
|
||||
})
|
||||
|
||||
const key = `__yx_avatar_color_${props.account}__`
|
||||
let color = uni.getStorageSync(key)
|
||||
if (!color) {
|
||||
const colorMap: { [key: number]: string } = {
|
||||
0: '#60CFA7',
|
||||
1: '#53C3F3',
|
||||
2: '#537FF4',
|
||||
3: '#854FE2',
|
||||
4: '#BE65D9',
|
||||
5: '#E9749D',
|
||||
6: '#F9B751',
|
||||
}
|
||||
const _color = colorMap[Math.floor(Math.random() * 7)]
|
||||
uni.setStorageSync(key, _color)
|
||||
color = _color
|
||||
}
|
||||
|
||||
const handleAvatarClick = () => {
|
||||
if (props.gotoUserCard && !isLongPress) {
|
||||
if (props.isRedirect) {
|
||||
if (props.account === uni.$UIKitStore?.userStore?.myUserInfo.accountId) {
|
||||
customRedirectTo({
|
||||
url: `/pages/User/my-detail/index`,
|
||||
})
|
||||
} else {
|
||||
customRedirectTo({
|
||||
url: `/pages/User/friend/index?account=${props.account}`,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (props.account === uni.$UIKitStore?.userStore?.myUserInfo.accountId) {
|
||||
customNavigateTo({
|
||||
url: `/pages/User/my-detail/index`,
|
||||
})
|
||||
} else {
|
||||
customNavigateTo({
|
||||
url: `/pages/User/friend/index?account=${props.account}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const longpress = () => {
|
||||
isLongPress = true
|
||||
$emit('onLongpress')
|
||||
}
|
||||
|
||||
const touchend = () => {
|
||||
const timeOut = setTimeout(() => {
|
||||
isLongPress = false
|
||||
clearTimeout(timeOut)
|
||||
}, 200)
|
||||
}
|
||||
onShow(()=>{
|
||||
userInfo.value=uni.getStorageSync('userInfo');
|
||||
})
|
||||
onReady(()=>{
|
||||
userInfo.value=uni.getStorageSync('userInfo');
|
||||
})
|
||||
onUnmounted(() => {
|
||||
userInfoWatch()
|
||||
appellationWatch()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.avatar {
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.img-mask {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-name-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.avatar-name-text {
|
||||
color: #fff;
|
||||
size: 14px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="dot" v-if="dot" :style="customStyle"></div>
|
||||
<div class="badge" v-else-if="text" :style="customStyle">{{ text }}</div>
|
||||
<div class="hidden">{{ props.num }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { StyleValue, computed, withDefaults } from 'vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
num: number
|
||||
max?: number
|
||||
dot?: boolean
|
||||
customStyle?: StyleValue
|
||||
}>(),
|
||||
{
|
||||
max: 99,
|
||||
dot: false,
|
||||
}
|
||||
)
|
||||
const max = props.max || 99
|
||||
const text = computed(() => {
|
||||
return props.num > 0 ? (props.num > max ? `${max}+` : props.num + '') : ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dot {
|
||||
background-color: #ff4d4f;
|
||||
color: #fff;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.badge {
|
||||
background-color: #ff4d4f;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
line-height: 19px;
|
||||
border-radius: 10px;
|
||||
padding: 0 5px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
z-index: 99;
|
||||
position: relative;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="empty-wrapper">
|
||||
<image
|
||||
class="empty-img"
|
||||
src="https://yx-web-nosdn.netease.im/common/e0f58096f06c18cdd101f2614e6afb09/empty.png"
|
||||
/>
|
||||
<div class="empty-text">{{ text }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
text?: string
|
||||
}>(),
|
||||
{
|
||||
text: '',
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.empty-wrapper {
|
||||
margin: 75px 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.empty-img {
|
||||
display: block;
|
||||
width: 125px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
display: block;
|
||||
color: #a6adb6;
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div>
|
||||
<div :class="inputClass">
|
||||
<slot name="addonBefore" />
|
||||
<input
|
||||
class="input"
|
||||
:type="type"
|
||||
:value="inputValue"
|
||||
@input="handleInput"
|
||||
:focus="inputFocus"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="maxlength"
|
||||
/>
|
||||
<div class="clear-icon" @tap="clearInput()">
|
||||
<icon v-show="modelValue && allowClear" type="clear" size="16" />
|
||||
</div>
|
||||
<slot name="addonAfter" />
|
||||
</div>
|
||||
|
||||
<div v-if="inputError && rule" class="error-tips">{{ rule.message }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
const $emit = defineEmits([
|
||||
'update:modelValue',
|
||||
'input',
|
||||
'focus',
|
||||
'blur',
|
||||
'clear',
|
||||
])
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
className?: string
|
||||
type?: string
|
||||
modelValue?: string
|
||||
placeholder?: string
|
||||
allowClear?: boolean
|
||||
rule?: any
|
||||
maxlength?: number
|
||||
}>(),
|
||||
{
|
||||
className: '',
|
||||
type: 'text',
|
||||
modelValue: '',
|
||||
placeholder: '',
|
||||
allowClear: false,
|
||||
rule: null,
|
||||
maxlength: 140,
|
||||
}
|
||||
)
|
||||
|
||||
const inputFocus = ref(false)
|
||||
const inputError = ref(false)
|
||||
// const inputKey = ref(0);
|
||||
|
||||
const inputClass = computed(() => {
|
||||
return [
|
||||
props.className,
|
||||
'form-input-item',
|
||||
{ focus: inputFocus.value, error: inputError.value },
|
||||
]
|
||||
})
|
||||
|
||||
const inputValue = computed(() => {
|
||||
return props.modelValue || ''
|
||||
})
|
||||
|
||||
const handleBlur = (event: any) => {
|
||||
inputFocus.value = false
|
||||
if (props.rule && props.rule.trigger === 'blur') {
|
||||
inputError.value = !props.rule.reg.test(props.modelValue || '')
|
||||
}
|
||||
$emit('blur', event)
|
||||
}
|
||||
|
||||
const handleFocus = (event: any) => {
|
||||
inputFocus.value = true
|
||||
$emit('blur', event)
|
||||
}
|
||||
|
||||
const handleInput = (event: any) => {
|
||||
if (!(props.maxlength && event.detail.value.length > props.maxlength)) {
|
||||
$emit('update:modelValue', event.detail.value)
|
||||
$emit('input', event.detail.value)
|
||||
}
|
||||
// 强制刷新input
|
||||
// inputKey.value++;
|
||||
}
|
||||
|
||||
const clearInput = () => {
|
||||
$emit('update:modelValue', null)
|
||||
$emit('input', null)
|
||||
$emit('clear', '')
|
||||
|
||||
inputFocus.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$primary-color: #337eff;
|
||||
$error-color: #f56c6c;
|
||||
|
||||
.form-input-item {
|
||||
border-bottom: 1px solid #dcdfe5;
|
||||
padding: 10px 10px 5px 0px;
|
||||
display: flex;
|
||||
height: 44px;
|
||||
align-items: center;
|
||||
|
||||
&.focus {
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: $error-color;
|
||||
}
|
||||
}
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
height: 30px;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
.clear-icon {
|
||||
width: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.error-tips {
|
||||
color: $error-color;
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<view v-show="visible" class="gd-mask" :class="alignClass" :style="maskStyle">
|
||||
<view
|
||||
class="gd-dialog"
|
||||
@touchstart="onTouchStart"
|
||||
@touchmove="onTouchMove"
|
||||
@touchend="onTouchEnd"
|
||||
>
|
||||
<view class="gd-title">{{ title }}</view>
|
||||
<scroll-view class="gd-content" scroll-y>
|
||||
<text class="gd-text">{{ content }}</text>
|
||||
</scroll-view>
|
||||
<!-- <view class="gd-footer">
|
||||
<view class="gd-btn gd-confirm" @click="handleConfirm">{{ confirmText }}</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
|
||||
|
||||
const visible = ref(false)
|
||||
const title = ref('消息通知')
|
||||
const content = ref('')
|
||||
const confirmText = ref('我知道了')
|
||||
const position = ref('center') // 'center' | 'top'
|
||||
const offsetTop = ref('20rpx')
|
||||
const autoHideTimer = ref(null)
|
||||
|
||||
const startY = ref(0)
|
||||
const hasSwipedUp = ref(false)
|
||||
|
||||
const emit = defineEmits(['confirm'])
|
||||
|
||||
function handleConfirm(){
|
||||
visible.value = false
|
||||
emit('confirm')
|
||||
}
|
||||
|
||||
function show(payload = {}){
|
||||
title.value = payload.title || '消息通知'
|
||||
content.value = payload.content || ''
|
||||
confirmText.value = payload.confirmText || '我知道了'
|
||||
position.value = payload.position === 'top' ? 'top' : 'center'
|
||||
offsetTop.value = payload.offsetTop || '20rpx'
|
||||
visible.value = true
|
||||
// 自动 5 秒后消失
|
||||
if (autoHideTimer.value) clearTimeout(autoHideTimer.value)
|
||||
autoHideTimer.value = setTimeout(() => {
|
||||
hide()
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
function hide(){
|
||||
visible.value = false
|
||||
if (autoHideTimer.value) {
|
||||
clearTimeout(autoHideTimer.value)
|
||||
autoHideTimer.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchStart(e){
|
||||
const touch = e.changedTouches ? e.changedTouches[0] : (e.touches ? e.touches[0] : null)
|
||||
if (!touch) return
|
||||
startY.value = touch.clientY || touch.pageY || 0
|
||||
hasSwipedUp.value = false
|
||||
}
|
||||
|
||||
function onTouchMove(e){
|
||||
const touch = e.changedTouches ? e.changedTouches[0] : (e.touches ? e.touches[0] : null)
|
||||
if (!touch) return
|
||||
const currentY = touch.clientY || touch.pageY || 0
|
||||
const deltaY = currentY - startY.value
|
||||
if (deltaY < -60) {
|
||||
hasSwipedUp.value = true
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchEnd(){
|
||||
if (hasSwipedUp.value) {
|
||||
hide()
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log('[GlobalDialog] mounted')
|
||||
uni.$on('global-dialog:show', show)
|
||||
uni.$on('global-dialog:hide', hide)
|
||||
// 便于全局手动触发测试
|
||||
// @ts-ignore
|
||||
uni.$showGlobalDialog = (payload = {}) => {
|
||||
console.log('[GlobalDialog] uni.$showGlobalDialog called', payload)
|
||||
uni.$emit('global-dialog:show', payload)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
uni.$off('global-dialog:show', show)
|
||||
uni.$off('global-dialog:hide', hide)
|
||||
})
|
||||
|
||||
const alignClass = computed(() => position.value === 'top' ? 'is-top' : 'is-center')
|
||||
const maskStyle = computed(() => position.value === 'top' ? { paddingTop: offsetTop.value } : {})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gd-mask{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// 非模态:容器不截获事件
|
||||
pointer-events: none;
|
||||
}
|
||||
.gd-mask.is-top{
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
.gd-dialog{
|
||||
width: 600rpx;
|
||||
max-width: 90%;
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
// 允许对话框自己接收事件(容器为非模态)
|
||||
pointer-events: auto;
|
||||
// 轻微上滑消失的过渡体验
|
||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
.gd-title{
|
||||
padding: 28rpx 32rpx 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #111;
|
||||
text-align: left;
|
||||
}
|
||||
.gd-content{
|
||||
max-height: 420rpx;
|
||||
padding: 0 32rpx 24rpx;
|
||||
}
|
||||
.gd-text{
|
||||
font-size: 28rpx;
|
||||
line-height: 1.7;
|
||||
color: #333;
|
||||
}
|
||||
.gd-footer{
|
||||
padding: 16rpx 24rpx 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.gd-btn{
|
||||
min-width: 200rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
text-align: center;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.gd-confirm{
|
||||
background: #2979ff;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
<template>
|
||||
<view :class="className" :style="iconStyle">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<image
|
||||
:src="iconUrl"
|
||||
:style="{
|
||||
width: (width || size) + 'px',
|
||||
height: (height || size) + 'px',
|
||||
}"
|
||||
class="icon"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<img
|
||||
:src="iconUrl"
|
||||
:style="{
|
||||
width: (width || size) + 'px',
|
||||
height: (height || size) + 'px',
|
||||
}"
|
||||
class="icon"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, withDefaults } from 'vue'
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
type: string
|
||||
size?: number
|
||||
width?: number
|
||||
height?: number
|
||||
iconClassName?: string
|
||||
iconStyle?: any
|
||||
}>(),
|
||||
{
|
||||
size: 16,
|
||||
}
|
||||
)
|
||||
const urlMap: any = {
|
||||
'icon-a-1':
|
||||
'https://yx-web-nosdn.netease.im/common/7c2e2c6ff08f4ed60f3ca7d5ab6d38ac/icon-a-1.png',
|
||||
'icon-a-2':
|
||||
'https://yx-web-nosdn.netease.im/common/bb61c05013350e980b3acf77a00aa7b7/icon-a-2.png',
|
||||
'icon-a-3':
|
||||
'https://yx-web-nosdn.netease.im/common/bfe80222635ec3f07e41b2819d002a4c/icon-a-3.png',
|
||||
'icon-a-4':
|
||||
'https://yx-web-nosdn.netease.im/common/e6dd252af94a4716edc191f7d3812042/icon-a-4.png',
|
||||
'icon-a-5':
|
||||
'https://yx-web-nosdn.netease.im/common/4e01e93f3e795d8aeb140e924d8b1206/icon-a-5.png',
|
||||
'icon-a-6':
|
||||
'https://yx-web-nosdn.netease.im/common/a1fa1174a588a984845ba871b1f1e3b0/icon-a-6.png',
|
||||
'icon-a-7':
|
||||
'https://yx-web-nosdn.netease.im/common/e0e30470561cf90446ec31c6d5b206a5/icon-a-7.png',
|
||||
'icon-a-8':
|
||||
'https://yx-web-nosdn.netease.im/common/e44ceea2c764bfbe773e61483ae857eb/icon-a-8.png',
|
||||
'icon-a-9':
|
||||
'https://yx-web-nosdn.netease.im/common/f4e5b303cb77d9ce67a0baf4efaa1125/icon-a-9.png',
|
||||
'icon-a-10':
|
||||
'https://yx-web-nosdn.netease.im/common/28e46e6cc468c4ff6f44532bd6b7f464/icon-a-10.png',
|
||||
'icon-a-11':
|
||||
'https://yx-web-nosdn.netease.im/common/f265ea5a782cebabae08a079045caf2c/icon-a-11.png',
|
||||
'icon-a-12':
|
||||
'https://yx-web-nosdn.netease.im/common/20043e6f8d619ab7bca69f1a0d5a0e56/icon-a-12.png',
|
||||
'icon-a-13':
|
||||
'https://yx-web-nosdn.netease.im/common/c2b2d52a97eea83efb10c9bbc34dc104/icon-a-13.png',
|
||||
'icon-a-14':
|
||||
'https://yx-web-nosdn.netease.im/common/37486551a8bd31e3446ae862cddd3067/icon-a-14.png',
|
||||
'icon-a-15':
|
||||
'https://yx-web-nosdn.netease.im/common/e383cc57dcb7a903887031ed0d341fef/icon-a-15.png',
|
||||
'icon-a-16':
|
||||
'https://yx-web-nosdn.netease.im/common/73e2f9507f8aac7238896a3f1ee8305a/icon-a-16.png',
|
||||
'icon-a-17':
|
||||
'https://yx-web-nosdn.netease.im/common/51a80e8e81a8aa531d1c68e6f79f7d58/icon-a-17.png',
|
||||
'icon-a-18':
|
||||
'https://yx-web-nosdn.netease.im/common/20f8c6153ba0f51c038e04f2fbedf767/icon-a-18.png',
|
||||
'icon-a-19':
|
||||
'https://yx-web-nosdn.netease.im/common/47d420b5251ca7b9ddc564b42564eb01/icon-a-19.png',
|
||||
'icon-a-20':
|
||||
'https://yx-web-nosdn.netease.im/common/8fad6b9427b49f5bfd1a8ec0f8a77fac/icon-a-20.png',
|
||||
'icon-a-21':
|
||||
'https://yx-web-nosdn.netease.im/common/6fa17035135cebe4ca1512b454fa38c2/icon-a-21.png',
|
||||
'icon-a-22':
|
||||
'https://yx-web-nosdn.netease.im/common/12189563eea22258b847cf900dcbc4d4/icon-a-22.png',
|
||||
'icon-a-23':
|
||||
'https://yx-web-nosdn.netease.im/common/3b7dcfe14788bd7d8c2da8aad6c24baa/icon-a-23.png',
|
||||
'icon-a-24':
|
||||
'https://yx-web-nosdn.netease.im/common/6bb0879272c8a3c73524f3b728a93c10/icon-a-24.png',
|
||||
'icon-a-25':
|
||||
'https://yx-web-nosdn.netease.im/common/1f93dac2bdef1f91ca2f7302065954d5/icon-a-25.png',
|
||||
'icon-a-26':
|
||||
'https://yx-web-nosdn.netease.im/common/aa3c8e63ee6c6d605f4606a8094f2094/icon-a-26.png',
|
||||
'icon-a-27':
|
||||
'https://yx-web-nosdn.netease.im/common/000447b3172d70d1b739a170c377eae2/icon-a-27.png',
|
||||
'icon-a-28':
|
||||
'https://yx-web-nosdn.netease.im/common/27c3b8d1acb6f234a7591c2358b549bf/icon-a-28.png',
|
||||
'icon-a-29':
|
||||
'https://yx-web-nosdn.netease.im/common/fbae68926f43367022d0b0c95c15adcf/icon-a-29.png',
|
||||
'icon-a-30':
|
||||
'https://yx-web-nosdn.netease.im/common/61c0b6c12bc6ad2b7e0511d843b03265/icon-a-30.png',
|
||||
'icon-a-31':
|
||||
'https://yx-web-nosdn.netease.im/common/202e7abeaecf651f6da3f7f695ef8752/icon-a-31.png',
|
||||
'icon-a-32':
|
||||
'https://yx-web-nosdn.netease.im/common/6ef4958d39866165212c1b60bc7c6a55/icon-a-32.png',
|
||||
'icon-a-33':
|
||||
'https://yx-web-nosdn.netease.im/common/18f8b53d57a6b47c3876b6938f2f57b9/icon-a-33.png',
|
||||
'icon-a-34':
|
||||
'https://yx-web-nosdn.netease.im/common/84d7491e6d5a6d53848b6a3d12a739b2/icon-a-34.png',
|
||||
'icon-a-35':
|
||||
'https://yx-web-nosdn.netease.im/common/f03fe01986e9e25f3faf1a17c0ef78c8/icon-a-35.png',
|
||||
'icon-a-36':
|
||||
'https://yx-web-nosdn.netease.im/common/4617253245617bcd38ed7165bdb592d8/icon-a-36.png',
|
||||
'icon-a-37':
|
||||
'https://yx-web-nosdn.netease.im/common/9168b11333f59b0ff948003dedb24c84/icon-a-37.png',
|
||||
'icon-a-38':
|
||||
'https://yx-web-nosdn.netease.im/common/1a3cd5d62e92895dbab3d356112b5079/icon-a-38.png',
|
||||
'icon-a-39':
|
||||
'https://yx-web-nosdn.netease.im/common/b465db737c737ab4308c9272a00a1fdf/icon-a-39.png',
|
||||
'icon-a-40':
|
||||
'https://yx-web-nosdn.netease.im/common/6bca766a4904e10934ea2f2450c341b5/icon-a-40.png',
|
||||
'icon-a-41':
|
||||
'https://yx-web-nosdn.netease.im/common/12d5055618b619b568342f0619cacf0c/icon-a-41.png',
|
||||
'icon-a-42':
|
||||
'https://yx-web-nosdn.netease.im/common/8851ccd815375180bd7f8728ead1cdf1/icon-a-42.png',
|
||||
'icon-a-43':
|
||||
'https://yx-web-nosdn.netease.im/common/1ac7cacc9d0063d165f8e2bc3020bfff/icon-a-43.png',
|
||||
'icon-a-44':
|
||||
'https://yx-web-nosdn.netease.im/common/5735260c7e240beaabc360365e6d60c5/icon-a-44.png',
|
||||
'icon-a-45':
|
||||
'https://yx-web-nosdn.netease.im/common/07372c06915a7d0a977a4f042522e2a7/icon-a-45.png',
|
||||
'icon-a-46':
|
||||
'https://yx-web-nosdn.netease.im/common/40c5b2b5769166b51c968942f4abed95/icon-a-46.png',
|
||||
'icon-a-47':
|
||||
'https://yx-web-nosdn.netease.im/common/9334c3ec8c8d54a9a3271a3536ff7c62/icon-a-47.png',
|
||||
'icon-a-48':
|
||||
'https://yx-web-nosdn.netease.im/common/5630ab646533dd6de7e3c1accc3d2ca1/icon-a-48.png',
|
||||
'icon-a-49':
|
||||
'https://yx-web-nosdn.netease.im/common/f2412538fa0da38549c23fd44b25bdfb/icon-a-49.png',
|
||||
'icon-a-50':
|
||||
'https://yx-web-nosdn.netease.im/common/1f28ffd1413aa3fcce1c17aff3694d41/icon-a-50.png',
|
||||
'icon-a-51':
|
||||
'https://yx-web-nosdn.netease.im/common/a99b57b586a85c23cbd8ed65d1a16765/icon-a-51.png',
|
||||
'icon-a-52':
|
||||
'https://yx-web-nosdn.netease.im/common/ce6f64bbe45a42108fd1b1a7b1dae606/icon-a-52.png',
|
||||
'icon-a-53':
|
||||
'https://yx-web-nosdn.netease.im/common/ba5dc56bf8f550da8c2dc1c94e2ee7fb/icon-a-53.png',
|
||||
'icon-a-54':
|
||||
'https://yx-web-nosdn.netease.im/common/81f5b3b693d9133030c013f0f21462ab/icon-a-54.png',
|
||||
'icon-a-55':
|
||||
'https://yx-web-nosdn.netease.im/common/758ed38dea207d60855969689a5dd68b/icon-a-55.png',
|
||||
'icon-a-56':
|
||||
'https://yx-web-nosdn.netease.im/common/a20bee2372cbe399191af3d76a5aad31/icon-a-56.png',
|
||||
'icon-a-57':
|
||||
'https://yx-web-nosdn.netease.im/common/a17fbdbc64cf4b55be377f18ed81879a/icon-a-57.png',
|
||||
'icon-a-58':
|
||||
'https://yx-web-nosdn.netease.im/common/784b31cda55da76d8278a5bd53c2c7e4/icon-a-58.png',
|
||||
'icon-a-59':
|
||||
'https://yx-web-nosdn.netease.im/common/c716afbc25b8809dfb9ca80a09051f6f/icon-a-59.png',
|
||||
'icon-a-60':
|
||||
'https://yx-web-nosdn.netease.im/common/54de44be20c5d21ffad08176b24560a0/icon-a-60.png',
|
||||
'icon-a-61':
|
||||
'https://yx-web-nosdn.netease.im/common/0628fd4507e2a3455028f376d8d5d80a/icon-a-61.png',
|
||||
'icon-a-62':
|
||||
'https://yx-web-nosdn.netease.im/common/fa336dc373d5e395a1e9a541dc9953d2/icon-a-62.png',
|
||||
'icon-a-63':
|
||||
'https://yx-web-nosdn.netease.im/common/868ee8c664b32b34d554d02fc406ab70/icon-a-63.png',
|
||||
'icon-a-64':
|
||||
'https://yx-web-nosdn.netease.im/common/4e33aadf3ca3b918e73ef07e21eb96ac/icon-a-64.png',
|
||||
'icon-a-65':
|
||||
'https://yx-web-nosdn.netease.im/common/c6e5563811d94c82426036b9f96d6de5/icon-a-65.png',
|
||||
'icon-a-66':
|
||||
'https://yx-web-nosdn.netease.im/common/8baa1f43b4e523e524c54f3340ef21cb/icon-a-66.png',
|
||||
'icon-a-67':
|
||||
'https://yx-web-nosdn.netease.im/common/307c3426dccf1252b5967956bcdcf58a/icon-a-67.png',
|
||||
'icon-a-68':
|
||||
'https://yx-web-nosdn.netease.im/common/196f62aa8e8a38bbbcd818ad42729714/icon-a-68.png',
|
||||
'icon-a-70':
|
||||
'https://yx-web-nosdn.netease.im/common/fb54482390faf9d8d9d607d7e3ab691f/icon-a-70.png',
|
||||
'icon-a-Frame7':
|
||||
'https://yx-web-nosdn.netease.im/common/c5c3d0ee0a4000736827cedfd0610172/icon-a-Frame7.png',
|
||||
'icon-a-Frame8':
|
||||
'https://yx-web-nosdn.netease.im/common/9f77f834a99c29ed5c4b4b54b7ade468/icon-a-Frame8.png',
|
||||
'icon-addition':
|
||||
'https://yx-web-nosdn.netease.im/common/6302fcf17e9c4ac65b392553aaccf9b1/icon-addition.png',
|
||||
'icon-biaoqing':
|
||||
'https://yx-web-nosdn.netease.im/common/1a98df356ed629193e50bea570e02a53/icon-biaoqing.png',
|
||||
'icon-chehui':
|
||||
'https://yx-web-nosdn.netease.im/common/958cb6797f69bdfbf5441da25ed997c3/icon-chehui.png',
|
||||
'icon-chuangjianqunzu':
|
||||
'https://yx-web-nosdn.netease.im/common/7b00839704359b7c10f32af7cc8b5911/icon-chuangjianqunzu.png',
|
||||
'icon-computed':
|
||||
'https://yx-web-nosdn.netease.im/common/352cd94c93347f01936b50bb1487b5a4/icon-computed.png',
|
||||
'icon-erfenzhiyiyidu':
|
||||
'https://yx-web-nosdn.netease.im/common/aa6b529567ee6aeb801f34f228600b04/icon-erfenzhiyiyidu.png',
|
||||
'icon-Excel':
|
||||
'https://yx-web-nosdn.netease.im/common/a9793bbb8a7237e9e92f57ad1b469baf/icon-Excel.png',
|
||||
'icon-fasong':
|
||||
'https://yx-web-nosdn.netease.im/common/f8d855dde4840989b4c88e904e1c23bf/icon-fasong.png',
|
||||
'icon-fuzhi1':
|
||||
'https://yx-web-nosdn.netease.im/common/9e0ba675eb4548bffe19da823fb712e3/icon-fuzhi1.png',
|
||||
'icon-guanbi':
|
||||
'https://yx-web-nosdn.netease.im/common/2d07f146ecb4b616632f0fcfdd02b5be/icon-guanbi.png',
|
||||
'icon-guanbi1':
|
||||
'https://yx-web-nosdn.netease.im/common/51bad0b424c2462df8213883e211fe07/icon-guanbi1.png',
|
||||
'icon-guanyu':
|
||||
'https://yx-web-nosdn.netease.im/common/24d2344c49b551d5a605b3e5e3e6f6da/icon-guanyu.png',
|
||||
'icon-huifu':
|
||||
'https://yx-web-nosdn.netease.im/common/153c273cb7b075fc0c37487655c5cbfc/icon-huifu.png',
|
||||
'icon-im-xuanzhong':
|
||||
'https://yx-web-nosdn.netease.im/common/468aaecf148e23c84b821835021dfee1/icon-im-xuanzhong.png',
|
||||
'icon-jiantou':
|
||||
'https://yx-web-nosdn.netease.im/common/c9bb28670c41e208b1d9bcedd6de88a1/icon-jiantou.png',
|
||||
'icon-jiaruqunzu':
|
||||
'https://yx-web-nosdn.netease.im/common/a27ba47b93131b7c52d829b7012fa966/icon-jiaruqunzu.png',
|
||||
'icon-kefu':
|
||||
'https://yx-web-nosdn.netease.im/common/4ddc1b9557e6672b0b45fb8fb992c992/icon-kefu.png',
|
||||
'icon-lahei':
|
||||
'https://yx-web-nosdn.netease.im/common/e9054279ca62db944ef6e5a76687a93a/icon-lahei.png',
|
||||
'icon-lishixiaoxi':
|
||||
'https://yx-web-nosdn.netease.im/common/77888d982110f3c709a3ff4fd24d48dd/icon-lishixiaoxi.png',
|
||||
'icon-More':
|
||||
'https://yx-web-nosdn.netease.im/common/137ad07f3245dc220d5546433db63786/icon-More.png',
|
||||
'icon-PPT':
|
||||
'https://yx-web-nosdn.netease.im/common/1991f8d57d1d432fcd930e4049403958/icon-PPT.png',
|
||||
'icon-qita':
|
||||
'https://yx-web-nosdn.netease.im/common/c6f687c792ef029bef1e59ccce986922/icon-qita.png',
|
||||
'icon-quxiaoxiaoximiandarao':
|
||||
'https://yx-web-nosdn.netease.im/common/f6f54973789b69939c57ae94a38e8d25/icon-quxiaoxiaoximiandarao.png',
|
||||
'icon-quxiaozhiding':
|
||||
'https://yx-web-nosdn.netease.im/common/ad2d451e8f1ee36ec9cec6787d6074c0/icon-quxiaozhiding.png',
|
||||
'icon-RAR1':
|
||||
'https://yx-web-nosdn.netease.im/common/27a743e5696c1ca4416b75c5dde0252c/icon-RAR1.png',
|
||||
'icon-shanchu':
|
||||
'https://yx-web-nosdn.netease.im/common/d96f9c0113af4d86dd4e5ecf2e49711b/icon-shanchu.png',
|
||||
'icon-shandiao':
|
||||
'https://yx-web-nosdn.netease.im/common/14eea1edc7801449a30700a3c9d604c6/icon-shandiao.png',
|
||||
'icon-shezhi':
|
||||
'https://yx-web-nosdn.netease.im/common/698d483a7aacade68ea976f727184e1e/setting.png',
|
||||
'icon-shezhi1':
|
||||
'https://yx-web-nosdn.netease.im/common/eced271ac35864b7c716262f1a37217e/icon-shezhi1.png',
|
||||
'icon-shipin':
|
||||
'https://yx-web-nosdn.netease.im/common/455c333219318f3b96f748d6753eda4a/icon-shipin.png',
|
||||
'icon-shipin8':
|
||||
'https://yx-web-nosdn.netease.im/common/73fededbe5b97dec0246e438d33ae614/icon-shipin8.png',
|
||||
'icon-shipinyuyin':
|
||||
'https://yx-web-nosdn.netease.im/common/09b16fe9a2b824ded4162f25333e44e1/icon-shipinyuyin.png',
|
||||
'icon-sifenzhisanyidu':
|
||||
'https://yx-web-nosdn.netease.im/common/b1234a4255d3187fa9a767bfed8f4d96/icon-sifenzhisanyidu.png',
|
||||
'icon-sifenzhiyiyidu':
|
||||
'https://yx-web-nosdn.netease.im/common/11c7a7e79c57eda20c5ca9d98b0d7e8a/icon-sifenzhiyiyidu.png',
|
||||
'icon-sousuo':
|
||||
'https://yx-web-nosdn.netease.im/common/2ccfdfa640c72167f228e7d76068e5f5/icon-sousuo.png',
|
||||
'icon-team':
|
||||
'https://yx-web-nosdn.netease.im/common/140e8fbd1cc2df4c878acb17405471f7/icon-team.png',
|
||||
'icon-zuojiantou':
|
||||
'https://yx-web-nosdn.netease.im/common/9ab796030ac24a126dedc60fd60613ce/icon-zuojiantou.png',
|
||||
'icon-zhuanfa':
|
||||
'https://yx-web-nosdn.netease.im/common/163a3343b0262a76d72d00bbbb4f8ac9/icon-zhuanfa.png',
|
||||
'icon-zhongyingwen':
|
||||
'https://yx-web-nosdn.netease.im/common/80a7dbae8c0207f1896e63746ac1a18a/icon-zhongyingwen.png',
|
||||
'icon-zhankai':
|
||||
'https://yx-web-nosdn.netease.im/common/d4f655bff9e278ea732adb6a5317bbca/icon-zhankai.png',
|
||||
'icon-yinle':
|
||||
'https://yx-web-nosdn.netease.im/common/98a2a366c7e06ab1b1b6ddf9b0c01d73/icon-yinle.png',
|
||||
'icon-yidu':
|
||||
'https://yx-web-nosdn.netease.im/common/d17d4aa7866faca55a6a1180c1e15bf6/icon-yidu.png',
|
||||
'icon-yanzheng':
|
||||
'https://yx-web-nosdn.netease.im/common/5a0c2769626284ff646298a7ef1f66c2/icon-yanzheng.png',
|
||||
'icon-xiaoxizhiding':
|
||||
'https://yx-web-nosdn.netease.im/common/cef2e824e603dde3d333d128434f90c1/icon-xiaoxizhiding.png',
|
||||
'icon-xiaoximiandarao':
|
||||
'https://yx-web-nosdn.netease.im/common/1c92731bb3fa91fa3fc5ff45bf9e4dbe/icon-xiaoximiandarao.png',
|
||||
'icon-Word':
|
||||
'https://yx-web-nosdn.netease.im/common/af0e4fa22c4b30a263a7f534b0504c23/icon-Word.png',
|
||||
'icon-wenjian':
|
||||
'https://yx-web-nosdn.netease.im/common/d3b36fc953447f9d9630f3b73aaa6ef1/icon-wenjian.png',
|
||||
'icon-weizhiwenjian':
|
||||
'https://yx-web-nosdn.netease.im/common/d51b39a07b3b482ab3b50a4b068588c6/icon-weizhiwenjian.png',
|
||||
'icon-weidu':
|
||||
'https://yx-web-nosdn.netease.im/common/5d50477d2afa387a59a67e30fcdceabd/icon-weidu.png',
|
||||
'icon-tupian2':
|
||||
'https://yx-web-nosdn.netease.im/common/51eb954ad971eb6890d0934858f950aa/icon-tupian2.png',
|
||||
'icon-tupian1':
|
||||
'https://yx-web-nosdn.netease.im/common/0737f1e187aa250d5090f38925672485/icon-tupian1.png',
|
||||
'icon-tupian':
|
||||
'https://yx-web-nosdn.netease.im/common/aa93aa9ffd0197b9a961455506f75078/icon-tupian.png',
|
||||
'icon-tuigejian':
|
||||
'https://yx-web-nosdn.netease.im/common/7bca7dffd1f8c3cd66b8ede7f176e4a8/icon-tuigejian.png',
|
||||
'icon-tuichudenglu':
|
||||
'https://yx-web-nosdn.netease.im/common/ce42192020620522a46763c758951b76/icon-tuichudenglu.png',
|
||||
'icon-touxiang5':
|
||||
'https://yx-web-nosdn.netease.im/common/769a3ba0615b3157d6b493fa5d2352c4/icon-touxiang5.png',
|
||||
'icon-touxiang4':
|
||||
'https://yx-web-nosdn.netease.im/common/c6ea2b6557913d2fe8017b68eb688515/icon-touxiang4.png',
|
||||
'icon-touxiang3':
|
||||
'https://yx-web-nosdn.netease.im/common/89bbfa21ce6d43fda25a8c4121284db6/icon-touxiang3.png',
|
||||
'icon-touxiang2':
|
||||
'https://yx-web-nosdn.netease.im/common/e2e3fdafb9201a0b693b36514eb378ae/icon-touxiang2.png',
|
||||
'icon-touxiang1':
|
||||
'https://yx-web-nosdn.netease.im/common/4e639e380f246e804b2f0f115f84215f/icon-touxiang1.png',
|
||||
'icon-tongxunlu-xuanzhong':
|
||||
'https://yx-web-nosdn.netease.im/common/f49a558e193325d185223f55b65711bf/icon-tongxunlu-xuanzhong.png',
|
||||
'icon-tongxunlu-weixuanzhong':
|
||||
'https://yx-web-nosdn.netease.im/common/e33c24318c1faeb73c79fa1b0b1c9c53/icon-tongxunlu-weixuanzhong.png',
|
||||
'icon-tianjiahaoyou':
|
||||
'https://yx-web-nosdn.netease.im/common/c5f19ef12df64f466bba0a611cf224d5/icon-tianjiahaoyou.png',
|
||||
'icon-tianjiaanniu':
|
||||
'https://yx-web-nosdn.netease.im/common/181feb34fc6324198f4d9d887a8759e1/icon-tianjiaanniu.png',
|
||||
'icon-team2':
|
||||
'https://yx-web-nosdn.netease.im/common/f9d8ea13b9b5d769f75e7f01edcab1df/icon-team2.png',
|
||||
'icon-lahei2':
|
||||
'https://yx-web-nosdn.netease.im/common/1ee2a3bffb33b81727583189a2562658/icon-lahei2.png',
|
||||
'icon-yuyin1':
|
||||
'https://yx-web-nosdn.netease.im/common/2c785931baec5a9b00cd5f59f81f4482/语音1.png',
|
||||
'icon-yuyin2':
|
||||
'https://yx-web-nosdn.netease.im/common/20043a54056311986c867edf93f51f62/语音2.png',
|
||||
'icon-yuyin3':
|
||||
'https://yx-web-nosdn.netease.im/common/786476a9bd129f6a7b027621f9818883/语音3.png',
|
||||
'icon-yuyin8':
|
||||
'https://yx-web-nosdn.netease.im/common/40d631410c18983f6ee0ca880976c2e9/icon-yuyin8.png',
|
||||
'icon-audio':
|
||||
'https://yx-web-nosdn.netease.im/common/27c4c8b528fac12d3f79bb3154be87d4/audio1.png',
|
||||
'audio-btn':
|
||||
'https://yx-web-nosdn.netease.im/common/abfd3577b9d29bb6d3445979336a5770/Vector.png',
|
||||
'audio-btn-selected':
|
||||
'https://yx-web-nosdn.netease.im/common/7f17c648e9b63f40b91832664668ac7a/Frame.png',
|
||||
'send-more':
|
||||
'https://yx-web-nosdn.netease.im/common/270ebff9ad75056b857c21f40b55d72d/send-more.png',
|
||||
'icon-paishe':
|
||||
'https://yx-web-nosdn.netease.im/common/be9638b843a70f307ecb6803ffe5775c/paishe.png',
|
||||
'icon-shipin2':
|
||||
'https://yx-web-nosdn.netease.im/common/3865bf597f9f5ca03b2b222ca07344e1/icon-shipin2.png',
|
||||
'icon-audio-call':
|
||||
'https://yx-web-nosdn.netease.im/common/99438364d757b51e7e36c18d254e70e7/icon-audio-call.png',
|
||||
'icon-video-call':
|
||||
'https://yx-web-nosdn.netease.im/common/ed7c85a59de3e247d10ecfc684b05226/icon-video-call.png',
|
||||
'icon-read':
|
||||
'https://yx-web-nosdn.netease.im/common/271c53e493cfd6ea98c51650d8b39b79/read.png',
|
||||
'icon-file':
|
||||
'https://yx-web-nosdn.netease.im/common/90485f277f50fc081970ded8772ec7c5/file.png',
|
||||
'icon-pin':
|
||||
'https://yx-web-nosdn.netease.im/common/6eb4fafcca008d2e93e90311696d6b96/black-pin.png',
|
||||
'icon-green-pin':
|
||||
'https://yx-web-nosdn.netease.im/common/4a1f15eff2f53563c4f1cf6ecde82d2c/green-pin.png',
|
||||
'choose-picture':
|
||||
'https://yx-web-nosdn.netease.im/common/97b3ca79a589d5753cbc0e8e8ec09501/choose-picture.png',
|
||||
'icon-collection':
|
||||
'https://yx-web-nosdn.netease.im/common/aa1bad3410009dea83d34d513dcd20f3/add-collection.png',
|
||||
'blue-collection':
|
||||
'https://yx-web-nosdn.netease.im/common/fb3836a8731b57720fcfdd3b589b3d5f/collection.png',
|
||||
}
|
||||
|
||||
//以上链接访问有频率控制,建议您将静态资源放到您服务器上,然后修改上面的链接即可
|
||||
|
||||
const iconUrl = computed(() => {
|
||||
return urlMap[props.type]
|
||||
})
|
||||
|
||||
const className = `${props.iconClassName || ''} icon-wrapper`
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.icon-wrapper {
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<template v-for="item in textArr" :key="item.key">
|
||||
<template v-if="item.type === 'text'" class="msg-reply-text">
|
||||
{{ item.value }}
|
||||
</template>
|
||||
<template class="icon" v-else-if="item.type === 'emoji'">
|
||||
<Icon
|
||||
:type="EMOJI_ICON_MAP_CONFIG[item.value]"
|
||||
:size="14"
|
||||
:iconStyle="{
|
||||
margin: '3px',
|
||||
verticalAlign: 'bottom',
|
||||
display: 'inline-block',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Icon from './Icon.vue'
|
||||
import { EMOJI_ICON_MAP_CONFIG, emojiRegExp } from '@/utils/im/emoji'
|
||||
import { computed, withDefaults } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{ text: string }>(), {})
|
||||
|
||||
// 筛选出文本和表情
|
||||
const parseText = (text: string) => {
|
||||
if (!text) return []
|
||||
const regexEmoji = emojiRegExp
|
||||
const matches: {
|
||||
type: 'emoji' | 'text'
|
||||
value: string
|
||||
index: number
|
||||
}[] = []
|
||||
let match
|
||||
|
||||
while ((match = regexEmoji.exec(text)) !== null) {
|
||||
matches.push({
|
||||
type: 'emoji',
|
||||
value: match[0],
|
||||
index: match.index,
|
||||
})
|
||||
const fillText = ' '.repeat(match[0].length)
|
||||
text = text.replace(match[0], fillText)
|
||||
}
|
||||
|
||||
text = text.replace(regexEmoji, ' ')
|
||||
|
||||
if (text) {
|
||||
text
|
||||
.split(' ')
|
||||
.filter((item) => item.trim())
|
||||
.map((item) => {
|
||||
const index = text?.indexOf(item)
|
||||
matches.push({
|
||||
type: 'text',
|
||||
value: item,
|
||||
index,
|
||||
})
|
||||
const fillText = ' '.repeat(item.length)
|
||||
text = text.replace(item, fillText)
|
||||
})
|
||||
}
|
||||
|
||||
return matches
|
||||
.sort((a, b) => a.index - b.index)
|
||||
.map((item, index) => {
|
||||
return {
|
||||
...item,
|
||||
key: index + item.type,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const textArr = computed(() => {
|
||||
return parseText(props.text)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.msg-reply-text {
|
||||
font-size: 13px !important;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
width: 100%;
|
||||
display: inline;
|
||||
}
|
||||
.ellipsis {
|
||||
display: inline-block;
|
||||
flex-basis: 25px;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="modal" v-if="visible">
|
||||
<div class="mask" @tap="handleMaskClick"></div>
|
||||
<div class="content">
|
||||
<div class="title">{{ title }}</div>
|
||||
<slot></slot>
|
||||
<div class="buttons">
|
||||
<div class="button cancel" @tap="handleCancelClick">
|
||||
{{ cancelText }}
|
||||
</div>
|
||||
<div class="button confirm" @tap="handleConfirmClick">
|
||||
{{ confirmText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
confirmText: string
|
||||
cancelText: string
|
||||
visible: boolean
|
||||
}>(),
|
||||
{}
|
||||
)
|
||||
|
||||
const emit = defineEmits(['confirm', 'cancel'])
|
||||
|
||||
const handleMaskClick = () => {
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
const handleConfirmClick = () => {
|
||||
emit('confirm')
|
||||
}
|
||||
|
||||
const handleCancelClick = () => {
|
||||
emit('cancel')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
z-index: 99999999999;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
touch-action: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 276px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
margin: 16px 0 0 16px;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 52px;
|
||||
border-top: 1px solid #e1e6e8;
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.cancel {
|
||||
color: #666666;
|
||||
height: 52px;
|
||||
line-height: 52px;
|
||||
border-right: 1px solid #e1e6e8;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
color: #337eff;
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<!-- domId 是要截图的容器 id -->
|
||||
<view class="my-html2canvas" :prop="domId" :change:prop="h2cRender.watchDomId">
|
||||
<!-- 用于触发 renderjs 截图 -->
|
||||
<text :prop="expOver" :change:prop="h2cRender.watchExpOver"></text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
domId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
expOver: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 业务层调用这个方法开始截图
|
||||
h2cRenderDom() {
|
||||
// #ifdef H5
|
||||
// H5 直接在当前环境(有 DOM)里跑 renderDom
|
||||
this.$emit('renderDomInH5')
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
// 非 H5(APP 等)通过 expOver 触发 renderjs 中的截图逻辑
|
||||
this.expOver++
|
||||
// #endif
|
||||
},
|
||||
// renderjs 截图完成后会 callMethod 回调到这里
|
||||
renderOver(base64) {
|
||||
this.$emit('renderOver', base64)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- renderjs 只能内联 -->
|
||||
<script module="h2cRender" lang="renderjs">
|
||||
import html2canvas from 'html2canvas'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
domIdValue: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async renderDom() {
|
||||
try {
|
||||
const el = document.getElementById(this.domIdValue)
|
||||
if (!el) {
|
||||
console.error('[MyHtml2canvas] dom 未找到,请检查 domId:', this.domIdValue)
|
||||
return
|
||||
}
|
||||
const canvas = await html2canvas(el, {
|
||||
width: el.offsetWidth,
|
||||
height: el.offsetHeight,
|
||||
x: 0,
|
||||
y: 0,
|
||||
useCORS: true,
|
||||
scale: 2
|
||||
})
|
||||
const base64 = canvas.toDataURL('image/png', 1)
|
||||
this.$ownerInstance.callMethod('renderOver', base64)
|
||||
} catch (err) {
|
||||
console.error('[MyHtml2canvas] html2canvas 失败:', err && err.message)
|
||||
}
|
||||
},
|
||||
// script 部分通过 :prop 传入 domId
|
||||
watchDomId(newVal) {
|
||||
this.domIdValue = newVal
|
||||
},
|
||||
// expOver 变化时触发渲染
|
||||
watchExpOver(newVal) {
|
||||
if (newVal !== 0) {
|
||||
this.renderDom()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.my-html2canvas {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<!-- 样式兼容微信小程序 -->
|
||||
<div>
|
||||
<div
|
||||
class="nav-bar-wrapper"
|
||||
:style="{
|
||||
backgroundColor: backgroundColor || '#ffffff',
|
||||
backgroundImage: `url(${title})`,
|
||||
height: isWeixinApp ? '55px' : '40px',
|
||||
alignItems: isWeixinApp ? 'flex-end' : 'center',
|
||||
}"
|
||||
>
|
||||
<slot v-if="showLeft" name="left"></slot>
|
||||
<div v-else @tap="back">
|
||||
<Icon type="icon-zuojiantou" :size="22"></Icon>
|
||||
</div>
|
||||
<div class="title-container">
|
||||
<div class="title">{{ title }}</div>
|
||||
<div class="subTitle" v-if="subTitle">{{ subTitle }}</div>
|
||||
<slot name="icon"></slot>
|
||||
</div>
|
||||
<div>
|
||||
<slot name="right"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="isWeixinApp ? 'block-wx' : 'block'"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getUniPlatform } from '../utils'
|
||||
import Icon from './Icon.vue'
|
||||
import { withDefaults } from 'vue'
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
subTitle?: string
|
||||
backgroundColor?: string
|
||||
showLeft?: boolean
|
||||
}>(),
|
||||
{
|
||||
subTitle: '',
|
||||
backgroundColor: '',
|
||||
}
|
||||
)
|
||||
|
||||
const isWeixinApp = getUniPlatform() === 'mp-weixin'
|
||||
|
||||
const back = () => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../pages/styles/common.scss';
|
||||
|
||||
.nav-bar-wrapper {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: var(--status-bar-height) 10px 5px 10px;
|
||||
z-index: 9999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
.title-container {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 230px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.subTitle {
|
||||
white-space: nowrap;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 100%;
|
||||
height: calc(45px + var(--status-bar-height));
|
||||
}
|
||||
|
||||
.block-wx {
|
||||
width: 100%;
|
||||
height: calc(55px + var(--status-bar-height));
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div v-if="!isConnected && text" class="network-alert">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { autorun } from 'mobx'
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { t } from '@/utils/im/i18n'
|
||||
import { V2NIMConst } from '@/utils/im/nim'
|
||||
|
||||
const isConnected = ref(true)
|
||||
const text = ref(t('connectingText'))
|
||||
// uni.onNetworkStatusChange((res) => {
|
||||
// if (!res.isConnected) {
|
||||
// isConnected.value = false;
|
||||
// text.value = t('offlineText');
|
||||
// } else {
|
||||
// text.value = t('connectingText');
|
||||
// }
|
||||
// });
|
||||
|
||||
onMounted(() => {
|
||||
if (
|
||||
uni.$UIKitStore?.connectStore?.connectStatus ===
|
||||
V2NIMConst.V2NIMConnectStatus.V2NIM_CONNECT_STATUS_CONNECTED
|
||||
) {
|
||||
isConnected.value = true
|
||||
} else if (
|
||||
uni.$UIKitStore?.connectStore?.connectStatus ===
|
||||
V2NIMConst.V2NIMConnectStatus.V2NIM_CONNECT_STATUS_DISCONNECTED
|
||||
) {
|
||||
isConnected.value = false
|
||||
text.value = t('offlineText')
|
||||
} else {
|
||||
isConnected.value = false
|
||||
text.value = t('connectingText')
|
||||
}
|
||||
})
|
||||
|
||||
const uninstallConnectWatch = autorun(() => {
|
||||
if (
|
||||
uni.$UIKitStore?.connectStore?.connectStatus ===
|
||||
V2NIMConst.V2NIMConnectStatus.V2NIM_CONNECT_STATUS_CONNECTED
|
||||
) {
|
||||
isConnected.value = true
|
||||
} else if (
|
||||
uni.$UIKitStore?.connectStore?.connectStatus ===
|
||||
V2NIMConst.V2NIMConnectStatus.V2NIM_CONNECT_STATUS_DISCONNECTED
|
||||
) {
|
||||
isConnected.value = false
|
||||
text.value = t('offlineText')
|
||||
} else {
|
||||
isConnected.value = false
|
||||
text.value = t('connectingText')
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
uninstallConnectWatch()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.network-alert {
|
||||
font-size: 14px;
|
||||
background: #fee3e6;
|
||||
color: #fc596a;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div v-if="personList.length > 0" class="friend-select-wrapper">
|
||||
<div class="member-wrapper">
|
||||
<radio-group v-if="radio" @change="checkboxChange">
|
||||
<div
|
||||
class="member-item"
|
||||
v-for="item in personList"
|
||||
:key="item.accountId"
|
||||
>
|
||||
<radio
|
||||
class="checkbox"
|
||||
:value="item.accountId"
|
||||
:checked="item.checked"
|
||||
:disabled="
|
||||
item.disabled ||
|
||||
(selectAccount.length >= max &&
|
||||
!selectAccount.includes(item.accountId))
|
||||
"
|
||||
/>
|
||||
<Avatar class="user-avatar" size="36" :account="item.accountId" />
|
||||
<div class="user-name">
|
||||
<Appellation :account="item.accountId" :teamId="item.teamId" />
|
||||
</div>
|
||||
</div>
|
||||
</radio-group>
|
||||
<checkbox-group v-else @change="checkboxChange">
|
||||
<div
|
||||
class="member-item"
|
||||
v-for="item in personList"
|
||||
:key="item.accountId"
|
||||
>
|
||||
<checkbox
|
||||
class="checkbox"
|
||||
:value="item.accountId"
|
||||
:checked="item.checked"
|
||||
:disabled="
|
||||
item.disabled ||
|
||||
(selectAccount.length >= max &&
|
||||
!selectAccount.includes(item.accountId))
|
||||
"
|
||||
/>
|
||||
<Avatar class="user-avatar" size="36" :account="item.accountId" />
|
||||
<div class="user-name">
|
||||
<Appellation :account="item.accountId" :teamId="item.teamId" />
|
||||
</div>
|
||||
</div>
|
||||
</checkbox-group>
|
||||
</div>
|
||||
<div
|
||||
:style="{ border: '1px solid #ccc' }"
|
||||
v-if="!!showBtn"
|
||||
@tap="onBtnClick"
|
||||
class="ok-btn"
|
||||
>
|
||||
{{ btnText || t('okText') }}
|
||||
</div>
|
||||
</div>
|
||||
<Empty v-else :text="t('noFriendText')"></Empty>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Avatar from './Avatar.vue'
|
||||
import Appellation from './Appellation.vue'
|
||||
import Empty from './Empty.vue'
|
||||
import { t } from '../utils/i18n'
|
||||
import { events } from '../utils/constants'
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
export type PersonSelectItem = {
|
||||
accountId: string
|
||||
teamId?: string
|
||||
disabled?: boolean
|
||||
checked?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
personList: PersonSelectItem[]
|
||||
showBtn?: boolean
|
||||
btnText?: string
|
||||
radio?: boolean
|
||||
max?: number
|
||||
}>(),
|
||||
{
|
||||
showBtn: true,
|
||||
btnText: '',
|
||||
radio: false,
|
||||
max: Number.MAX_SAFE_INTEGER,
|
||||
}
|
||||
)
|
||||
|
||||
const $emit = defineEmits<{
|
||||
(event: 'checkboxChange', selectList: string | string[]): void
|
||||
(event: 'onBtnClick'): void
|
||||
}>()
|
||||
|
||||
const onBtnClick = () => {
|
||||
uni.$emit(events.FRIEND_SELECT)
|
||||
$emit('onBtnClick')
|
||||
}
|
||||
|
||||
const checkboxChange = (event: any) => {
|
||||
const value = event.detail.value
|
||||
selectAccount.value = value
|
||||
$emit('checkboxChange', value)
|
||||
}
|
||||
|
||||
const selectAccount = ref<string[]>([])
|
||||
|
||||
onMounted(() => {
|
||||
selectAccount.value = props.personList
|
||||
.filter((item) => item.checked)
|
||||
.map((item) => item.accountId)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../pages/styles/common.scss';
|
||||
|
||||
.friend-select-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.member-wrapper {
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
|
||||
.member-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 8px 20px;
|
||||
// width: 100vw;
|
||||
|
||||
.user-avatar {
|
||||
margin: 0 14px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
max-width: 70%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ok-btn {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.ok-btn-mp {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,353 @@
|
||||
<template>
|
||||
<view
|
||||
class="zb-tooltip"
|
||||
:style="{
|
||||
'--theme-bg-color': color,
|
||||
}"
|
||||
>
|
||||
<view class="zb_tooltip_content" @longpress.stop="handleClick">
|
||||
<slot></slot>
|
||||
<view
|
||||
class="zb_tooltip__mask"
|
||||
@longpress.stop
|
||||
v-show="isShow"
|
||||
@touchstart="close"
|
||||
></view>
|
||||
<view
|
||||
class="zb_tooltip__popper"
|
||||
@tap.stop="() => {}"
|
||||
:style="[
|
||||
style,
|
||||
{
|
||||
visibility: isShow ? 'visible' : 'hidden',
|
||||
color: color === 'white' ? '' : '#fff',
|
||||
boxShadow:
|
||||
color === 'white'
|
||||
? '0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d'
|
||||
: '',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<slot name="content">{{ content }}</slot>
|
||||
<!-- <view
|
||||
class="zb_popper__icon"
|
||||
:style="[arrowStyle]"
|
||||
:class="[
|
||||
{
|
||||
zb_popper__up: placement.indexOf('bottom') === 0,
|
||||
zb_popper__arrow: placement.indexOf('top') === 0,
|
||||
zb_popper__right: placement.indexOf('right') === 0,
|
||||
zb_popper__left: placement.indexOf('left') === 0,
|
||||
},
|
||||
]"
|
||||
>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Tooltip',
|
||||
props: {
|
||||
visible: Boolean,
|
||||
align: Boolean,
|
||||
color: {
|
||||
type: String,
|
||||
default: '#303133',
|
||||
},
|
||||
// placement: {
|
||||
// type: String,
|
||||
// default: 'top',
|
||||
// },
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isShow: this.visible,
|
||||
title: 'Hello',
|
||||
arrowLeft: 0,
|
||||
query: null,
|
||||
style: {},
|
||||
arrowStyle: {},
|
||||
placement: 'top',
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
watch: {
|
||||
isShow: {
|
||||
handler(val) {
|
||||
this.$emit('update:visible', val)
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
visible: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.$nextTick(() => {
|
||||
this.getPosition()
|
||||
})
|
||||
}
|
||||
this.isShow = val
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef H5
|
||||
window.addEventListener('click', () => {
|
||||
this.isShow = false
|
||||
})
|
||||
// #endif
|
||||
this.getPosition()
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.isShow = false
|
||||
},
|
||||
fixedWrap() {
|
||||
this.isShow = false
|
||||
},
|
||||
async handleClick() {
|
||||
if (this.isShow) {
|
||||
return (this.isShow = false)
|
||||
}
|
||||
await this.getPosition()
|
||||
this.isShow = true
|
||||
},
|
||||
getPosition() {
|
||||
return new Promise((resolve) => {
|
||||
uni
|
||||
.createSelectorQuery()
|
||||
.in(this)
|
||||
.selectAll('.zb_tooltip_content,.zb_tooltip__popper')
|
||||
.boundingClientRect(async (data) => {
|
||||
let { left, bottom, right, top, width, height } = data[0] || {}
|
||||
let obj1 = data[1] || {}
|
||||
let objStyle = {}
|
||||
let objStyle1 = {}
|
||||
if (top <= 300) {
|
||||
this.placement = 'bottom'
|
||||
} else {
|
||||
this.placement = 'top'
|
||||
}
|
||||
switch (this.placement) {
|
||||
case 'top':
|
||||
// if (obj1.width > width) {
|
||||
// objStyle.left = `-${(obj1.width - width + 120) / 2}px`
|
||||
// } else {
|
||||
// objStyle.left = `${Math.abs(obj1.width - width) / 2}px`
|
||||
// }
|
||||
if (this.align) {
|
||||
objStyle.left = '-100px'
|
||||
if (width < 90) {
|
||||
objStyle.left = '-200px'
|
||||
}
|
||||
} else {
|
||||
objStyle.left = '50px'
|
||||
}
|
||||
objStyle.bottom = `${height + 8}px`
|
||||
// objStyle.left = '30%'
|
||||
// objStyle1.left = obj1.width - 6 + 'px'
|
||||
break
|
||||
case 'bottom':
|
||||
// if (obj1.width > width) {
|
||||
// objStyle.left = `-${(obj1.width - width) / 2}px`
|
||||
// } else {
|
||||
// objStyle.left = `${Math.abs(obj1.width - width) / 2}px`
|
||||
// }
|
||||
if (this.align) {
|
||||
objStyle.left = '-100px'
|
||||
if (width < 100) {
|
||||
objStyle.left = '-200px'
|
||||
}
|
||||
} else {
|
||||
objStyle.left = '50px'
|
||||
}
|
||||
// objStyle.left = `-${obj1.width - width - 100}px`
|
||||
objStyle.top = `${height + 8}px`
|
||||
// objStyle1.left = obj1.width / 2 - 6 + 'px'
|
||||
break
|
||||
// case 'top-start':
|
||||
// objStyle.left = `0px`
|
||||
// objStyle.bottom = `${height + 8}px`
|
||||
// break;
|
||||
// case 'top-end':
|
||||
// objStyle.right = `0px`
|
||||
// objStyle.bottom = `${height + 8}px`
|
||||
// objStyle1.right = `8px`
|
||||
// break;
|
||||
// case 'bottom-start':
|
||||
// objStyle.left = `0px`
|
||||
// objStyle.top = `${height + 8}px`
|
||||
// objStyle1.left = `8px`
|
||||
// break;
|
||||
|
||||
// case 'bottom-end':
|
||||
// objStyle.right = `0px`
|
||||
// objStyle.top = `${height + 8}px`
|
||||
// objStyle1.right = `8px`
|
||||
// break;
|
||||
|
||||
// case 'right':
|
||||
// objStyle.left = `${width + 8}px`
|
||||
// if (obj1.height > height) {
|
||||
// objStyle.top = `-${(obj1.height - height) / 2}px`
|
||||
// } else {
|
||||
// objStyle.top = `${Math.abs((obj1.height - height) / 2)}px`
|
||||
// }
|
||||
|
||||
// objStyle1.top = `${obj1.height / 2 - 6}px`
|
||||
// break;
|
||||
// case 'right-start':
|
||||
// objStyle.left = `${width + 8}px`
|
||||
// objStyle.top = `0px`
|
||||
// objStyle1.top = `8px`
|
||||
// break;
|
||||
|
||||
// case 'right-end':
|
||||
// objStyle.left = `${width + 8}px`
|
||||
// objStyle.bottom = `0px`
|
||||
// objStyle1.bottom = `8px`
|
||||
// break;
|
||||
|
||||
// case 'left':
|
||||
// objStyle.right = `${width + 8}px`
|
||||
|
||||
// if (obj1.height > height) {
|
||||
// objStyle.top = `-${(obj1.height - height) / 2}px`
|
||||
// } else {
|
||||
// objStyle.top = `${Math.abs((obj1.height - height) / 2)}px`
|
||||
// }
|
||||
|
||||
// objStyle1.top = `${obj1.height / 2 - 6}px`
|
||||
// break;
|
||||
|
||||
// case 'left-start':
|
||||
// objStyle.right = `${width + 8}px`
|
||||
// objStyle.top = `0px`
|
||||
// objStyle1.top = `8px`
|
||||
// break;
|
||||
|
||||
// case 'left-end':
|
||||
// objStyle.right = `${width + 8}px`
|
||||
// objStyle.bottom = `0px`
|
||||
// objStyle1.bottom = `8px`
|
||||
// break;
|
||||
}
|
||||
this.style = objStyle
|
||||
// 三角形箭头
|
||||
this.arrowStyle = objStyle1
|
||||
resolve()
|
||||
})
|
||||
.exec()
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$theme-bg-color: var(--theme-bg-color);
|
||||
|
||||
.zb-tooltip {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.zb_tooltip_content {
|
||||
height: 100%;
|
||||
/* float: left; */
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
// display: flex;
|
||||
// flex-direction: row;
|
||||
// align-items: center;
|
||||
/* overflow: hidden; */
|
||||
}
|
||||
|
||||
.zb_tooltip__popper {
|
||||
/* transform-origin: center top; */
|
||||
background: $theme-bg-color;
|
||||
|
||||
visibility: hidden;
|
||||
// color:'#fff';
|
||||
position: absolute;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
padding: 10px;
|
||||
min-width: 10px;
|
||||
word-wrap: break-word;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.zb_tooltip__mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background-color: rgba(256, 256, 256, 0);
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
.zb_popper__icon {
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: 9;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.zb_popper__arrow {
|
||||
bottom: -5px;
|
||||
/* transform-origin: center top; */
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid $theme-bg-color;
|
||||
}
|
||||
|
||||
.zb_popper__right {
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-right: 6px solid $theme-bg-color;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.zb_popper__left {
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-left: 6px solid $theme-bg-color;
|
||||
right: -5px;
|
||||
}
|
||||
|
||||
.zb_popper__up {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid $theme-bg-color;
|
||||
top: -5px;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
pointer-events: auto;
|
||||
background: red;
|
||||
z-index: -1;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="user-wrapper">
|
||||
<div class="avatar-wrapper">
|
||||
<Avatar v-if="props.account" size="70" :account="props.account"></Avatar>
|
||||
</div>
|
||||
<div class="account-wrapper">
|
||||
<div v-if="alias">
|
||||
<div class="main">{{ alias }}</div>
|
||||
<div class="deputy">{{ t('name') }}:{{ nick || account }}</div>
|
||||
</div>
|
||||
<div v-else class="main">{{ nick || account }}</div>
|
||||
<div class="deputy">
|
||||
{{ t('accountText') }}:{{ props.account }}
|
||||
<div @tap.stop="copyAccount">
|
||||
<Icon
|
||||
class="copy-icon"
|
||||
type="icon-fuzhi1"
|
||||
color="#A6ADB6"
|
||||
:size="20"
|
||||
></Icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Avatar from './Avatar.vue'
|
||||
import Icon from './Icon.vue'
|
||||
import { onUnmounted, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { autorun } from 'mobx'
|
||||
import { t } from '../utils/i18n'
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
account?: string
|
||||
nick?: string
|
||||
}>(),
|
||||
{
|
||||
account: '',
|
||||
nick: '',
|
||||
}
|
||||
)
|
||||
const alias = ref<string>()
|
||||
let uninstallFriendsWatch = () => {}
|
||||
|
||||
onLoad((props) => {
|
||||
let account = props ? props.account : ''
|
||||
uninstallFriendsWatch = autorun(() => {
|
||||
const friend = { ...uni.$UIKitStore.friendStore.friends.get(account) }
|
||||
alias.value = friend ? friend.alias : ''
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
uninstallFriendsWatch()
|
||||
})
|
||||
|
||||
const copyAccount = () => {
|
||||
uni.setClipboardData({
|
||||
data: props.account,
|
||||
showToast: false,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: t('copySuccessText'),
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: t('copyFailText'),
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '../pages/styles/common.scss';
|
||||
|
||||
.user-wrapper {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
height: 140px;
|
||||
align-items: center;
|
||||
|
||||
.avatar-wrapper {
|
||||
margin: 0 15px;
|
||||
flex: 0 0 70px;
|
||||
}
|
||||
|
||||
.account-wrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding-right: 40px;
|
||||
|
||||
.main {
|
||||
font-size: 20px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.deputy {
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 当父组件传递的prop属性数据发生变化的时候 ,生成海报图片-->
|
||||
<view :prop="domId" :change:prop="html2canvas.emitData" class="html2canvas">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { base64ToPath } from '@/utils/image-tools.js';
|
||||
export default {
|
||||
props: {
|
||||
domId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted:function(){
|
||||
console.log("组件加载完成");
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 接收renderjs发回的数据
|
||||
async receiveRenderData(imgData) {
|
||||
let posterHeight=imgData.height;
|
||||
let posterWidth=imgData.width;
|
||||
let imgPath =await base64ToPath(imgData.imgVal, '.jpeg');
|
||||
this.$emit('renderFinish', {"posterPath":imgPath,"posterHeight":posterHeight,"posterWidth":posterWidth});
|
||||
uni.hideLoading();
|
||||
},
|
||||
showLoading() {
|
||||
uni.showLoading({
|
||||
title: "正在生成导出",
|
||||
icon: "none",
|
||||
mask: true,
|
||||
duration: 3000
|
||||
})
|
||||
},
|
||||
hideLoading() {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script module="html2canvas" lang="renderjs">
|
||||
import html2canvas from 'html2canvas';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
mounted:function(){
|
||||
console.log("视图层渲染完成");
|
||||
},
|
||||
methods: {
|
||||
// 发送数据到逻辑层,下面这里最好是加一个settimeout延迟,因为主界面数据还没加载渲染完成
|
||||
emitData(domId) {
|
||||
this.$ownerInstance.callMethod('showLoading', true);
|
||||
const dom = document.getElementById('poster');
|
||||
console.log("dom",dom);
|
||||
let width= dom.offsetWidth;
|
||||
let height=dom.offsetHeight;
|
||||
let windowHeight= uni.getSystemInfoSync().windowHeight;
|
||||
let windowWidth=uni.getSystemInfoSync().windowWidth;
|
||||
html2canvas(dom, {
|
||||
width:width,
|
||||
height:height,
|
||||
//scale:2.5, // 缩放倍数
|
||||
scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
|
||||
scrollX: 0,
|
||||
x:0,
|
||||
y:0,
|
||||
windowWidth:windowWidth,
|
||||
windowHeight:windowHeight,
|
||||
useCORS: true, //支持跨域,但好像没什么用
|
||||
}).then((canvas) => {
|
||||
let imgVal= canvas.toDataURL('image/png');
|
||||
this.$ownerInstance.callMethod('receiveRenderData',{imgVal:imgVal,height:height,width:width});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 当父组件传递的prop属性数据发生变化的时候 ,生成海报图片-->
|
||||
<view :prop="domId" :change:prop="html2canvas.emitData" class="html2canvas">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { base64ToPath } from '@/utils/image-tools.js';
|
||||
export default {
|
||||
props: {
|
||||
domId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted:function(){
|
||||
console.log("组件加载完成");
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 接收renderjs发回的数据
|
||||
async receiveRenderData(imgData) {
|
||||
let posterHeight=imgData.height;
|
||||
let posterWidth=imgData.width;
|
||||
let imgPath =await base64ToPath(imgData.imgVal, '.jpeg');
|
||||
this.$emit('renderFinish', {"posterPath":imgPath,"posterHeight":posterHeight,"posterWidth":posterWidth});
|
||||
uni.hideLoading();
|
||||
},
|
||||
showLoading() {
|
||||
uni.showLoading({
|
||||
title: "正在生成导出",
|
||||
icon: "none",
|
||||
mask: true,
|
||||
duration: 3000
|
||||
})
|
||||
},
|
||||
hideLoading() {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script module="html2canvas" lang="renderjs">
|
||||
import html2canvas from 'html2canvas';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
mounted:function(){
|
||||
console.log("视图层渲染完成");
|
||||
},
|
||||
methods: {
|
||||
// 发送数据到逻辑层,下面这里最好是加一个settimeout延迟,因为主界面数据还没加载渲染完成
|
||||
emitData(domId) {
|
||||
this.$ownerInstance.callMethod('showLoading', true);
|
||||
const dom = document.getElementById('poster');
|
||||
console.log("dom",dom);
|
||||
let width= dom.offsetWidth;
|
||||
let height=dom.offsetHeight;
|
||||
let windowHeight= uni.getSystemInfoSync().windowHeight;
|
||||
let windowWidth=uni.getSystemInfoSync().windowWidth;
|
||||
html2canvas(dom, {
|
||||
width:width,
|
||||
height:height,
|
||||
//scale:2.5, // 缩放倍数
|
||||
scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
|
||||
scrollX: 0,
|
||||
x:0,
|
||||
y:0,
|
||||
windowWidth:windowWidth,
|
||||
windowHeight:windowHeight,
|
||||
useCORS: true, //支持跨域,但好像没什么用
|
||||
}).then((canvas) => {
|
||||
let imgVal= canvas.toDataURL('image/png');
|
||||
this.$ownerInstance.callMethod('receiveRenderData',{imgVal:imgVal,height:height,width:width});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -3,7 +3,7 @@
|
||||
<view class="dialog-container" @click.stop>
|
||||
<!-- 弹窗标题 -->
|
||||
<view class="dialog-header">
|
||||
<text class="dialog-title">{{ title }}</text>
|
||||
<text class="dialog-title" :style="{ color: titleColor }">{{ title }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 弹窗内容 -->
|
||||
@@ -42,13 +42,13 @@
|
||||
|
||||
@click="oncancel"
|
||||
>
|
||||
<text class="btn-text">取消</text>
|
||||
<text class="btn-text">{{ cancelText }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="dialog-btn confirm"
|
||||
@click="onconfirm"
|
||||
>
|
||||
<text class="btn-text">确定</text>
|
||||
<text class="btn-text">{{ confirmText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -63,6 +63,10 @@
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
titleColor: {
|
||||
type: String,
|
||||
default: '#8B2316'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '温馨提示'
|
||||
@@ -130,6 +134,8 @@
|
||||
}
|
||||
|
||||
.dialog-container {
|
||||
position: relative;
|
||||
z-index:100;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
width: 92%;
|
||||
|
||||
@@ -1,23 +1,85 @@
|
||||
<template>
|
||||
<view class="emptybox">
|
||||
<up-image :src="emptyImg" width="176rpx" height="204rpx" ></up-image>
|
||||
<text class="empty-text">暂无数据</text>
|
||||
<view class="empty-image-wrap" :style="imageWrapStyle">
|
||||
<up-image
|
||||
:src="emptyImage || emptyImg"
|
||||
:width="renderWidth"
|
||||
:height="renderHeight"
|
||||
:mode="imgMode"
|
||||
></up-image>
|
||||
</view>
|
||||
<text class="empty-text">{{ emptyDesc }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import { computed } from 'vue';
|
||||
import emptyImg from "@/static/icon_empty.png"
|
||||
const props = defineProps({
|
||||
emptyImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
imgWidth: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
imgHeight: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
emptyDesc: {
|
||||
type: String,
|
||||
default: '暂无数据'
|
||||
}
|
||||
})
|
||||
|
||||
const normalizeSize = (size) => {
|
||||
if (size === '' || size === null || size === undefined) return '';
|
||||
// 直传字符串(如 50%、206rpx、120px),数字交给 up-image 按组件规则处理
|
||||
return typeof size === 'string' ? size.trim() : size;
|
||||
};
|
||||
const isPercentSize = (size) => typeof size === 'string' && size.endsWith('%');
|
||||
|
||||
const imgWidth = computed(() => {
|
||||
const width = normalizeSize(props.imgWidth);
|
||||
const height = normalizeSize(props.imgHeight);
|
||||
if (width !== '') return width;
|
||||
if (height === '') return '206rpx';
|
||||
return '';
|
||||
});
|
||||
const imgHeight = computed(() => normalizeSize(props.imgHeight));
|
||||
const renderWidth = computed(() => (isPercentSize(imgWidth.value) ? '100%' : imgWidth.value));
|
||||
const renderHeight = computed(() => (isPercentSize(imgHeight.value) ? '100%' : imgHeight.value));
|
||||
const imageWrapStyle = computed(() => {
|
||||
const style = {};
|
||||
if (isPercentSize(imgWidth.value)) style.width = imgWidth.value;
|
||||
if (isPercentSize(imgHeight.value)) style.height = imgHeight.value;
|
||||
return style;
|
||||
});
|
||||
const imgMode = computed(() => {
|
||||
// 只传宽/高时按比例缩放,避免图片被拉伸
|
||||
if (imgWidth.value && !imgHeight.value) return 'widthFix';
|
||||
if (!imgWidth.value && imgHeight.value) return 'heightFix';
|
||||
return 'aspectFit';
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.emptybox{
|
||||
width:100%;
|
||||
height:800rpx;
|
||||
min-width:600rpx;
|
||||
display: flex;
|
||||
margin:0 auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.empty-image-wrap{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.empty-text{
|
||||
font-size: 30rpx;
|
||||
color:#999;
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
<template>
|
||||
<!-- 顶部导航栏 -->
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
<view class="navbox">
|
||||
<view class="status_bar"></view>
|
||||
<uni-nav-bar
|
||||
:left-icon="showLeft?'left':''"
|
||||
:title="title"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eeeeee"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
cosnt props=defineProps({
|
||||
const props=defineProps({
|
||||
showLeft:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
noticeBack:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
title:{
|
||||
type:String,
|
||||
default:''
|
||||
@@ -29,10 +38,21 @@
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.navbox{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height:(var(--status-bar-height)+44px);
|
||||
z-index: 9999;
|
||||
}
|
||||
.status_bar{
|
||||
height: var(--status-bar-height);
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file 拖动进度提示组件
|
||||
*/
|
||||
<template>
|
||||
<view class="plv-player-drag-tips">
|
||||
<view class="plv-player-drag-tips__box">
|
||||
<image class="plv-player-drag-tips__direction-img" :src="imgSrc"
|
||||
@error="imageError">
|
||||
</image>
|
||||
<text class="plv-player-drag-tips__time">
|
||||
{{changeTimeFormat}} / {{durationFormat}}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from '@/common/util.js';
|
||||
import backImg from '@/static/skin/back.png';
|
||||
import forwardImg from '@/static/skin/forward.png'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
currentTime: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
duration: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
changeTime: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isForward: false
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
watch: {
|
||||
changeTime(newValue, oldValue){
|
||||
this.isForward = newValue > oldValue;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
timeFormatType() {
|
||||
this.duration >= 3600 ? 2 : 1;
|
||||
},
|
||||
|
||||
changeTimeFormat() {
|
||||
return utils.formatTimeByDuration(this.changeTime, this.timeFormatType);
|
||||
},
|
||||
|
||||
durationFormat() {
|
||||
return utils.formatTimeByDuration(this.duration, this.timeFormatType)
|
||||
},
|
||||
|
||||
imgSrc() {
|
||||
return this.isForward ? forwardImg : backImg;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.plv-player-drag-tips {
|
||||
width: 250rpx;
|
||||
height: 160rpx;
|
||||
background: rgba(0,0,0,.7);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.plv-player-drag-tips__box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.plv-player-drag-tips__direction-img {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.plv-player-drag-tips__time {
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<view class="plv-player-gesture"
|
||||
@touchstart="touchstart"
|
||||
@touchmove="touchmove"
|
||||
@longpress="handleLongPress"
|
||||
@touchcancel="handleTouchCancel"
|
||||
@touchend="touchend">
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 屏幕宽度(物理像素)
|
||||
holeWidth: Number,
|
||||
// 视频总时长
|
||||
duration: Number,
|
||||
// 视频当前播放时间
|
||||
currentTime: Number
|
||||
},
|
||||
|
||||
computed: {
|
||||
halfWidth() {
|
||||
return parseInt(this.holeWidth / 2);
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 是否在左区域按下手势
|
||||
downLeft: false,
|
||||
// 滑动方向
|
||||
swipeDir: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.addHandler();
|
||||
},
|
||||
|
||||
methods:{
|
||||
addHandler() {
|
||||
// 增加父容器左右滑动监听
|
||||
let finalTime = -1;
|
||||
// 计算左右滑动seek进度
|
||||
const countTime = (position) => {
|
||||
const { holeWidth, duration, currentTime } = this;
|
||||
const precent = Math.abs(position) / holeWidth;
|
||||
const nowTime = currentTime || 0;
|
||||
const constSecond = duration < 60 ? duration : 60;
|
||||
let plusTime = parseInt(Math.abs(precent * constSecond));
|
||||
if (position < 0) plusTime = plusTime * -1;
|
||||
finalTime = nowTime + plusTime;
|
||||
finalTime = this.limit(finalTime, 0, duration);
|
||||
return finalTime;
|
||||
};
|
||||
|
||||
this.addGesture((type, position) => {
|
||||
switch (type) {
|
||||
// 下滑
|
||||
case -1:
|
||||
// console.log('//下滑');
|
||||
this.$emit('onGestureEvent', {
|
||||
type: this.downLeft ? 'LEFT_DOWN' : 'RIGHT_DOWN',
|
||||
position
|
||||
});
|
||||
break;
|
||||
// 上滑
|
||||
case -2:
|
||||
// console.log('//上滑');
|
||||
this.$emit('onGestureEvent', {
|
||||
type: this.downLeft ? 'LEFT_UP' : 'RIGHT_UP',
|
||||
position
|
||||
});
|
||||
break;
|
||||
// 左滑
|
||||
case 0:
|
||||
// console.log('//左滑');
|
||||
this.swipeDir = type;
|
||||
countTime(position);
|
||||
this.$emit('onGestureEvent', {
|
||||
type: 'SEEK_TIME_UPDATE',
|
||||
finalTime
|
||||
});
|
||||
break;
|
||||
// 右滑
|
||||
case 1:
|
||||
// console.log('//右滑');
|
||||
this.swipeDir = type;
|
||||
countTime(position);
|
||||
this.$emit('onGestureEvent', {
|
||||
type: 'SEEK_TIME_UPDATE',
|
||||
finalTime
|
||||
});
|
||||
break;
|
||||
// touchend for swipe
|
||||
case 3:
|
||||
if (this.swipeDir > -1) {
|
||||
this.$emit('onGestureEvent', {
|
||||
type: this.swipeDir ? 'SWIPE_RIGHT' : 'SWIPE_LEFT'
|
||||
});
|
||||
this.swipeDir = -1;
|
||||
}
|
||||
|
||||
if (finalTime > -1) {
|
||||
this.$emit('onGestureSeekTo', finalTime);
|
||||
finalTime = -1;
|
||||
}
|
||||
break;
|
||||
// doubleTap
|
||||
case 4:
|
||||
// console.log('>>>> 双击');
|
||||
this.$emit('onGestureEvent', {
|
||||
type: 'DOUBLE_CLICK'
|
||||
});
|
||||
break;
|
||||
// tap
|
||||
case 5:
|
||||
// console.log('>>>> 单击');
|
||||
this.handleClick();
|
||||
break;
|
||||
// longTap
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addGesture(callback) {
|
||||
const { options } = this;
|
||||
let startX, startY, moveEndX, moveEndY, X, Y, position, hasType;
|
||||
let T, lastTap, isJustTouch = true;
|
||||
|
||||
|
||||
const excuteCb = (type) => {
|
||||
// type 手势类型 -2 上滑 -1 下滑 0 左滑 1 右滑 2 just touch 3 touchend 4 doubleTap 5 tap 6 longTap
|
||||
if (callback && typeof callback === 'function')
|
||||
callback(type, position);
|
||||
};
|
||||
|
||||
const YPlus = 20;
|
||||
const YReduce = YPlus * -1;
|
||||
const XPlus = 50;
|
||||
const XReduce = XPlus * -1;
|
||||
|
||||
const isXchange = () => {
|
||||
if (X > XPlus || X < XReduce) {
|
||||
position = X;
|
||||
hasType = 'X';
|
||||
isJustTouch = false;
|
||||
}
|
||||
|
||||
if (X > XPlus) excuteCb(1);
|
||||
// 左滑
|
||||
else if (X < XReduce) excuteCb(0);
|
||||
};
|
||||
|
||||
const isYchange = () => {
|
||||
if (Y > YPlus || Y < YReduce) {
|
||||
position = Y;
|
||||
hasType = 'Y';
|
||||
isJustTouch = false;
|
||||
}
|
||||
|
||||
if (Y > YPlus) excuteCb(-1);
|
||||
// 上滑
|
||||
else if (Y < YReduce) excuteCb(-2);
|
||||
};
|
||||
|
||||
const countDirect = () => {
|
||||
if (hasType) {
|
||||
hasType === 'X' ? isXchange() : isYchange();
|
||||
return;
|
||||
}
|
||||
isXchange();
|
||||
isYchange();
|
||||
};
|
||||
|
||||
this.handleTouch = (type, e) => {
|
||||
switch(type) {
|
||||
case 'start':
|
||||
startX = e.changedTouches[0].pageX;
|
||||
startY = e.changedTouches[0].pageY;
|
||||
T = Date.now();
|
||||
hasType = '';
|
||||
isJustTouch = true;
|
||||
this.downLeft = startX < this.halfWidth ? true : false;
|
||||
|
||||
break;
|
||||
case 'move':
|
||||
moveEndX = e.changedTouches[0].pageX;
|
||||
moveEndY = e.changedTouches[0].pageY;
|
||||
X = moveEndX - startX;
|
||||
Y = moveEndY - startY;
|
||||
countDirect();
|
||||
break;
|
||||
case 'end':
|
||||
if (isJustTouch)
|
||||
if (lastTap && Date.now() - lastTap <= 300)
|
||||
excuteCb(4);
|
||||
else if (Date.now() - T < 1000)
|
||||
excuteCb(5);
|
||||
else
|
||||
excuteCb(6);
|
||||
else
|
||||
excuteCb(3);
|
||||
|
||||
lastTap = Date.now();
|
||||
isJustTouch = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
handleClick() {
|
||||
this.$emit('onGestureClick');
|
||||
},
|
||||
|
||||
touchstart(e) {
|
||||
this.handleTouch('start', e);
|
||||
},
|
||||
|
||||
touchmove(e) {
|
||||
this.handleTouch('move', e);
|
||||
},
|
||||
|
||||
touchend(e) {
|
||||
this.handleTouch('end', e);
|
||||
this.$emit('onTouchEnd');
|
||||
},
|
||||
|
||||
handleTouchCancel() {
|
||||
this.$emit('onTouchCancel');
|
||||
},
|
||||
|
||||
handleLongPress() {
|
||||
this.$emit('onLongPress');
|
||||
},
|
||||
|
||||
/**
|
||||
* 控制最小值,最大值
|
||||
* @param num
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns {*}
|
||||
*/
|
||||
limit(num, min, max) {
|
||||
if (num < min) return min;
|
||||
if (num > max) return max;
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.plv-player-gesture {
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.plv-player-gesture__left {
|
||||
flex: 5;
|
||||
}
|
||||
|
||||
.plv-player-gesture__right {
|
||||
flex: 5;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<view v-if="isShow" class="plv-player-icon">
|
||||
<image class="plv-player-icon__img" :src="imgUrl"></image>
|
||||
<text class="plv-player-icon__text">{{ precent + '%' }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
imgUrl: {
|
||||
type: 'string',
|
||||
required: true
|
||||
},
|
||||
precent: {
|
||||
type: 'Number',
|
||||
default: 100,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
precent(num) {
|
||||
if (!this.isShow) this.isShow = true;
|
||||
this.startClock();
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isShow: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
startClock() {
|
||||
this.clearClock();
|
||||
|
||||
this.clock = setTimeout(() => {
|
||||
this.isShow = false;
|
||||
}, 1500);
|
||||
},
|
||||
|
||||
clearClock() {
|
||||
if (this.clock) clearTimeout(this.clock);
|
||||
this.clock = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.plv-player-icon {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.plv-player-icon__img {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.plv-player-icon__text {
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<view v-if="isShow" class="plv-player-volume-wrap">
|
||||
<image class="plv-player-volume__img" :src="value === 0 ? muteImgUrl : imgUrl "></image>
|
||||
<view class="plv-player-volume__progress">
|
||||
<view class="plv-player-volume__progress__played" :style="'flex:' + value"></view>
|
||||
<view class="plv-player-volume__progress_surplus" :style="'flex:' + valueLeft"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
imgUrl: {
|
||||
type: 'string',
|
||||
required: true
|
||||
},
|
||||
muteImgUrl: {
|
||||
type: 'string',
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: 'Number',
|
||||
default: 0.5,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(num) {
|
||||
if (!this.isShow) this.isShow = true;
|
||||
this.startClock();
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
valueLeft() {
|
||||
return 1 - this.value;
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isShow: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
startClock() {
|
||||
this.clearClock();
|
||||
|
||||
this.clock = setTimeout(() => {
|
||||
this.isShow = false;
|
||||
}, 1500);
|
||||
},
|
||||
|
||||
clearClock() {
|
||||
if (this.clock) clearTimeout(this.clock);
|
||||
this.clock = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.plv-player-volume-wrap {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.plv-player-volume__img {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.plv-player-volume__progress {
|
||||
width: 260rpx;
|
||||
height: 8rpx;
|
||||
flex-direction: row;
|
||||
background-color: #09BB07;
|
||||
}
|
||||
|
||||
.plv-player-volume__progress__played {
|
||||
background-color: #007AFF;
|
||||
}
|
||||
|
||||
.plv-player-volume__progress_surplus {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
@@ -5,7 +5,7 @@
|
||||
v-for="(item, index) in tabList"
|
||||
:key="index"
|
||||
@click="switchTab(index, item)"
|
||||
:class="{ active: currentTab === index }"
|
||||
:class="{ active: 2 === index }"
|
||||
>
|
||||
<!-- 图标容器 -->
|
||||
<view class="icon-container">
|
||||
@@ -33,11 +33,13 @@
|
||||
<!-- <view class="active-indicator" v-if="currentTab === index"></view> -->
|
||||
</view>
|
||||
</view>
|
||||
<GlobalDialog />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||
import GlobalDialog from "@/components/GlobalDialog.vue"
|
||||
import home from '@/static/home_nor.png'
|
||||
import homeOn from '@/static/home_sel.png'
|
||||
import classroom from "@/static/classroom.png"
|
||||
@@ -70,7 +72,7 @@
|
||||
activeColor: '#007aff',
|
||||
badge: 0,
|
||||
showRedDot: false,
|
||||
pagePath: '/pages/index/index'
|
||||
pagePath: '/pages/index/index?from=push'
|
||||
},
|
||||
{
|
||||
icon: classroom,
|
||||
@@ -119,35 +121,56 @@
|
||||
if (currentTab.value === index) return;
|
||||
|
||||
// 更新当前tab
|
||||
currentTab.value = index;
|
||||
|
||||
// 清除红点
|
||||
if (item.showRedDot) {
|
||||
item.showRedDot = false;
|
||||
//currentTab.value = index;
|
||||
let msg="home"
|
||||
if(index == 0){
|
||||
msg="home"
|
||||
}else if(index == 1){
|
||||
msg="patientClass"
|
||||
}else if(index == 2){
|
||||
msg="live"
|
||||
}else if(index == 3){
|
||||
msg="education"
|
||||
}else if(index == 4){
|
||||
msg="mine"
|
||||
}
|
||||
|
||||
try{
|
||||
uni.sendNativeEvent('goTabbarPage', {
|
||||
msg: msg
|
||||
},ret => {
|
||||
|
||||
console.log(ret);
|
||||
})
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
plus.runtime.quit()
|
||||
// 清除红点
|
||||
// if (item.showRedDot) {
|
||||
// item.showRedDot = false;
|
||||
// }
|
||||
|
||||
// 页面跳转
|
||||
uni.switchTab({
|
||||
url: item.pagePath,
|
||||
fail: () => {
|
||||
// 如果页面不存在,使用navigateTo
|
||||
uni.navigateTo({
|
||||
url: item.pagePath,
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '页面开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// uni.redirectTo({
|
||||
// url: item.pagePath,
|
||||
// fail: () => {
|
||||
// // 如果页面不存在,使用navigateTo
|
||||
// uni.navigateTo({
|
||||
// url: item.pagePath,
|
||||
// fail: () => {
|
||||
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// 触发父组件事件
|
||||
emit('tabChange', {
|
||||
index,
|
||||
item
|
||||
});
|
||||
// emit('tabChange', {
|
||||
// index,
|
||||
// item
|
||||
// });
|
||||
|
||||
};
|
||||
|
||||
// 设置徽章数量
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<view class="top-tip" v-if="visible">
|
||||
<view class="title">{{ title }}</view>
|
||||
<view class="content">
|
||||
{{ content }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
}
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.top-tip{
|
||||
position: fixed;
|
||||
top: 180rpx;
|
||||
left: 40rpx;
|
||||
right:40rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
z-index: 99999999999;
|
||||
.title{
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
|
||||
}
|
||||
.content{
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
margin-top: 25rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<a
|
||||
v-if="isShowA"
|
||||
class="uni-link"
|
||||
:href="href"
|
||||
:class="{
|
||||
'uni-link--withline': showUnderLine === true || showUnderLine === 'true',
|
||||
}"
|
||||
:style="{ color, fontSize: fontSize + 'px' }"
|
||||
:download="download"
|
||||
>
|
||||
<slot>{{ text }}</slot>
|
||||
</a>
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<text
|
||||
v-else
|
||||
class="uni-link"
|
||||
:class="{
|
||||
'uni-link--withline': showUnderLine === true || showUnderLine === 'true',
|
||||
}"
|
||||
:style="{ color, fontSize: fontSize + 'px' }"
|
||||
@click="openURL"
|
||||
>
|
||||
<slot>{{ text }}</slot>
|
||||
</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<text
|
||||
v-else
|
||||
class="uni-link"
|
||||
:class="{
|
||||
'uni-link--withline': showUnderLine === true || showUnderLine === 'true',
|
||||
}"
|
||||
:style="{ color, fontSize: fontSize + 'px' }"
|
||||
@click="openURL"
|
||||
>
|
||||
{{ text }}
|
||||
</text>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Link 外部网页超链接组件
|
||||
* @description uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=1182
|
||||
* @property {String} href 点击后打开的外部网页url
|
||||
* @property {String} text 显示的文字
|
||||
* @property {String} downlaod H5平台下载文件名
|
||||
* @property {Boolean} showUnderLine 是否显示下划线
|
||||
* @property {String} copyTips 在小程序端复制链接时显示的提示语
|
||||
* @property {String} color 链接文字颜色
|
||||
* @property {String} fontSize 链接文字大小
|
||||
* @example * <uni-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn"></uni-link>
|
||||
*/
|
||||
export default {
|
||||
name: 'uniLink',
|
||||
props: {
|
||||
href: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
download: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
showUnderLine: {
|
||||
type: [Boolean, String],
|
||||
default: true,
|
||||
},
|
||||
copyTips: {
|
||||
type: String,
|
||||
default: '已自动复制网址,请在手机浏览器里粘贴该网址',
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#999999',
|
||||
},
|
||||
fontSize: {
|
||||
type: [Number, String],
|
||||
default: 14,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isShowA() {
|
||||
// #ifdef H5
|
||||
this._isH5 = true
|
||||
// #endif
|
||||
if ((this.isMail() || this.isTel()) && this._isH5 === true) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this._isH5 = null
|
||||
},
|
||||
methods: {
|
||||
isMail() {
|
||||
return this.href.startsWith('mailto:')
|
||||
},
|
||||
isTel() {
|
||||
return this.href.startsWith('tel:')
|
||||
},
|
||||
openURL() {
|
||||
// #ifdef APP-PLUS
|
||||
if (this.isTel()) {
|
||||
this.makePhoneCall(this.href.replace('tel:', ''))
|
||||
} else {
|
||||
plus.runtime.openURL(this.href)
|
||||
}
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
window.open(this.href)
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
uni.setClipboardData({
|
||||
data: this.href,
|
||||
showToast: false,
|
||||
})
|
||||
uni.showModal({
|
||||
content: this.copyTips,
|
||||
showCancel: false,
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
makePhoneCall(phoneNumber) {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.uni-link--withline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
// #ifdef H5
|
||||
export default {
|
||||
name: 'Keypress',
|
||||
props: {
|
||||
disable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const keyNames = {
|
||||
esc: ['Esc', 'Escape'],
|
||||
tab: 'Tab',
|
||||
enter: 'Enter',
|
||||
space: [' ', 'Spacebar'],
|
||||
up: ['Up', 'ArrowUp'],
|
||||
left: ['Left', 'ArrowLeft'],
|
||||
right: ['Right', 'ArrowRight'],
|
||||
down: ['Down', 'ArrowDown'],
|
||||
delete: ['Backspace', 'Delete', 'Del'],
|
||||
}
|
||||
const listener = ($event) => {
|
||||
if (this.disable) {
|
||||
return
|
||||
}
|
||||
const keyName = Object.keys(keyNames).find((key) => {
|
||||
const keyName = $event.key
|
||||
const value = keyNames[key]
|
||||
return (
|
||||
value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||
)
|
||||
})
|
||||
if (keyName) {
|
||||
// 避免和其他按键事件冲突
|
||||
setTimeout(() => {
|
||||
this.$emit(keyName, {})
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
document.addEventListener('keyup', listener)
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
document.removeEventListener('keyup', listener)
|
||||
})
|
||||
},
|
||||
render: () => {
|
||||
return null
|
||||
},
|
||||
}
|
||||
// #endif
|
||||
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<view class="uni-popup-dialog">
|
||||
<view class="uni-dialog-title">
|
||||
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
|
||||
</view>
|
||||
<view v-if="mode === 'base'" class="uni-dialog-content">
|
||||
<slot>
|
||||
<text class="uni-dialog-content-text">{{content}}</text>
|
||||
</slot>
|
||||
</view>
|
||||
<view v-else class="uni-dialog-content">
|
||||
<slot>
|
||||
<input class="uni-dialog-input" v-model="val" :type="inputType" :placeholder="placeholderText" :focus="focus" >
|
||||
</slot>
|
||||
</view>
|
||||
<view class="uni-dialog-button-group">
|
||||
<view class="uni-dialog-button" @click="closeDialog">
|
||||
<text class="uni-dialog-button-text">{{closeText}}</text>
|
||||
</view>
|
||||
<view class="uni-dialog-button uni-border-left" @click="onOk">
|
||||
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import popup from '../uni-popup/popup.js'
|
||||
import {
|
||||
initVueI18n
|
||||
} from '@dcloudio/uni-i18n'
|
||||
import messages from '../uni-popup/i18n/index.js'
|
||||
const { t } = initVueI18n(messages)
|
||||
/**
|
||||
* PopUp 弹出层-对话框样式
|
||||
* @description 弹出层-对话框样式
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||
* @property {String} value input 模式下的默认值
|
||||
* @property {String} placeholder input 模式下输入提示
|
||||
* @property {String} type = [success|warning|info|error] 主题样式
|
||||
* @value success 成功
|
||||
* @value warning 提示
|
||||
* @value info 消息
|
||||
* @value error 错误
|
||||
* @property {String} mode = [base|input] 模式、
|
||||
* @value base 基础对话框
|
||||
* @value input 可输入对话框
|
||||
* @property {String} content 对话框内容
|
||||
* @property {Boolean} beforeClose 是否拦截取消事件
|
||||
* @event {Function} confirm 点击确认按钮触发
|
||||
* @event {Function} close 点击取消按钮触发
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "uniPopupDialog",
|
||||
mixins: [popup],
|
||||
emits:['confirm','close'],
|
||||
props: {
|
||||
inputType:{
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'error'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'base'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
beforeClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
cancelText:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
confirmText:{
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogType: 'error',
|
||||
focus: false,
|
||||
val: ""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
okText() {
|
||||
return this.confirmText || t("uni-popup.ok")
|
||||
},
|
||||
closeText() {
|
||||
return this.cancelText || t("uni-popup.cancel")
|
||||
},
|
||||
placeholderText() {
|
||||
return this.placeholder || t("uni-popup.placeholder")
|
||||
},
|
||||
titleText() {
|
||||
return this.title || t("uni-popup.title")
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
type(val) {
|
||||
this.dialogType = val
|
||||
},
|
||||
mode(val) {
|
||||
if (val === 'input') {
|
||||
this.dialogType = 'info'
|
||||
}
|
||||
},
|
||||
value(val) {
|
||||
this.val = val
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 对话框遮罩不可点击
|
||||
this.popup.disableMask()
|
||||
// this.popup.closeMask()
|
||||
if (this.mode === 'input') {
|
||||
this.dialogType = 'info'
|
||||
this.val = this.value
|
||||
} else {
|
||||
this.dialogType = this.type
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.focus = true
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 点击确认按钮
|
||||
*/
|
||||
onOk() {
|
||||
if (this.mode === 'input'){
|
||||
this.$emit('confirm', this.val)
|
||||
}else{
|
||||
this.$emit('confirm')
|
||||
}
|
||||
if(this.beforeClose) return
|
||||
this.popup.close()
|
||||
},
|
||||
/**
|
||||
* 点击取消按钮
|
||||
*/
|
||||
closeDialog() {
|
||||
this.$emit('close')
|
||||
if(this.beforeClose) return
|
||||
this.popup.close()
|
||||
},
|
||||
close(){
|
||||
this.popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" >
|
||||
.uni-popup-dialog {
|
||||
width: 300px;
|
||||
border-radius: 11px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.uni-dialog-title {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
.uni-dialog-title-text {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.uni-dialog-content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.uni-dialog-content-text {
|
||||
font-size: 14px;
|
||||
color: #6C6C6C;
|
||||
}
|
||||
|
||||
.uni-dialog-button-group {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
border-top-color: #f5f5f5;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.uni-dialog-button {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.uni-border-left {
|
||||
border-left-color: #f0f0f0;
|
||||
border-left-style: solid;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.uni-dialog-button-text {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.uni-button-color {
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.uni-dialog-input {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
border: 1px #eee solid;
|
||||
height: 40px;
|
||||
padding: 0 10px;
|
||||
border-radius: 5px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.uni-popup__success {
|
||||
color: #4cd964;
|
||||
}
|
||||
|
||||
.uni-popup__warn {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.uni-popup__error {
|
||||
color: #dd524d;
|
||||
}
|
||||
|
||||
.uni-popup__info {
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<view class="uni-popup-message">
|
||||
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
|
||||
<slot>
|
||||
<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import popup from '../uni-popup/popup.js'
|
||||
/**
|
||||
* PopUp 弹出层-消息提示
|
||||
* @description 弹出层-消息提示
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||
* @property {String} type = [success|warning|info|error] 主题样式
|
||||
* @value success 成功
|
||||
* @value warning 提示
|
||||
* @value info 消息
|
||||
* @value error 错误
|
||||
* @property {String} message 消息提示文字
|
||||
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'uniPopupMessage',
|
||||
mixins:[popup],
|
||||
props: {
|
||||
/**
|
||||
* 主题 success/warning/info/error 默认 success
|
||||
*/
|
||||
type: {
|
||||
type: String,
|
||||
default: 'success'
|
||||
},
|
||||
/**
|
||||
* 消息文字
|
||||
*/
|
||||
message: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 显示时间,设置为 0 则不会自动关闭
|
||||
*/
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 3000
|
||||
},
|
||||
maskShow:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
created() {
|
||||
this.popup.maskShow = this.maskShow
|
||||
this.popup.messageChild = this
|
||||
},
|
||||
methods: {
|
||||
timerClose(){
|
||||
if(this.duration === 0) return
|
||||
clearTimeout(this.timer)
|
||||
this.timer = setTimeout(()=>{
|
||||
this.popup.close()
|
||||
},this.duration)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" >
|
||||
.uni-popup-message {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.uni-popup-message__box {
|
||||
background-color: #e1f3d8;
|
||||
padding: 10px 15px;
|
||||
border-color: #eee;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
.fixforpc-width {
|
||||
margin-top: 20px;
|
||||
border-radius: 4px;
|
||||
flex: none;
|
||||
min-width: 380px;
|
||||
/* #ifndef APP-NVUE */
|
||||
max-width: 50%;
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
max-width: 500px;
|
||||
/* #endif */
|
||||
}
|
||||
}
|
||||
|
||||
.uni-popup-message-text {
|
||||
font-size: 14px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.uni-popup__success {
|
||||
background-color: #e1f3d8;
|
||||
}
|
||||
|
||||
.uni-popup__success-text {
|
||||
color: #67C23A;
|
||||
}
|
||||
|
||||
.uni-popup__warn {
|
||||
background-color: #faecd8;
|
||||
}
|
||||
|
||||
.uni-popup__warn-text {
|
||||
color: #E6A23C;
|
||||
}
|
||||
|
||||
.uni-popup__error {
|
||||
background-color: #fde2e2;
|
||||
}
|
||||
|
||||
.uni-popup__error-text {
|
||||
color: #F56C6C;
|
||||
}
|
||||
|
||||
.uni-popup__info {
|
||||
background-color: #F2F6FC;
|
||||
}
|
||||
|
||||
.uni-popup__info-text {
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<view class="uni-popup-share">
|
||||
<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
|
||||
<view class="uni-share-content">
|
||||
<view class="uni-share-content-box">
|
||||
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
|
||||
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
|
||||
<text class="uni-share-text">{{item.text}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-share-button-box">
|
||||
<button class="uni-share-button" @click="close">{{cancelText}}</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import popup from '../uni-popup/popup.js'
|
||||
import {
|
||||
initVueI18n
|
||||
} from '@dcloudio/uni-i18n'
|
||||
import messages from '../uni-popup/i18n/index.js'
|
||||
const { t } = initVueI18n(messages)
|
||||
export default {
|
||||
name: 'UniPopupShare',
|
||||
mixins:[popup],
|
||||
emits:['select'],
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
beforeClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
bottomData: [{
|
||||
text: '微信',
|
||||
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
|
||||
name: 'wx'
|
||||
},
|
||||
{
|
||||
text: '支付宝',
|
||||
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
|
||||
name: 'wx'
|
||||
},
|
||||
{
|
||||
text: 'QQ',
|
||||
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
|
||||
name: 'qq'
|
||||
},
|
||||
{
|
||||
text: '新浪',
|
||||
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
|
||||
name: 'sina'
|
||||
},
|
||||
// {
|
||||
// text: '百度',
|
||||
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
|
||||
// name: 'copy'
|
||||
// },
|
||||
// {
|
||||
// text: '其他',
|
||||
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
|
||||
// name: 'more'
|
||||
// }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
computed: {
|
||||
cancelText() {
|
||||
return t("uni-popup.cancel")
|
||||
},
|
||||
shareTitleText() {
|
||||
return this.title || t("uni-popup.shareTitle")
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 选择内容
|
||||
*/
|
||||
select(item, index) {
|
||||
this.$emit('select', {
|
||||
item,
|
||||
index
|
||||
})
|
||||
this.close()
|
||||
|
||||
},
|
||||
/**
|
||||
* 关闭窗口
|
||||
*/
|
||||
close() {
|
||||
if(this.beforeClose) return
|
||||
this.popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" >
|
||||
.uni-popup-share {
|
||||
background-color: #fff;
|
||||
border-top-left-radius: 11px;
|
||||
border-top-right-radius: 11px;
|
||||
}
|
||||
.uni-share-title {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
}
|
||||
.uni-share-title-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
.uni-share-content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.uni-share-content-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.uni-share-content-item {
|
||||
width: 90px;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-share-content-item:active {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.uni-share-image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.uni-share-text {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: #3B4144;
|
||||
}
|
||||
|
||||
.uni-share-button-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.uni-share-button {
|
||||
flex: 1;
|
||||
border-radius: 50px;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.uni-share-button::after {
|
||||
border-radius: 50px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"uni-popup.cancel": "cancel",
|
||||
"uni-popup.ok": "ok",
|
||||
"uni-popup.placeholder": "pleace enter",
|
||||
"uni-popup.title": "Hint",
|
||||
"uni-popup.shareTitle": "Share to"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import en from './en.json'
|
||||
import zhHans from './zh-Hans.json'
|
||||
import zhHant from './zh-Hant.json'
|
||||
export default {
|
||||
en,
|
||||
'zh-Hans': zhHans,
|
||||
'zh-Hant': zhHant,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"uni-popup.cancel": "取消",
|
||||
"uni-popup.ok": "确定",
|
||||
"uni-popup.placeholder": "请输入",
|
||||
"uni-popup.title": "提示",
|
||||
"uni-popup.shareTitle": "分享到"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"uni-popup.cancel": "取消",
|
||||
"uni-popup.ok": "確定",
|
||||
"uni-popup.placeholder": "請輸入",
|
||||
"uni-popup.title": "提示",
|
||||
"uni-popup.shareTitle": "分享到"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// #ifdef H5
|
||||
export default {
|
||||
name: 'Keypress',
|
||||
props: {
|
||||
disable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const keyNames = {
|
||||
esc: ['Esc', 'Escape'],
|
||||
tab: 'Tab',
|
||||
enter: 'Enter',
|
||||
space: [' ', 'Spacebar'],
|
||||
up: ['Up', 'ArrowUp'],
|
||||
left: ['Left', 'ArrowLeft'],
|
||||
right: ['Right', 'ArrowRight'],
|
||||
down: ['Down', 'ArrowDown'],
|
||||
delete: ['Backspace', 'Delete', 'Del'],
|
||||
}
|
||||
const listener = ($event) => {
|
||||
if (this.disable) {
|
||||
return
|
||||
}
|
||||
const keyName = Object.keys(keyNames).find((key) => {
|
||||
const keyName = $event.key
|
||||
const value = keyNames[key]
|
||||
return (
|
||||
value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||
)
|
||||
})
|
||||
if (keyName) {
|
||||
// 避免和其他按键事件冲突
|
||||
setTimeout(() => {
|
||||
this.$emit(keyName, {})
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
document.addEventListener('keyup', listener)
|
||||
// this.$once('hook:beforeDestroy', () => {
|
||||
// document.removeEventListener('keyup', listener)
|
||||
// })
|
||||
},
|
||||
render: () => {
|
||||
return null
|
||||
},
|
||||
}
|
||||
// #endif
|
||||
@@ -0,0 +1,23 @@
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
created() {
|
||||
this.popup = this.getParent()
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取父元素实例
|
||||
*/
|
||||
getParent(name = 'uniPopup') {
|
||||
let parent = this.$parent
|
||||
let parentName = parent.$options.name
|
||||
while (parentName !== name) {
|
||||
parent = parent.$parent
|
||||
if (!parent) return false
|
||||
parentName = parent.$options.name
|
||||
}
|
||||
return parent
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
<template>
|
||||
<view
|
||||
v-if="showPopup"
|
||||
class="uni-popup"
|
||||
:class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']"
|
||||
>
|
||||
<view @touchstart="touchstart">
|
||||
<UniTransition
|
||||
key="1"
|
||||
v-if="maskShow"
|
||||
name="mask"
|
||||
mode-class="fade"
|
||||
:styles="maskClass"
|
||||
:duration="duration"
|
||||
:show="showTrans"
|
||||
@click="onTap"
|
||||
/>
|
||||
<UniTransition
|
||||
key="2"
|
||||
:mode-class="ani"
|
||||
name="content"
|
||||
:styles="transClass"
|
||||
:duration="duration"
|
||||
:show="showTrans"
|
||||
@click="onTap"
|
||||
>
|
||||
<view
|
||||
class="uni-popup__wrapper"
|
||||
:style="{ backgroundColor: bg }"
|
||||
:class="[popupstyle]"
|
||||
@click="clear"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</UniTransition>
|
||||
</view>
|
||||
<!-- #ifdef H5 -->
|
||||
<keypress v-if="maskShow" @esc="onTap" />
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef H5
|
||||
import keypress from './keypress.js'
|
||||
// #endif
|
||||
import UniTransition from '../../../uni-transition/components/uni-transition/uni-transition.vue'
|
||||
/**
|
||||
* PopUp 弹出层
|
||||
* @description 弹出层组件,为了解决遮罩弹层的问题
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||
* @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
|
||||
* @value top 顶部弹出
|
||||
* @value center 中间弹出
|
||||
* @value bottom 底部弹出
|
||||
* @value left 左侧弹出
|
||||
* @value right 右侧弹出
|
||||
* @value message 消息提示
|
||||
* @value dialog 对话框
|
||||
* @value share 底部分享示例
|
||||
* @property {Boolean} animation = [true|false] 是否开启动画
|
||||
* @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
|
||||
* @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
|
||||
* @property {String} backgroundColor 主窗口背景色
|
||||
* @property {String} maskBackgroundColor 蒙版颜色
|
||||
* @property {Boolean} safeArea 是否适配底部安全区
|
||||
* @event {Function} change 打开关闭弹窗触发,e={show: false}
|
||||
* @event {Function} maskClick 点击遮罩触发
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'uniPopup',
|
||||
components: {
|
||||
UniTransition,
|
||||
// #ifdef H5
|
||||
keypress,
|
||||
// #endif
|
||||
},
|
||||
emits: ['change', 'maskClick'],
|
||||
props: {
|
||||
// 开启动画
|
||||
animation: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||
// message: 消息提示 ; dialog : 对话框
|
||||
type: {
|
||||
type: String,
|
||||
default: 'center',
|
||||
},
|
||||
// maskClick
|
||||
isMaskClick: {
|
||||
type: Boolean,
|
||||
default: null,
|
||||
},
|
||||
// TODO 2 个版本后废弃属性 ,使用 isMaskClick
|
||||
maskClick: {
|
||||
type: Boolean,
|
||||
default: null,
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: 'none',
|
||||
},
|
||||
safeArea: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
maskBackgroundColor: {
|
||||
type: String,
|
||||
default: 'rgba(0, 0, 0, 0.4)',
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
/**
|
||||
* 监听type类型
|
||||
*/
|
||||
type: {
|
||||
handler: function (type) {
|
||||
if (!this.config[type]) return
|
||||
this[this.config[type]](true)
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
isDesktop: {
|
||||
handler: function (newVal) {
|
||||
if (!this.config[newVal]) return
|
||||
this[this.config[this.type]](true)
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
/**
|
||||
* 监听遮罩是否可点击
|
||||
* @param {Object} val
|
||||
*/
|
||||
maskClick: {
|
||||
handler: function (val) {
|
||||
this.mkclick = val
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
isMaskClick: {
|
||||
handler: function (val) {
|
||||
this.mkclick = val
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
// H5 下禁止底部滚动
|
||||
showPopup(show) {
|
||||
// #ifdef H5
|
||||
// fix by mehaotian 处理 h5 滚动穿透的问题
|
||||
document.getElementsByTagName('body')[0].style.overflow = show
|
||||
? 'hidden'
|
||||
: 'visible'
|
||||
// #endif
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
duration: 300,
|
||||
ani: [],
|
||||
showPopup: false,
|
||||
showTrans: false,
|
||||
popupWidth: 0,
|
||||
popupHeight: 0,
|
||||
config: {
|
||||
top: 'top',
|
||||
bottom: 'bottom',
|
||||
center: 'center',
|
||||
left: 'left',
|
||||
right: 'right',
|
||||
message: 'top',
|
||||
dialog: 'center',
|
||||
share: 'bottom',
|
||||
},
|
||||
maskClass: {
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
||||
},
|
||||
transClass: {
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
right: 0,
|
||||
},
|
||||
maskShow: true,
|
||||
mkclick: true,
|
||||
popupstyle: this.isDesktop ? 'fixforpc-top' : 'top',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isDesktop() {
|
||||
return this.popupWidth >= 500 && this.popupHeight >= 500
|
||||
},
|
||||
bg() {
|
||||
if (this.backgroundColor === '' || this.backgroundColor === 'none') {
|
||||
return 'transparent'
|
||||
}
|
||||
return this.backgroundColor
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const fixSize = () => {
|
||||
const {
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
windowTop,
|
||||
safeArea,
|
||||
screenHeight,
|
||||
safeAreaInsets,
|
||||
} = uni.getSystemInfoSync()
|
||||
this.popupWidth = windowWidth
|
||||
this.popupHeight = windowHeight + (windowTop || 0)
|
||||
// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
|
||||
if (safeArea && this.safeArea) {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.safeAreaInsets = screenHeight - safeArea.bottom
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
this.safeAreaInsets = safeAreaInsets.bottom
|
||||
// #endif
|
||||
} else {
|
||||
this.safeAreaInsets = 0
|
||||
}
|
||||
}
|
||||
fixSize()
|
||||
// #ifdef H5
|
||||
// window.addEventListener('resize', fixSize)
|
||||
// this.$once('hook:beforeDestroy', () => {
|
||||
// window.removeEventListener('resize', fixSize)
|
||||
// })
|
||||
// #endif
|
||||
},
|
||||
// #ifndef VUE3
|
||||
// TODO vue2
|
||||
destroyed() {
|
||||
this.setH5Visible()
|
||||
},
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
// TODO vue3
|
||||
unmounted() {
|
||||
this.setH5Visible()
|
||||
},
|
||||
// #endif
|
||||
created() {
|
||||
// this.mkclick = this.isMaskClick || this.maskClick
|
||||
if (this.isMaskClick === null && this.maskClick === null) {
|
||||
this.mkclick = true
|
||||
} else {
|
||||
this.mkclick =
|
||||
this.isMaskClick !== null ? this.isMaskClick : this.maskClick
|
||||
}
|
||||
if (this.animation) {
|
||||
this.duration = 300
|
||||
} else {
|
||||
this.duration = 0
|
||||
}
|
||||
// TODO 处理 message 组件生命周期异常的问题
|
||||
this.messageChild = null
|
||||
// TODO 解决头条冒泡的问题
|
||||
this.clearPropagation = false
|
||||
this.maskClass.backgroundColor = this.maskBackgroundColor
|
||||
},
|
||||
methods: {
|
||||
setH5Visible() {
|
||||
// #ifdef H5
|
||||
// fix by mehaotian 处理 h5 滚动穿透的问题
|
||||
document.getElementsByTagName('body')[0].style.overflow = 'visible'
|
||||
// #endif
|
||||
},
|
||||
/**
|
||||
* 公用方法,不显示遮罩层
|
||||
*/
|
||||
closeMask() {
|
||||
this.maskShow = false
|
||||
},
|
||||
/**
|
||||
* 公用方法,遮罩层禁止点击
|
||||
*/
|
||||
disableMask() {
|
||||
this.mkclick = false
|
||||
},
|
||||
// TODO nvue 取消冒泡
|
||||
clear(e) {
|
||||
// #ifndef APP-NVUE
|
||||
e.stopPropagation()
|
||||
// #endif
|
||||
this.clearPropagation = true
|
||||
},
|
||||
|
||||
open(direction) {
|
||||
// fix by mehaotian 处理快速打开关闭的情况
|
||||
if (this.showPopup) {
|
||||
return
|
||||
}
|
||||
let innerType = [
|
||||
'top',
|
||||
'center',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'message',
|
||||
'dialog',
|
||||
'share',
|
||||
]
|
||||
if (!(direction && innerType?.indexOf(direction) !== -1)) {
|
||||
direction = this.type
|
||||
}
|
||||
if (!this.config[direction]) {
|
||||
console.error('缺少类型:', direction)
|
||||
return
|
||||
}
|
||||
this[this.config[direction]]()
|
||||
this.$emit('change', {
|
||||
show: true,
|
||||
type: direction,
|
||||
})
|
||||
},
|
||||
close(type) {
|
||||
this.showTrans = false
|
||||
this.$emit('change', {
|
||||
show: false,
|
||||
type: this.type,
|
||||
})
|
||||
clearTimeout(this.timer)
|
||||
// // 自定义关闭事件
|
||||
// this.customOpen && this.customClose()
|
||||
this.timer = setTimeout(() => {
|
||||
this.showPopup = false
|
||||
}, 300)
|
||||
},
|
||||
// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
|
||||
touchstart() {
|
||||
this.clearPropagation = false
|
||||
},
|
||||
|
||||
onTap() {
|
||||
if (this.clearPropagation) {
|
||||
// fix by mehaotian 兼容 nvue
|
||||
this.clearPropagation = false
|
||||
return
|
||||
}
|
||||
this.$emit('maskClick')
|
||||
if (!this.mkclick) return
|
||||
this.close()
|
||||
},
|
||||
/**
|
||||
* 顶部弹出样式处理
|
||||
*/
|
||||
top(type) {
|
||||
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
|
||||
this.ani = ['slide-top']
|
||||
this.transClass = {
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: this.bg,
|
||||
}
|
||||
// TODO 兼容 type 属性 ,后续会废弃
|
||||
if (type) return
|
||||
this.showPopup = true
|
||||
this.showTrans = true
|
||||
this.$nextTick(() => {
|
||||
if (this.messageChild && this.type === 'message') {
|
||||
this.messageChild.timerClose()
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 底部弹出样式处理
|
||||
*/
|
||||
bottom(type) {
|
||||
this.popupstyle = 'bottom'
|
||||
this.ani = ['slide-bottom']
|
||||
this.transClass = {
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
paddingBottom: this.safeAreaInsets + 'px',
|
||||
backgroundColor: this.bg,
|
||||
}
|
||||
// TODO 兼容 type 属性 ,后续会废弃
|
||||
if (type) return
|
||||
this.showPopup = true
|
||||
this.showTrans = true
|
||||
},
|
||||
/**
|
||||
* 中间弹出样式处理
|
||||
*/
|
||||
center(type) {
|
||||
this.popupstyle = 'center'
|
||||
this.ani = ['zoom-out', 'fade']
|
||||
this.transClass = {
|
||||
position: 'fixed',
|
||||
/* #ifndef APP-NVUE */
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
/* #endif */
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}
|
||||
// TODO 兼容 type 属性 ,后续会废弃
|
||||
if (type) return
|
||||
this.showPopup = true
|
||||
this.showTrans = true
|
||||
},
|
||||
left(type) {
|
||||
this.popupstyle = 'left'
|
||||
this.ani = ['slide-left']
|
||||
this.transClass = {
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
backgroundColor: this.bg,
|
||||
/* #ifndef APP-NVUE */
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
/* #endif */
|
||||
}
|
||||
// TODO 兼容 type 属性 ,后续会废弃
|
||||
if (type) return
|
||||
this.showPopup = true
|
||||
this.showTrans = true
|
||||
},
|
||||
right(type) {
|
||||
this.popupstyle = 'right'
|
||||
this.ani = ['slide-right']
|
||||
this.transClass = {
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
backgroundColor: this.bg,
|
||||
/* #ifndef APP-NVUE */
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
/* #endif */
|
||||
}
|
||||
// TODO 兼容 type 属性 ,后续会废弃
|
||||
if (type) return
|
||||
this.showPopup = true
|
||||
this.showTrans = true
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.uni-popup {
|
||||
position: fixed;
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 999999;
|
||||
|
||||
/* #endif */
|
||||
&.top,
|
||||
&.left,
|
||||
&.right {
|
||||
/* #ifdef H5 */
|
||||
top: var(--window-top);
|
||||
/* #endif */
|
||||
/* #ifndef H5 */
|
||||
top: 0;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-popup__wrapper {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: block;
|
||||
/* #endif */
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
|
||||
/* iphonex 等安全区设置,底部安全区适配 */
|
||||
/* #ifndef APP-NVUE */
|
||||
// padding-bottom: constant(safe-area-inset-bottom);
|
||||
// padding-bottom: env(safe-area-inset-bottom);
|
||||
/* #endif */
|
||||
&.left,
|
||||
&.right {
|
||||
/* #ifdef H5 */
|
||||
padding-top: var(--window-top);
|
||||
/* #endif */
|
||||
/* #ifndef H5 */
|
||||
padding-top: 0;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fixforpc-z-index {
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 999;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fixforpc-top {
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,15 @@
|
||||
## 1.0.3(2022-01-21)
|
||||
|
||||
- 优化 组件示例
|
||||
|
||||
## 1.0.2(2021-11-22)
|
||||
|
||||
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
|
||||
|
||||
## 1.0.1(2021-11-22)
|
||||
|
||||
- 修复 vue3 中 scss 语法兼容问题
|
||||
|
||||
## 1.0.0(2021-11-18)
|
||||
|
||||
- init
|
||||
@@ -0,0 +1 @@
|
||||
@import './styles/index.scss';
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"id": "uni-scss",
|
||||
"displayName": "uni-scss 辅助样式",
|
||||
"version": "1.0.3",
|
||||
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
|
||||
"keywords": [
|
||||
"uni-scss",
|
||||
"uni-ui",
|
||||
"辅助样式"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"JS SDK",
|
||||
"通用 SDK"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "n",
|
||||
"联盟": "n"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
|
||||
|
||||
#### 如使用过程中有任何问题,或者您对 uni-ui 有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||
@@ -0,0 +1,7 @@
|
||||
@import './setting/_variables.scss';
|
||||
@import './setting/_border.scss';
|
||||
@import './setting/_color.scss';
|
||||
@import './setting/_space.scss';
|
||||
@import './setting/_radius.scss';
|
||||
@import './setting/_text.scss';
|
||||
@import './setting/_styles.scss';
|
||||
@@ -0,0 +1,3 @@
|
||||
.uni-border {
|
||||
border: 1px $uni-border-1 solid;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
|
||||
// @mixin get-styles($k,$c) {
|
||||
// @if $k == size or $k == weight{
|
||||
// font-#{$k}:#{$c}
|
||||
// }@else{
|
||||
// #{$k}:#{$c}
|
||||
// }
|
||||
// }
|
||||
$uni-ui-color:(
|
||||
// 主色
|
||||
primary: $uni-primary,
|
||||
primary-disable: $uni-primary-disable,
|
||||
primary-light: $uni-primary-light,
|
||||
// 辅助色
|
||||
success: $uni-success,
|
||||
success-disable: $uni-success-disable,
|
||||
success-light: $uni-success-light,
|
||||
warning: $uni-warning,
|
||||
warning-disable: $uni-warning-disable,
|
||||
warning-light: $uni-warning-light,
|
||||
error: $uni-error,
|
||||
error-disable: $uni-error-disable,
|
||||
error-light: $uni-error-light,
|
||||
info: $uni-info,
|
||||
info-disable: $uni-info-disable,
|
||||
info-light: $uni-info-light,
|
||||
// 中性色
|
||||
main-color: $uni-main-color,
|
||||
base-color: $uni-base-color,
|
||||
secondary-color: $uni-secondary-color,
|
||||
extra-color: $uni-extra-color,
|
||||
// 背景色
|
||||
bg-color: $uni-bg-color,
|
||||
// 边框颜色
|
||||
border-1: $uni-border-1,
|
||||
border-2: $uni-border-2,
|
||||
border-3: $uni-border-3,
|
||||
border-4: $uni-border-4,
|
||||
// 黑色
|
||||
black:$uni-black,
|
||||
// 白色
|
||||
white:$uni-white,
|
||||
// 透明
|
||||
transparent:$uni-transparent
|
||||
) !default;
|
||||
@each $key, $child in $uni-ui-color {
|
||||
.uni-#{"" + $key} {
|
||||
color: $child;
|
||||
}
|
||||
.uni-#{"" + $key}-bg {
|
||||
background-color: $child;
|
||||
}
|
||||
}
|
||||
.uni-shadow-sm {
|
||||
box-shadow: $uni-shadow-sm;
|
||||
}
|
||||
.uni-shadow-base {
|
||||
box-shadow: $uni-shadow-base;
|
||||
}
|
||||
.uni-shadow-lg {
|
||||
box-shadow: $uni-shadow-lg;
|
||||
}
|
||||
.uni-mask {
|
||||
background-color:$uni-mask;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
@mixin radius($r,$d:null ,$important: false){
|
||||
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
|
||||
// Key exists within the $uni-radius variable
|
||||
@if (map-has-key($uni-radius, $r) and $d){
|
||||
@if $d == t {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == r {
|
||||
border-top-right-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == b {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == l {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}@else if $d == tl {
|
||||
border-top-left-radius:$radius-value;
|
||||
}@else if $d == tr {
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == br {
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == bl {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}
|
||||
}@else{
|
||||
border-radius:$radius-value;
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $key} {
|
||||
@include radius($key)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius {
|
||||
@include radius($key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in t, r, b, l,tl, tr, br, bl {
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $direction}-#{"" + $key} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius-#{$direction} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
@mixin fn($space,$direction,$size,$n) {
|
||||
@if $n {
|
||||
#{$space}-#{$direction}: #{$size*$uni-space-root}px
|
||||
} @else {
|
||||
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
|
||||
}
|
||||
}
|
||||
@mixin get-styles($direction,$i,$space,$n){
|
||||
@if $direction == t {
|
||||
@include fn($space, top,$i,$n);
|
||||
}
|
||||
@if $direction == r {
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == b {
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == l {
|
||||
@include fn($space, left,$i,$n);
|
||||
}
|
||||
@if $direction == x {
|
||||
@include fn($space, left,$i,$n);
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == y {
|
||||
@include fn($space, top,$i,$n);
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == a {
|
||||
@if $n {
|
||||
#{$space}:#{$i*$uni-space-root}px;
|
||||
} @else {
|
||||
#{$space}:#{-$i*$uni-space-root}px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $orientation in m,p {
|
||||
$space: margin;
|
||||
@if $orientation == m {
|
||||
$space: margin;
|
||||
} @else {
|
||||
$space: padding;
|
||||
}
|
||||
@for $i from 0 through 16 {
|
||||
@each $direction in t, r, b, l, x, y, a {
|
||||
.uni-#{$orientation}#{$direction}-#{$i} {
|
||||
@include get-styles($direction,$i,$space,true);
|
||||
}
|
||||
.uni-#{$orientation}#{$direction}-n#{$i} {
|
||||
@include get-styles($direction,$i,$space,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/* #ifndef APP-NVUE */
|
||||
|
||||
$-color-white:#fff;
|
||||
$-color-black:#000;
|
||||
@mixin base-style($color) {
|
||||
color: #fff;
|
||||
background-color: $color;
|
||||
border-color: mix($-color-black, $color, 8%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-black, $color, 10%);
|
||||
border-color: mix($-color-black, $color, 20%);
|
||||
color: $-color-white;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
@mixin is-color($color) {
|
||||
@include base-style($color);
|
||||
&[loading] {
|
||||
@include base-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&[loading],
|
||||
&:not([hover-class]):active {
|
||||
color: $-color-white;
|
||||
border-color: mix(darken($color,10%), $-color-white);
|
||||
background-color: mix($color, $-color-white);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@mixin base-plain-style($color) {
|
||||
color:$color;
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 70%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-white, $color, 80%);
|
||||
color: $color;
|
||||
outline: none;
|
||||
border-color: mix($-color-white, $color, 50%);
|
||||
}
|
||||
}
|
||||
@mixin is-plain($color){
|
||||
&[plain] {
|
||||
@include base-plain-style($color);
|
||||
&[loading] {
|
||||
@include base-plain-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&:active {
|
||||
color: mix($-color-white, $color, 40%);
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.uni-btn {
|
||||
margin: 5px;
|
||||
color: #393939;
|
||||
border:1px solid #ccc;
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
background-color: #F9F9F9;
|
||||
// TODO 暂时处理边框隐藏一边的问题
|
||||
overflow: visible;
|
||||
&::after{
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:not([type]),&[type=default] {
|
||||
color: #999;
|
||||
&[loading] {
|
||||
background: none;
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&[disabled]{
|
||||
color: mix($-color-white, #999, 60%);
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
color: mix($-color-white, #999, 60%);
|
||||
background-color: mix($-color-white,$-color-black , 98%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
|
||||
&[plain] {
|
||||
color: #999;
|
||||
background: none;
|
||||
border-color: $uni-border-1;
|
||||
&:not([hover-class]):active {
|
||||
background: none;
|
||||
color: mix($-color-white, $-color-black, 80%);
|
||||
border-color: mix($-color-white, $-color-black, 90%);
|
||||
outline: none;
|
||||
}
|
||||
&[disabled]{
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
background: none;
|
||||
color: mix($-color-white, #999, 60%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not([hover-class]):active {
|
||||
color: mix($-color-white, $-color-black, 50%);
|
||||
}
|
||||
|
||||
&[size=mini] {
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
&.uni-btn-small {
|
||||
font-size: 14px;
|
||||
}
|
||||
&.uni-btn-mini {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&.uni-btn-radius {
|
||||
border-radius: 999px;
|
||||
}
|
||||
&[type=primary] {
|
||||
@include is-color($uni-primary);
|
||||
@include is-plain($uni-primary)
|
||||
}
|
||||
&[type=success] {
|
||||
@include is-color($uni-success);
|
||||
@include is-plain($uni-success)
|
||||
}
|
||||
&[type=error] {
|
||||
@include is-color($uni-error);
|
||||
@include is-plain($uni-error)
|
||||
}
|
||||
&[type=warning] {
|
||||
@include is-color($uni-warning);
|
||||
@include is-plain($uni-warning)
|
||||
}
|
||||
&[type=info] {
|
||||
@include is-color($uni-info);
|
||||
@include is-plain($uni-info)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
@@ -0,0 +1,24 @@
|
||||
@mixin get-styles($k,$c) {
|
||||
@if $k == size or $k == weight{
|
||||
font-#{$k}:#{$c}
|
||||
}@else{
|
||||
#{$k}:#{$c}
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-headings {
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
.container .uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
// @use "sass:math";
|
||||
@import '../tools/functions.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2 !default;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px !default;
|
||||
$uni-radius: () !default;
|
||||
// 边框半径断点
|
||||
$uni-radius: map-deep-merge(
|
||||
(
|
||||
0: 0,
|
||||
// TODO 当前版本暂时不支持 sm 属性
|
||||
// 'sm': math.div($uni-radius-root, 2),
|
||||
null: $uni-radius-root,
|
||||
'lg': $uni-radius-root * 2,
|
||||
'xl': $uni-radius-root * 6,
|
||||
'pill': 9999px,
|
||||
'circle': 50%
|
||||
),
|
||||
$uni-radius
|
||||
);
|
||||
// 字体家族
|
||||
$body-font-family: 'Roboto', sans-serif !default;
|
||||
// 文本
|
||||
$heading-font-family: $body-font-family !default;
|
||||
$uni-headings: () !default;
|
||||
$letterSpacing: -0.01562em;
|
||||
$uni-headings: map-deep-merge(
|
||||
(
|
||||
'h1': (
|
||||
size: 32px,
|
||||
weight: 300,
|
||||
line-height: 50px,
|
||||
// letter-spacing:-0.01562em
|
||||
),
|
||||
'h2': (
|
||||
size: 28px,
|
||||
weight: 300,
|
||||
line-height: 40px,
|
||||
// letter-spacing: -0.00833em
|
||||
),
|
||||
'h3': (
|
||||
size: 24px,
|
||||
weight: 400,
|
||||
line-height: 32px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h4': (
|
||||
size: 20px,
|
||||
weight: 400,
|
||||
line-height: 30px,
|
||||
// letter-spacing: 0.00735em
|
||||
),
|
||||
'h5': (
|
||||
size: 16px,
|
||||
weight: 400,
|
||||
line-height: 24px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h6': (
|
||||
size: 14px,
|
||||
weight: 500,
|
||||
line-height: 18px,
|
||||
// letter-spacing: 0.0125em
|
||||
),
|
||||
'subtitle': (
|
||||
size: 12px,
|
||||
weight: 400,
|
||||
line-height: 20px,
|
||||
// letter-spacing: 0.00937em
|
||||
),
|
||||
'body': (
|
||||
font-size: 14px,
|
||||
font-weight: 400,
|
||||
line-height: 22px,
|
||||
// letter-spacing: 0.03125em
|
||||
),
|
||||
'caption': (
|
||||
'size': 12px,
|
||||
'weight': 400,
|
||||
'line-height': 20px,
|
||||
// 'letter-spacing': 0.03333em,
|
||||
// 'text-transform': false
|
||||
)
|
||||
),
|
||||
$uni-headings
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff !default;
|
||||
$uni-primary-disable:lighten($uni-primary,20%) !default;
|
||||
$uni-primary-light: lighten($uni-primary,25%) !default;
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37 !default;
|
||||
$uni-success-disable:lighten($uni-success,20%) !default;
|
||||
$uni-success-light: lighten($uni-success,25%) !default;
|
||||
|
||||
$uni-warning: #f3a73f !default;
|
||||
$uni-warning-disable:lighten($uni-warning,20%) !default;
|
||||
$uni-warning-light: lighten($uni-warning,25%) !default;
|
||||
|
||||
$uni-error: #e43d33 !default;
|
||||
$uni-error-disable:lighten($uni-error,20%) !default;
|
||||
$uni-error-light: lighten($uni-error,25%) !default;
|
||||
|
||||
$uni-info: #8f939c !default;
|
||||
$uni-info-disable:lighten($uni-info,20%) !default;
|
||||
$uni-info-light: lighten($uni-info,25%) !default;
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a !default; // 主要文字
|
||||
$uni-base-color: #6a6a6a !default; // 常规文字
|
||||
$uni-secondary-color: #909399 !default; // 次要文字
|
||||
$uni-extra-color: #c7c7c7 !default; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0 !default;
|
||||
$uni-border-2: #EDEDED !default;
|
||||
$uni-border-3: #DCDCDC !default;
|
||||
$uni-border-4: #B9B9B9 !default;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000 !default;
|
||||
$uni-white: #ffffff !default;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7 !default;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px !default;
|
||||
$uni-spacing-base: 15px !default;
|
||||
$uni-spacing-lg: 30px !default;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
|
||||
@@ -0,0 +1,19 @@
|
||||
// 合并 map
|
||||
@function map-deep-merge($parent-map, $child-map){
|
||||
$result: $parent-map;
|
||||
@each $key, $child in $child-map {
|
||||
$parent-has-key: map-has-key($result, $key);
|
||||
$parent-value: map-get($result, $key);
|
||||
$parent-type: type-of($parent-value);
|
||||
$child-type: type-of($child);
|
||||
$parent-is-map: $parent-type == map;
|
||||
$child-is-map: $child-type == map;
|
||||
|
||||
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
|
||||
$result: map-merge($result, ( $key: $child ));
|
||||
}@else {
|
||||
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
|
||||
}
|
||||
}
|
||||
@return $result;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
// 辅助色
|
||||
$uni-success: #4cd964;
|
||||
// 警告色
|
||||
$uni-warning: #f0ad4e;
|
||||
// 错误色
|
||||
$uni-error: #dd524d;
|
||||
// 描述色
|
||||
$uni-info: #909399;
|
||||
// 中性色
|
||||
$uni-main-color: #303133;
|
||||
$uni-base-color: #606266;
|
||||
$uni-secondary-color: #909399;
|
||||
$uni-extra-color: #C0C4CC;
|
||||
// 背景色
|
||||
$uni-bg-color: #f5f5f5;
|
||||
// 边框颜色
|
||||
$uni-border-1: #DCDFE6;
|
||||
$uni-border-2: #E4E7ED;
|
||||
$uni-border-3: #EBEEF5;
|
||||
$uni-border-4: #F2F6FC;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
@@ -0,0 +1,62 @@
|
||||
@import './styles/setting/_variables.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
$uni-primary-disable:mix(#fff,$uni-primary,50%);
|
||||
$uni-primary-light: mix(#fff,$uni-primary,80%);
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37;
|
||||
$uni-success-disable:mix(#fff,$uni-success,50%);
|
||||
$uni-success-light: mix(#fff,$uni-success,80%);
|
||||
|
||||
$uni-warning: #f3a73f;
|
||||
$uni-warning-disable:mix(#fff,$uni-warning,50%);
|
||||
$uni-warning-light: mix(#fff,$uni-warning,80%);
|
||||
|
||||
$uni-error: #e43d33;
|
||||
$uni-error-disable:mix(#fff,$uni-error,50%);
|
||||
$uni-error-light: mix(#fff,$uni-error,80%);
|
||||
|
||||
$uni-info: #8f939c;
|
||||
$uni-info-disable:mix(#fff,$uni-info,50%);
|
||||
$uni-info-light: mix(#fff,$uni-info,80%);
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a; // 主要文字
|
||||
$uni-base-color: #6a6a6a; // 常规文字
|
||||
$uni-secondary-color: #909399; // 次要文字
|
||||
$uni-extra-color: #c7c7c7; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0;
|
||||
$uni-border-2: #EDEDED;
|
||||
$uni-border-3: #DCDCDC;
|
||||
$uni-border-4: #B9B9B9;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px;
|
||||
$uni-spacing-base: 15px;
|
||||
$uni-spacing-lg: 30px;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4);
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
// const defaultOption = {
|
||||
// duration: 300,
|
||||
// timingFunction: 'linear',
|
||||
// delay: 0,
|
||||
// transformOrigin: '50% 50% 0'
|
||||
// }
|
||||
// #ifdef APP-NVUE
|
||||
const nvueAnimation = uni.requireNativePlugin('animation')
|
||||
// #endif
|
||||
class MPAnimation {
|
||||
constructor(options, _this) {
|
||||
this.options = options
|
||||
// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
|
||||
this.animation = uni.createAnimation({
|
||||
...options,
|
||||
})
|
||||
this.currentStepAnimates = {}
|
||||
this.next = 0
|
||||
this.$ = _this
|
||||
}
|
||||
|
||||
_nvuePushAnimates(type, args) {
|
||||
let aniObj = this.currentStepAnimates[this.next]
|
||||
let styles = {}
|
||||
if (!aniObj) {
|
||||
styles = {
|
||||
styles: {},
|
||||
config: {},
|
||||
}
|
||||
} else {
|
||||
styles = aniObj
|
||||
}
|
||||
if (animateTypes1.includes(type)) {
|
||||
if (!styles.styles.transform) {
|
||||
styles.styles.transform = ''
|
||||
}
|
||||
let unit = ''
|
||||
if (type === 'rotate') {
|
||||
unit = 'deg'
|
||||
}
|
||||
styles.styles.transform += `${type}(${args + unit}) `
|
||||
} else {
|
||||
styles.styles[type] = `${args}`
|
||||
}
|
||||
this.currentStepAnimates[this.next] = styles
|
||||
}
|
||||
_animateRun(styles = {}, config = {}) {
|
||||
let ref = this.$.$refs['ani'].ref
|
||||
if (!ref) return
|
||||
return new Promise((resolve, reject) => {
|
||||
nvueAnimation.transition(
|
||||
ref,
|
||||
{
|
||||
styles,
|
||||
...config,
|
||||
},
|
||||
(res) => {
|
||||
resolve()
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
_nvueNextAnimate(animates, step = 0, fn) {
|
||||
let obj = animates[step]
|
||||
if (obj) {
|
||||
let { styles, config } = obj
|
||||
this._animateRun(styles, config).then(() => {
|
||||
step += 1
|
||||
this._nvueNextAnimate(animates, step, fn)
|
||||
})
|
||||
} else {
|
||||
this.currentStepAnimates = {}
|
||||
typeof fn === 'function' && fn()
|
||||
this.isEnd = true
|
||||
}
|
||||
}
|
||||
|
||||
step(config = {}) {
|
||||
// #ifndef APP-NVUE
|
||||
this.animation.step(config)
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
this.currentStepAnimates[this.next].config = Object.assign(
|
||||
{},
|
||||
this.options,
|
||||
config
|
||||
)
|
||||
this.currentStepAnimates[this.next].styles.transformOrigin =
|
||||
this.currentStepAnimates[this.next].config.transformOrigin
|
||||
this.next++
|
||||
// #endif
|
||||
return this
|
||||
}
|
||||
|
||||
run(fn) {
|
||||
// #ifndef APP-NVUE
|
||||
this.$.animationData = this.animation.export()
|
||||
this.$.timer = setTimeout(() => {
|
||||
typeof fn === 'function' && fn()
|
||||
}, this.$.durationTime)
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
this.isEnd = false
|
||||
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
|
||||
if (!ref) return
|
||||
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
|
||||
this.next = 0
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
const animateTypes1 = [
|
||||
'matrix',
|
||||
'matrix3d',
|
||||
'rotate',
|
||||
'rotate3d',
|
||||
'rotateX',
|
||||
'rotateY',
|
||||
'rotateZ',
|
||||
'scale',
|
||||
'scale3d',
|
||||
'scaleX',
|
||||
'scaleY',
|
||||
'scaleZ',
|
||||
'skew',
|
||||
'skewX',
|
||||
'skewY',
|
||||
'translate',
|
||||
'translate3d',
|
||||
'translateX',
|
||||
'translateY',
|
||||
'translateZ',
|
||||
]
|
||||
const animateTypes2 = ['opacity', 'backgroundColor']
|
||||
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
||||
animateTypes1.concat(animateTypes2, animateTypes3).forEach((type) => {
|
||||
MPAnimation.prototype[type] = function (...args) {
|
||||
// #ifndef APP-NVUE
|
||||
this.animation[type](...args)
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
this._nvuePushAnimates(type, args)
|
||||
// #endif
|
||||
return this
|
||||
}
|
||||
})
|
||||
|
||||
export function createAnimation(option, _this) {
|
||||
if (!_this) return
|
||||
clearTimeout(_this.timer)
|
||||
return new MPAnimation(option, _this)
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createAnimation } from './createAnimation'
|
||||
|
||||
/**
|
||||
* Transition 过渡动画
|
||||
* @description 简单过渡动画组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
|
||||
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
|
||||
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
|
||||
* @value fade 渐隐渐出过渡
|
||||
* @value slide-top 由上至下过渡
|
||||
* @value slide-right 由右至左过渡
|
||||
* @value slide-bottom 由下至上过渡
|
||||
* @value slide-left 由左至右过渡
|
||||
* @value zoom-in 由小到大过渡
|
||||
* @value zoom-out 由大到小过渡
|
||||
* @property {Number} duration 过渡动画持续时间
|
||||
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
|
||||
*/
|
||||
export default {
|
||||
name: 'uniTransition',
|
||||
emits:['click','change'],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modeClass: {
|
||||
type: [Array, String],
|
||||
default() {
|
||||
return 'fade'
|
||||
}
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 300
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
customClass:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
onceRender:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
transform: '',
|
||||
opacity: 1,
|
||||
animationData: {},
|
||||
durationTime: 300,
|
||||
config: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.open()
|
||||
} else {
|
||||
// 避免上来就执行 close,导致动画错乱
|
||||
if (this.isShow) {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 生成样式数据
|
||||
stylesObject() {
|
||||
let styles = {
|
||||
...this.styles,
|
||||
'transition-duration': this.duration / 1000 + 's'
|
||||
}
|
||||
let transform = ''
|
||||
for (let i in styles) {
|
||||
let line = this.toLine(i)
|
||||
transform += line + ':' + styles[i] + ';'
|
||||
}
|
||||
return transform
|
||||
},
|
||||
// 初始化动画条件
|
||||
transformStyles() {
|
||||
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 动画默认配置
|
||||
this.config = {
|
||||
duration: this.duration,
|
||||
timingFunction: 'ease',
|
||||
transformOrigin: '50% 50%',
|
||||
delay: 0
|
||||
}
|
||||
this.durationTime = this.duration
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* ref 触发 初始化动画
|
||||
*/
|
||||
init(obj = {}) {
|
||||
if (obj.duration) {
|
||||
this.durationTime = obj.duration
|
||||
}
|
||||
this.animation = createAnimation(Object.assign(this.config, obj),this)
|
||||
},
|
||||
/**
|
||||
* 点击组件触发回调
|
||||
*/
|
||||
onClick() {
|
||||
this.$emit('click', {
|
||||
detail: this.isShow
|
||||
})
|
||||
},
|
||||
/**
|
||||
* ref 触发 动画分组
|
||||
* @param {Object} obj
|
||||
*/
|
||||
step(obj, config = {}) {
|
||||
if (!this.animation) return
|
||||
for (let i in obj) {
|
||||
try {
|
||||
if(typeof obj[i] === 'object'){
|
||||
this.animation[i](...obj[i])
|
||||
}else{
|
||||
this.animation[i](obj[i])
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`方法 ${i} 不存在`)
|
||||
}
|
||||
}
|
||||
this.animation.step(config)
|
||||
return this
|
||||
},
|
||||
/**
|
||||
* ref 触发 执行动画
|
||||
*/
|
||||
run(fn) {
|
||||
if (!this.animation) return
|
||||
this.animation.run(fn)
|
||||
},
|
||||
// 开始过度动画
|
||||
open() {
|
||||
clearTimeout(this.timer)
|
||||
this.transform = ''
|
||||
this.isShow = true
|
||||
let { opacity, transform } = this.styleInit(false)
|
||||
if (typeof opacity !== 'undefined') {
|
||||
this.opacity = opacity
|
||||
}
|
||||
this.transform = transform
|
||||
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
|
||||
this.$nextTick(() => {
|
||||
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
|
||||
this.timer = setTimeout(() => {
|
||||
this.animation = createAnimation(this.config, this)
|
||||
this.tranfromInit(false).step()
|
||||
this.animation.run()
|
||||
this.$emit('change', {
|
||||
detail: this.isShow
|
||||
})
|
||||
}, 20)
|
||||
})
|
||||
},
|
||||
// 关闭过度动画
|
||||
close(type) {
|
||||
if (!this.animation) return
|
||||
this.tranfromInit(true)
|
||||
.step()
|
||||
.run(() => {
|
||||
this.isShow = false
|
||||
this.animationData = null
|
||||
this.animation = null
|
||||
let { opacity, transform } = this.styleInit(false)
|
||||
this.opacity = opacity || 1
|
||||
this.transform = transform
|
||||
this.$emit('change', {
|
||||
detail: this.isShow
|
||||
})
|
||||
})
|
||||
},
|
||||
// 处理动画开始前的默认样式
|
||||
styleInit(type) {
|
||||
let styles = {
|
||||
transform: ''
|
||||
}
|
||||
let buildStyle = (type, mode) => {
|
||||
if (mode === 'fade') {
|
||||
styles.opacity = this.animationType(type)[mode]
|
||||
} else {
|
||||
styles.transform += this.animationType(type)[mode] + ' '
|
||||
}
|
||||
}
|
||||
if (typeof this.modeClass === 'string') {
|
||||
buildStyle(type, this.modeClass)
|
||||
} else {
|
||||
this.modeClass.forEach(mode => {
|
||||
buildStyle(type, mode)
|
||||
})
|
||||
}
|
||||
return styles
|
||||
},
|
||||
// 处理内置组合动画
|
||||
tranfromInit(type) {
|
||||
let buildTranfrom = (type, mode) => {
|
||||
let aniNum = null
|
||||
if (mode === 'fade') {
|
||||
aniNum = type ? 0 : 1
|
||||
} else {
|
||||
aniNum = type ? '-100%' : '0'
|
||||
if (mode === 'zoom-in') {
|
||||
aniNum = type ? 0.8 : 1
|
||||
}
|
||||
if (mode === 'zoom-out') {
|
||||
aniNum = type ? 1.2 : 1
|
||||
}
|
||||
if (mode === 'slide-right') {
|
||||
aniNum = type ? '100%' : '0'
|
||||
}
|
||||
if (mode === 'slide-bottom') {
|
||||
aniNum = type ? '100%' : '0'
|
||||
}
|
||||
}
|
||||
this.animation[this.animationMode()[mode]](aniNum)
|
||||
}
|
||||
if (typeof this.modeClass === 'string') {
|
||||
buildTranfrom(type, this.modeClass)
|
||||
} else {
|
||||
this.modeClass.forEach(mode => {
|
||||
buildTranfrom(type, mode)
|
||||
})
|
||||
}
|
||||
|
||||
return this.animation
|
||||
},
|
||||
animationType(type) {
|
||||
return {
|
||||
fade: type ? 1 : 0,
|
||||
'slide-top': `translateY(${type ? '0' : '-100%'})`,
|
||||
'slide-right': `translateX(${type ? '0' : '100%'})`,
|
||||
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
|
||||
'slide-left': `translateX(${type ? '0' : '-100%'})`,
|
||||
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
|
||||
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
|
||||
}
|
||||
},
|
||||
// 内置动画类型与实际动画对应字典
|
||||
animationMode() {
|
||||
return {
|
||||
fade: 'opacity',
|
||||
'slide-top': 'translateY',
|
||||
'slide-right': 'translateX',
|
||||
'slide-bottom': 'translateY',
|
||||
'slide-left': 'translateX',
|
||||
'zoom-in': 'scale',
|
||||
'zoom-out': 'scale'
|
||||
}
|
||||
},
|
||||
// 驼峰转中横线
|
||||
toLine(name) {
|
||||
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -77,7 +77,7 @@
|
||||
this.videoVid = event.detail.value;
|
||||
},
|
||||
|
||||
setVid() {
|
||||
setVid(vid) {
|
||||
if(!this.videoVid) {
|
||||
uni.showToast({
|
||||
title: "请输入视频Vid",
|
||||
@@ -87,7 +87,7 @@
|
||||
}
|
||||
const { vodPlayer } = this;
|
||||
vodPlayer.setVid({
|
||||
vid:this.videoVid,
|
||||
vid:this.videoVid || vid,
|
||||
level:0
|
||||
}, (ret) => {
|
||||
this.text = JSON.stringify(ret);
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
|
||||
*/
|
||||
|
||||
var isIos
|
||||
// #ifdef APP-PLUS
|
||||
isIos = (plus.os.name == "iOS")
|
||||
// #endif
|
||||
|
||||
// 判断推送权限是否开启
|
||||
function judgeIosPermissionPush() {
|
||||
var result = false;
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var app = UIApplication.sharedApplication();
|
||||
var enabledTypes = 0;
|
||||
if (app.currentUserNotificationSettings) {
|
||||
var settings = app.currentUserNotificationSettings();
|
||||
enabledTypes = settings.plusGetAttribute("types");
|
||||
console.log("enabledTypes1:" + enabledTypes);
|
||||
if (enabledTypes == 0) {
|
||||
console.log("推送权限没有开启");
|
||||
} else {
|
||||
result = true;
|
||||
console.log("已经开启推送功能!")
|
||||
}
|
||||
plus.ios.deleteObject(settings);
|
||||
} else {
|
||||
enabledTypes = app.enabledRemoteNotificationTypes();
|
||||
if (enabledTypes == 0) {
|
||||
console.log("推送权限没有开启!");
|
||||
} else {
|
||||
result = true;
|
||||
console.log("已经开启推送功能!")
|
||||
}
|
||||
console.log("enabledTypes2:" + enabledTypes);
|
||||
}
|
||||
plus.ios.deleteObject(app);
|
||||
plus.ios.deleteObject(UIApplication);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断定位权限是否开启
|
||||
function judgeIosPermissionLocation() {
|
||||
var result = false;
|
||||
var cllocationManger = plus.ios.import("CLLocationManager");
|
||||
var status = cllocationManger.authorizationStatus();
|
||||
result = (status != 2)
|
||||
console.log("定位权限开启:" + result);
|
||||
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
|
||||
/* var enable = cllocationManger.locationServicesEnabled();
|
||||
var status = cllocationManger.authorizationStatus();
|
||||
console.log("enable:" + enable);
|
||||
console.log("status:" + status);
|
||||
if (enable && status != 2) {
|
||||
result = true;
|
||||
console.log("手机定位服务已开启且已授予定位权限");
|
||||
} else {
|
||||
console.log("手机系统的定位没有打开或未给予定位权限");
|
||||
} */
|
||||
plus.ios.deleteObject(cllocationManger);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断麦克风权限是否开启
|
||||
function judgeIosPermissionRecord() {
|
||||
var result = false;
|
||||
var avaudiosession = plus.ios.import("AVAudioSession");
|
||||
var avaudio = avaudiosession.sharedInstance();
|
||||
var permissionStatus = avaudio.recordPermission();
|
||||
console.log("permissionStatus:" + permissionStatus);
|
||||
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
|
||||
console.log("麦克风权限没有开启");
|
||||
} else {
|
||||
result = true;
|
||||
console.log("麦克风权限已经开启");
|
||||
}
|
||||
plus.ios.deleteObject(avaudiosession);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断相机权限是否开启
|
||||
function judgeIosPermissionCamera() {
|
||||
var result = false;
|
||||
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
|
||||
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
|
||||
console.log("authStatus:" + authStatus);
|
||||
if (authStatus == 3) {
|
||||
result = true;
|
||||
console.log("相机权限已经开启");
|
||||
} else {
|
||||
console.log("相机权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(AVCaptureDevice);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断相册权限是否开启
|
||||
function judgeIosPermissionPhotoLibrary() {
|
||||
var result = false;
|
||||
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
|
||||
var authStatus = PHPhotoLibrary.authorizationStatus();
|
||||
console.log("authStatus:" + authStatus);
|
||||
if (authStatus == 3) {
|
||||
result = true;
|
||||
console.log("相册权限已经开启");
|
||||
} else {
|
||||
console.log("相册权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(PHPhotoLibrary);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断通讯录权限是否开启
|
||||
function judgeIosPermissionContact() {
|
||||
var result = false;
|
||||
var CNContactStore = plus.ios.import("CNContactStore");
|
||||
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
|
||||
if (cnAuthStatus == 3) {
|
||||
result = true;
|
||||
console.log("通讯录权限已经开启");
|
||||
} else {
|
||||
console.log("通讯录权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(CNContactStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断日历权限是否开启
|
||||
function judgeIosPermissionCalendar() {
|
||||
var result = false;
|
||||
var EKEventStore = plus.ios.import("EKEventStore");
|
||||
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
|
||||
if (ekAuthStatus == 3) {
|
||||
result = true;
|
||||
console.log("日历权限已经开启");
|
||||
} else {
|
||||
console.log("日历权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(EKEventStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断备忘录权限是否开启
|
||||
function judgeIosPermissionMemo() {
|
||||
var result = false;
|
||||
var EKEventStore = plus.ios.import("EKEventStore");
|
||||
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
|
||||
if (ekAuthStatus == 3) {
|
||||
result = true;
|
||||
console.log("备忘录权限已经开启");
|
||||
} else {
|
||||
console.log("备忘录权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(EKEventStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Android权限查询
|
||||
function requestAndroidPermission(permissionID) {
|
||||
return new Promise((resolve, reject) => {
|
||||
plus.android.requestPermissions(
|
||||
[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
|
||||
function(resultObj) {
|
||||
var result = 0;
|
||||
for (var i = 0; i < resultObj.granted.length; i++) {
|
||||
var grantedPermission = resultObj.granted[i];
|
||||
console.log('已获取的权限:' + grantedPermission);
|
||||
result = 1
|
||||
}
|
||||
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
|
||||
var deniedPresentPermission = resultObj.deniedPresent[i];
|
||||
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
|
||||
result = 0
|
||||
}
|
||||
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
|
||||
var deniedAlwaysPermission = resultObj.deniedAlways[i];
|
||||
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
|
||||
result = -1
|
||||
}
|
||||
resolve(result);
|
||||
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
|
||||
// if (result != 1) {
|
||||
// gotoAppPermissionSetting()
|
||||
// }
|
||||
},
|
||||
function(error) {
|
||||
console.log('申请权限错误:' + error.code + " = " + error.message);
|
||||
resolve({
|
||||
code: error.code,
|
||||
message: error.message
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// 使用一个方法,根据参数判断权限
|
||||
function judgeIosPermission(permissionID) {
|
||||
if (permissionID == "location") {
|
||||
return judgeIosPermissionLocation()
|
||||
} else if (permissionID == "camera") {
|
||||
return judgeIosPermissionCamera()
|
||||
} else if (permissionID == "photoLibrary") {
|
||||
return judgeIosPermissionPhotoLibrary()
|
||||
} else if (permissionID == "record") {
|
||||
return judgeIosPermissionRecord()
|
||||
} else if (permissionID == "push") {
|
||||
return judgeIosPermissionPush()
|
||||
} else if (permissionID == "contact") {
|
||||
return judgeIosPermissionContact()
|
||||
} else if (permissionID == "calendar") {
|
||||
return judgeIosPermissionCalendar()
|
||||
} else if (permissionID == "memo") {
|
||||
return judgeIosPermissionMemo()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 跳转到**应用**的权限页面
|
||||
function gotoAppPermissionSetting() {
|
||||
if (isIos) {
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var application2 = UIApplication.sharedApplication();
|
||||
var NSURL2 = plus.ios.import("NSURL");
|
||||
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
|
||||
var setting2 = NSURL2.URLWithString("app-settings:");
|
||||
application2.openURL(setting2);
|
||||
|
||||
plus.ios.deleteObject(setting2);
|
||||
plus.ios.deleteObject(NSURL2);
|
||||
plus.ios.deleteObject(application2);
|
||||
} else {
|
||||
// console.log(plus.device.vendor);
|
||||
var Intent = plus.android.importClass("android.content.Intent");
|
||||
var Settings = plus.android.importClass("android.provider.Settings");
|
||||
var Uri = plus.android.importClass("android.net.Uri");
|
||||
var mainActivity = plus.android.runtimeMainActivity();
|
||||
var intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
mainActivity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查系统的设备服务是否开启
|
||||
// var checkSystemEnableLocation = async function () {
|
||||
function checkSystemEnableLocation() {
|
||||
if (isIos) {
|
||||
var result = false;
|
||||
var cllocationManger = plus.ios.import("CLLocationManager");
|
||||
var result = cllocationManger.locationServicesEnabled();
|
||||
console.log("系统定位开启:" + result);
|
||||
plus.ios.deleteObject(cllocationManger);
|
||||
return result;
|
||||
} else {
|
||||
var context = plus.android.importClass("android.content.Context");
|
||||
var locationManager = plus.android.importClass("android.location.LocationManager");
|
||||
var main = plus.android.runtimeMainActivity();
|
||||
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
|
||||
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
|
||||
console.log("系统定位开启:" + result);
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// module.exports = {
|
||||
// judgeIosPermission: judgeIosPermission,
|
||||
// requestAndroidPermission: requestAndroidPermission,
|
||||
// checkSystemEnableLocation: checkSystemEnableLocation,
|
||||
// gotoAppPermissionSetting: gotoAppPermissionSetting
|
||||
// }
|
||||
export default {judgeIosPermission,requestAndroidPermission,checkSystemEnableLocation,gotoAppPermissionSetting}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"messageText": "Message",
|
||||
"cantactsText": "Cantact",
|
||||
"mineText": "Me"
|
||||
}
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
// en.js
|
||||
export default {
|
||||
appText: 'NIM',
|
||||
messageText: 'Message',
|
||||
contactText: 'Contacts',
|
||||
mineText: 'Me',
|
||||
logoutText: 'Log out',
|
||||
commsEaseText: 'About NIM',
|
||||
logoutConfirmText: 'Are you sure you want to log out?',
|
||||
avatarText: 'Avatar',
|
||||
accountText: 'Account',
|
||||
name: 'Nickname',
|
||||
genderText: 'Gender',
|
||||
remark: 'remark',
|
||||
mobile: 'Phone',
|
||||
email: 'Email',
|
||||
sign: 'Signature',
|
||||
man: 'Male',
|
||||
woman: 'Female',
|
||||
unknow: 'Unknown',
|
||||
birthText: 'Birthday',
|
||||
userOnlineText: 'Online',
|
||||
userOfflineText: 'Offline',
|
||||
updateAvatarText: 'Update Avatar',
|
||||
updateNameText: 'Update Name',
|
||||
|
||||
FriendPageText: 'Friend Card',
|
||||
startConversationText: 'Start Chat',
|
||||
addText: 'Add',
|
||||
applyFriendSuccessText: 'Request Sent',
|
||||
applyFriendFailText: 'Request Failed',
|
||||
addFriendText: 'Add Friend',
|
||||
addFriendFailText: 'Add Friend Failed',
|
||||
deleteFriendText: 'Delete Friend',
|
||||
deleteFriendConfirmText: 'Are you sure you want to delete this friend?',
|
||||
deleteFriendSuccessText: 'Delete Friend Success',
|
||||
deleteFriendFailText: 'Delete Friend Failed',
|
||||
setBlackFailText: 'Add to blacklist failed',
|
||||
removeBlackFailText: 'Remove from blacklist failed',
|
||||
removeBlackSuccessText: 'Remove from blacklist success',
|
||||
addPermissionText:
|
||||
'Please add relevant permissions in the system settings page',
|
||||
FailAvatarText: 'Avatar upload failed',
|
||||
chooseDefaultImage: 'Choose default image',
|
||||
chatButtonText: 'Go to Chat',
|
||||
gotoChatFailText: 'Go to chat failed',
|
||||
chatWithFriendText: 'Chat',
|
||||
okText: 'OK',
|
||||
updateText: 'Update',
|
||||
cancelText: 'Cancel',
|
||||
friendSelectText: 'Select Friend',
|
||||
telErrorText: 'Invalid phone number format',
|
||||
emailErrorText: 'Invalid email format',
|
||||
createButtonText: 'Create',
|
||||
createP2PText: 'Start Chat',
|
||||
createTeamText: 'Create Group',
|
||||
addTeamMemberText: 'Add Group Member',
|
||||
discussionMemberText: '讨论组成员',
|
||||
addTeamMemberFailText: 'Add Group Member Failed',
|
||||
teamTitlePlaceholder: 'Enter Group Name',
|
||||
maxSelectedText: 'You can only select up to 200 friends',
|
||||
createTeamSuccessText: 'Create Group Success',
|
||||
createTeamFailedText: 'Create Group Failed',
|
||||
PersonalPageText: 'PersonalCard',
|
||||
deleteSessionText: 'Delete',
|
||||
sessionMuteText: 'Mute Notifications',
|
||||
sessionMuteFailText: 'Mute Notifications Failed',
|
||||
sessionUnMuteFailText: 'Unmute Notifications Failed',
|
||||
stickTopText: 'Pin Chat',
|
||||
deleteStickTopText: 'Unpin Chat',
|
||||
addStickTopText: 'Pin',
|
||||
deleteSessionFailText: 'Delete Conversation Failed',
|
||||
deleteStickTopFailText: 'Unpin Chat Failed',
|
||||
addStickTopFailText: 'Pin Message Failed',
|
||||
teamMemberText: 'Group Members',
|
||||
saveText: 'Save',
|
||||
setText: 'Settings',
|
||||
failText: 'Failed',
|
||||
saveSuccessText: 'Save Success',
|
||||
saveFailedText: 'Save Failed',
|
||||
searchTeamPlaceholder: 'Enter Group Name',
|
||||
teamTitle: 'Group Name',
|
||||
discussionTitle: 'Discussion Group Name',
|
||||
teamInfoText: 'Group Information',
|
||||
discussionInfoText: 'Discussion Group Information',
|
||||
teamAvatar: 'Group Avatar',
|
||||
discussionAvatarText: 'Discussion Group Avatar',
|
||||
networkError: 'Current network error',
|
||||
searchFailText: 'Search Failed',
|
||||
offlineText: 'Network is unavailable, please check network settings.',
|
||||
connectingText:
|
||||
'The current IM connection has been disconnected and is reconnecting…',
|
||||
teamMenuText: 'My Groups',
|
||||
teamChooseText: 'My Group Chats',
|
||||
chooseText: 'Choose',
|
||||
friendSelect: 'Please select a contact',
|
||||
getHistoryMsgFailedText: 'Failed to get message history',
|
||||
deleteText: 'Delete',
|
||||
recallText: 'Recall',
|
||||
copyText: 'Copy',
|
||||
forwardText: 'Forward',
|
||||
forwardComment: 'forward comment',
|
||||
replyText: 'Reply',
|
||||
replyNotFindText: 'Message has recalled or deleted',
|
||||
forwardToTeamText: 'Forward to Group',
|
||||
forwardToFriendText: 'Forward to Contact',
|
||||
sessionRecordText: 'Conversation Record',
|
||||
chatInputPlaceHolder: 'What would you like to say?',
|
||||
enableV2CloudConversationText: 'Enable V2 Cloud Conversation',
|
||||
SwitchToEnglishText: 'Switch to English',
|
||||
pinText: 'Mark',
|
||||
pinFailedText: 'Mark Failed',
|
||||
unpinText: 'Unmark',
|
||||
unpinFailedText: 'Unmark Failed',
|
||||
noPinListText: 'No Mark',
|
||||
collectionText: 'Collection',
|
||||
deleteCollectionText: 'Delete collection',
|
||||
addCollectionSuccessText: 'Add collection success',
|
||||
addCollectionFailedText: 'Add collection Failed',
|
||||
deleteCollectionFailedText: 'Delete collection Failed',
|
||||
noCollectionsText: 'No collection',
|
||||
teamBannedText: 'Message Banned',
|
||||
you: 'You',
|
||||
pinThisText: 'Marked this message',
|
||||
delete: 'Delete this message',
|
||||
recall: 'Recalled a message',
|
||||
recall2: 'This message has been recalled',
|
||||
recall3: 'Recall this message',
|
||||
recallMsgFailText: 'Recall Message Failed',
|
||||
reeditText: 'Edit',
|
||||
loadingMoreText: 'Loading…',
|
||||
noMoreText: 'No more',
|
||||
deleteMsgSuccessText: 'Delete Success',
|
||||
deleteMsgFailText: 'Delete Failed',
|
||||
conversationEmptyText: 'No conversation',
|
||||
teamOwner: 'Group Owner',
|
||||
teamManager: 'Group Manager',
|
||||
teamEmptyText: 'NoGroup Chats',
|
||||
blacklistEmptyText: 'No Blocked Contacts',
|
||||
blacklistSubTitle: 'You will not get messages from anyone on the list. ',
|
||||
validEmptyText: 'No Verification Messages',
|
||||
dismissTeamText: 'Dismiss Group',
|
||||
dismissTeamConfirmText: 'Are you sure you want to dismiss this group?',
|
||||
leaveTeamTitle: 'Leave Group',
|
||||
leaveDiscussionTitle: 'Leave Discussion Group',
|
||||
leaveTeamConfirmText: 'Are you sure you want to leave this group?',
|
||||
leaveTeamSuccessText: 'You have left this group',
|
||||
leaveTeamFailedText: 'Failed to leave this group',
|
||||
leaveDiscussionSuccessText: 'Successfully left the discussion group',
|
||||
leaveDiscussionFailedText: 'Failed to leave the discussion group',
|
||||
dismissTeamSuccessText: 'Dismiss Group Success',
|
||||
dismissTeamFailedText: 'Dismiss Group Failed',
|
||||
updateTeamSuccessText: 'Update Success',
|
||||
updateTeamFailedText: 'Update Failed',
|
||||
teamTitleConfirmText: 'Group name cannot be empty',
|
||||
teamIntroConfirmText: 'Group introduction cannot be empty',
|
||||
aliasConfirmText: 'Alias cannot be empty',
|
||||
sendImageFailedText: 'Failed to send Image',
|
||||
sendVideoFailedText: 'Failed to send Video',
|
||||
sendAudioFailedText: 'Failed to send Audio',
|
||||
sendFileFailedText: 'Failed to send File',
|
||||
sendMsgFailedText: 'Failed to send Message',
|
||||
weekText: 'Weeks ago',
|
||||
dayText: 'Days ago',
|
||||
hourText: 'Hours ago',
|
||||
minuteText: 'Minutes ago',
|
||||
nowText: 'Just now',
|
||||
sendText: 'Send',
|
||||
sendToText: 'Send to',
|
||||
textMsgText: 'Text Message',
|
||||
audioMsgText: 'Audio Message',
|
||||
videoMsgText: 'Video Message',
|
||||
fileMsgText: 'File Message',
|
||||
callMsgText: 'Call Message',
|
||||
geoMsgText: 'Location Message',
|
||||
imgMsgText: 'Image Message',
|
||||
notiMsgText: 'Notification Message',
|
||||
robotMsgText: 'Robot Message',
|
||||
tipMsgText: 'Tip Message',
|
||||
customMsgText: 'Custom Message',
|
||||
unknowMsgText: 'Unknown Message',
|
||||
noFriendText: 'No Friends',
|
||||
onDismissTeamText: 'This group has been dismissed',
|
||||
onRemoveTeamText: 'You have left the group',
|
||||
selectSessionFailText: 'Failed to select conversation',
|
||||
noExistUser: 'This user does not exist',
|
||||
enterAccount: 'Enter account',
|
||||
validMsgText: 'Verification Message',
|
||||
blacklistText: 'Blocked Contacts',
|
||||
applyTeamText: 'Apply to Join Group',
|
||||
acceptResultText: 'Accepted',
|
||||
rejectResultText: 'Rejected',
|
||||
rejectTeamInviteText: 'Rejected group invitation',
|
||||
beRejectResultText: 'Rejected friend request',
|
||||
passResultText: 'Accepted friend request',
|
||||
acceptedText: 'This request has been accepted',
|
||||
acceptFailedText: 'Failed to accept this request',
|
||||
rejectedText: 'This request has been rejected',
|
||||
rejectFailedText: 'Failed to reject this request',
|
||||
passFriendAskText:
|
||||
"I have accepted your friend request, let's start chatting!",
|
||||
applyFriendText: 'Add you as a friend',
|
||||
rejectText: 'Reject',
|
||||
acceptText: 'Accept',
|
||||
inviteTeamText: 'Invite to Group',
|
||||
addBlacklist: 'Block',
|
||||
removeBlacklist: 'Unblock',
|
||||
forwardSuccessText: 'Forward Success',
|
||||
forwardFailText: 'Forward Failed',
|
||||
getMessageFailed: 'Fail to get message',
|
||||
getForwardMessageFailed: 'Fail to get forward message',
|
||||
sendFailWithInBlackText:
|
||||
'The other party has blocked you, message sending failed',
|
||||
sendFailWithDeleteText:
|
||||
'The relationship between both parties has been terminated, please reapply for contact',
|
||||
friendVerificationText: 'Friend Verification',
|
||||
teamAll: 'all',
|
||||
chooseMentionText: 'Choose Mention',
|
||||
someoneText: 'someone',
|
||||
meText: 'mention',
|
||||
teamMutePlaceholder: 'The current group owner has set the group to mute',
|
||||
viewMoreText: 'View More',
|
||||
resendMsgFailText: 'Resend Failed',
|
||||
audioBtnText: 'Press and hold to speak',
|
||||
audioRemindText: 'Release to send',
|
||||
audioErrorText: 'Recording failed',
|
||||
videoPlayText: 'Video Play',
|
||||
voiceCallText: 'Voice Call',
|
||||
videoCallText: 'Video Call',
|
||||
callDurationText: 'call duration',
|
||||
callCancelText: 'canceled',
|
||||
callRejectedText: 'rejected',
|
||||
callTimeoutText: 'Missed call',
|
||||
callBusyText: 'busy line',
|
||||
callFailedText: 'call failed',
|
||||
wxAppFileCopyText: 'Please paste the URL in the mobile browser.',
|
||||
shootText: 'shoot',
|
||||
albumText: 'album',
|
||||
msgReadPageTitleText: 'Message Reading Status',
|
||||
readText: 'Read',
|
||||
unreadText: 'Unread',
|
||||
fileText: 'file',
|
||||
allUnReadText: 'All Unread',
|
||||
msgRecallTimeErrorText: 'Message recall time exceeded',
|
||||
allReadText: 'All Read',
|
||||
searchText: 'Search',
|
||||
searchTitleText: 'Search',
|
||||
friendText: 'Friend',
|
||||
teamText: 'Group',
|
||||
discussionText: 'Discussion Group',
|
||||
searchResultNullText: 'User does not exist',
|
||||
conversationSendFailText: '[Send Failed]',
|
||||
conversationNotificationText: '[Notification]',
|
||||
fileMsgTitleText: '[File Message]',
|
||||
collectionFromText: 'Collection from',
|
||||
copySuccessText: 'Copy Success',
|
||||
openUrlText: 'Copied. Open in browser.',
|
||||
teamManagerText: 'Team Manager',
|
||||
teamManagerSettingText: 'Team Manager Setting',
|
||||
updateTeamInfoText: 'Who is allowed to edit group details',
|
||||
teamOwnerAndManagerText: 'TeamOwnerAndManager',
|
||||
updateTeamInviteText: 'Who is allowed to invite group members',
|
||||
updateTeamAtText: 'Who is allowed to @',
|
||||
addMemberText: 'Add Member',
|
||||
removeText: 'remove',
|
||||
|
||||
securityTipText:
|
||||
'For test only. Beware of money transfer, lottery winnings & strange call scams.',
|
||||
createDiscussionText: 'Create Discussion',
|
||||
|
||||
// emoji 不能随便填,要用固定 key
|
||||
Laugh: '[Laugh]',
|
||||
Happy: '[Happy]',
|
||||
Sexy: '[Sexy]',
|
||||
Cool: '[Cool]',
|
||||
Mischievous: '[Mischievous]',
|
||||
Kiss: '[Kiss]',
|
||||
Spit: '[Spit]',
|
||||
Squint: '[Squint]',
|
||||
Cute: '[Cute]',
|
||||
Grimace: '[Grimace]',
|
||||
Snicker: '[Snicker]',
|
||||
Joy: '[Joy]',
|
||||
Ecstasy: '[Ecstasy]',
|
||||
Surprise: '[Surprise]',
|
||||
Tears: '[Tears]',
|
||||
Sweat: '[Sweat]',
|
||||
Angle: '[Angle]',
|
||||
Funny: '[Funny]',
|
||||
Awkward: '[Awkward]',
|
||||
Thrill: '[Thrill]',
|
||||
Cry: '[Cry]',
|
||||
Fretting: '[Fretting]',
|
||||
Terrorist: '[Terrorist]',
|
||||
Halo: '[Halo]',
|
||||
Shame: '[Shame]',
|
||||
Sleep: '[Sleep]',
|
||||
Tired: '[Tired]',
|
||||
Mask: '[Mask]',
|
||||
ok: '[ok]',
|
||||
AllRight: '[All right]',
|
||||
Despise: '[Despise]',
|
||||
Uncomfortable: '[Uncomfortable]',
|
||||
Disdain: '[Disdain]',
|
||||
ill: '[ill]',
|
||||
Mad: '[Mad]',
|
||||
Ghost: '[Ghost]',
|
||||
Angry: '[Angry]',
|
||||
Unhappy: '[Unhappy]',
|
||||
Frown: '[Frown]',
|
||||
Broken: '[Broken]',
|
||||
Beckoning: '[Beckoning]',
|
||||
Ok: '[Ok]',
|
||||
Low: '[Low]',
|
||||
Nice: '[Nice]',
|
||||
Applause: '[Applause]',
|
||||
GoodJob: '[Good job]',
|
||||
Hit: '[Hit]',
|
||||
Please: '[Please]',
|
||||
Bye: '[Bye]',
|
||||
First: '[First]',
|
||||
Fist: '[Fist]',
|
||||
GiveMeFive: '[Give me five]',
|
||||
Knife: '[Knife]',
|
||||
Hi: '[Hi]',
|
||||
No: '[No]',
|
||||
Hold: '[Hold]',
|
||||
Think: '[Think]',
|
||||
Pig: '[Pig]',
|
||||
NoListen: '[No listen]',
|
||||
NoLook: '[No look]',
|
||||
NoWords: '[No words]',
|
||||
Monkey: '[Monkey]',
|
||||
Bomb: '[Bomb]',
|
||||
Cloud: '[Cloud]',
|
||||
Rocket: '[Rocket]',
|
||||
Ambulance: '[Ambulance]',
|
||||
Poop: '[Poop]',
|
||||
// 错误码及提示内容
|
||||
// 通用错误码
|
||||
190001: 'internal error',
|
||||
190002: 'illegal state',
|
||||
191001: 'misuse',
|
||||
191002: 'cancelled',
|
||||
191003: 'callback failed',
|
||||
191004: 'invalid parameter',
|
||||
191005: 'timeout',
|
||||
191006: 'resource not exist',
|
||||
191007: 'resource already exist',
|
||||
// 连接相关
|
||||
192001: 'connect failed',
|
||||
192002: 'connect timeout',
|
||||
192003: 'disconnected',
|
||||
192004: 'protocol timeout',
|
||||
192005: 'protocol send failed',
|
||||
192006: 'request failed',
|
||||
// 消息相关
|
||||
107319: 'PIN limit exceeded',
|
||||
107320: 'PIN not exist',
|
||||
107322: 'PIN already exist',
|
||||
107327: 'PIN function disabled',
|
||||
189301: 'collection limit exceeded',
|
||||
189302: 'collection not exist',
|
||||
189449: 'collection concurrent operation failed',
|
||||
// 群相关
|
||||
109432: 'no permission',
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"messageText": "消息",
|
||||
"cantactsText": "通讯录",
|
||||
"mineText": "我的"
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
// zn.js
|
||||
export default {
|
||||
appText: '云信IM',
|
||||
messageText: '消息',
|
||||
contactText: '通讯录',
|
||||
mineText: '我的',
|
||||
logoutText: '退出登录',
|
||||
commsEaseText: '关于云信',
|
||||
logoutConfirmText: '确定退出登录吗?',
|
||||
avatarText: '头像',
|
||||
updateAvatarText: '修改头像',
|
||||
updateNameText: '修改名称',
|
||||
accountText: '账号',
|
||||
name: '昵称',
|
||||
genderText: '性别',
|
||||
remarkText: '备注名',
|
||||
mobile: '手机',
|
||||
email: '邮箱',
|
||||
sign: '签名',
|
||||
man: '男',
|
||||
woman: '女',
|
||||
unknow: '未知',
|
||||
birthText: '生日',
|
||||
userOnlineText: '在线',
|
||||
userOfflineText: '离线',
|
||||
FriendPageText: '好友名片',
|
||||
startConversationText: '发起单聊',
|
||||
addText: '添加',
|
||||
removeText: '移除',
|
||||
addTeamManagerSuccessText: '添加管理员成功',
|
||||
addTeamManagerFailText: '添加管理员失败',
|
||||
confirmRemoveText: '是否移除?',
|
||||
removeManagerExplain: '移除后该成员将无管理权限',
|
||||
removeMemberExplain: '将移除该成员',
|
||||
removeSuccessText: '移除成功',
|
||||
removeFailText: '移除失败',
|
||||
userNotInTeam: '该用户不在群里',
|
||||
noTeamManager: '暂无群管理员',
|
||||
noTeamMember: '暂无群成员',
|
||||
applyFriendSuccessText: '好友申请已发送',
|
||||
applyFriendFailText: '发送申请失败',
|
||||
addFriendText: '添加好友',
|
||||
addMemberText: '添加成员',
|
||||
addFriendFailText: '添加好友失败',
|
||||
deleteFriendText: '删除好友',
|
||||
deleteFriendConfirmText: '是否确认删除好友',
|
||||
deleteFriendSuccessText: '删除好友成功',
|
||||
deleteFriendFailText: '删除好友失败',
|
||||
setBlackFailText: '加入黑名单失败',
|
||||
removeBlackFailText: '解除黑名单失败',
|
||||
removeBlackSuccessText: '解除黑名单成功',
|
||||
addPermissionText: '请在系统设置页添加相关权限',
|
||||
FailAvatarText: '上传头像失败',
|
||||
chooseDefaultImage: '选择默认图标',
|
||||
chatButtonText: '去聊天',
|
||||
gotoChatFailText: '去聊天失败',
|
||||
chatWithFriendText: '聊天',
|
||||
okText: '确定',
|
||||
updateText: '修改',
|
||||
cancelText: '取消',
|
||||
friendSelectText: '选择好友',
|
||||
telErrorText: '手机格式不正确',
|
||||
emailErrorText: '邮箱格式不正确',
|
||||
createButtonText: '创建',
|
||||
createP2PText: '发起单聊',
|
||||
createTeamText: '创建群聊',
|
||||
addTeamMemberText: '添加群成员',
|
||||
addTeamMemberFailText: '添加群成员失败',
|
||||
teamTitlePlaceholder: '请输入群名称',
|
||||
maxSelectedText: '最多只能选择200位好友',
|
||||
createTeamSuccessText: '创建群组成功',
|
||||
createDiscussionSuccessText: '创建讨论组成功',
|
||||
createTeamFailedText: '创建群组失败',
|
||||
createDiscussionFailedText: '创建讨论组失败',
|
||||
PersonalPageText: '个人名片',
|
||||
deleteSessionText: '删除会话',
|
||||
sessionMuteText: '开启消息提醒',
|
||||
sessionMuteFailText: '开启消息提醒失败',
|
||||
sessionUnMuteFailText: '关闭消息提醒失败',
|
||||
stickTopText: '聊天置顶',
|
||||
deleteStickTopText: '取消置顶',
|
||||
addStickTopText: '置顶消息',
|
||||
deleteSessionFailText: '删除会话失败',
|
||||
deleteStickTopFailText: '取消置顶失败',
|
||||
addStickTopFailText: '置顶消息失败',
|
||||
teamMemberText: '群成员',
|
||||
discussionMemberText: '讨论组成员',
|
||||
teamManagerText: '群管理',
|
||||
teamManagerSettingText: '管理管理员',
|
||||
updateTeamInfoText: '谁可以编辑群信息',
|
||||
updateTeamInviteText: '谁可以邀请新成员',
|
||||
updateTeamAtText: '谁可以@所有人',
|
||||
transformTeam: '转让群主',
|
||||
transformTeamContent: '确认转让群主给',
|
||||
doubt: '吗?',
|
||||
transformTeamSuccessText: '转让群主成功',
|
||||
transformTeamFailedText: '转让群主失败',
|
||||
transformTeamText: '选择转让成员',
|
||||
teamBannedText: '群禁言',
|
||||
saveText: '保存',
|
||||
setText: '设置',
|
||||
failText: '失败',
|
||||
saveSuccessText: '保存成功',
|
||||
saveFailedText: '保存失败',
|
||||
searchTeamPlaceholder: '请输入群名称',
|
||||
nickInTeamEmptyText: '请输入群昵称',
|
||||
teamTitle: '群名称',
|
||||
discussionTitle: '讨论组名称',
|
||||
teamInfoText: '群信息',
|
||||
discussionInfoText: '讨论组信息',
|
||||
teamIntro: '群介绍',
|
||||
teamAvatar: '群头像',
|
||||
discussionAvatarText: '讨论组头像',
|
||||
networkError: '当前网络错误',
|
||||
searchFailText: '查找失败',
|
||||
offlineText: '当前网络不可用,请检查你当前网络设置。',
|
||||
connectingText: '当前IM连接已断开,正在重连...',
|
||||
teamMenuText: '我的群组',
|
||||
teamChooseText: '我的群聊',
|
||||
chooseText: '选择',
|
||||
friendSelect: '请选择联系人',
|
||||
pleaseSelectMember: '请选择成员',
|
||||
teamMemebrSelect: '人员选择',
|
||||
getHistoryMsgFailedText: '获取失败',
|
||||
deleteText: '删除',
|
||||
recallText: '撤回',
|
||||
copyText: '复制',
|
||||
forwardText: '转发',
|
||||
forwardComment: '留言',
|
||||
forwardSuccessText: '转发成功',
|
||||
forwardFailedText: '转发失败',
|
||||
getMessageFailed: '获取消息失败',
|
||||
replyText: '回复',
|
||||
replyNotFindText: '该消息已撤回或删除',
|
||||
msgRecallTimeErrorText: '已超过时间无法撤回',
|
||||
enableV2CloudConversationText: '是否开启云端会话',
|
||||
SwitchToEnglish: '切换语言为英文',
|
||||
copySuccessText: '复制成功',
|
||||
|
||||
forwardToTeamText: '转发到群组',
|
||||
forwardToFriendText: '转发到个人',
|
||||
sessionRecordText: '的会话记录',
|
||||
chatInputPlaceHolder: '说点什么呢~',
|
||||
pinText: '标记',
|
||||
pinFailedText: '标记失败',
|
||||
unpinText: '取消标记',
|
||||
unpinFailedText: '取消标记失败',
|
||||
noPinListText: '暂无标记消息',
|
||||
collectionText: '收藏',
|
||||
deleteCollectionText: '删除收藏',
|
||||
addCollectionSuccessText: '收藏成功',
|
||||
addCollectionFailedText: '添加收藏失败',
|
||||
deleteCollectionFailedText: '删除收藏失败',
|
||||
noCollectionsText: '暂无收藏',
|
||||
you: '你',
|
||||
pinThisText: '标记了这条消息',
|
||||
delete: '删除此消息',
|
||||
recall: '撤回了一条消息',
|
||||
recall2: '此消息已撤回',
|
||||
recall3: '撤回此消息',
|
||||
recallMsgFailText: '撤回消息失败',
|
||||
reeditText: '重新编辑',
|
||||
loadingMoreText: '加载更多……',
|
||||
noMoreText: '没有更多了',
|
||||
deleteMsgSuccessText: '删除成功',
|
||||
deleteMsgFailText: '删除失败',
|
||||
conversationEmptyText: '暂无会话',
|
||||
teamOwner: '群主',
|
||||
teamManager: '群管理员',
|
||||
manager: '管理员',
|
||||
teamEmptyText: '暂无群聊',
|
||||
blacklistEmptyText: '暂无黑名单',
|
||||
blacklistSubTitle: '你不会收到列表中任何联系人的消息',
|
||||
validEmptyText: '暂无验证消息',
|
||||
dismissTeamText: '解散群组',
|
||||
dismissTeamConfirmText: '是否确认解散该群组',
|
||||
leaveTeamTitle: '退出群聊',
|
||||
leaveDiscussionTitle: '退出讨论组',
|
||||
leaveTeamConfirmText: '是否确认退出该群组',
|
||||
leaveDiscussionConfirmText: '是否确认退出该讨论组',
|
||||
leaveTeamSuccessText: '已成功退出此群',
|
||||
leaveDiscussionSuccessText: '已成功退出此讨论组',
|
||||
leaveTeamFailedText: '退出此群失败',
|
||||
leaveDiscussionFailedText: '退出此讨论组失败',
|
||||
dismissTeamSuccessText: '群解散成功',
|
||||
dismissTeamFailedText: '群解散失败',
|
||||
updateTeamSuccessText: '修改成功',
|
||||
updateTeamFailedText: '修改失败',
|
||||
teamTitleConfirmText: '群名称不能为空',
|
||||
teamIntroConfirmText: '群介绍不能为空',
|
||||
aliasConfirmText: '备注名不能为空',
|
||||
sendImageFailedText: '发送图片失败',
|
||||
sendVideoFailedText: '发送视频失败',
|
||||
sendAudioFailedText: '发送音频失败',
|
||||
sendFileFailedText: '发送文件失败',
|
||||
sendMsgFailedText: '发送消息失败',
|
||||
weekText: '周前',
|
||||
dayText: '天前',
|
||||
hourText: '小时前',
|
||||
minuteText: '分钟前',
|
||||
nowText: '刚刚',
|
||||
sendText: '发送',
|
||||
sendToText: '发送给',
|
||||
textMsgText: '文本消息',
|
||||
audioMsgText: '音频消息',
|
||||
videoMsgText: '视频消息',
|
||||
fileMsgText: '文件消息',
|
||||
callMsgText: '话单消息',
|
||||
geoMsgText: '地理位置消息',
|
||||
imgMsgText: '图片消息',
|
||||
notiMsgText: '通知消息',
|
||||
robotMsgText: '机器消息',
|
||||
tipMsgText: '提示消息',
|
||||
customMsgText: '自定义消息',
|
||||
unknowMsgText: '未知消息体',
|
||||
noFriendText: '暂无好友',
|
||||
onDismissTeamText: '该群聊已解散',
|
||||
onRemoveTeamText: '您已离开群组',
|
||||
selectSessionFailText: '选择会话失败',
|
||||
noExistUser: '该用户不存在',
|
||||
enterAccount: '请输入账号',
|
||||
validMsgText: '验证消息',
|
||||
blacklistText: '黑名单',
|
||||
applyTeamText: '申请入群',
|
||||
acceptResultText: '已同意',
|
||||
rejectResultText: '已拒绝',
|
||||
rejectTeamInviteText: '拒绝了群邀请',
|
||||
beRejectResultText: '拒绝了好友申请',
|
||||
passResultText: '通过了好友申请',
|
||||
acceptedText: '已同意该申请',
|
||||
acceptFailedText: '同意该申请失败',
|
||||
rejectedText: '已拒绝该申请',
|
||||
rejectFailedText: '拒绝该申请失败',
|
||||
passFriendAskText: '我已经同意了你的申请,现在开始聊天吧~',
|
||||
applyFriendText: '添加您为好友',
|
||||
rejectText: '拒绝',
|
||||
acceptText: '同意',
|
||||
inviteTeamText: '邀请入群',
|
||||
addBlacklist: '加入黑名单',
|
||||
removeBlacklist: '解除',
|
||||
teamAll: '所有人',
|
||||
sendFailWithInBlackText: '对方已将你拉黑,消息发送失败',
|
||||
sendFailWithDeleteText: '双方关系已解除,如需沟通,请申请',
|
||||
friendVerificationText: '好友验证',
|
||||
chooseMentionText: '选择提醒',
|
||||
someoneText: '有人',
|
||||
meText: '我',
|
||||
teamMutePlaceholder: '当前群主已经设置为群禁言',
|
||||
noPermission: '您暂无权限操作',
|
||||
muteAllTeamFailedText: '全员禁言失败',
|
||||
unmuteAllTeamFailedText: '解除全员禁言失败',
|
||||
|
||||
nickInTeam: '我在群里的昵称',
|
||||
viewMoreText: '查看更多',
|
||||
resendMsgFailText: '重发失败',
|
||||
audioBtnText: '按住说话',
|
||||
audioRemindText: '松开发送',
|
||||
audioErrorText: '录音失败,请检查是否开启权限',
|
||||
videoPlayText: '视频播放',
|
||||
updateTeamAvatar: '更新了群头像',
|
||||
updateTeamName: '更新群名称为',
|
||||
updateTeamIntro: '更新了群介绍',
|
||||
updateTeamInviteMode: '更新了群权限“邀请他人权限”为',
|
||||
updateTeamUpdateTeamMode: '更新了群权限“群资料修改权限”为',
|
||||
updateAllowAt: '更新了“@所有人权限”为',
|
||||
updateTeamMute: '更新了“群禁言”为',
|
||||
onlyTeamOwner: '仅群主',
|
||||
teamOwnerAndManagerText: '群主和管理员',
|
||||
closeText: '关闭',
|
||||
openText: '开启',
|
||||
joinTeamText: '加入群组',
|
||||
leaveTeamText: '离开了群组',
|
||||
beRemoveTeamText: '被移出群组',
|
||||
beAddTeamManagersText: '被任命为管理员',
|
||||
beRemoveTeamManagersText: '被移除管理员',
|
||||
newGroupOwnerText: '成为新群主',
|
||||
callDurationText: '通话时长',
|
||||
callCancelText: '已取消',
|
||||
callRejectedText: '已拒绝',
|
||||
callTimeoutText: '超时未接听',
|
||||
callBusyText: '忙线未接听',
|
||||
callFailedText: '呼叫失败',
|
||||
wxAppFileCopyText: '已自动复制网址,请在手机浏览器里粘贴该网址',
|
||||
shootText: '拍摄',
|
||||
albumText: '相册',
|
||||
voiceCallText: '语音通话',
|
||||
videoCallText: '视频通话',
|
||||
msgReadPageTitleText: '消息阅读状态',
|
||||
readText: '已读',
|
||||
unreadText: '未读',
|
||||
fileText: '文件',
|
||||
allUnReadText: '全部成员未读',
|
||||
allReadText: '全部成员已读',
|
||||
searchText: '请输入你要搜索的关键字',
|
||||
searchTitleText: '搜索',
|
||||
friendText: '好友',
|
||||
teamText: '群组',
|
||||
discussionText: '讨论组',
|
||||
searchResultNullText: '该用户不存在',
|
||||
conversationSendFailText: '[发送失败]',
|
||||
conversationNotificationText: '[通知消息]',
|
||||
getForwardMessageFailed: '该消息已撤回或删除',
|
||||
fileMsgTitleText: '[文件消息]',
|
||||
collectionFromText: '来自',
|
||||
openUrlText: '已复制链接,请在浏览器打开链接',
|
||||
SwitchToEnglishText: '是否切换为英文',
|
||||
securityTipText:
|
||||
'仅用于体验云信IM 产品功能,请勿轻信汇款、中奖等涉及钱款的信息,勿轻易拨打陌生电话,谨防上当受骗。',
|
||||
createDiscussionText: '创建讨论组',
|
||||
|
||||
// emoji 不能随便填,要用固定 key
|
||||
Laugh: '[大笑]',
|
||||
Happy: '[开心]',
|
||||
Sexy: '[色]',
|
||||
Cool: '[酷]',
|
||||
Mischievous: '[奸笑]',
|
||||
Kiss: '[亲]',
|
||||
Spit: '[伸舌头]',
|
||||
Squint: '[眯眼]',
|
||||
Cute: '[可爱]',
|
||||
Grimace: '[鬼脸]',
|
||||
Snicker: '[偷笑]',
|
||||
Joy: '[喜悦]',
|
||||
Ecstasy: '[狂喜]',
|
||||
Surprise: '[惊讶]',
|
||||
Tears: '[流泪]',
|
||||
Sweat: '[流汗]',
|
||||
Angle: '[天使]',
|
||||
Funny: '[笑哭]',
|
||||
Awkward: '[尴尬]',
|
||||
Thrill: '[惊恐]',
|
||||
Cry: '[大哭]',
|
||||
Fretting: '[烦躁]',
|
||||
Terrorist: '[恐怖]',
|
||||
Halo: '[两眼冒星]',
|
||||
Shame: '[害羞]',
|
||||
Sleep: '[睡着]',
|
||||
Tired: '[冒星]',
|
||||
Mask: '[口罩]',
|
||||
ok: '[OK]',
|
||||
AllRight: '[好吧]',
|
||||
Despise: '[鄙视]',
|
||||
Uncomfortable: '[难受]',
|
||||
Disdain: '[不屑]',
|
||||
ill: '[不舒服]',
|
||||
Mad: '[愤怒]',
|
||||
Ghost: '[鬼怪]',
|
||||
Angry: '[发怒]',
|
||||
Unhappy: '[不高兴]',
|
||||
Frown: '[皱眉]',
|
||||
Broken: '[心碎]',
|
||||
Beckoning: '[心动]',
|
||||
Ok: '[好的]',
|
||||
Low: '[低级]',
|
||||
Nice: '[赞]',
|
||||
Applause: '[鼓掌]',
|
||||
GoodJob: '[给力]',
|
||||
Hit: '[打你]',
|
||||
Please: '[阿弥陀佛]',
|
||||
Bye: '[拜拜]',
|
||||
First: '[第一]',
|
||||
Fist: '[拳头]',
|
||||
GiveMeFive: '[手掌]',
|
||||
Knife: '[剪刀]',
|
||||
Hi: '[招手]',
|
||||
No: '[不要]',
|
||||
Hold: '[举着]',
|
||||
Think: '[思考]',
|
||||
Pig: '[猪头]',
|
||||
NoListen: '[不听]',
|
||||
NoLook: '[不看]',
|
||||
NoWords: '[不说]',
|
||||
Monkey: '[猴子]',
|
||||
Bomb: '[炸弹]',
|
||||
Cloud: '[筋斗云]',
|
||||
Rocket: '[火箭]',
|
||||
Ambulance: '[救护车]',
|
||||
Poop: '[便便]',
|
||||
// 错误码及提示内容
|
||||
// 通用错误码
|
||||
190001: '内部错误',
|
||||
190002: '非法状态',
|
||||
191001: '使用姿势错误',
|
||||
191002: '操作取消',
|
||||
191003: '回调失败',
|
||||
191004: '参数错误',
|
||||
191005: '请求超时',
|
||||
191006: '资源不存在',
|
||||
191007: '资源已存在',
|
||||
// 连接相关
|
||||
192001: '连接错误',
|
||||
192002: '连接超时',
|
||||
192003: '连接断开',
|
||||
192004: '协议超时',
|
||||
192005: '协议发送失败',
|
||||
192006: '请求失败',
|
||||
// 消息相关
|
||||
107319: 'PIN 数量超限',
|
||||
107320: 'PIN 消息不存在',
|
||||
107322: '重复 PIN',
|
||||
107327: '未开启 PIN 功能',
|
||||
189301: '收藏数量超限',
|
||||
189302: '收藏不存在',
|
||||
189449: '并发操作收藏失败',
|
||||
// 群相关
|
||||
109432: '没有权限',
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
|
||||
// ES6模块化引入
|
||||
//import VConsole from 'vconsole'
|
||||
import App from './App'
|
||||
import uviewPlus, { setConfig } from 'uview-plus'
|
||||
//const vConsole = new VConsole();
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
|
||||
+115
-22
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name" : "肝胆相照专家端",
|
||||
"name" : "肝胆相照专家版",
|
||||
"appid" : "__UNI__89F511F",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"versionName" : "4.2.7",
|
||||
"versionCode" : 427,
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
/* 5+App特有相关 */
|
||||
"runmode" : "liberate",
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
@@ -16,14 +17,28 @@
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"compatible" : {
|
||||
"ignoreVersion" : true
|
||||
},
|
||||
"useragent" : {
|
||||
"value" : "gdxz",
|
||||
"concatenate" : true
|
||||
},
|
||||
"modules" : {
|
||||
"Share" : {},
|
||||
"Webview-x5" : {},
|
||||
"UIWebview" : {},
|
||||
"VideoPlayer" : {},
|
||||
"OAuth" : {},
|
||||
"Barcode" : {},
|
||||
"Camera" : {},
|
||||
"Payment" : {}
|
||||
},
|
||||
/* 模块配置 */
|
||||
"distribute" : {
|
||||
/* 应用发布信息 */
|
||||
"android" : {
|
||||
"hasTaskAffinity" : true,
|
||||
/* android打包配置 */
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
@@ -42,11 +57,18 @@
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
],
|
||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
|
||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
|
||||
"minSdkVersion" : 21,
|
||||
"targetSdkVersion" : 30
|
||||
},
|
||||
"ios" : {
|
||||
"dSYMs" : false,
|
||||
"idfa" : false
|
||||
"idfa" : false,
|
||||
"urlschemewhitelist" : [ "weixin", "wechat" ],
|
||||
"permission" : {
|
||||
"NSPhotoLibraryUsageDescription" : "需要访问相册以选择图片",
|
||||
"NSCameraUsageDescription" : "需要访问相机以拍照"
|
||||
}
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"sdkConfigs" : {
|
||||
@@ -54,6 +76,12 @@
|
||||
"weixin" : {
|
||||
"appid" : "wxbf3658f5e674667c",
|
||||
"UniversalLinks" : "https://doc.igandan.com/gdxzExpert/"
|
||||
},
|
||||
"univerify" : {},
|
||||
"sina" : {
|
||||
"appkey" : "2071931330",
|
||||
"redirect_uri" : "http://sns.whalecloud.com/sina2/callback",
|
||||
"UniversalLinks" : ""
|
||||
}
|
||||
},
|
||||
"payment" : {
|
||||
@@ -62,47 +90,110 @@
|
||||
"appid" : "wxbf3658f5e674667c",
|
||||
"UniversalLinks" : "https://doc.igandan.com/gdxzExpert/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ad" : {},
|
||||
"share" : {
|
||||
"weixin" : {
|
||||
"appid" : "wxbf3658f5e674667c",
|
||||
"UniversalLinks" : "https://doc.igandan.com/gdxzExpert/"
|
||||
},
|
||||
"sina" : {
|
||||
"appkey" : "2071931330",
|
||||
"redirect_uri" : "http://sns.whalecloud.com/sina2/callback",
|
||||
"UniversalLinks" : "https://doc.igandan.com/gdxzExpert/"
|
||||
}
|
||||
},
|
||||
"speech" : {},
|
||||
"push" : {}
|
||||
},
|
||||
"splashscreen" : {
|
||||
"androidStyle" : "common"
|
||||
"androidStyle" : "common",
|
||||
"useOriginalMsgbox" : false,
|
||||
"iosStyle" : "common"
|
||||
},
|
||||
"icons" : {
|
||||
"android" : {
|
||||
"hdpi" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/72.png",
|
||||
"xhdpi" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/96.png",
|
||||
"xxhdpi" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/144.png",
|
||||
"xxxhdpi" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/192.png"
|
||||
"hdpi" : "D:/uniapp/专家版图标/72.png",
|
||||
"xhdpi" : "D:/uniapp/专家版图标/96.png",
|
||||
"xxhdpi" : "D:/uniapp/专家版图标/144.png",
|
||||
"xxxhdpi" : "D:/uniapp/专家版图标/192.png"
|
||||
},
|
||||
"ios" : {
|
||||
"appstore" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/1024.png",
|
||||
"appstore" : "D:/uniapp/专家版图标/1024.png",
|
||||
"iphone" : {
|
||||
"app@2x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/120.png",
|
||||
"app@3x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/180.png",
|
||||
"spotlight@2x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/80.png",
|
||||
"spotlight@3x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/120.png",
|
||||
"settings@2x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/58.png",
|
||||
"settings@3x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/87.png",
|
||||
"notification@2x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/40.png",
|
||||
"notification@3x" : "D:/haomi/Documents/WeChat Files/wxid_x5u4rycntnkq21/FileStorage/File/2025-09/专家版图标/专家版图标/60.png"
|
||||
"app@2x" : "D:/uniapp/专家版图标/120.png",
|
||||
"app@3x" : "D:/uniapp/专家版图标/180.png",
|
||||
"spotlight@2x" : "D:/uniapp/专家版图标/80.png",
|
||||
"spotlight@3x" : "D:/uniapp/专家版图标/120.png",
|
||||
"settings@2x" : "D:/uniapp/专家版图标/58.png",
|
||||
"settings@3x" : "D:/uniapp/专家版图标/87.png",
|
||||
"notification@2x" : "D:/uniapp/专家版图标/40.png",
|
||||
"notification@3x" : "D:/uniapp/专家版图标/60.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"nativePlugins" : {
|
||||
"NIMUniPlugin" : {
|
||||
"PUSH_VIVO_APPID" : "100034326",
|
||||
"PUSH_VIVO_APPKEY" : "e789634c1f76c8f184b1def1101ce824",
|
||||
"PUSH_HONOR_APPID" : "900782424",
|
||||
"__plugin_info__" : {
|
||||
"name" : "NIMUniPlugin",
|
||||
"description" : "uni消息推送插件",
|
||||
"platforms" : "Android,iOS",
|
||||
"url" : "",
|
||||
"android_package_name" : "",
|
||||
"ios_bundle_id" : "",
|
||||
"isCloud" : false,
|
||||
"bought" : -1,
|
||||
"pid" : "",
|
||||
"parameters" : {
|
||||
"PUSH_VIVO_APPID" : {
|
||||
"des" : "厂商VIVO-app_id",
|
||||
"key" : "com.vivo.push.app_id",
|
||||
"value" : ""
|
||||
},
|
||||
"PUSH_VIVO_APPKEY" : {
|
||||
"des" : "厂商VIVO-app_key",
|
||||
"key" : "com.vivo.push.api_key",
|
||||
"value" : ""
|
||||
},
|
||||
"PUSH_HONOR_APPID" : {
|
||||
"des" : "厂商HONOR-app_id",
|
||||
"key" : "com.hihonor.push.app_id",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PLV-MediaPlayer" : {
|
||||
"__plugin_info__" : {
|
||||
"name" : "Polyv播放器插件",
|
||||
"description" : "该插件封装了保利威底层播放器,是云直播和云点播插件必须的附属插件",
|
||||
"platforms" : "Android,iOS",
|
||||
"url" : "https://ext.dcloud.net.cn/plugin?id=4798",
|
||||
"android_package_name" : "",
|
||||
"android_package_name" : "cn.shangyu.gdxzExpert",
|
||||
"ios_bundle_id" : "cn.shangyu.gdxzExport",
|
||||
"isCloud" : true,
|
||||
"bought" : 1,
|
||||
"pid" : "4798",
|
||||
"parameters" : {}
|
||||
}
|
||||
},
|
||||
"PLV-VodUniPlugin" : {
|
||||
"__plugin_info__" : {
|
||||
"name" : "polyv保利威视频云点播插件",
|
||||
"description" : "polyv保利威视频云点播软件组件,支持聊天弹幕、视频加密、多码率、去广告等,还支持视频多维数据统计,适用于教学录播、产品介绍片、视频门户等",
|
||||
"platforms" : "Android,iOS",
|
||||
"url" : "https://ext.dcloud.net.cn/plugin?id=2802",
|
||||
"android_package_name" : "cn.shangyu.gdxzExpert",
|
||||
"ios_bundle_id" : "cn.shangyu.gdxzExport",
|
||||
"isCloud" : true,
|
||||
"bought" : 1,
|
||||
"pid" : "2802",
|
||||
"parameters" : {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -120,5 +211,7 @@
|
||||
"vueVersion" : "3",
|
||||
"uniStatistics" : {
|
||||
"version" : "2"
|
||||
}
|
||||
},
|
||||
"fallbackLocale" : "zh-Hans",
|
||||
"locale" : "zh-Hans"
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"agcgw":{"url":"connect-drcn.dbankcloud.cn","backurl":"connect-drcn.hispace.hicloud.com","websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn","websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com"},"agcgw_all":{"SG":"connect-dra.dbankcloud.cn","SG_back":"connect-dra.hispace.hicloud.com","CN":"connect-drcn.dbankcloud.cn","CN_back":"connect-drcn.hispace.hicloud.com","RU":"connect-drru.hispace.dbankcloud.ru","RU_back":"connect-drru.hispace.dbankcloud.cn","DE":"connect-dre.dbankcloud.cn","DE_back":"connect-dre.hispace.hicloud.com"},"websocketgw_all":{"SG":"connect-ws-dra.hispace.dbankcloud.cn","SG_back":"connect-ws-dra.hispace.dbankcloud.com","CN":"connect-ws-drcn.hispace.dbankcloud.cn","CN_back":"connect-ws-drcn.hispace.dbankcloud.com","RU":"connect-ws-drru.hispace.dbankcloud.ru","RU_back":"connect-ws-drru.hispace.dbankcloud.cn","DE":"connect-ws-dre.hispace.dbankcloud.cn","DE_back":"connect-ws-dre.hispace.dbankcloud.com"},"client":{"cp_id":"890086000102014306","product_id":"9105163812218585677","client_id":"178572405214545024","client_secret":"B90774CD63B8A6AB5C2C587DC9D7C4C666EF53A19DBA70C4D549C6302ED6CFBE","project_id":"9105163812218585677","app_id":"10526652","api_key":"CV58Raxnpwbfazn6iLPkESUy7KoiUzZ5iTv8lFg/WuexwYZceAK6F9BjRf0HVmT+039dGKt5yecdkRdQ4FCHsmLZ1Zvh","package_name":"cn.shangyu.gdxzExpert"},"oauth_client":{"client_id":"10526652","client_type":1},"app_info":{"app_id":"10526652","package_name":"cn.shangyu.gdxzExpert"},"service":{"analytics":{"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn","collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com","collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn","resource_id":"p1","channel_id":""},"ml":{"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"},"cloudstorage":{"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg":"https://ops-dra.agcstorage.link","storage_url_de":"https://ops-dre.agcstorage.link","storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia","storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu","storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn"},"search":{"url":"https://search-drcn.cloud.huawei.com"},"edukit":{"edu_url":"edukit.cloud.huawei.com.cn","dh_url":"edukit.cloud.huawei.com.cn"}},"region":"CN","configuration_version":"3.0","appInfos":[{"package_name":"cn.shangyu.gdxzExpert","client":{"app_id":"10526652"},"app_info":{"package_name":"cn.shangyu.gdxzExpert","app_id":"10526652"},"oauth_client":{"client_type":1,"client_id":"10526652"}}]}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"developer_id":"109999967097",
|
||||
"app_id":"900782424",
|
||||
"package_name":"cn.shangyu.gdxzExpert",
|
||||
"version":"1.0"
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Info.plist</key>
|
||||
<data>
|
||||
MxazSmkOgOArGHG40O8L+mZ4ULU=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict/>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "NIMUniPlugin",
|
||||
"id": "NIMUniPlugin",
|
||||
"version": "1.1.3",
|
||||
"git": "3ff8678",
|
||||
"buildAt": "7/21/2025, 10:17:00 AM",
|
||||
"description": "uni消息推送插件",
|
||||
"_dp_type": "nativeplugin",
|
||||
"_dp_nativeplugin": {
|
||||
"android": {
|
||||
"plugins": [
|
||||
{
|
||||
"type": "module",
|
||||
"name": "NIMUniPlugin-PluginModule",
|
||||
"class": "com.netease.nimlib.uniapp.push.PushModule"
|
||||
}
|
||||
],
|
||||
"hooksClass": "com.netease.nimlib.uniapp.push.PushModule",
|
||||
"integrateType": "aar",
|
||||
"dependencies": [
|
||||
"com.huawei.hms:push:6.9.0.300",
|
||||
"com.meizu.flyme.internet:push-internal:4.2.3",
|
||||
"com.google.android.gms:play-services-base:18.2.0",
|
||||
"com.google.firebase:firebase-messaging:23.1.2",
|
||||
"com.google.firebase:firebase-core:21.1.1",
|
||||
"com.google.code.gson:gson:2.6.2",
|
||||
"commons-codec:commons-codec:1.6",
|
||||
"com.netease.nimlib:basesdk:9.16.1",
|
||||
"com.netease.nimlib:push:9.16.1"
|
||||
],
|
||||
"compileOptions": {
|
||||
"sourceCompatibility": "1.8",
|
||||
"targetCompatibility": "1.8"
|
||||
},
|
||||
"abis": [
|
||||
"armeabi-v7a",
|
||||
"arm64-v8a",
|
||||
"x86"
|
||||
],
|
||||
"minSdkVersion": "21",
|
||||
"useAndroidX": true,
|
||||
"parameters": {
|
||||
"PUSH_VIVO_APPID": {
|
||||
"des": "厂商VIVO-app_id",
|
||||
"key": "com.vivo.push.app_id"
|
||||
},
|
||||
"PUSH_VIVO_APPKEY": {
|
||||
"des": "厂商VIVO-app_key",
|
||||
"key": "com.vivo.push.api_key"
|
||||
},
|
||||
"PUSH_HONOR_APPID": {
|
||||
"des": "厂商HONOR-app_id",
|
||||
"key": "com.hihonor.push.app_id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ios": {
|
||||
"plugins": [
|
||||
{
|
||||
"type": "module",
|
||||
"name": "NIMUniPlugin-PluginModule",
|
||||
"class": "NIMPluginModule"
|
||||
}
|
||||
],
|
||||
"hooksClass": "NIMPluginProxy",
|
||||
"integrateType": "framework",
|
||||
"deploymentTarget": "9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -8,11 +8,20 @@
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@xkit-yx/im-store-v2": "^0.8.3",
|
||||
"@xkit-yx/utils": "^0.7.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.18",
|
||||
"html2canvas": "^1.4.1",
|
||||
"image-tools": "^1.4.0",
|
||||
"js-base64": "^3.7.8",
|
||||
"js-md5": "^0.8.3",
|
||||
"mobx": "^6.6.1",
|
||||
"nim-web-sdk-ng": "^10.9.50",
|
||||
"pinyin": "^4.0.0",
|
||||
"uview-plus": "^3.4.73"
|
||||
"uni-packing-wgt": "^1.2.3",
|
||||
"uniapp-video-player": "^1.3.0",
|
||||
"uview-plus": "^3.4.73",
|
||||
"vconsole": "^3.15.1"
|
||||
}
|
||||
}
|
||||
|
||||
+1668
-928
File diff suppressed because it is too large
Load Diff
+197
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<view class="ad-container" v-if="adData.path">
|
||||
<!-- 广告图片 -->
|
||||
<image
|
||||
class="ad-image"
|
||||
:src="adData.path"
|
||||
mode="aspectFill"
|
||||
@click="handleAdClick"
|
||||
></image>
|
||||
|
||||
<!-- 右上角倒计时跳过按钮 -->
|
||||
<view class="skip-button" @click="skipAd">
|
||||
<text class="skip-text">跳过 {{countdown}}s</text>
|
||||
</view>
|
||||
|
||||
<!-- 底部点击跳转按钮 -->
|
||||
<view class="bottom-button" v-if="adData.url" @click="handleAdClick">
|
||||
<text class="button-text">点击查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-container" v-else>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, nextTick, computed, onUnmounted } from 'vue';
|
||||
import { onShow, onLoad, onPageScroll } from "@dcloudio/uni-app";
|
||||
import my_api from '@/api/my_api.js'
|
||||
import docUrl from "@/utils/docUrl.js";
|
||||
const app = getApp()
|
||||
// 广告数据
|
||||
const adData = ref({
|
||||
path: '',
|
||||
url: ''
|
||||
});
|
||||
|
||||
// 倒计时
|
||||
const countdown = ref(5);
|
||||
let timer = null;
|
||||
|
||||
// 页面加载
|
||||
onLoad(() => {
|
||||
console.log('开屏广告页面加载');
|
||||
getStartpage();
|
||||
});
|
||||
|
||||
// 获取开屏广告数据
|
||||
const getStartpage = () => {
|
||||
my_api.startpage().then(res => {
|
||||
console.log('开屏广告数据:', res);
|
||||
if (res && res.data) {
|
||||
adData.value = {
|
||||
path: docUrl + res.data.path || '',
|
||||
url: res.data.url || ''
|
||||
};
|
||||
|
||||
// 如果有广告图片,开始倒计时
|
||||
if (res.data.path) {
|
||||
|
||||
startCountdown();
|
||||
|
||||
} else {
|
||||
// 没有广告,直接跳转到首页
|
||||
navigateToHome();
|
||||
}
|
||||
} else {
|
||||
// 接口返回异常,直接跳转到首页
|
||||
navigateToHome();
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取开屏广告失败:', err);
|
||||
// 接口调用失败,直接跳转到首页
|
||||
navigateToHome();
|
||||
});
|
||||
}
|
||||
|
||||
// 开始倒计时
|
||||
const startCountdown = () => {
|
||||
timer = setInterval(() => {
|
||||
countdown.value--;
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer);
|
||||
if(app.globalData.plAd){
|
||||
navigateToHome();
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// 跳过广告
|
||||
const skipAd = () => {
|
||||
clearInterval(timer);
|
||||
navigateToHome();
|
||||
}
|
||||
|
||||
// 点击广告
|
||||
const handleAdClick = () => {
|
||||
if (adData.value.url) {
|
||||
// 有跳转链接,跳转到指定页面
|
||||
uni.navigateTo({
|
||||
url: '/pages/webview/webview?url=' + adData.value.url
|
||||
});
|
||||
} else {
|
||||
// 没有跳转链接,直接跳转到首页
|
||||
navigateToHome();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转到首页
|
||||
const navigateToHome = () => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}
|
||||
|
||||
// 页面卸载时清理定时器
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ad-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #000;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.ad-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
|
||||
.skip-button {
|
||||
position: absolute;
|
||||
top: 60rpx;
|
||||
right: 30rpx;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
border-radius: 40rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.skip-text {
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.bottom-button {
|
||||
position: absolute;
|
||||
bottom: 100rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 50rpx;
|
||||
padding: 24rpx 60rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(102, 126, 234, 0.3);
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.button-text {
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: #666;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<uni-nav-bar title="继续教育" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
|
||||
<navBar :title="'继续教育'"></navBar>
|
||||
<view class="page">
|
||||
<!-- 课程列表 -->
|
||||
<view class="course-list">
|
||||
@@ -103,21 +103,22 @@
|
||||
import xueyuanImg from "@/static/ganbingxueyuan.png"
|
||||
import newerImg from "@/static/xinshoujiaocheng.png"
|
||||
import navTo from '@/utils/navTo.js';
|
||||
import navBar from "@/components/navBar/navBar.vue"
|
||||
// 方法
|
||||
// 方法
|
||||
const goToCourse = (courseType) => {
|
||||
console.log('进入课程:', courseType);
|
||||
|
||||
|
||||
// 根据课程类型进行不同的处理
|
||||
switch(courseType) {
|
||||
case 'course':
|
||||
navTo({
|
||||
url: '/pages_course/course/course'
|
||||
uni.sendNativeEvent('goCourse',{
|
||||
msg: 'course'
|
||||
})
|
||||
break;
|
||||
case 'video':
|
||||
navTo({
|
||||
url: '/pages_app/video/video'
|
||||
url: '/pages_app/video/video?from=education'
|
||||
})
|
||||
break;
|
||||
case 'ppt':
|
||||
@@ -166,9 +167,8 @@ $padding-small: 10px;
|
||||
|
||||
.page {
|
||||
background-color: $gray-bg;
|
||||
min-height: calc(100vh - 140rpx);
|
||||
|
||||
padding-bottom: 120rpx;
|
||||
min-height: calc(100vh - var(--status-bar-height) - 44px);
|
||||
margin-top:calc(var(--status-bar-height) + 44px);
|
||||
}
|
||||
|
||||
// 课程列表
|
||||
|
||||
+1037
-557
File diff suppressed because it is too large
Load Diff
+1468
-1119
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<navBar :showLeft="false" :title="'加载中...'"></navBar>
|
||||
<view class="loading-page"></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted,ref} from 'vue';
|
||||
import { onLoad,onUnload,onHide,onShow } from '@dcloudio/uni-app';
|
||||
import navBar from '@/components/navBar/navBar.vue';
|
||||
const timer=ref(null);
|
||||
const count=ref(0);
|
||||
const countDown=()=>{
|
||||
if(timer.value){
|
||||
return
|
||||
}
|
||||
timer.value=setInterval(()=>{
|
||||
count.value++;
|
||||
if(count.value>=8){
|
||||
clearInterval(timer.value);
|
||||
plus.runtime.quit();
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
onShow(() => {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
});
|
||||
countDown()
|
||||
});
|
||||
|
||||
onUnload(() => {
|
||||
uni.hideLoading();
|
||||
if(timer.value){
|
||||
clearInterval(timer.value);
|
||||
}
|
||||
});
|
||||
onHide(() => {
|
||||
uni.hideLoading();
|
||||
if(timer.value){
|
||||
clearInterval(timer.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loading-page{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<uni-nav-bar title="肝胆会议" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
|
||||
<navBar :title="'肝胆会议'"></navBar>
|
||||
<view class="page">
|
||||
<!-- 筛选标签栏 -->
|
||||
<view class="filter-bar">
|
||||
@@ -146,6 +146,7 @@
|
||||
import timeImg from "@/static/play_long.png"
|
||||
import api from '@/api/api';
|
||||
import docUrl from '@/utils/docUrl';
|
||||
import navBar from "@/components/navBar/navBar.vue"
|
||||
// 弹窗状态
|
||||
const isTimePopupShow = ref(false);
|
||||
const isLocationPopupShow = ref(false);
|
||||
@@ -407,7 +408,7 @@
|
||||
meetingListBySearchU(filters).then(() => {
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
});
|
||||
});
|
||||
|
||||
+593
-51
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<uni-nav-bar title="我的" fixed color="#8B2316" height="140rpx" :border="false"
|
||||
backgroundColor="#eeeeee"></uni-nav-bar>
|
||||
<navBar :title="'我的'" :showLeft="false"></navBar>
|
||||
<view class="page">
|
||||
|
||||
|
||||
@@ -8,8 +7,22 @@
|
||||
<view class="user-card"
|
||||
:style="{'background-image': `url(${myInfoBackGround || '/static/big_background_my.png'})`, 'background-size':'cover','background-repeat':'no-repeat'}">
|
||||
<view class="user-info">
|
||||
<image class="avatar" :src="avatar" mode="aspectFill"></image>
|
||||
<text class="username">{{username}}</text>
|
||||
<image class="avatar" :src="avatar" mode="aspectFill" @click="goToPage('myInfo')"></image>
|
||||
<view class="user-info-content">
|
||||
<text class="username">{{username}}</text>
|
||||
<scroll-view class="honor_box" scroll-x="true" show-scrollbar="false">
|
||||
<view class="honor_wrap">
|
||||
<view class="honor_item" v-if="ranking > 0">
|
||||
<image class="honor_image" :src="suifangImg" mode="aspectFill"></image>
|
||||
<text class="honor_text">随访达人|排名{{ranking}}</text>
|
||||
</view>
|
||||
<view class="honor_item" v-for="item in honor_list" :key="item.id" @click="getHonorDetail(item.id)">
|
||||
<image class="honor_image" :src="rongyu" mode="aspectFill"></image>
|
||||
<text class="honor_text">{{ item.nick_name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 统计数据 -->
|
||||
@@ -27,9 +40,12 @@
|
||||
<text class="stats-label">患者送花数</text>
|
||||
</view>
|
||||
<view class="divder"></view>
|
||||
<view class="signbox">
|
||||
<view class="signbox" v-if="sign_in == 0" @click="onSignClick">
|
||||
<view class="sign">签到</view>
|
||||
</view>
|
||||
<view class="signbox_1" v-else @click="goToPage('pointMall')">
|
||||
<view class="sign">{{ formatToChineseUnit(totalPoints) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -54,7 +70,7 @@
|
||||
<up-image :src="sfImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>随访二维码</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToPage('qrcode')">
|
||||
<view class="service-item" @click="goToPage('plan')">
|
||||
<up-image :src="czjhImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>出诊计划</text>
|
||||
</view>
|
||||
@@ -88,9 +104,9 @@
|
||||
<!-- 账户明细 -->
|
||||
<view class="section">
|
||||
<view class="section-title">账户明细</view>
|
||||
<up-scroll-list indicatorActiveColor="#8B2316" indicatorWidth="40rpx" indicatorBarWidth="20rpx"
|
||||
<up-scroll-list :indicator="isAccount" indicatorActiveColor="#8B2316" indicatorWidth="40rpx" indicatorBarWidth="20rpx"
|
||||
class="account-grid">
|
||||
<view class="account-item" @click="goToPage('myAccount')">
|
||||
<view class="account-item" @click="goToPage('myAccount')" v-if="isAccount">
|
||||
<up-image :src="wdzzImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>我的账户</text>
|
||||
</view>
|
||||
@@ -102,11 +118,11 @@
|
||||
<up-image :src="wdflImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>我的福利</text>
|
||||
</view>
|
||||
<view class="account-item" @click="goToPage('myFlower')">
|
||||
<view class="account-item" @click="goToPage('myFlower')" v-if="isAccount">
|
||||
<up-image :src="wdxhImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>我的鲜花</text>
|
||||
</view>
|
||||
<view class="account-item" @click="goToPage('pptDetail')">
|
||||
<view class="account-item" @click="goToPage('pptDetail')" v-if="isAccount">
|
||||
<up-image :src="kjmxImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>课件明细</text>
|
||||
</view>
|
||||
@@ -117,28 +133,31 @@
|
||||
</up-scroll-list>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef APP -->
|
||||
<!-- 常用操作 -->
|
||||
<view class="section">
|
||||
<view class="section-title">常用操作</view>
|
||||
<view class="operation-grid">
|
||||
<view class="operation-item" @click="goToPage('wechatUnbind')">
|
||||
<up-image :src="wxjbImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>微信解绑</text>
|
||||
<text v-if="isBoundWechat">微信解绑</text>
|
||||
<text v-else>微信绑定</text>
|
||||
</view>
|
||||
<view class="operation-item" @click="goToPage('changePhone')">
|
||||
<up-image :src="ghsjhImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>更换手机号</text>
|
||||
</view>
|
||||
<view class="operation-item" @click="goToPage('notifications')">
|
||||
<view class="operation-item" @click="switchPushPermissions">
|
||||
<up-image :src="tzykImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>通知已开</text>
|
||||
<text>通知已{{notice_on?'开':'关'}}</text>
|
||||
</view>
|
||||
<view class="operation-item" @click="showVersion">
|
||||
<up-image :src="versionImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>V4.1.4</text>
|
||||
<up-image :src="hasNewVersion?versionImgOn:versionImg" width="48rpx" height="48rpx"></up-image>
|
||||
<text>{{hasNewVersion?'有新版本':'V'+version}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view class="setbox">
|
||||
<!-- 福利卡兑换 -->
|
||||
<view class="sectioncell benefit-section">
|
||||
@@ -159,7 +178,7 @@
|
||||
|
||||
<!-- 常用银行卡 -->
|
||||
<view class="sectioncell bank-section">
|
||||
<view class="bank-item" @click="goToPage('bankCard')">
|
||||
<view class="bank-item" @click="goToPage('bankCard')" v-if="isAccount">
|
||||
<view class="bank-icon">
|
||||
<up-image :src="cyyhk" width="48rpx" height="48rpx"></up-image>
|
||||
</view>
|
||||
@@ -178,10 +197,12 @@
|
||||
<view class="settings-icon">
|
||||
<up-image :src="settingImg" width="48rpx" height="48rpx"></up-image>
|
||||
</view>
|
||||
<view class="settings-content">
|
||||
<view class="settings-content flex-row" >
|
||||
<text class="settings-title">设置与帮助</text>
|
||||
<text v-if="hasNewVersion && isIos" class="new-version">有新版本</text>
|
||||
</view>
|
||||
<view class="settings-arrow">
|
||||
|
||||
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@@ -199,16 +220,69 @@
|
||||
<!-- 底部导航栏 -->
|
||||
<CustomTabbar></CustomTabbar>
|
||||
</view>
|
||||
<unidialog :visible="hasSign" content="今日已签到,每天只能签到一次。<br>请明日继续哦~" @close="hasSign=false" :showCancel="true" cancelText="关闭"></unidialog>
|
||||
<up-overlay :show="showSign" >
|
||||
<view class="signwrap">
|
||||
<view class="signbox">
|
||||
<view class="close" @click="showSign=false"></view>
|
||||
<view class="signbg">
|
||||
<up-image :src="signImg" width="604rpx" height="964rpx" ></up-image>
|
||||
</view>
|
||||
<view class="signcontent">
|
||||
<view class="day">今天是我们相识的第{{signInfo.gdxzday}}天</view>
|
||||
<view class="signtotal">本周共签到{{signInfo.totalDay}}次</view>
|
||||
<view class="signcontinue">已经连续签到{{signInfo.continuous_day}}天</view>
|
||||
<view class="tip">连续签到获取更多积分</view>
|
||||
<view class="news" @click.stop="goNews">
|
||||
{{signInfo.news.summary}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</up-overlay>
|
||||
<up-overlay :show="showHonor" >
|
||||
<view class="honorwrap">
|
||||
<view class="honorbox">
|
||||
<image :src="docUrl+honnor_detail.img" class="honor_image"></image>
|
||||
<uni-icons type="close" class="close_honor" size="24" color="#fff" @click="showHonor=false"></uni-icons>
|
||||
<view class="content">
|
||||
<view class="content_title">
|
||||
{{honnor_detail.title}}
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="row_item" v-for="item in honnor_detail.honorlist" :key="item.id">
|
||||
{{ item.nick_name }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="content_content">
|
||||
{{honnor_detail.note}}
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</up-overlay>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import unidialog from '@/components/dialog/dialog.vue'
|
||||
import signImg from "@/static/sign_in_bng_big.png"
|
||||
import CustomTabbar from '@/components/tabBar/tabBar.vue';
|
||||
import navBar from "@/components/navBar/navBar.vue"
|
||||
import {
|
||||
ref
|
||||
ref,reactive
|
||||
} from 'vue';
|
||||
import {
|
||||
onShow
|
||||
} from "@dcloudio/uni-app";
|
||||
const showHonor=ref(false);
|
||||
import docUrl from "@/utils/docUrl.js"
|
||||
import honnorExpert from "@/static/zixunexpert.png"
|
||||
import honnorYingxiong from "@/static/yingxiongbanglog.png"
|
||||
import rongyu from "@/static/yxb.png"
|
||||
import version from '@/utils/version.js'
|
||||
import hzshImg from "@/static/hzsh.png"
|
||||
import hzfzImg from "@/static/hzfz.png"
|
||||
import qfxxImg from "@/static/qfxz.png"
|
||||
@@ -229,18 +303,27 @@
|
||||
import ghsjhImg from "@/static/ghsjh.png"
|
||||
import tzykImg from "@/static/xxtx.png"
|
||||
import versionImg from "@/static/fxxbb.png"
|
||||
|
||||
|
||||
import versionImgOn from "@/static/fxbb.png"
|
||||
import jifenImg from "@/static/point_buy.png"
|
||||
import suifangImg from "@/static/suifang.png"
|
||||
import fulicard from "@/static/fulicard.png"
|
||||
import fpgl from "@/static/fpgl.png"
|
||||
import cyyhk from "@/static/cyhhk.png"
|
||||
import settingImg from "@/static/setting.png"
|
||||
import api from '@/api/api.js'
|
||||
import my_api from '@/api/my_api.js'
|
||||
import navTo from "@/utils/navTo"
|
||||
import linkUrl from "@/utils/docUrl"
|
||||
|
||||
// 响应式数据
|
||||
const isLargeFont = ref(false);
|
||||
|
||||
const hasSign = ref(false)
|
||||
const showSign = ref(false)
|
||||
const signInfo=reactive({
|
||||
news:{
|
||||
summary:''
|
||||
}
|
||||
})
|
||||
// 新增:我的信息数据
|
||||
const avatar = ref('')
|
||||
const username = ref('')
|
||||
@@ -248,7 +331,46 @@
|
||||
const consultCount = ref(0)
|
||||
const flowerCount = ref(0)
|
||||
const myInfoBackGround = ref('')
|
||||
|
||||
const totalPoints = ref(0)
|
||||
const sign_in = ref(0)
|
||||
const honor_list = ref([])
|
||||
const ranking = ref(0)
|
||||
|
||||
const notice_on = ref(false)
|
||||
const hasNewVersion = ref(false)
|
||||
const checkVersion=()=>{
|
||||
api.checkVersion().then(res=>{
|
||||
if(res.code==80002){
|
||||
hasNewVersion.value=true
|
||||
}
|
||||
})
|
||||
}
|
||||
const isAccount = ref(false);
|
||||
const getIsAccount=()=>{
|
||||
api.getIsAccount().then(res=>{
|
||||
if(res.code==1){
|
||||
isAccount.value=res.is_account==0?false:true;
|
||||
}
|
||||
})
|
||||
}
|
||||
const goNews=()=>{
|
||||
let url=docUrl+signInfo.news.path;
|
||||
// #ifdef H5
|
||||
window.open(url, '_blank');
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(url);
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
const encoded = encodeURIComponent(url);
|
||||
navTo({
|
||||
url: `/pages_app/webview/webview?url=${encoded}`
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 从storage获取用户信息
|
||||
const getUserInfoFromStorage = () => {
|
||||
try {
|
||||
@@ -263,35 +385,81 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 签到点击事件
|
||||
const onSignClick = async () => {
|
||||
|
||||
try {
|
||||
// 调用添加积分接口
|
||||
const res = await api.addBonusPointsN({
|
||||
score_type:1
|
||||
});
|
||||
|
||||
if (res && res.code ==1) {
|
||||
// 签到成功
|
||||
sign_in.value = 1;
|
||||
uni.showToast({
|
||||
title: '签到成功,获得'+res.bonuspoints+'积分',
|
||||
icon: 'none'
|
||||
});
|
||||
Object.assign(signInfo,res);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res?.msg || '签到失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('签到失败:', error);
|
||||
uni.showToast({
|
||||
title: '签到失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const fetchMyInfo = async () => {
|
||||
try {
|
||||
const res = await api.getMyInfo({})
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const data = res.data
|
||||
myInfoBackGround.value = data.myInfoBackGround;
|
||||
followupCount.value = data.follow_patient_num || data.relationPatientNum || 0
|
||||
consultCount.value = data.consult_total || data.consultCount || 0
|
||||
flowerCount.value = data.give_flower_num || data.flowerCount || 0
|
||||
myInfoBackGround.value = data.myInfoBackGround;
|
||||
followupCount.value = data.expert_apply_num || 0
|
||||
consultCount.value = data.consult_total_num || 0
|
||||
flowerCount.value = data.ping_flowewr_num || 0
|
||||
totalPoints.value = data.total_points || 0
|
||||
sign_in.value = data.sign_in || 0
|
||||
honor_list.value = data.honor_list || []
|
||||
ranking.value = data.ranking || 0
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取我的信息失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 数字格式化为中文单位(万/亿)
|
||||
const formatToChineseUnit = (value, fractionDigits = 1) => {
|
||||
if (value == null || value === '' || isNaN(Number(value))) return value;
|
||||
const num = Number(value);
|
||||
const sign = num < 0 ? '-' : '';
|
||||
const abs = Math.abs(num);
|
||||
|
||||
if (abs < 10000) {
|
||||
return sign + String(abs);
|
||||
}
|
||||
if (abs < 100000000) {
|
||||
const v = (abs / 10000).toFixed(fractionDigits);
|
||||
return sign + (v.indexOf('.') > -1 ? v.replace(/\.0+$/, '').replace(/(\.\d*?)0+$/, '$1') : v) + '万';
|
||||
}
|
||||
const v = (abs / 100000000).toFixed(fractionDigits);
|
||||
return sign + (v.indexOf('.') > -1 ? v.replace(/\.0+$/, '').replace(/(\.\d*?)0+$/, '$1') : v) + '亿';
|
||||
}
|
||||
|
||||
// 方法
|
||||
const toggleFontSize = () => {
|
||||
isLargeFont.value = !isLargeFont.value;
|
||||
console.log('切换字体大小:', isLargeFont.value ? '大字版' : '普通版');
|
||||
};
|
||||
|
||||
const checkin = () => {
|
||||
console.log('签到');
|
||||
uni.showToast({
|
||||
title: '签到成功',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const goToPage = (page) => {
|
||||
console.log('跳转到页面:', page);
|
||||
let url="";
|
||||
@@ -304,11 +472,17 @@
|
||||
url="/pages_app/patientGroup/patientGroup"
|
||||
break;
|
||||
case 'groupMessage':
|
||||
url="/pages_app/groupMessage/groupMessage"
|
||||
url="/pages_chat/groupMessage/groupMessage"
|
||||
break;
|
||||
case 'qrcode':
|
||||
url="/pages_app/myCode/myCode"
|
||||
break;
|
||||
case 'myInfo':
|
||||
url="/pages_app/personInfo/personInfo"
|
||||
break;
|
||||
case 'plan':
|
||||
url="/pages_chat/outPatient/outPatient"
|
||||
break;
|
||||
case 'myVideos':
|
||||
url="/pages_app/myVideo/myVideo"
|
||||
break;
|
||||
@@ -327,6 +501,9 @@
|
||||
case 'myPoints':
|
||||
url="/pages_app/myPoint/myPoint"
|
||||
break;
|
||||
case 'pointMall':
|
||||
url="/pages_goods/pointMall/pointMall"
|
||||
break;
|
||||
case 'myBenefits':
|
||||
url="/pages_app/myWelfare/myWelfare"
|
||||
break;
|
||||
@@ -346,7 +523,7 @@
|
||||
url="/pages_app/changeMobile/changeMobile"
|
||||
break;
|
||||
case 'benefitExchange':
|
||||
url="/pages_app/myWelfareCard/myWelfareCard"
|
||||
url="/pages_app/myWelfareCard/myWelfareCard?from=my"
|
||||
break;
|
||||
case 'bankCard':
|
||||
url="/pages_app/idcardAuth/bankCardList"
|
||||
@@ -355,8 +532,9 @@
|
||||
url="/pages_app/setting/setting"
|
||||
break;
|
||||
default:
|
||||
const push_clientid = uni.getStorageSync("push_clientid")
|
||||
uni.showToast({
|
||||
title: '功能开发中',
|
||||
title: 'push_clientid: '+push_clientid,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
@@ -365,6 +543,131 @@
|
||||
})
|
||||
};
|
||||
|
||||
// 判断通知权限是否开启
|
||||
const isNoticeOn = () => {
|
||||
// #ifdef APP-PLUS
|
||||
if (plus.os.name == "Android") {
|
||||
var main = plus.android.runtimeMainActivity();
|
||||
var NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");
|
||||
if (NotificationManagerCompat == null) {
|
||||
NotificationManagerCompat = plus.android.importClass("androidx.core.app.NotificationManagerCompat");
|
||||
}
|
||||
var areNotificationsEnabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
|
||||
notice_on.value = areNotificationsEnabled
|
||||
return areNotificationsEnabled;
|
||||
} else if (plus.os.name == "iOS") {
|
||||
var isIosOn = undefined;
|
||||
var types = 0;
|
||||
var app = plus.ios.invoke("UIApplication", "sharedApplication");
|
||||
var settings = plus.ios.invoke(app, "currentUserNotificationSettings");
|
||||
if (settings) {
|
||||
types = settings.plusGetAttribute("types");
|
||||
plus.ios.deleteObject(settings);
|
||||
} else {
|
||||
types = plus.ios.invoke(app, "enabledRemoteNotificationTypes");
|
||||
}
|
||||
plus.ios.deleteObject(app);
|
||||
isIosOn = 0 != types;
|
||||
notice_on.value = isIosOn
|
||||
return isIosOn;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 前往系统设置页面开启或关闭通知权限
|
||||
const switchPushPermissions = () => {
|
||||
const push_clientid = uni.getStorageSync("push_clientid")
|
||||
// #ifdef APP-PLUS
|
||||
let title = isNoticeOn() ? "通知权限关闭提醒" : "通知权限开启提醒";
|
||||
let content = isNoticeOn()
|
||||
? "通知权限已开启,是否前往设置关闭?"+push_clientid
|
||||
: "您还没有开启通知权限,无法接受到消息通知,是否前往设置?"+push_clientid;
|
||||
// 打开安卓系统设置页面
|
||||
let openAndroidSetting = () => {
|
||||
var main = plus.android.runtimeMainActivity();
|
||||
var pkName = main.getPackageName();
|
||||
var uid = main.getApplicationInfo().plusGetAttribute("uid");
|
||||
var Intent = plus.android.importClass("android.content.Intent");
|
||||
var Build = plus.android.importClass("android.os.Build");
|
||||
//android 8.0引导
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
var intent = new Intent("android.settings.APP_NOTIFICATION_SETTINGS");
|
||||
intent.putExtra("android.provider.extra.APP_PACKAGE", pkName);
|
||||
} else if (Build.VERSION.SDK_INT >= 21) {
|
||||
//android 5.0-7.0
|
||||
var intent = new Intent("android.settings.APP_NOTIFICATION_SETTINGS");
|
||||
intent.putExtra("app_package", pkName);
|
||||
intent.putExtra("app_uid", uid);
|
||||
} else {
|
||||
//(<21)其他--跳转到该应用管理的详情页
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
}
|
||||
// 跳转到该应用的系统通知设置页
|
||||
main.startActivity(intent);
|
||||
};
|
||||
// 打开苹果系统设置页面
|
||||
let openIOSSetting = () => {
|
||||
var app = plus.ios.invoke("UIApplication", "sharedApplication");
|
||||
var setting = plus.ios.invoke("NSURL", "URLWithString:", "app-settings:");
|
||||
plus.ios.invoke(app, "openURL:", setting);
|
||||
plus.ios.deleteObject(setting);
|
||||
plus.ios.deleteObject(app);
|
||||
// ios18跳转不过去的解决方案
|
||||
// 方案一:使用uni.openAppAuthorizeSetting(),文档地址:https://uniapp.dcloud.net.cn/api/system/openappauthorizesetting.html
|
||||
// 方案二:待验证,AI生成;来源评论区:iOS 18以后,openURL:完全被弃用,需要用openURL:options:completionHandler:替代。
|
||||
// var app = plus.ios.invoke("UIApplication", "sharedApplication");
|
||||
// var url;
|
||||
// // 获取安全 URL(iOS 8+)
|
||||
// if (plus.ios.invoke("UIApplication", "respondsToSelector:", "openSettingsURLString")) {
|
||||
// var urlString = plus.ios.invoke("UIApplication", "openSettingsURLString");
|
||||
// url = plus.ios.invoke("NSURL", "URLWithString:", urlString);
|
||||
// } else {
|
||||
// url = plus.ios.invoke("NSURL", "URLWithString:", "app-settings:");
|
||||
// }
|
||||
// // 判断新 API 可用性(iOS 10+)
|
||||
// var supportsNewAPI = plus.ios.invoke(app, "respondsToSelector:", "openURL:options:completionHandler:");
|
||||
// if (supportsNewAPI) {
|
||||
// var options = plus.ios.newObject("NSDictionary");
|
||||
// var completion = plus.ios.newBlock(function(success) {
|
||||
// console.log("跳转结果:" + success);
|
||||
// if (!success) {
|
||||
// plus.nativeUI.toast("无法打开设置,请手动前往");
|
||||
// }
|
||||
// }, "v@:B");
|
||||
// plus.ios.invoke(app, "openURL:options:completionHandler:", url, options, completion);
|
||||
// plus.ios.deleteObject(completion);
|
||||
// } else {
|
||||
// if (plus.ios.invoke(app, "canOpenURL:", url)) {
|
||||
// plus.ios.invoke(app, "openURL:", url);
|
||||
// } else {
|
||||
// throw new Error("当前系统不支持跳转设置");
|
||||
// }
|
||||
// }
|
||||
// plus.ios.deleteObject(url);
|
||||
// plus.ios.deleteObject(app);
|
||||
};
|
||||
// 弹窗提醒开通或关闭权限,点击确认后,跳转到系统设置页面进行设置
|
||||
uni.showModal({
|
||||
title: title,
|
||||
content: content,
|
||||
showCancel: true,
|
||||
confirmColor: "#ff903f",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
if (plus.os.name == "Android") {
|
||||
openAndroidSetting();
|
||||
} else if (plus.os.name == "iOS") {
|
||||
openIOSSetting();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
||||
const showYearSummary = () => {
|
||||
console.log('显示年度总结');
|
||||
uni.showToast({
|
||||
@@ -376,11 +679,20 @@
|
||||
const showVersion = () => {
|
||||
uni.showModal({
|
||||
title: '版本信息',
|
||||
content: '当前版本:V4.1.4',
|
||||
content: '当前版本:V'+version,
|
||||
showCancel: false
|
||||
});
|
||||
};
|
||||
|
||||
const honnor_detail=ref({});
|
||||
const getHonorDetail=async(id)=>{
|
||||
const res = await api.gethonorDetail({
|
||||
id:id
|
||||
})
|
||||
if (res.code == 1 ) {
|
||||
honnor_detail.value = res.data;
|
||||
showHonor.value = true;
|
||||
}
|
||||
}
|
||||
const onStatsClick = (key) => {
|
||||
let url = '';
|
||||
switch (key) {
|
||||
@@ -405,10 +717,30 @@
|
||||
})
|
||||
}
|
||||
|
||||
const getIsBoundWechat = async () => {
|
||||
const res = await my_api.isBoundWechat()
|
||||
console.log(res)
|
||||
if (res.code === 200 && res.data) {
|
||||
isBoundWechat.value = res.data
|
||||
}
|
||||
}
|
||||
const isBoundWechat = ref(false);
|
||||
const isIos = ref(false);
|
||||
onShow(() => {
|
||||
console.log('我的页面显示');
|
||||
getUserInfoFromStorage() // 先从storage获取用户信息
|
||||
fetchMyInfo() // 然后从API获取最新数据
|
||||
getIsBoundWechat()
|
||||
isNoticeOn();
|
||||
checkVersion();
|
||||
getIsAccount();
|
||||
let systemInfo = uni.getSystemInfoSync();
|
||||
console.log(systemInfo)
|
||||
if(systemInfo.osName == 'ios'){
|
||||
isIos.value = true;
|
||||
}else{
|
||||
isIos.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -432,12 +764,151 @@
|
||||
|
||||
.page {
|
||||
background-color: $gray-bg;
|
||||
height: calc(100vh - 140rpx);
|
||||
margin-top:calc(var(--status-bar-height) + 44px);
|
||||
height: calc(100vh - var(--status-bar-height) - 44px);
|
||||
overflow-y: scroll;
|
||||
padding-bottom: 100rpx;
|
||||
}
|
||||
|
||||
|
||||
.flex-row{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.new-version{
|
||||
background:#8B2316;
|
||||
color:#fff;
|
||||
font-size: 24rpx;
|
||||
margin-right: 10rpx;
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.honorwrap{
|
||||
width:100%;
|
||||
height:100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.honorbox{
|
||||
|
||||
width:80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
min-height:200rpx;
|
||||
background:linear-gradient(to bottom, #54049b, #da4ee2);
|
||||
border-radius: 20rpx;
|
||||
padding: 20rpx;
|
||||
.row{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr); /* 创建两列,每列等宽 */
|
||||
gap: 20px;
|
||||
.row_item{
|
||||
font-size: 26rpx;
|
||||
color: #da4ee2;
|
||||
margin-right: 20rpx;
|
||||
text-align: center;
|
||||
padding: 10rpx 20rpx;
|
||||
background:#fff;
|
||||
white-space: nowrap;
|
||||
border-radius: 10rpx;
|
||||
border:1rpx solid #da4ee2;
|
||||
}
|
||||
}
|
||||
.close_honor{
|
||||
position: absolute;
|
||||
top:20rpx;
|
||||
right:20rpx;
|
||||
}
|
||||
.honor_image{
|
||||
width:269rpx;
|
||||
height:213rpx;
|
||||
position: absolute;
|
||||
top:-76rpx;
|
||||
left:50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.content{
|
||||
margin-top:73rpx;
|
||||
background:#fff;
|
||||
border-radius: 5rpx;
|
||||
padding: 20rpx;
|
||||
.content_title{
|
||||
font-weight: bold;
|
||||
padding: 35rpx 0 20rpx;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
color: #da4ee2;
|
||||
}
|
||||
.content_content{
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-top: 20rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.signwrap{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height:100%;
|
||||
.signbox{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index:0;
|
||||
.close{
|
||||
position:absolute;
|
||||
right:0;
|
||||
height:60rpx;
|
||||
width:60rpx;
|
||||
opacity: 0;
|
||||
background:#fff;
|
||||
z-index:2;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.signwrap .signcontent{
|
||||
width:100%;
|
||||
top:0;
|
||||
position: absolute;
|
||||
z-index:1;
|
||||
}
|
||||
.signwrap .signcontent .day{
|
||||
margin-top: 384rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.signwrap .signtotal{
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.signwrap .signcontinue{
|
||||
font-size: 30rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.signwrap .signcontent .tip{
|
||||
margin-top: 40rpx;
|
||||
color:red;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.signwrap .signcontent .news{
|
||||
margin: 196rpx 60rpx 0;
|
||||
height: 116rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.signwrap .signbg{
|
||||
width:604rpx;
|
||||
height:964rpx;
|
||||
}
|
||||
// 用户信息卡片
|
||||
.user-card {
|
||||
|
||||
@@ -459,14 +930,65 @@
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 10rpx;
|
||||
|
||||
}
|
||||
|
||||
.username {
|
||||
color: $white;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
.user-info-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10rpx;
|
||||
margin-left: 10rpx;
|
||||
|
||||
.username {
|
||||
color: $white;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.honor_box {
|
||||
width: 500rpx;
|
||||
/* 根据设计可调整宽度,使内容可横向滚动 */
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.honor_wrap {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.honor_item {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
flex: 0 0 auto;
|
||||
padding: 6rpx 12rpx;
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.6);
|
||||
border-radius: 24rpx;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.honor_image {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
|
||||
.honor_text {
|
||||
font-size: 24rpx;
|
||||
color: $white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.bar_rank{
|
||||
padding:0 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.stats-section {
|
||||
@@ -491,7 +1013,7 @@
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 54rpx;
|
||||
width: 160rpx;
|
||||
width: 150rpx;
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -508,6 +1030,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
.signbox_1 {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 54rpx;
|
||||
width: 160rpx;
|
||||
height: 54rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1rpx solid #fc564a;
|
||||
border-right: none;
|
||||
border-radius: 30rpx 0 0 30rpx;
|
||||
background: #fff url("@/static/qd_bg.9.png")no-repeat 0 0;
|
||||
background-size: 57rpx 56rpx;
|
||||
|
||||
.sign {
|
||||
margin-left: 60rpx;
|
||||
font-size: 28rpx;
|
||||
color: #fc564a;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -540,8 +1083,7 @@
|
||||
gap: 8rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 通用section样式
|
||||
.section {
|
||||
background-color: $white;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<uni-nav-bar title="患教学堂" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
|
||||
<navBar :title="'患教学堂'" :showLeft="false"></navBar>
|
||||
<view class="page">
|
||||
<!-- 顶部标题栏 -->
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
<view class="tab-item" :class="{ active: activeTab === 0 }" @click="switchTab(0)">
|
||||
患教文库
|
||||
</view>
|
||||
<view class="bar"></view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 1 }" @click="switchTab(1)">
|
||||
患教视频
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 2 }" @click="switchTab(2)">
|
||||
<!-- <view class="tab-item" :class="{ active: activeTab === 2 }" @click="switchTab(2)">
|
||||
常见问题
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
@@ -51,7 +52,7 @@
|
||||
:class="{ active: tag.selected }"
|
||||
@click="toggleTag(index)"
|
||||
>
|
||||
{{ tag.DES }}
|
||||
{{ tag.NAME }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -74,20 +75,20 @@
|
||||
:lower-threshold="100"
|
||||
>
|
||||
<view class="article-item" v-for="(article, index) in articleList" :key="article.uuid || index" @click="goToDetail(article)">
|
||||
<image class="article-image" :src="article.image" mode="aspectFill"></image>
|
||||
<image class="article-image" :src="article.image"></image>
|
||||
<view class="article-content">
|
||||
<view class="article-title">{{ article.title }}</view>
|
||||
<view class="article-meta">
|
||||
<view class="date-tag" v-if="article.isToday">今日</view>
|
||||
<view class="date" v-else>{{ article.date }}</view>
|
||||
<view class="stats">
|
||||
<view class="stat-item">
|
||||
<view class="stat-item readnum">
|
||||
<uni-icons type="eye" size="12" color="#999"></uni-icons>
|
||||
<text>{{ article.views }}</text>
|
||||
<text>{{ formatNumber(article.views) }}</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<uni-icons type="hand-up" size="13" color="#999"></uni-icons>
|
||||
<text>{{ article.likes }}</text>
|
||||
<text>{{ formatNumber(article.likes) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -107,8 +108,9 @@
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="articleList.length === 0 && !loading">
|
||||
<uni-icons type="article" size="80" color="#cccccc"></uni-icons>
|
||||
<text class="empty-text">暂无文章</text>
|
||||
<empty :emptyDesc="'暂无患教信息'"></empty>
|
||||
<!-- <uni-icons type="article" size="80" color="#cccccc"></uni-icons>
|
||||
<text class="empty-text">暂无文章</text> -->
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
@@ -120,7 +122,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import {onShow,onLoad,onBackPress } from "@dcloudio/uni-app";
|
||||
import CustomTabbar from '@/components/tabBar/tabBar.vue';
|
||||
import upImg from "@/static/cb_up.png"
|
||||
import downImg from "@/static/cb_up.png"
|
||||
@@ -129,9 +131,24 @@
|
||||
import api from "@/api/api.js"
|
||||
import docUrl from '@/utils/docUrl.js';
|
||||
import navTo from '@/utils/navTo.js';
|
||||
|
||||
import navBar from "@/components/navBar/navBar.vue"
|
||||
import formatNumber from '@/utils/formatNumber.js';
|
||||
const type=ref(1)
|
||||
|
||||
onBackPress(() => {
|
||||
plus.runtime.quit();
|
||||
return true;
|
||||
});
|
||||
onLoad(() => {
|
||||
uni.sendNativeEvent("portraitReport",{
|
||||
msg:{
|
||||
event_nickname: "list_page",
|
||||
page_type: "患教文库",
|
||||
},
|
||||
},
|
||||
(ret) => {
|
||||
console.log(ret);
|
||||
});
|
||||
})
|
||||
// 分页相关状态
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
@@ -147,7 +164,8 @@
|
||||
// 重置分页状态
|
||||
currentPage.value = 1;
|
||||
hasMore.value = true;
|
||||
polularScienceArticleListByKeywordsNew(true);
|
||||
articleList.value = [];
|
||||
polularScienceArticleListByKeywordsNew(false);
|
||||
};
|
||||
const loadGuideTags = async () => {
|
||||
try {
|
||||
@@ -195,9 +213,9 @@
|
||||
// 判断是否还有更多数据
|
||||
hasMore.value = newData.length >= pageSize.value;
|
||||
|
||||
if (!isRefresh) {
|
||||
currentPage.value++;
|
||||
}
|
||||
// if (!isRefresh) {
|
||||
// currentPage.value++;
|
||||
// }
|
||||
|
||||
console.log('文章数据加载成功:', articleList.value);
|
||||
}
|
||||
@@ -240,9 +258,18 @@
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (date) => {
|
||||
const today = new Date();
|
||||
const year = date.getFullYear();
|
||||
const currentYear = today.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${month}-${day}`;
|
||||
|
||||
// 如果年份是今年,只显示月日,否则显示年月日
|
||||
if (year === currentYear) {
|
||||
return `${month}-${day}`;
|
||||
} else {
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
};
|
||||
// 筛选标签数据
|
||||
const filterTags = ref([]);
|
||||
@@ -255,12 +282,12 @@
|
||||
|
||||
if(index==1){
|
||||
navTo({
|
||||
url: '/pages_app/patientVideo/patientVideo'
|
||||
url: '/pages_app/patientVideo/patientVideo?from=patientClass'
|
||||
})
|
||||
}else if(index==2){
|
||||
let url=encodeURIComponent('https://wx.igandan.com/wxPatient/index.htm#/problem?link=share&fromtype=doctor')
|
||||
navTo({
|
||||
url: '/pages_app/webview/webview?url='+url
|
||||
url: '/pages_app/webview/webview?url='+url+'&title='+'常见问题'
|
||||
})
|
||||
}
|
||||
};
|
||||
@@ -270,15 +297,15 @@
|
||||
// 跳转到详情页
|
||||
if (article.path) {
|
||||
uni.navigateTo({
|
||||
url: `/pages_app/webview/webview?url=${encodeURIComponent(docUrl+article.path)}&title=${encodeURIComponent(article.title)}`
|
||||
url: `/pages_app/webview/webviewClass?url=${encodeURIComponent(docUrl+article.path+'?fromtype=doctor')}&title=患教详情&uuid=${article.uuid}&sharetitle=${article.title}&summary=${article.summary}&type=huanjiao&imgPath=${encodeURIComponent(article.image)}&tags=${article.tags}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 跳转到搜索页面
|
||||
const goToSearch = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages_app/search/search'
|
||||
uni.sendNativeEvent('goHomeSearch',{
|
||||
msg: 'patientClass'
|
||||
});
|
||||
};
|
||||
|
||||
@@ -288,7 +315,7 @@
|
||||
await polularScienceArticleListByKeywordsNew(true);
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
});
|
||||
};
|
||||
@@ -296,6 +323,7 @@
|
||||
// 上拉加载更多
|
||||
const onLoadMore = async () => {
|
||||
if (!hasMore.value || loading.value) return;
|
||||
currentPage.value++
|
||||
await polularScienceArticleListByKeywordsNew(false);
|
||||
};
|
||||
|
||||
@@ -319,7 +347,19 @@
|
||||
};
|
||||
|
||||
const toggleTag = (index) => {
|
||||
filterTags.value[index].selected = !filterTags.value[index].selected;
|
||||
const tag = filterTags.value[index];
|
||||
// 若当前为未选中状态,且已选满3个,则禁止再选
|
||||
if (!tag.selected) {
|
||||
const selectedCount = filterTags.value.filter(t => t.selected).length;
|
||||
if (selectedCount >= 3) {
|
||||
uni.showToast({
|
||||
title: '最多选择3个标签',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
tag.selected = !tag.selected;
|
||||
};
|
||||
|
||||
const resetFilter = () => {
|
||||
@@ -333,25 +373,26 @@
|
||||
// 检查是否有选中的标签
|
||||
const hasSelected = filterTags.value.some(tag => tag.selected);
|
||||
isFilterActive.value = hasSelected;
|
||||
|
||||
let words='';
|
||||
// 执行筛选逻辑
|
||||
if (hasSelected) {
|
||||
const selectedTags = filterTags.value.filter(tag => tag.selected).map(tag => tag.DES);
|
||||
const selectedTags = filterTags.value.filter(tag => tag.selected).map(tag => tag.NAME);
|
||||
console.log('选中的标签:', selectedTags);
|
||||
keywords.value = selectedTags.join(',');
|
||||
words = selectedTags.join(',');
|
||||
} else {
|
||||
keywords.value = '';
|
||||
words = '';
|
||||
}
|
||||
|
||||
keywords.value = words;
|
||||
// 重置分页状态
|
||||
currentPage.value = 1;
|
||||
hasMore.value = true;
|
||||
|
||||
articleList.value = [];
|
||||
showFilter.value = false;
|
||||
polularScienceArticleListByKeywordsNew(true);
|
||||
polularScienceArticleListByKeywordsNew(false);
|
||||
};
|
||||
|
||||
onShow(() => {
|
||||
|
||||
polularScienceArticleListByKeywordsNew(true);
|
||||
loadGuideTags();
|
||||
});
|
||||
@@ -369,14 +410,14 @@ $gray-dark: #666;
|
||||
$text-color: #333;
|
||||
|
||||
// 尺寸变量
|
||||
$border-radius: 8px;
|
||||
$border-radius-small: 6px;
|
||||
$padding: 15px;
|
||||
$padding-small: 10px;
|
||||
$border-radius: 16rpx;
|
||||
$border-radius-small: 12rpx;
|
||||
$padding: 30rpx;
|
||||
$padding-small: 20rpx;
|
||||
|
||||
.page {
|
||||
background-color: $gray-bg;
|
||||
height: calc(100vh - 140rpx);
|
||||
height: calc(100vh - 180rpx);
|
||||
display: flex;
|
||||
overflow-y: hidden;
|
||||
flex-direction: column;
|
||||
@@ -385,19 +426,25 @@ $padding-small: 10px;
|
||||
.top{
|
||||
width:100%;
|
||||
position: fixed;
|
||||
top:140rpx;
|
||||
top:calc(var(--status-bar-height) + 44px);
|
||||
}
|
||||
// 选项卡
|
||||
.tabs {
|
||||
background-color: $white;
|
||||
display: flex;
|
||||
border-bottom: 1px solid $gray-light;
|
||||
|
||||
align-items: center;
|
||||
border-bottom: 2rpx solid $gray-light;
|
||||
.bar{
|
||||
width: 2rpx;
|
||||
height: 98rpx;
|
||||
background-color: $gray-light;
|
||||
|
||||
}
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: $padding 0;
|
||||
font-size: 16px;
|
||||
font-size: 32rpx;
|
||||
color: $gray-dark;
|
||||
position: relative;
|
||||
|
||||
@@ -411,8 +458,8 @@ $padding-small: 10px;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 30px;
|
||||
height: 2px;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -425,25 +472,25 @@ $padding-small: 10px;
|
||||
padding: $padding-small $padding;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $gray-light;
|
||||
border-bottom: 2rpx solid $gray-light;
|
||||
|
||||
.search-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
gap: 10rpx;
|
||||
|
||||
.search-text {
|
||||
font-size: 14px;
|
||||
font-size: 28rpx;
|
||||
color: $gray-medium;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
background-color: $gray-medium;
|
||||
width: 2rpx;
|
||||
height: 32rpx;
|
||||
background-color: $gray-light;
|
||||
margin: 0 $padding;
|
||||
}
|
||||
|
||||
@@ -452,8 +499,8 @@ $padding-small: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
font-size: 14px;
|
||||
gap: 6rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
@@ -466,23 +513,24 @@ $padding-small: 10px;
|
||||
// 文章列表
|
||||
.article-list {
|
||||
position: fixed;
|
||||
height:calc(100vh - 450rpx);
|
||||
top: 342rpx;
|
||||
// height:calc(100vh - var(--status-bar-height) - 44px - 207rpx);
|
||||
top: calc(var(--status-bar-height) + 44px + 188rpx);
|
||||
|
||||
padding-bottom: 130rpx;
|
||||
bottom: 128rpx;
|
||||
.article-item {
|
||||
background-color: $white;
|
||||
margin-bottom: $padding-small;
|
||||
border-radius: $border-radius;
|
||||
padding: $padding;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
|
||||
.article-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
width: 260rpx;
|
||||
height: 160rpx;
|
||||
border-radius: $border-radius-small;
|
||||
flex-shrink: 0;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
@@ -492,7 +540,7 @@ $padding-small: 10px;
|
||||
justify-content: space-between;
|
||||
|
||||
.article-title {
|
||||
font-size: 16px;
|
||||
font-size: 32rpx;
|
||||
color: $text-color;
|
||||
line-height: 1.4;
|
||||
margin-bottom: $padding-small;
|
||||
@@ -506,32 +554,40 @@ $padding-small: 10px;
|
||||
|
||||
.article-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.date-tag {
|
||||
background-color: $primary-color;
|
||||
color: $white;
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 24rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 12px;
|
||||
width: 125rpx;
|
||||
font-size: 24rpx;
|
||||
color: $gray-medium;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
gap: $padding;
|
||||
|
||||
margin-left: 50rpx;
|
||||
.readnum{
|
||||
width:100rpx;
|
||||
}
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
font-size: 12px;
|
||||
gap: 10rpx;
|
||||
|
||||
font-size: 24rpx;
|
||||
color: $gray-medium;
|
||||
text{
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -591,8 +647,8 @@ $padding-small: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
font-size: 12px;
|
||||
gap: 4rpx;
|
||||
font-size: 24rpx;
|
||||
color: $gray-medium;
|
||||
|
||||
&.active {
|
||||
@@ -600,7 +656,7 @@ $padding-small: 10px;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 10px;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -619,7 +675,7 @@ $padding-small: 10px;
|
||||
z-index: 9999;
|
||||
|
||||
.filter-content {
|
||||
margin-top:329rpx;
|
||||
margin-top:calc(var(--status-bar-height) + 44px + 188rpx);;
|
||||
|
||||
background-color: $white;
|
||||
// border-radius: 20rpx 20rpx 0 0;
|
||||
@@ -630,17 +686,21 @@ $padding-small: 10px;
|
||||
.filter-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 60rpx;
|
||||
max-height: 65vh;
|
||||
overflow-y: auto;
|
||||
|
||||
.tag-item {
|
||||
background-color: #f8f8f8;
|
||||
color: $gray-dark;
|
||||
padding: 8rpx 24rpx;
|
||||
padding: 8rpx 0rpx;
|
||||
width:152rpx;
|
||||
margin:8rpx;
|
||||
text-align:center;
|
||||
border-radius: 30rpx;
|
||||
font-size: 26rpx;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border: 2rpx solid #efefef;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||
|
||||
// 页面加载
|
||||
onLoad(() => {
|
||||
console.log('登录页面加载完成');
|
||||
// #ifdef APP
|
||||
|
||||
console.log('一键登录');
|
||||
uni.login({
|
||||
provider: 'univerify',
|
||||
univerifyStyle: {
|
||||
"fullScreen": true, // 是否全屏显示,默认值: false
|
||||
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
|
||||
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
|
||||
"icon": {
|
||||
"path": "static/xxx.png", // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
|
||||
"width": "60px", //图标宽度 默认值:60px
|
||||
"height": "60px" //图标高度 默认值:60px
|
||||
},
|
||||
"closeIcon": {
|
||||
"path": "static/xxx.png", // 自定义显示在授权框中的logo,仅支持本地图片
|
||||
"width": "60px", //图标宽度 默认值:60px (HBuilderX 4.0+ 仅iOS支持)
|
||||
"height": "60px" //图标高度 默认值:60px (HBuilderX 4.0+ 仅iOS支持)
|
||||
},
|
||||
"phoneNum": {
|
||||
"color": "#202020" // 手机号文字颜色 默认值:#202020
|
||||
},
|
||||
"slogan": {
|
||||
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
|
||||
},
|
||||
"authButton": {
|
||||
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
|
||||
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
|
||||
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
|
||||
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
|
||||
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
|
||||
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
|
||||
},
|
||||
"otherLoginButton": {
|
||||
"visible": true, // 是否显示其他登录按钮,默认值:true
|
||||
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
|
||||
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
|
||||
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
|
||||
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
|
||||
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
|
||||
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)
|
||||
},
|
||||
"privacyTerms": {
|
||||
"defaultCheckBoxState": true, // 条款勾选框初始状态 默认值: true
|
||||
"isCenterHint": false, //未勾选服务条款时点击登录按钮的提示是否居中显示 默认值: false (3.7.13+ 版本支持)
|
||||
"uncheckedImage": "", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
|
||||
"checkedImage": "", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
|
||||
"checkBoxSize": 12, // 可选 条款勾选框大小
|
||||
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
|
||||
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
|
||||
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
|
||||
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
|
||||
"privacyItems": [ // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
|
||||
{
|
||||
"url": "https://", // 点击跳转的协议详情页面
|
||||
"title": "用户服务协议" // 协议名称
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
success(res) { // 登录成功
|
||||
console.log(res.authResult); // {openid:'登录授权唯一标识',access_token:'接口返回的 token'}
|
||||
},
|
||||
fail(res) { // 登录失败
|
||||
console.log(res.errCode)
|
||||
console.log(res.errMsg)
|
||||
uni.redirectTo({
|
||||
url: '/pages_app/login/login?univerify=0'
|
||||
});
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
});
|
||||
|
||||
// 页面显示
|
||||
onShow(() => {
|
||||
console.log('登录页面显示');
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view :class="isFull ? 'player-full' : 'player'">
|
||||
<plv-player
|
||||
ref="vodPlayer"
|
||||
class="vod-player"
|
||||
seekType=1
|
||||
autoPlay=true
|
||||
disableScreenCAP=false
|
||||
rememberLastPosition=false
|
||||
@onPlayStatus="onPlayStatus"
|
||||
@onPlayError="onPlayError"
|
||||
@positionChange="positionChange"
|
||||
@onEnableSubtitle="onEnableSubtitle"
|
||||
@onSRTTextConfig="onSRTTextConfig"
|
||||
@onSRTTitle="onSRTTitle">
|
||||
</plv-player>
|
||||
<skin ref="skinRef"
|
||||
class="skin-control"
|
||||
:defaultVolume="defaultVolume"
|
||||
@onPlayBtnClick="onPlayBtnClick"
|
||||
@onToSeek="onToSeek"
|
||||
@onFullBtnClick="onFullBtnClick"
|
||||
@onHdBtnClick="onHdBtnClick"
|
||||
@onRateBtnClick="onRateBtnClick"
|
||||
@onVolumeChanged="onVolumeChanged"
|
||||
@onScalingBtnClick="onScalingBtnClick"
|
||||
@onScreenShot="onScreenShot"
|
||||
@onChangeSRTBtnClick="onChangeSRTBtnClick"
|
||||
@onChangeSRTSingleMode="onChangeSRTSingleMode"
|
||||
@onOpenSRT="onOpenSRT">
|
||||
</skin>
|
||||
</view>
|
||||
<view v-if="!isFull" style="padding: 20rpx;">
|
||||
<input class="uni-input" style="min-height: 35px; height: 35px; border: 1px solid #cccccc;font-size: 14px;" :value="videoVid"
|
||||
@input="onVidInput" placeholder="请输入视频vid" />
|
||||
<button type="primary" @click="setVid()">播放</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
//import Head from '../../components/page-head.nvue';
|
||||
//import skin from '@/components/plv-player-skin/skin.nvue';
|
||||
//import DragTips from '@/components/plv-player-skin/drag-tips.nvue';
|
||||
const dom = weex.requireModule('dom');
|
||||
var configModule = uni.requireNativePlugin("PLV-VodUniPlugin-ConfigModule")
|
||||
const vod=ref(null);
|
||||
|
||||
const title='播放器Demo';
|
||||
// 播放器组件
|
||||
const vodPlayer=ref(null);
|
||||
const skinRef=ref(null);
|
||||
const isFull=ref(false);
|
||||
const defaultVolume=ref(0.5);
|
||||
const videoVid=ref('4ae3fe3ab5a2009a8d6605d81b2e3c9b_4');
|
||||
|
||||
onShow(() => {
|
||||
configModule.setConfig({
|
||||
'config': "dDzXiPJ8psA/7LvtlPgpNfdOjzKVVEYvca1QBOp2MqCVKC93YiligqqfzOzETkDmolLNBUF4vAykBuUnn+U4V9NoK9vaofwESluIMO9WSB0eWhrw+fBkn+h+OZAmwmYgHQ6fCtsggZKN6cW/FhjWAQ==", //加密串配置
|
||||
},
|
||||
(ret) => {
|
||||
if (ret.isSuccess == true) {
|
||||
uni.showToast({
|
||||
title: '设置加密串成功',
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
const onVidInput=(event)=> {
|
||||
videoVid.value = event.detail.value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const setVid=()=> {
|
||||
if(!videoVid.value) {
|
||||
uni.showToast({
|
||||
title: "请输入视频Vid",
|
||||
icon: "none"
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
vodPlayer.value.setVid({
|
||||
vid:videoVid.value,
|
||||
level:0
|
||||
}, (ret) => {
|
||||
console.log(12)
|
||||
console.log(ret)
|
||||
text.value = JSON.stringify(ret);
|
||||
if (ret.errMsg != null) {
|
||||
uni.showToast({
|
||||
title: ret.errMsg,
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onPlayError=(e)=>{
|
||||
console.log(e);
|
||||
if (e.detail.errEvent != null) {
|
||||
uni.showToast({
|
||||
title:'playErrorEvent - '+e.detail.errEvent,
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
const positionChange=(e)=>{
|
||||
skinRef.value.timeUpdate(e.detail.currentPosition);
|
||||
};
|
||||
|
||||
const onEnableSubtitle=(e)=>{
|
||||
console.log("===1" + e.detail);
|
||||
skinRef.value.setEnableSubtitle(e.detail.isEnableSubtitle, e.detail.isEnableDoubleSubtitle);
|
||||
};
|
||||
|
||||
const onSRTTextConfig=(e)=>{
|
||||
console.log("===1 fontColor: " + e.detail.fontColor);
|
||||
skinRef.value.setSRTTextConfig(e.detail);
|
||||
};
|
||||
|
||||
const onSRTTitle=(e)=>{
|
||||
console.log("===1 onSRTTitle" + e.detail);
|
||||
|
||||
};
|
||||
|
||||
const onPlayStatus=(e)=>{
|
||||
//const { skin, vodPlayer } = this;
|
||||
const state = e.detail.playbackState;
|
||||
const preparedToPlay = e.detail.preparedToPlay;
|
||||
if (state != null) {
|
||||
skinRef.value.changePlayStatus(state === 'start');
|
||||
} else if (preparedToPlay != null) {
|
||||
updateDuration();
|
||||
updateLevels();
|
||||
updateScaling();
|
||||
}
|
||||
};
|
||||
|
||||
const updateDuration=()=> {
|
||||
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.getDuration(null, ret => {
|
||||
skinRef.value.updateDuration(ret.duration);
|
||||
});
|
||||
};
|
||||
|
||||
const updateLevels=()=> {
|
||||
if (vodPlayer.value) return;
|
||||
|
||||
vodPlayer.value.getLevelNum(null, ret => {
|
||||
skinRef.value.updateLevels(ret.levelNum);
|
||||
});
|
||||
|
||||
vodPlayer.value.getCurrentLevel(null, ret => {
|
||||
skinRef.value.updateCurrentLevel(ret.currentLevel);
|
||||
});
|
||||
};
|
||||
|
||||
const updateScaling=()=> {
|
||||
if (vodPlayer.value) return;
|
||||
|
||||
vodPlayer.value.getScalingMode({}, ret => {
|
||||
skinRef.value.updateScaling(ret.scalingMode);
|
||||
});
|
||||
};
|
||||
|
||||
const onPlayBtnClick=(isPlaying)=> {
|
||||
if (vodPlayer.value) return;
|
||||
isPlaying ? vodPlayer.value.start() : vodPlayer.value.pause();
|
||||
};
|
||||
|
||||
const onHdBtnClick=(level)=> {
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.changeLevel({level});
|
||||
};
|
||||
|
||||
const onRateBtnClick=(speed)=> {
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.setSpeed({speed});
|
||||
};
|
||||
|
||||
const onScalingBtnClick=(scalingMode)=> {
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.setScalingMode({scalingMode});
|
||||
};
|
||||
|
||||
const onChangeSRTBtnClick=(srt)=> {
|
||||
console.log("===1 " + srt);
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.changeSRT(srt);
|
||||
};
|
||||
|
||||
const onChangeSRTSingleMode=(isSingle)=> {
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.changeSRTSingleMode(isSingle);
|
||||
};
|
||||
|
||||
const onOpenSRT=(isOpen)=> {
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.setOpenSRT({
|
||||
openSrt: isOpen
|
||||
});
|
||||
};
|
||||
|
||||
const onFullBtnClick=(isFull)=> {
|
||||
// plus.screen.unlockOrientation();
|
||||
plus.navigator.setFullscreen(isFull);
|
||||
if (vodPlayer.value) return;
|
||||
isFull ? vodPlayer.value.changeToLandscape() : vodPlayer.value.changeToPortrait();
|
||||
isFull.value = isFull;
|
||||
};
|
||||
|
||||
const onToSeek=(time)=> {
|
||||
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.seekTo({seconds: time});
|
||||
};
|
||||
|
||||
const onVolumeChanged=(value)=> {
|
||||
|
||||
if (vodPlayer.value) return;
|
||||
vodPlayer.value.getVolume(null, ret => {
|
||||
const changedValue = ret.volume + value;
|
||||
|
||||
const realValue =limit(changedValue, 0, 1);
|
||||
|
||||
vodPlayer.value.setVolume({volume: realValue});
|
||||
|
||||
skinRef.value.updateVolumeValue(realValue);
|
||||
});
|
||||
};
|
||||
|
||||
const onScreenShot=()=> {
|
||||
if (vodPlayer.value) return;
|
||||
|
||||
vodPlayer.value.snapshot(null, result =>{
|
||||
if(result.errMsg != null){
|
||||
console.log(result.errMsg)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 控制最小值,最大值
|
||||
* @param num
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns {*}
|
||||
*/
|
||||
const limit=(num, min, max)=> {
|
||||
if (num < min) return min;
|
||||
if (num > max) return max;
|
||||
return num;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrap {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.player {
|
||||
height: 400rpx;
|
||||
}
|
||||
|
||||
.player-full {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.vod-player {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.skin-control {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hide {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view :class="isFull ? 'player-full' : 'player'">
|
||||
<plv-player
|
||||
ref="vod"
|
||||
class="vod-player"
|
||||
seekType=1
|
||||
autoPlay=true
|
||||
disableScreenCAP=false
|
||||
rememberLastPosition=false
|
||||
@onPlayStatus="onPlayStatus"
|
||||
@onPlayError="onPlayError"
|
||||
@positionChange="positionChange"
|
||||
@onEnableSubtitle="onEnableSubtitle"
|
||||
@onSRTTextConfig="onSRTTextConfig"
|
||||
@onSRTTitle="onSRTTitle">
|
||||
</plv-player>
|
||||
<Skin ref="skin"
|
||||
class="skin-control"
|
||||
:defaultVolume="defaultVolume"
|
||||
@onPlayBtnClick="onPlayBtnClick"
|
||||
@onToSeek="onToSeek"
|
||||
@onFullBtnClick="onFullBtnClick"
|
||||
@onHdBtnClick="onHdBtnClick"
|
||||
@onRateBtnClick="onRateBtnClick"
|
||||
@onVolumeChanged="onVolumeChanged"
|
||||
@onScalingBtnClick="onScalingBtnClick"
|
||||
@onScreenShot="onScreenShot"
|
||||
@onChangeSRTBtnClick="onChangeSRTBtnClick"
|
||||
@onChangeSRTSingleMode="onChangeSRTSingleMode"
|
||||
@onOpenSRT="onOpenSRT">
|
||||
</Skin>
|
||||
</view>
|
||||
<view v-if="!isFull" style="padding: 20rpx;">
|
||||
<input class="uni-input" style="min-height: 35px; height: 35px; border: 1px solid #cccccc;font-size: 14px;" :value="videoVid"
|
||||
@input="onVidInput" placeholder="请输入视频vid" />
|
||||
<button type="primary" @click="setVid()">播放</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//import Head from '../../components/page-head.nvue';
|
||||
import Skin from '@/components/plv-player-skin2/skin.nvue';
|
||||
//import DragTips from '@/components/plv-player-skin/drag-tips.nvue';
|
||||
const dom = weex.requireModule('dom');
|
||||
var configModule = uni.requireNativePlugin("PLV-VodUniPlugin-ConfigModule")
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Skin,
|
||||
//Head
|
||||
},
|
||||
|
||||
onReady() {
|
||||
configModule.setConfig({
|
||||
'config': "dDzXiPJ8psA/7LvtlPgpNfdOjzKVVEYvca1QBOp2MqCVKC93YiligqqfzOzETkDmolLNBUF4vAykBuUnn+U4V9NoK9vaofwESluIMO9WSB0eWhrw+fBkn+h+OZAmwmYgHQ6fCtsggZKN6cW/FhjWAQ==", //加密串配置
|
||||
},
|
||||
(ret) => {
|
||||
if (ret.isSuccess == true) {
|
||||
uni.showToast({
|
||||
title: '设置加密串成功',
|
||||
icon: "none"
|
||||
})
|
||||
} else {
|
||||
let errMsg = ret.errMsg;
|
||||
uni.showToast({
|
||||
title: '设置加密串失败:' + errMsg,
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
})
|
||||
this.vodPlayer = this.$refs.vod;
|
||||
this.skin = this.$refs.skin;
|
||||
// plus.screen.lockOrientation('portrait-primary');
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
title: '播放器Demo',
|
||||
// 播放器组件
|
||||
vodPlayer: null,
|
||||
// 控制栏组件
|
||||
skin: null,
|
||||
//是否全屏
|
||||
isFull: false,
|
||||
// 默认音量
|
||||
defaultVolume: 0.5,
|
||||
videoVid: '4ae3fe3ab5a2009a8d6605d81b2e3c9b_4'
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
//输入vid
|
||||
onVidInput: function(event) {
|
||||
this.videoVid = event.detail.value;
|
||||
},
|
||||
|
||||
setVid() {
|
||||
if(!this.videoVid) {
|
||||
uni.showToast({
|
||||
title: "请输入视频Vid",
|
||||
icon: "none"
|
||||
})
|
||||
return;
|
||||
}
|
||||
const { vodPlayer } = this;
|
||||
vodPlayer.setVid({
|
||||
vid:this.videoVid,
|
||||
level:0
|
||||
}, (ret) => {
|
||||
console.log(12)
|
||||
console.log(ret)
|
||||
this.text = JSON.stringify(ret);
|
||||
if (ret.errMsg != null) {
|
||||
uni.showToast({
|
||||
title: ret.errMsg,
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onPlayError(e){
|
||||
console.log(e);
|
||||
if (e.detail.errEvent != null) {
|
||||
uni.showToast({
|
||||
title:'playErrorEvent - '+e.detail.errEvent,
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
positionChange(e){
|
||||
this.skin.timeUpdate(e.detail.currentPosition);
|
||||
},
|
||||
|
||||
onEnableSubtitle(e){
|
||||
console.log("===1" + e.detail);
|
||||
this.skin.setEnableSubtitle(e.detail.isEnableSubtitle, e.detail.isEnableDoubleSubtitle);
|
||||
},
|
||||
|
||||
onSRTTextConfig(e) {
|
||||
console.log("===1 fontColor: " + e.detail.fontColor);
|
||||
this.skit.setSRTTextConfig(e.detail);
|
||||
},
|
||||
|
||||
onSRTTitle(e) {
|
||||
console.log("===1 onSRTTitle" + e.detail);
|
||||
|
||||
},
|
||||
|
||||
onPlayStatus(e){
|
||||
const { skin, vodPlayer } = this;
|
||||
const state = e.detail.playbackState;
|
||||
const preparedToPlay = e.detail.preparedToPlay;
|
||||
if (state != null) {
|
||||
this.skin.changePlayStatus(state === 'start');
|
||||
} else if (preparedToPlay != null) {
|
||||
this.updateDuration();
|
||||
this.updateLevels();
|
||||
this.updateScaling();
|
||||
}
|
||||
},
|
||||
|
||||
updateDuration() {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.getDuration(null, ret => {
|
||||
this.skin.updateDuration(ret.duration);
|
||||
});
|
||||
},
|
||||
|
||||
updateLevels() {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
|
||||
vodPlayer.getLevelNum(null, ret => {
|
||||
this.skin.updateLevels(ret.levelNum);
|
||||
});
|
||||
|
||||
vodPlayer.getCurrentLevel(null, ret => {
|
||||
this.skin.updateCurrentLevel(ret.currentLevel);
|
||||
});
|
||||
},
|
||||
|
||||
updateScaling() {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
|
||||
vodPlayer.getScalingMode({}, ret => {
|
||||
this.skin.updateScaling(ret.scalingMode);
|
||||
});
|
||||
},
|
||||
|
||||
onPlayBtnClick(isPlaying) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
isPlaying ? vodPlayer.start() : vodPlayer.pause();
|
||||
},
|
||||
|
||||
onHdBtnClick(level) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.changeLevel({level});
|
||||
},
|
||||
|
||||
onRateBtnClick(speed) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.setSpeed({speed});
|
||||
},
|
||||
|
||||
onScalingBtnClick(scalingMode) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.setScalingMode({scalingMode});
|
||||
},
|
||||
|
||||
onChangeSRTBtnClick(srt) {
|
||||
console.log("===1 " + srt);
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.changeSRT(srt);
|
||||
},
|
||||
|
||||
onChangeSRTSingleMode(isSingle) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.changeSRTSingleMode(isSingle);
|
||||
},
|
||||
|
||||
onOpenSRT(isOpen) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.setOpenSRT({
|
||||
openSrt: isOpen
|
||||
});
|
||||
},
|
||||
|
||||
onFullBtnClick(isFull) {
|
||||
// plus.screen.unlockOrientation();
|
||||
plus.navigator.setFullscreen(isFull);
|
||||
|
||||
//通过h5+实现横竖屏
|
||||
// isFull ? plus.screen.lockOrientation('landscape-primary') : plus.screen.lockOrientation('portrait-primary');
|
||||
|
||||
//通过原生实现横竖屏切换
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
isFull ? vodPlayer.changeToLandscape() : vodPlayer.changeToPortrait();
|
||||
|
||||
this.isFull = isFull;
|
||||
},
|
||||
|
||||
onToSeek(time) {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.seekTo({seconds: time});
|
||||
},
|
||||
|
||||
onVolumeChanged(value) {
|
||||
const { vodPlayer, skin } = this;
|
||||
if (!vodPlayer) return;
|
||||
vodPlayer.getVolume(null, ret => {
|
||||
const changedValue = ret.volume + value;
|
||||
|
||||
const realValue = this.limit(changedValue, 0, 1);
|
||||
|
||||
vodPlayer.setVolume({volume: realValue});
|
||||
|
||||
skin.updateVolumeValue(realValue);
|
||||
});
|
||||
},
|
||||
|
||||
onScreenShot() {
|
||||
const { vodPlayer } = this;
|
||||
if (!vodPlayer) return;
|
||||
|
||||
vodPlayer.snapshot(null, result =>{
|
||||
if(result.errMsg != null){
|
||||
console.log(result.errMsg)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 控制最小值,最大值
|
||||
* @param num
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns {*}
|
||||
*/
|
||||
limit(num, min, max) {
|
||||
if (num < min) return min;
|
||||
if (num > max) return max;
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrap {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.player {
|
||||
height: 400rpx;
|
||||
}
|
||||
|
||||
.player-full {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.vod-player {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.skin-control {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hide {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user