Compare commits

...

2 Commits

Author SHA1 Message Date
cansnow 271ec4b9c2 增加音乐,摇一摇,服务等页面 2026-02-15 19:41:13 +08:00
cansnow abd279e7a7 恢复视频的发布 2026-02-15 19:40:36 +08:00
96 changed files with 14257 additions and 131 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
"name" : "瞬聊", "name" : "瞬聊",
"appid" : "__UNI__E41111F", "appid" : "__UNI__E41111F",
"description" : "一款即时聊天软件", "description" : "一款即时聊天软件",
"versionName" : "3.5.0", "versionName" : "3.5.1",
"versionCode" : 350, "versionCode" : 351,
"transformPx" : false, "transformPx" : false,
"app-plus" : { "app-plus" : {
"bounce" : "none", "bounce" : "none",
+138
View File
@@ -389,6 +389,144 @@
"style": { "style": {
"navigationBarTitleText": "" "navigationBarTitleText": ""
} }
},
{
"path": "pages/find/shake/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/linked_list",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/set",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/user_detail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/friend_home",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/agree_apply_friend",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/chatting/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/shake/chatting/zhuanfa_pop",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/music/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/find/music/song_list",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/bill/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/bill/detail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/bill/question",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/bill/statistics",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/set",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet_option",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet_pay",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet_sub_page/bind_bank",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet_sub_page/lin_qian_tong",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet_sub_page/qin_shu_ka",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/service/wallet_sub_page/fenfu-page",
"style": {
"navigationBarTitleText": ""
}
} }
], ],
"tabBar": { "tabBar": {
+44 -32
View File
@@ -1,21 +1,27 @@
<template> <template>
<view class="contact_choose_container"> <view class="contact_choose_container">
<custom-nav-bar title="联系人"> <uni-nav-bar
<view slot="more" style="margin-right: 10rpx;"> left-icon="back"
<u-button type="primary" @click="confirm" :disabled="!isConfirmEnable">确定</u-button> @clickLeft="uni.$u.route({type:'back'})"
</view> statusBar
</custom-nav-bar> title="联系人">
<template v-slot:right>
<u-button type="primary" size="mini" @click="confirm" :disabled="!isConfirmEnable">确定</u-button>
</template>
</uni-nav-bar>
<view class="search_bar_wrap"> <view class="search_bar_wrap">
<u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" /> <u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" />
</view> </view>
<view class="tab_container"> <view class="tab_container">
<template v-if="activeTab === 0"> <template v-if="activeTab === 0">
<setting-item @click="tabChange(tabs[0].idx)" :title="tabs[0].title" :border="false" /> <div @click="tabChange(tabs[0].idx)" style="display: flex; align-items: center;justify-content: space-between;padding: 20rpx 40rpx;">
{{ tabs[0].title }}
<u-icon name="arrow-right" />
</div>
<view class="tab_pane"> <view class="tab_pane">
<template v-for="cell in conversationList"> <template v-for="cell in conversationList">
<template v-if="cell.groupID"> <template v-if="cell.groupID && type!='Invite'">
<user-item <user-item
v-if="allowGroup" v-if="allowGroup"
@itemClick="updateCheckedUserOrGroup" @itemClick="updateCheckedUserOrGroup"
@@ -25,7 +31,7 @@
:checkVisible="muitple" :checkVisible="muitple"
:item="cell" :key="cell.groupID" /> :item="cell" :key="cell.groupID" />
</template> </template>
<template v-if="cell.userID"> <template v-if="cell.userID && !cell.userID.startsWith('system')">
<user-item <user-item
@itemClick="updateCheckedUserOrGroup" @itemClick="updateCheckedUserOrGroup"
@updateCheck="updateCheckedUserOrGroup" @updateCheck="updateCheckedUserOrGroup"
@@ -54,23 +60,19 @@
</template> </template>
<script> <script>
import {mapGetters} from "vuex"; import { mapGetters } from "vuex";
import {ContactChooseTypes} from "@/constant"; import {ContactChooseTypes} from "@/constant";
import {formatChooseData,toastWithCallback} from "@/util/common"; import {formatChooseData,toastWithCallback} from "@/util/common";
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill"
import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserItem from "@/components/UserItem/index.vue"; import UserItem from "@/components/UserItem/index.vue";
import ChooseIndexList from "@/components/ChooseIndexList/index.vue"; import ChooseIndexList from "@/components/ChooseIndexList/index.vue";
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue"; import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
import SettingItem from "@/components/SettingItem/index.vue";
export default { export default {
components: { components: {
CustomNavBar,
UserItem, UserItem,
ChooseIndexList, ChooseIndexList,
ChooseIndexFooter, ChooseIndexFooter
SettingItem,
}, },
data() { data() {
return { return {
@@ -94,18 +96,23 @@
}; };
}, },
computed: { computed: {
...mapGetters([ ...mapGetters(["storeCurrentUserID","storeFriendList","storeConversationList",'storeCurrentConversation']),
"storeFriendList",
"storeCurrentConversation",
"storeCurrentUserID",
"storeConversationList",
]),
getChooseData() { getChooseData() {
const _this = this;
let list = [...this.storeFriendList];
list = list.filter((item)=>{
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
});
if(!this.allowGroup){
list = list.filter((item)=>{
return !item.groupID
});
}
if (this.keyword) { if (this.keyword) {
return { return {
indexList: ["#"], indexList: ["#"],
dataList: [ dataList: [
this.storeFriendList.filter( list.filter(
(friend) => (friend) =>
friend.nickname.includes(this.keyword) || friend.nickname.includes(this.keyword) ||
friend.remark.includes(this.keyword) friend.remark.includes(this.keyword)
@@ -113,12 +120,20 @@
], ],
}; };
} }
return formatChooseData(this.storeFriendList); return formatChooseData(list);
}, },
conversationList(){ conversationList(){
const _this = this; const _this = this;
let list = [...this.storeConversationList]; let list = [...this.storeConversationList];
list = list.filter((item)=>{
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
});
if(!this.allowGroup){
list = list.filter((item)=>{
return !item.groupID
});
}
if(this.keyword){ if(this.keyword){
list = list.filter((item)=>{ list = list.filter((item)=>{
return item.showName.indexOf(_this.kw)>-1 || item.userID.indexOf(_this.kw)>-1 || item.groupID.indexOf(_this.kw)>-1 return item.showName.indexOf(_this.kw)>-1 || item.userID.indexOf(_this.kw)>-1 || item.groupID.indexOf(_this.kw)>-1
@@ -165,18 +180,16 @@
} }
}, },
onLoad(options) { onLoad(options) {
const {groupID,type,checkedUserIDList,muitple} = options; const {groupID,type,checkedUserIDList,muitple,allowType} = options;
this.type = type; this.type = type;
if(allowType){
this.allowGroup = allowType === 'All';
}
this.groupID = groupID; this.groupID = groupID;
if(muitple){ if(muitple){
this.muitple = muitple; this.muitple = muitple;
} }
//this.muitple = true;
this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : []; this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : [];
//console.log(this.checkedUserIDList);
//console.log(this.groupID);
//console.log(this.muitple);
//console.log(this.type);
if (this.type === ContactChooseTypes.Invite) { if (this.type === ContactChooseTypes.Invite) {
this.allowGroup = false; this.allowGroup = false;
this.checkDisabledUser(); this.checkDisabledUser();
@@ -299,7 +312,7 @@
} }
.contact_choose_container { .contact_choose_container {
height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -311,7 +324,6 @@
.tab_container { .tab_container {
@include colBox(false); @include colBox(false);
flex: 1; flex: 1;
overflow: hidden;
.setting_item { .setting_item {
padding: 32rpx 36rpx; padding: 32rpx 36rpx;
@@ -1,10 +1,14 @@
<template> <template>
<view class="contact_choose_container"> <view class="contact_choose_container">
<custom-nav-bar title="群成员"> <uni-nav-bar
<view slot="more" style="margin-right: 10rpx;"> left-icon="back"
<u-button type="primary" @click="confirm" :disabled="!isConfirmEnable">确定</u-button> @clickLeft="uni.$u.route({type:'back'})"
</view> statusBar
</custom-nav-bar> title="群成员">
<template v-slot:right>
<u-button type="primary" size="mini" @click="confirm" :disabled="!isConfirmEnable">确定</u-button>
</template>
</uni-nav-bar>
<view class="search_bar_wrap"> <view class="search_bar_wrap">
<u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" /> <u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" />
@@ -25,16 +29,13 @@
</template> </template>
<script> <script>
import {mapGetters} from "vuex";
import {formatChooseData,toastWithCallback} from "@/util/common"; import {formatChooseData,toastWithCallback} from "@/util/common";
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill"
import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserItem from "@/components/UserItem/index.vue"; import UserItem from "@/components/UserItem/index.vue";
import ChooseIndexList from "@/components/ChooseIndexList/index.vue"; import ChooseIndexList from "@/components/ChooseIndexList/index.vue";
export default { export default {
components: { components: {
CustomNavBar,
UserItem, UserItem,
ChooseIndexList ChooseIndexList
}, },
+54 -20
View File
@@ -1,6 +1,11 @@
<template> <template>
<view class="contact_choose_container"> <view class="contact_choose_container">
<custom-nav-bar title="联系人" /> <uni-nav-bar
left-icon="back"
@clickLeft="uni.$u.route({type:'back'})"
statusBar
title="联系人">
</uni-nav-bar>
<view class="search_bar_wrap"> <view class="search_bar_wrap">
<u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" /> <u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" />
@@ -8,14 +13,17 @@
<view class="tab_container"> <view class="tab_container">
<template v-if="activeTab === 0"> <template v-if="activeTab === 0">
<setting-item @click="tabChange(tabs[0].idx)" :title="tabs[0].title" :border="false" /> <div @click="tabChange(tabs[0].idx)" style="display: flex; align-items: center;justify-content: space-between;padding: 20rpx 40rpx;">
{{ tabs[0].title }}
<u-icon name="arrow-right" />
</div>
<view class="tab_pane"> <view class="tab_pane">
<user-item <user-item
@updateCheck="updateCheckedUser" @updateCheck="updateCheckedUser"
:checked="checkedUserIDList.includes(cell.userID)" :checked="checkedUserIDList.includes(cell.userID)"
:disabled="disabledUserIDList.includes(cell.userID)" :disabled="disabledUserIDList.includes(cell.userID)"
:checkVisible="true" :checkVisible="true"
v-for="cell in storeConversationList" :item="cell" :key="cell.userID" /> v-for="cell in conversationList" :item="cell" :key="cell.userID" />
</view> </view>
</template> </template>
@@ -33,23 +41,19 @@
</template> </template>
<script> <script>
import {mapGetters} from "vuex"; import { mapGetters } from "vuex";
import {ContactChooseTypes} from "@/constant"; import {ContactChooseTypes} from "@/constant";
import {formatChooseData,toastWithCallback} from "@/util/common"; import {formatChooseData,toastWithCallback} from "@/util/common";
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill"
import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserItem from "@/components/UserItem/index.vue"; import UserItem from "@/components/UserItem/index.vue";
import ChooseIndexList from "@/components/ChooseIndexList/index.vue"; import ChooseIndexList from "@/components/ChooseIndexList/index.vue";
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue"; import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
import SettingItem from "@/components/SettingItem/index.vue";
export default { export default {
components: { components: {
CustomNavBar,
UserItem, UserItem,
ChooseIndexList, ChooseIndexList,
ChooseIndexFooter, ChooseIndexFooter
SettingItem,
}, },
data() { data() {
return { return {
@@ -70,18 +74,42 @@
}; };
}, },
computed: { computed: {
...mapGetters([ ...mapGetters(["storeFriendList","storeConversationList",'storeCurrentConversation',"storeCurrentUserID"]),
"storeFriendList",
"storeCurrentConversation", conversationList(){
"storeCurrentUserID", const _this = this;
"storeConversationList", let list = [...this.storeConversationList];
]), list = list.filter((item)=>{
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
});
if(!this.allowGroup){
list = list.filter((item)=>{
return !item.groupID
});
}
if(this.keyword){
list = list.filter((item)=>{
return item.showName.indexOf(_this.kw)>-1 || item.userID.indexOf(_this.kw)>-1 || item.groupID.indexOf(_this.kw)>-1
})
}
return list;
},
getChooseData() { getChooseData() {
const _this = this;
let list = [...this.storeFriendList];
list = list.filter((item)=>{
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
});
if(!this.allowGroup){
list = list.filter((item)=>{
return !item.groupID
});
}
if (this.keyword) { if (this.keyword) {
return { return {
indexList: ["#"], indexList: ["#"],
dataList: [ dataList: [
this.storeFriendList.filter( list.filter(
(friend) => (friend) =>
friend.nickname.includes(this.keyword) || friend.nickname.includes(this.keyword) ||
friend.remark.includes(this.keyword) friend.remark.includes(this.keyword)
@@ -89,7 +117,7 @@
], ],
}; };
} }
return formatChooseData(this.storeFriendList); return formatChooseData(list);
}, },
getCheckedInfo() { getCheckedInfo() {
const tmpUserIDList = [...this.checkedUserIDList]; const tmpUserIDList = [...this.checkedUserIDList];
@@ -106,10 +134,16 @@
}, },
}, },
onLoad(options) { onLoad(options) {
const {groupID,type,checkedUserIDList,limit} = options; //cardInfo
//console.log(this.storeFriendList); const {groupID,type,checkedUserIDList,muitple,allowType,limit} = options;
this.type = type; this.type = type;
if(allowType){
this.allowGroup = allowType === 'All';
}
this.groupID = groupID; this.groupID = groupID;
if(muitple){
this.muitple = muitple;
}
this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : []; this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : [];
if (this.type === ContactChooseTypes.Invite) { if (this.type === ContactChooseTypes.Invite) {
this.checkDisabledUser(); this.checkDisabledUser();
+1 -1
View File
@@ -84,7 +84,7 @@ export default {
(member) => member.userID, (member) => member.userID,
); );
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.GetList}&checkedUserIDList=${JSON.stringify(checkedIDList)}`, url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.GetList}&checkedUserIDList=${JSON.stringify(checkedIDList)}&allowType=User`,
}); });
}, },
complateCreate() { complateCreate() {
+3 -3
View File
@@ -130,7 +130,7 @@
info = { info = {
...friendInfo ...friendInfo
}; };
console.log(info); //console.log(info);
} else { } else {
const { const {
data data
@@ -142,7 +142,7 @@
info = { info = {
...(data[0] ?? {}) ...(data[0] ?? {})
}; };
console.log(info); //console.log(info);
} }
this.isLoading = true this.isLoading = true
try { try {
@@ -157,7 +157,7 @@
info = {}; info = {};
} }
this.isLoading = false this.isLoading = false
console.log(info); //console.log(info);
this.sourceUserInfo = { this.sourceUserInfo = {
...info, ...info,
}; };
+6 -1
View File
@@ -75,7 +75,12 @@
}, },
confirmRemove() { confirmRemove() {
IMSDK.asyncApi(IMSDK.IMMethods.DeleteFriend,IMSDK.uuid(),this.sourceInfo.userID,) IMSDK.asyncApi(IMSDK.IMMethods.DeleteFriend,IMSDK.uuid(),this.sourceInfo.userID,)
.then(() => this.showToast("操作成功")) .then(() => {
this.showToast("操作成功");
uni.navigateBack({
delta: 2,
})
})
.catch(() => this.showToast("操作失败")) .catch(() => this.showToast("操作失败"))
.finally(() => (this.showConfirm = false)); .finally(() => (this.showConfirm = false));
}, },
@@ -180,9 +180,9 @@
this.$refs.customEditor.clear(); this.$refs.customEditor.clear();
} }
let method = IMMethods.SendMessage; let method = IMMethods.SendMessage;
if([MessageType.PictureMessage,MessageType.VoiceMessage,MessageType.VideoMessage,MessageType.FileMessage].includes(message.contentType)){ // if([MessageType.PictureMessage,MessageType.VoiceMessage,MessageType.VideoMessage,MessageType.FileMessage].includes(message.contentType)){
method = IMMethods.SendMessageNotOss; // method = IMMethods.SendMessageNotOss;
} // }
this.$emit("scrollToBottom"); this.$emit("scrollToBottom");
IMSDK.asyncApi(method, IMSDK.uuid(), { IMSDK.asyncApi(method, IMSDK.uuid(), {
recvID: user_id, recvID: user_id,
@@ -271,16 +271,8 @@
}, },
async sendVoiceMessage(audio){ async sendVoiceMessage(audio){
const _this = this; const _this = this;
const message = await IMSDK.asyncApi( const message = await IM.createVoiceMessage(audio.tempFilePath,audio.contentDuration);
IMMethods.CreateSoundMessageFromFullPath,
IMSDK.uuid(),
{
soundPath:getPurePath(audio.tempFilePath),
duration:audio.contentDuration
}
);
_this.sendMessage(message,_this.storeCurrentConversation.userID,_this.storeCurrentConversation.groupID); _this.sendMessage(message,_this.storeCurrentConversation.userID,_this.storeCurrentConversation.groupID);
}, },
// from comp // from comp
sendMediaMesage(paths) { sendMediaMesage(paths) {
@@ -290,8 +282,10 @@
try { try {
let message = null; let message = null;
if(item.search('.mp4')>0){ if(item.search('.mp4')>0){
console.log('1');
message = await IM.createVideoMessage(item); message = await IM.createVideoMessage(item);
}else{ }else{
console.log('2');
message = await IM.createImageMessage(item); message = await IM.createImageMessage(item);
} }
console.log(message); console.log(message);
@@ -335,7 +329,7 @@
const _this = this; const _this = this;
if(e.type=="atevent" && this.storeCurrentConversation.groupID){ if(e.type=="atevent" && this.storeCurrentConversation.groupID){
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/contactChoose/chooseGroupMember?groupID=${this.storeCurrentConversation.groupID}&checkedUserIDList=[]&hideUserIDList=[${this.storeCurrentUserID}]`, url: `/pages/common/contactChoose/chooseGroupMember?groupID=${this.storeCurrentConversation.groupID}&checkedUserIDList=[]&hideUserIDList=[${this.storeCurrentUserID}]&allowType=User`,
events: { events: {
onSelectedConfirm(userList) { onSelectedConfirm(userList) {
userList.forEach((user)=>{ userList.forEach((user)=>{
@@ -398,8 +392,7 @@
//crop:null, //crop:null,
editable:true, editable:true,
filename:"_doc/", filename:"_doc/",
//filter:"none",//image,none,video filter:"none",//image,none,video
filter:"image",
maximum:9, maximum:9,
multiple:true, multiple:true,
permissionAlert:true, permissionAlert:true,
@@ -51,11 +51,6 @@
return 120 * aspectRatio; return 120 * aspectRatio;
} }
}, },
watch: {
src(newVal, oldVal) {
console.log(newVal,oldVal);
}
},
created() { created() {
this.init(); this.init();
}, },
@@ -63,18 +58,38 @@
async init(){ async init(){
const self = this; const self = this;
let url = ""; let url = "";
const pictureElem = this.message.pictureElem;
// 如果有远程 snapshotUrl,则下载到 coverCachePath // 如果有远程 snapshotUrl,则下载到 coverCachePath
//const snapshotUrl = (this.message.pictureElem.snapshotPicture?.url ?? this.message.pictureElem.sourcePath ); let snapshotUrl = pictureElem?.sourcePath;
const snapshotUrl = this.message.pictureElem.sourcePicture?.url; if(snapshotUrl && await util.fileExsit(snapshotUrl)){
self.src = snapshotUrl;
return ;
}
snapshotUrl = (pictureElem?.sourcePicture.url ?? pictureElem.bigPicture?.url);
if(!snapshotUrl){ if(!snapshotUrl){
console.log(this.message); console.log(this.message);
return; return;
} }
//console.log(snapshotUrl); console.log(snapshotUrl);
util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{ util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{
self.coverDownloading = false; self.coverDownloading = false;
self.src = fn; self.src = fn;
//console.log(fn); console.log(fn);
});
},
getShowPath(url){
return new Promise((resolve,reject)=>{
if(url.startsWith('file')||url.startsWith('_')||url.startsWith('http')||url.startsWith('blob')){
return resolve(url);
}
plus.io.resolveLocalFileSystemURL(url, function(entry) {
return resolve(entry.toLocalURL());
}, function(e) {
console.log(e);
resolve(url);
});
}); });
}, },
clickMediaItem() { clickMediaItem() {
@@ -162,7 +162,7 @@
}, },
deleteConversation(conversationID){ deleteConversation(conversationID){
IMSDK.asyncApi(IMSDK.IMMethods.DeleteConversationAndDeleteAllMsg, IMSDK.uuid(), conversationID).then(res=>{ this.$store.dispatch('conversation/deleteConversation',conversationID).then(res=>{
console.log('删除成功'); console.log('删除成功');
}).catch(e=>{ }).catch(e=>{
@@ -85,7 +85,7 @@
}, },
inviteMember() { inviteMember() {
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}`, url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}&allowType=User`,
}); });
}, },
removeMember() { removeMember() {
+2 -2
View File
@@ -30,15 +30,15 @@
<u-loading-icon></u-loading-icon> <u-loading-icon></u-loading-icon>
</view> </view>
</u-list> </u-list>
<template v-if="showCheck" >
<choose-index-footer <choose-index-footer
v-if="showCheck"
:comfirmLoading="comfirmLoading" :comfirmLoading="comfirmLoading"
@removeItem="updateCheck" @removeItem="updateCheck"
@confirm="confirm" @confirm="confirm"
:choosedData="getChoosedData" :choosedData="getChoosedData"
:isRemove="isRemove" :isRemove="isRemove"
:maxLength="groupMemberLength" /> :maxLength="groupMemberLength" />
</template>
<u-modal <u-modal
:show="showConfirmModal" :show="showConfirmModal"
@@ -76,7 +76,7 @@
}, },
inviteMember() { inviteMember() {
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/contactChoose/choose?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}`, url: `/pages/common/contactChoose/choose?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}&allowType=User`,
}); });
}, },
kickMember() { kickMember() {
+1 -1
View File
@@ -245,7 +245,7 @@
showTypeSheet() { showTypeSheet() {
const _this = this; const _this = this;
uni.showActionSheet({ uni.showActionSheet({
itemList:['文字','照片'/*,'视频'*/], itemList:['文字','照片','视频'],
success: function (res) { success: function (res) {
//toChooseRelease //toChooseRelease
if([1,2].includes(res.tapIndex)){ if([1,2].includes(res.tapIndex)){
+2 -2
View File
@@ -22,9 +22,9 @@
<u-gap :height="10"></u-gap> <u-gap :height="10"></u-gap>
<uni-list> <uni-list>
<uni-list-item title="扫一扫" thumb="/static/images/find/03.png" :thumbSize="thumbSize" @click="scan" clickable showArrow></uni-list-item> <uni-list-item title="扫一扫" thumb="/static/images/find/03.png" :thumbSize="thumbSize" @click="scan" clickable showArrow></uni-list-item>
<uni-list-item v-if="1==2" title="摇一摇" thumb="/static/images/find/05.png" :thumbSize="thumbSize" to="/pages/find/friend-circle/friend-circle" showArrow></uni-list-item> <uni-list-item v-if="1==2" title="摇一摇" thumb="/static/images/find/05.png" :thumbSize="thumbSize" to="/pages/find/shake/index" showArrow></uni-list-item>
<uni-list-item v-if="1==2" title="看一看" thumb="/static/images/find/06.png" :thumbSize="thumbSize" to="/pages/find/friend-circle/friend-circle" showArrow></uni-list-item> <uni-list-item v-if="1==2" title="看一看" thumb="/static/images/find/06.png" :thumbSize="thumbSize" to="/pages/find/friend-circle/friend-circle" showArrow></uni-list-item>
<uni-list-item v-if="1==2" title="听一听" thumb="/static/images/find/06.png" :thumbSize="thumbSize" to="/pages/find/friend-circle/friend-circle" showArrow></uni-list-item> <uni-list-item v-if="1==2" title="听一听" thumb="/static/images/find/06.png" :thumbSize="thumbSize" to="/pages/find/music/index" showArrow></uni-list-item>
<uni-list-item v-if="config.near_user_open == '1'" title="附近" thumb="/static/images/find/08.png" :thumbSize="thumbSize" to="/pages/find/near/near" showArrow></uni-list-item> <uni-list-item v-if="config.near_user_open == '1'" title="附近" thumb="/static/images/find/08.png" :thumbSize="thumbSize" to="/pages/find/near/near" showArrow></uni-list-item>
<uni-list-item v-if="1===2" title="购物" thumb="/static/images/find/09.png" :thumbSize="thumbSize" :to="'/pages/common/webview?url='+encodeURI('http://pinduoduo.com')" showArrow></uni-list-item> <uni-list-item v-if="1===2" title="购物" thumb="/static/images/find/09.png" :thumbSize="thumbSize" :to="'/pages/common/webview?url='+encodeURI('http://pinduoduo.com')" showArrow></uni-list-item>
</uni-list> </uni-list>
+130
View File
@@ -0,0 +1,130 @@
<template>
<view v-if="currentPlaySong != null" class="play-bar flex-v-center" @click="bindOnShowPlayViewPopup">
<view class="music-cover flex-v-h-center" :class="currentPlayer.playState ? 'spin-start':'spin-stop'">
<u-avatar :src="currentPlaySong.pic" mode="circle" size='70'></u-avatar>
</view>
<view style="width: 64%;">
<view class="music-info flex-v-center text-line-1">
<view class="music-name text-line-1">{{currentPlaySong.songName}}</view>
<view class="line">-</view>
<view class="music-singer text-line-1">{{currentPlaySong.artist}}</view>
</view>
<view class="u-p-l-20 u-p-r-20 u-flex u-row-between u-col-center">
<view style="width: 80%;">
<u-line-progress active-color="#19be6b"
:striped="true"
:height="8"
:striped-active="true"
:show-percent="false"
:percent="currentPlayer.progress"></u-line-progress>
</view>
<view class="u-font-24 u-tips-color">
<text> {{currentPlaySong.songTimeMinutes}}</text>
</view>
</view>
</view>
<view class="bars flex-v-center flex-space-between">
<view style="width: 64rpx;">
<view class="u-progress-content flex-v-h-center btn-active" @tap.stop="bindOnControllerPlay">
<u-icon :class="currentPlayer.playState ? 'play' : 'pause'"
:name="currentPlayer.playState ? 'pause-circle' : 'play-circle'" size="54"></u-icon>
</view>
</view>
<view class="tools-item btn-active" style="display: inline-block;" @tap.stop="bindOnShowPlayListPopup">
<u-icon name="music-list" custom-prefix="custom-icon" size="54"></u-icon>
</view>
</view>
</view>
<view v-else class="play-bar flex-v-center test-border u-tips-color">
<view style="text-align: center;width: 100%;">
<text>当前暂无播放歌曲记录</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods:{
bindOnControllerPlay(){
this.$emit("changePlayStatus");
},
bindOnShowPlayListPopup(){
this.$emit("showPlayList")
},
bindOnShowPlayViewPopup(){
this.$emit("showPlayView")
},
}
}
</script>
<style>
@import "@/static/music/music.css";
</style>
<style lang="scss" scoped>
.play-bar{
position: fixed;
bottom: 30px;
left: 0;
width: 100%;
height: 120rpx;
background-color: #ffffff;
padding: 0 40rpx;
z-index: 1000;
.music-cover{
width: 100rpx;
height: 100rpx;
background-image: url('@/static/music/disc-plus.png');
background-size: 100% 100%;
flex-shrink:0;
-webkit-transform: rotate(360deg);
animation: rotation 10s linear infinite;
-moz-animation: rotation 10s linear infinite;
-webkit-animation: rotation 10s linear infinite;
-o-animation: rotation 10s linear infinite;
}
@-webkit-keyframes rotation{
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
.spin-stop{
-webkit-animation-play-state:paused
}
.spin-start{
-webkit-animation-play-state:running
}
.music-info{
display: flex;
padding: 0 20rpx;
flex: 1;
.music-name{
max-width: 65%;
flex-shrink:0;
}
.line{
padding: 0 10rpx;
color: $uni-text-color-disable;
font-size: $uni-font-size-sm;
}
.music-singer{
max-width: 35%;
color: $uni-text-color-disable;
font-size: $uni-font-size-sm;
}
}
.bars{
width: 160rpx;
text-align: right;
height: 100%;
.u-progress-content{
width: 100%;
height: 100%;
padding-left: 4rpx;
}
}
}
</style>
+265
View File
@@ -0,0 +1,265 @@
<template>
<view>
<u-navbar :is-back="true" title="" :background="{ background: '#ffffff' }"
:border-bottom="false" z-index="1001">
<view class="slot-wrap u-font-32">
<view class="u-font-32" style="width: 100%;">
<u-tabs :list="tabList" active-color="#2ebe4b"
:is-scroll="false" :show-bar="true" :font-size="34"
:current="currentTab" :active-item-style="activeItemStyle"
@change="tabChange"></u-tabs>
</view>
</view>
</u-navbar>
<view>
<view class="u-p-l-40 u-p-r-40">
<view class="u-m-t-20 u-m-b-20">
<u-search placeholder="支持搜索歌手,歌名,专辑"
border-color="#eeeeee"
bg-color="#ffffff"
shape="square"
:clearabled="true"
:show-action="true"
:action-style="actionStyle"
:animation="false"
height="80"
@search="search"
@custom="search"
v-model="searchWord">
</u-search>
</view>
<scroll-view
:scroll-x="false" :scroll-y="true" :style="'height:'+(pageHeight)+'px'">
<u-row>
<u-col :span="12">
<view class="u-p-30 u-font-36" style="font-weight: bold;">
<text>热门男歌手</text>
</view>
</u-col>
<u-col :span="4" v-for="(item,index) in singerManList" :key="index">
<view class="u-m-b-30" @click="toSongList(item)">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image width="100%" height="130rpx"
border-radius="16rpx"
mode="heightFix"
:src="item.avatar"></u-image>
</view>
</view>
<view style="text-align: center;margin-top:4rpx;font-size: 26rpx;color: #000000;">
<text>{{item.singerName}}</text>
</view>
</view>
</u-col>
</u-row>
<u-row>
<u-col :span="12">
<view class="u-p-30 u-font-36" style="font-weight: bold;">
<text>热门女歌手</text>
</view>
</u-col>
<u-col :span="4" v-for="(item,index) in singerWomenList" :key="index">
<view class="u-m-b-30" @click="toSongList(item)">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image width="100%" height="130rpx"
border-radius="16rpx"
mode="heightFix"
:src="item.avatar"></u-image>
</view>
</view>
<view style="text-align: center;margin-top:4rpx;font-size: 26rpx;color: #000000;">
<text>{{item.singerName}}</text>
</view>
</view>
</u-col>
</u-row>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
pageHeight:0,
tabList:[
{
name: '在线听'
},
{
name: '本地听'
},
],
currentTab:0,
activeItemStyle:{
fontSize:'36rpx',
},
actionStyle:{
backgroundColor:'#46be72',
color:'#ffffff',
height:'80rpx',
lineHeight:'80rpx',
position:'relative',
left:'0rpx',
textAlign:'center',
width:'140rpx',
borderRadius:'10rpx',
borderTopRightRadius:'10rpx',
borderBottomRightRadius:'10rpx'
},
searchWord:'',
singerManList:[
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M0000025NhlN2yWrP4.jpg?max_age=2592000',
singerName:'周杰伦'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001BLpXF2DyJe2.jpg?max_age=2592000',
singerName:'林俊杰'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002J4UUk29y8BY.jpg?max_age=2592000',
singerName:'薛之谦'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000003Nz2So3XXYek.jpg?max_age=2592000',
singerName:'陈奕迅'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002azErJ0UcDN6.jpg?max_age=2592000',
singerName:'张杰'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000003aQYLo2x8izP_4.jpg?max_age=2592000',
singerName:'刘德华'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000004NMZuf2BLjg8_2.jpg?max_age=2592000',
singerName:'周传雄'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000aHmbL2aPXWH.jpg?max_age=2592000',
singerName:'李荣浩'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000003fA5G40k6hKc.jpg?max_age=2592000',
singerName:'周深'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001IoTZp19YMDG.jpg?max_age=2592000',
singerName:'易烊千玺'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001z2JmX09LLgL.jpg?max_age=2592000',
singerName:'汪苏泷'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000CK5xN3yZDJt.jpg?max_age=2592000',
singerName:'许嵩'
}
],
singerWomenList:[
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001fNHEf1SFEFN.jpg?max_age=2592000',
singerName:'G.E.M.邓紫棋'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M0000003ZpE43ypssl.jpg?max_age=2592000',
singerName:'张碧晨'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000oCQfT3kdonw.jpg?max_age=2592000',
singerName:'黄霄雲'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002lKaDq2lLLtk.jpg?max_age=2592000',
singerName:'蔡健雅'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002azErJ0UcDN6.jpg?max_age=2592000',
singerName:'苏星婕'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000003iPzNg35cWzp.jpg?max_age=2592000',
singerName:'程响'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000000aw4WC2EQYTv_5.jpg?max_age=2592000',
singerName:'张靓颖'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000000GGDys0yA0Nk_2.jpg?max_age=2592000',
singerName:'梁静茹'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001pWERg3vFgg8.jpg?max_age=2592000',
singerName:'孙燕姿'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000GDDuQ3sGQiT.jpg?max_age=2592000',
singerName:'王菲'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000003jJGvv3C82KZ_5.jpg?max_age=2592000',
singerName:'刘若英'
},
{
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000002raUWw3PXdkT_5.jpg?max_age=2592000',
singerName:'张韶涵'
}
]
};
},
created:function(){
let pageHeight= this.$u.sys().windowHeight*0.82;
this.pageHeight=pageHeight;
},
methods: {
tabChange:function(index){
this.currentTab = index;
},
search:function(value){
console.log("搜索关键字",value);
let that=this;
if(value.length>0){
this.$u.route({
url:'pages/tabbar/find/music/song-list',
params:{
keyWords:value
}
})
}
},
toSongList:function(singer){
let that=this;
this.$u.route({
url:'pages/tabbar/find/music/song-list',
params:{
keyWords:singer.singerName
}
})
}
},
}
</script>
<style lang="scss">
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1;
/* 如果您想让slot内容与导航栏左右有空隙 */
padding: 0 30rpx;
}
.status_bar {
height: var(--status-bar-height);
width: 100%;
}
</style>
+218
View File
@@ -0,0 +1,218 @@
<template>
<view>
<u-navbar :is-back="true" :title="navbarTitle" :background="{ background: '#ffffff' }"
:title-bold="true" title-size="34"
:border-bottom="true" z-index="1001">
</u-navbar>
<view>
<view class="u-p-30 u-flex u-row-between u-col-center">
<view style="font-size: 36rpx;font-weight: bold;">
<text>列表</text>
<text>({{songList.length}})</text>
</view>
<view class="u-flex u-row-left u-col-center">
<view class="u-m-r-30">
<u-icon name="play-circle-fill" size="42" color="#2979ff" @click="playAll()"
label="播放全部" label-size="32"></u-icon>
</view>
<view class="u-m-l-30">
<u-icon name="heart-fill" size="42" color="#fa3534" @click="addToLocal()"
label="添加本地" label-size="32"></u-icon>
</view>
</view>
</view>
<scroll-view :scroll-x="false" :scroll-y="true" :style="'height:'+(pageHeight-50)+'px'" @scrolltolower="loadMore">
<view class="u-flex u-row-between u-col-center u-p-30 u-border-bottom"
v-for="(song,index) in songList" :key="index">
<view class="u-flex u-row-left u-col-center">
<view class="u-m-r-30">
<u-image :src="song.pic" width="100rpx" height="100rpx" border-radius="12rpx"></u-image>
</view>
<view>
<view class="u-font-34 u-m-b-10 u-line-1" style="color: #000000;width: 400rpx;">{{escape2Html(song.name)}}</view>
<view class="u-font-28 u-m-t-10 u-flex u-row-left u-col-center u-line-3" style="color: #808288;width: 400rpx;">
{{escape2Html(song.artist)}}-{{escape2Html(song.album)}}
</view>
</view>
</view>
<view class="u-flex u-row-around u-col-center">
<view>
<u-icon v-if="currentPlaySong&&currentPlaySong.id==song.rid&&currentPlayer.playState" name="pause-circle" size="50" color="#797979"></u-icon>
<u-icon v-else @click="toPlaySong(song)" name="play-circle" size="50" color="#797979"></u-icon>
</view>
<view class="u-m-l-30">
<u-icon @click="download(song)" name="download" size="50" color="#797979"></u-icon>
</view>
</view>
</view>
</scroll-view>
</view>
<view>
<play-bar @changePlayStatus="changePlayStatus" @showPlayView='bindOnPlayBarChange' @showPlayList='bindOnShowPlayListPopup'></play-bar>
</view>
</view>
</template>
<script>
import playBar from './components/play-bar.vue';
import playerUtil from '@/util/music/music-player.js';
export default {
components:{
playBar
},
data() {
return {
navbarTitle:"歌曲列表",
pageHeight:0,
pageNum:1,
pageSize:30,
searchWord:"",
total:0,
songList:[],
loadMoreFlag:false
};
},
watch:{
currentPlaySong:function(newSong){
let that=this;
console.log("====监听到播放歌曲发生变化======");
if(newSong!=null&&newSong.id){
playerUtil.initPlayer(that);
}
}
},
created:function(){
let pageHeight= this.$u.sys().windowHeight*0.79;
this.pageHeight=pageHeight;
},
onLoad:function(option){
let that=this;
console.log("搜索词",option);
let keyWords= option.keyWords;
if(keyWords){
this.navbarTitle=keyWords;
this.searchWord=keyWords;
};
this.getSongList();
that.$u.vuex("currentPlayer.canPlay",false);
//当前是是否暂停或停止状态,true 表示暂停或停止,false 表示正在播放
if(playerUtil.bgAudioManager.paused==true){
playerUtil.initPlayer(that);
}
},
methods:{
getSongList:function(){
let that=this;
let param={
pageNum:that.pageNum,
pageSize:that.pageSize,
keyWords:encodeURI(this.searchWord)
};
console.log("搜索歌曲列表",param);
this.$u.api.music.searchMusicList(param).then(res => {
//console.log("获取歌曲列表结果",res);
if(res.code==200){
let result= res.data;
if(result!=null&&result!=undefined){
let reqData= result.data;
this.total= reqData.total;
let list=reqData.list;
if(that.loadMoreFlag==true){
this.songList=this.songList.concat(list);
return;
}else{
this.songList=list;
}
}
}
});
},
loadMore:function(){
let that=this;
if(that.songList.length>=that.total){
that.globalUtil.utilAlert("暂无更多");
that.loadMoreFlag=false;
return;
}
that.pageNum++;
that.loadMoreFlag=true;
console.log("加载更多");
that.getSongList();
},
toPlaySong:function(song){
//console.log("当前选中播放歌曲",song);
//this.$u.vuex("currentPlaySong",song);
let param={
musicId:song.rid
};
this.$u.api.music.getSongInfoAndLrc(param).then(res => {
if(res.code==200){
let baseInfoResult= res.data;
let lrclist= baseInfoResult.data.lrclist;
let songInfo= baseInfoResult.data.songinfo;
songInfo.lrclist=lrclist;
this.$u.api.music.getSongSrc(param).then(res => {
if(res.code==200){
let songSrcResult= res.data;
let songSrc=songSrcResult.data.url;
songInfo.playSrc=songSrc;
console.log("获取歌曲详细信息结果",songInfo);
this.$u.vuex("currentPlaySong",songInfo);
}
})
}
})
//this.$forceUpdate();
},
changePlayStatus:function(){
let that=this;
console.log("改变状态")
playerUtil.bindOnControllerPlay(that);
},
bindOnPlayBarChange(){
//this.$refs.playViewPopup.show();
},
bindOnShowPlayListPopup(){
//this.$refs.playListPopup.show();
},
playAll:function(){
},
addToLocal:function(){
let that=this;
},
download:function(song){
let that=this;
let param={
musicId:song.rid,
songName:that.escape2Html(song.name),
saveDir:that.escape2Html(song.artist),
};
console.log("下载参数",param);
this.$u.api.music.downLoadSong(param).then(res => {
console.log("下载结果",res);
if(res.code==200){
that.globalUtil.utilAlert("下载成功");
let playSrc= res.data.url;
}else{
that.globalUtil.utilAlert("下载失败");
}
})
},
escape2Html:function(str) {
var arrEntities={'lt':'<','gt':'>','nbsp':' ','amp':'&','quot':'"','$':','};
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig,function(all,t){
return arrEntities[t];
});
}
}
}
</script>
<style lang="scss">
</style>
+249
View File
@@ -0,0 +1,249 @@
<template>
<view>
<u-navbar :is-back="true" back-icon-color="#333333"
title="通过朋友验证" :title-bold="true" :title-size="34"
:background="{ background: '#ffffff' }"
title-color="#404133" :border-bottom="false">
</u-navbar>
<view class="">
<scroll-view :scroll-x="false" :scroll-y="true" class="u-p-t-10 u-p-b-30"
:style="'width:100%;height:'+scrollviewHeight+'px'">
<view class="u-p-l-40 u-p-r-40">
<view class="u-p-l-20 u-title-color u-font-28">
<text>设置备注</text>
</view>
<view class="inputBox">
<u-input :custom-style="customInputStyle"
v-model="form.nickName" type="text"
:border="false" :height="60" :clearable="false"/>
</view>
<view class="u-title-color u-p-l-30 u-m-t-10">
<text>
<text style="font-size: 28rpx;">"{{form.userRemark}}"</text>
<text style="color: #36648b;margin-left: 20rpx;">选词填入</text>
</text>
</view>
</view>
<view class="u-m-t-30 u-p-l-40 u-p-r-40">
<view class="u-p-l-20 u-title-color u-font-28">
<text>添加标签与描述</text>
</view>
<view style="background-color: #f0f0f0;border-radius: 16rpx;margin-top: 20rpx;font-size: 32rpx;">
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
<view class="u-p-20 label-font">
<text>标签</text>
</view>
<view class="u-p-20">
<u-icon name="arrow-right" color="#909399" :size="32"></u-icon>
</view>
</view>
<u-gap :height="1" bg-color="#e5e8ec"></u-gap>
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
<view class="u-p-20 label-font">
<text>描述</text>
</view>
<view class="u-p-20">
<u-icon name="arrow-right" color="#909399" :size="32"></u-icon>
</view>
</view>
</view>
</view>
<view class="u-m-t-30 u-p-l-40 u-p-r-40">
<view class="u-p-l-20 u-title-color u-font-28">
<text>设置朋友权限</text>
</view>
<view style="background-color: #f0f0f0;border-radius: 16rpx;margin-top: 20rpx;font-size: 32rpx;">
<view class="u-flex u-row-between u-col-center"
@click="changePower(0)"
style="padding:16rpx 26rpx;">
<view class="u-p-20 label-font">
<text>聊天朋友圈微信运动等</text>
</view>
<view class="u-p-20" v-show="form.friendPower==0">
<u-icon name="checkbox-mark" color="#19be6b" :size="32"></u-icon>
</view>
</view>
<u-gap :height="1" bg-color="#e5e8ec"></u-gap>
<view class="u-flex u-row-between u-col-center"
@click="changePower(1)"
style="padding:16rpx 26rpx;">
<view class="u-p-20 label-font">
<text>仅聊天</text>
</view>
<view class="u-p-20" v-show="form.friendPower==1">
<u-icon name="checkbox-mark" color="#19be6b" :size="32"></u-icon>
</view>
</view>
</view>
</view>
<view class="u-m-t-30 u-p-l-40 u-p-r-40" v-if="form.friendPower==0">
<view class="u-p-l-20 u-title-color u-font-28">
<text>朋友圈和状态</text>
</view>
<view style="background-color: #f0f0f0;border-radius: 16rpx;margin-top: 20rpx;font-size: 32rpx;">
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
<view class="u-p-20 label-font">
<text>不让他()</text>
</view>
<view class="u-p-20">
<u-switch v-model="form.forbidSelf" :size="40" active-color="#19be6b" inactive-color="#eee"></u-switch>
</view>
</view>
<u-gap :height="1" bg-color="#e5e8ec"></u-gap>
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
<view class="u-p-20 label-font">
<text>不看他()</text>
</view>
<view class="u-p-20">
<u-switch v-model="form.forbidHis" :size="40" active-color="#19be6b" inactive-color="#eee"></u-switch>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view :style="'height:'+footerHeight+'px'"
class="u-flex u-row-center u-col-top footerbox">
<u-button type="success" :custom-style="customBtnStyle" @click="submitApply">完成</u-button>
</view>
<u-popup v-model="loadingShow"
:mask-close-able="false" :mask="false"
mode="center" border-radius="20" width="250rpx" height="250rpx">
<view class="u-flex u-row-center u-col-center"
style="flex-direction: column; text-align: center;
background-color: #000000;color: #ffffff;height: 250rpx;width: 250rpx;">
<view v-if="loadingStep==1">
<view>
<!-- <u-circle-progress :percent="100" bg-color="none"
inactive-color="#909399"
active-color="#ffffff"
:border-width="6"
:duration="1000" :width="100">
</u-circle-progress> -->
<u-loading mode="circle" :size="80" color="#909399"></u-loading>
</view>
<view class="u-m-t-20 u-font-32" style="font-weight: 420rpx;">正在处理...</view>
</view>
<view v-if="loadingStep==2">
<view>
<u-icon name="checkmark" color="#ffffff" :size="80"></u-icon>
</view>
<view class="u-m-t-20 u-font-32" style="font-weight: 420rpx;">已通过验证</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
scrollviewHeight:0,
footerHeight:0,
customInputStyle:{
fontSize:'32rpx',
color:'#909399',
paddingLeft:'10rpx'
},
form:{
id:'3',
avatar:'/static/image/default/default-user/3.jpg',
nickName:'王工',
signature:'',
userRemark:'你好,美女',
address:'浙江 杭州',
sex:0,
friendPower:0,
forbidSelf:false,
forbidHis:false,
},
customBtnStyle:{
padding:'20rpx 40rpx',
width:'300rpx'
},
loadingShow:false,
loadingStep:1,
};
},
created:function(){
let pageHeight= this.$u.sys().windowHeight;
this.scrollviewHeight=pageHeight*0.783;
this.footerHeight=pageHeight*0.09;
},
onLoad:function(option){
let that=this;
/* let param=JSON.parse(decodeURIComponent(option.personInfo));
this.form=param; */
this.form=this.yyy_current_user;
},
methods:{
friendNameFocus:function(){
let that=this;
},
changePower:function(status){
let that=this;
},
submitApply:function(){
let that=this;
that.loadingStep=1;
that.loadingShow=true;
setTimeout(function(){
that.loadingStep=2;
setTimeout(function(){
that.loadingShow=false;
uni.navigateTo({
animationType:'slide-in-left',
url:'/pages/find/shake/friend_home?personInfo='+encodeURIComponent(JSON.stringify(that.form))
});
/* that.$u.route({
url:'/pages/find/shake/friend_home',
animationType:'slide-in-left',
params:{
personInfo:encodeURIComponent(JSON.stringify(that.form))
},
}) */
},400)
},800);
}
}
}
</script>
<style lang="scss" scoped>
.inputBox{
background-color: #f0f0f0;
border-radius: 16rpx;
margin-top: 20rpx;
padding:16rpx 26rpx;
font-size: 32rpx;
}
.footerbox{
position: absolute;
bottom: 0px;
width: 100%;
background-color: #ffffff;
//opacity: 0.7;
}
.label-font{
font-size: 34rpx;
color: #000000;
font-weight: 420;
}
.u-title-color{
color: #606266 !important;
font-size: 30rpx;
}
</style>
<style lang="scss">
page{
background-color: #ffffff;
}
</style>
@@ -0,0 +1,554 @@
<template>
<view class="message-item-container"
:class="checkBoxFlag?'u-flex u-row-left u-col-center':''">
<view v-if="checkBoxFlag">
<template v-if="item.messageType!=0">
<u-checkbox :size="46" v-model="item.checked"
shape="circle" active-color="#19be6b" @click.native="checkChange(item)"></u-checkbox>
</template>
</view>
<view class="u-p-b-20 u-p-t-20" style="width: 100%;">
<!-- 系统信息-->
<view v-if="item.messageType==0">
<view v-if="item.showTimeFlag" style="text-align: center;color:#aaaaaa;font-size: 28rpx;margin-top: 20rpx;">
<text v-if="item.formatTimeStr&&item.formatTimeStr.length>0">
{{item.formatTimeStr}}
</text>
<text v-else>
{{item.createTime.substring(10,16)}}
</text>
</view>
<view style="text-align: center;color:#aaaaaa;font-size: 30rpx;margin-top: 20rpx;">
{{parseSYSContent(item)}}
</view>
</view>
<view v-else>
<view class="chat-time">
<text v-if="item.showTimeFlag">
<text v-if="item.formatTimeStr&&item.formatTimeStr.length>0">
{{item.formatTimeStr}}
</text>
<text v-else>
{{item.createTime.length>10?item.createTime.substring(10,16):item.createTime}}
</text>
</text>
</view>
<view :class="{'chat-container':true,'chat-location-me':item.meFlag}">
<view class="chat-icon-container u-flex u-row-center u-col-center"
@click="toYYYPerson(item)">
<view hover-class="my-hover-class"
class="u-flex u-row-center u-col-center">
<u-image :class="{'chat-icon':true,'chat-icon-me':item.meFlag}"
:src="item.userAvatar" width="80rpx" height="80rpx"
mode="aspectFill">
<view slot="error"
class="u-flex u-row-center u-col-center u-p-t-10"
style="width: 80rpx;height: 80rpx;border-radius: 12rpx;">
<view>
<image src="/static/image/default/default-user/default-user.png"
style="width: 50rpx;height:50rpx;"></image>
</view>
</view>
</u-image>
</view>
</view>
<view class="chat-content-container u-p-t-10">
<!-- 文本信息 -->
<view v-if="item.contentType == messageApi.CONTENT_TYPE.TEXT_CONTENT_TYPE">
<zb-tooltip placement="top" :visible.sync="toolTipFlag" color="#4c4c4c">
<view slot="content" style="width: 550rpx;"
class="u-flex u-flex-wrap u-row-left u-col-center">
<view v-for="(item,index) in toolTipData" :key="index"
style="text-align: center;padding: 20rpx 30rpx;">
<view class="u-flex u-row-center u-col-center" @click="handleMessage(item)">
<view>
<u-image :src="item.icon" :width="36" :height="36"></u-image>
</view>
</view>
<view style="font-size:26rpx;margin-top: 6rpx;">
<text>{{item.title}}</text>
</view>
</view>
</view>
<view @longpress="toolTipFlag=!toolTipFlag"
:class="{'chat-text-container':true,'chat-text-container-me u-text-reserve':item.meFlag}">
<u-parse :html="parseTextContent(item)"
:tag-style="tagStyle">
</u-parse>
</view>
</zb-tooltip>
</view>
<!-- 图片信息 -->
<view v-if="item.contentType == messageApi.CONTENT_TYPE.IMG_CONTENT_TYPE">
<view class="content contentType3" @tap="showPic(item)">
<u-image :width="item.content.width*2" :height="item.content.height*2"
:lazy-load="true" mode="widthFix" :src="parseImageSrc(item)">
<u-loading slot="loading"></u-loading>
</u-image>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
var previewSrcArr = [];
export default {
name: "message-item",
props: {
item: {
type: Object,
default: function() {
return {
"id": "",
"chatGroupId": "",
"userId": 0,
"meFlag": true,
"userName": '',
"userAvatar": "",
'messageType': "",
"contentType": "",
"content": {},
"timestamp": "",
"createTime": "",
"platFrom": this.messageApi.msgPlat,
}
}
},
checkBoxFlag:{
type:Boolean,
default:false
}
},
data() {
return {
toolTipFlag: false,
toolTipData: [{
id: 1,
icon: '/static/image/wx/handle-msg/copy.jpg',
title: '复制',
disabled: false
},
{
id: 2,
icon: '/static/image/wx/handle-msg/zhuanfa.jpg',
title: '转发', //转发
disabled: false
},
{
id: 4,
icon: '/static/image/wx/handle-msg/shoucang.jpg',
title: '收藏',
disabled: false
},
{
id: 5,
icon: '/static/image/wx/handle-msg/shanchu.jpg',
title: '删除',
disabled: false
},
{
id: 6,
icon: '/static/image/wx/handle-msg/duoxuan.jpg',
title: '多选',
disabled: false
},
{
id: 7,
icon: '/static/image/wx/handle-msg/yinyong.jpg',
title: '引用',
disabled: false
},
{
id: 8,
icon: '/static/image/wx/handle-msg/tixing.jpg',
title: '提醒',
disabled: false
},
{
id: 9,
icon: '/static/image/wx/handle-msg/souyisou.jpg',
title: '搜一搜',
disabled: false
},
],
tagStyle:{
img:'width:22px;height:22px;position:relative;top:10rpx;',
span:'margin:0px;padding:0px;font-size:30rpx',
},
previewVideoFlag:false, //播放视频控制器
previewVideoSrc:'',
redbagPopFlag:false,
maskCustomStyle:{
background: 'rgba(255, 255, 255, 0.7)'
},
currentRedBagInfo:null,
};
},
methods: {
parseSYSContent:function(item){
let that=this;
let contentType = item.contentType;
let contentObj=item.content;
if (contentType == 1) {
let msgStr = contentObj.text;
console.log("transText",msgStr);
return msgStr;
}
},
//内容格式化
parseTextContent: function(item) {
let that=this;
let contentType = item.contentType;
let contentObj=item.content;
let msgStr = contentObj.text;
let sysType = contentObj.contentType; //内容类型
let optionType = contentObj.optionType;
let transText = this.transform(msgStr,'','',contentObj.linkName);
return transText;
},
//预览图片
showPic:function(item){
let url= item.content.fullPath;
let target= item.content.fileSaveTarget;
if(target=="local"){
url= this.$u.api.multipartAddress.getFileByPath+url;
}
uni.previewImage({
urls: previewSrcArr.length > 0 ? previewSrcArr : [url],
current: url,
loop: false,
});
},
parseImageSrc:function(item){
let that=this;
let msgId= item.id;
let localSrc= uni.getStorageSync("image"+msgId);
if(localSrc){
return localSrc;
}
let contentObj=item.content;
let url= contentObj.fullPath;
let target= contentObj.fileSaveTarget;
if(target=="local"){
let fileName= contentObj.fileName;
url=this.$u.api.multipartAddress.showFile+fileName;
}
that.setImageLocalSrc(url,msgId);
return url;
},
parseImgSize: function(item, type) {
let contentObj=item.content;
let height = contentObj.height;
let width = contentObj.width;
if (type == "h") {
if (height == null || height == undefined) {
return "auto";
} else {
return height * 2;
}
} else {
if (width == null || width == undefined) {
return 300;
} else {
return width * 2;
}
}
},
setImageLocalSrc(url,msgId){
let that=this;
that.messageApi.setImageLocalSrc(url,msgId);
},
toYYYPerson:function(item){
let that=this;
if(item.meFlag==false){
that.$emit("toYYYPerson",item);
}
},
checkChange:function(msg){
let that=this;
that.$emit("checkChange",msg);
},
handleMessage:function(menuItem){
this.toolTipFlag=false;
this.$emit("handleMessage",menuItem,this.item);
},
transform (content, fileSize, fileSuffix,linkName) {
if (fileSize === undefined) {
fileSize = '';
}
if (fileSuffix === undefined) {
fileSuffix = '';
}
let html = function(end) {
return new RegExp('\\n*\\[' + (end || '') +
'(code|pre|div|span|p|table|thead|th|tbody|tr|td|ul|li|ol|li|dl|dt|dd|h2|h3|h4|h5)([\\s\\S]*?)]\\n*',
'g');
};
if (content)
{
content = content.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&#39;')
.replace(/"/g, '&quot;') // XSS
.replace(html(), '<$1 $2>')
.replace(html('/'), '</$1>') // 转移HTML代码
.replace(/\n/g, '<br>'); // 转义换行
content=getUrl(content);
content=content.replace(/face\[([^\s\[\]]+?)]/g, function(face) {
let alt = face.replace(/^face/g, '');
let fa =faceUtil.emojiMap;
let srcPrefix=faceUtil.emojiUrl;
let imageSrc=srcPrefix+ fa[alt];
//console.log("表情",imageSrc);
let imgContent= '<img class="emoji" src="' +imageSrc+ '"/>';
return imgContent;
})
// 转义图片
.replace(/img\[([^\s]+?)]/g, function(img) {
let href = img.replace(/(^img\[)|(]$)/g, '');
return '<img class="message-img" src="' + href + '" alt="消息图片不能加载">';
})
// 转义文件
.replace(/file\([\s\S]+?\)\[[\s\S]*?]/g, function(str) {
let href = (str.match(/file\(([\s\S]+?)\)\[/) || [])[1];
let text = (str.match(/\)\[([\s\S]*?)]/) || [])[1];
if (!href) return str;
return '<div class="flex"><i class="iconfont icon-xiazai-yun"></i><a class="message-file" href="' +
href + '">' + (text || href) + '</a><span>' + fileSize + '</span></div>'
})
// 转义音频
.replace(/audio\[([^\s]+?)]/g, function(audio) {
return '<div class="message-audio" data-src="' + audio.replace(/(^audio\[)|(]$)/g, '') +
'"><i class="layui-icon">&#xe652;</i><p>音频消息</p></div>';
})
// 转义视频
.replace(/video\[([^\s]+?)]/g, function(video) {
return '<div class="message-video" data-src="' + video.replace(/(^video\[)|(]$)/g, '') +
'"><i class="layui-icon">&#xe652;</i></div>';
})
// 转义链接
.replace(/a\([\s\S]+?\)\[[\s\S]*?]/g, function(str) {
let href = (str.match(/a\(([\s\S]+?)\)\[/) || [])[1];
let text = (str.match(/\)\[([\s\S]*?)]/) || [])[1];
if (!href) return str;
if(linkName&&linkName.length>0){
return '<a href="' + href + '" target="_blank">' + linkName + '</a>';
};
return '<a href="' + href + '" target="_blank">' + (text || href) + '</a>';
})
}
return content;
}
}
}
</script>
<style lang="scss" scoped>
.message-item-container {
padding:0rpx 20rpx;
}
.chat-time {
padding: 4rpx 0rpx;
text-align: center;
font-size: 28rpx;
color: #aaaaaa;
}
.chat-container {
width: 100%;
display: flex;
flex-direction: row;
justify-content: flex-start;
justify-items: flex-start;
align-items: flex-start;
}
.chat-location-me {
flex-direction: row-reverse;
text-align: right;
}
.chat-icon-me {
margin-right: 10rpx;
}
.chat-icon-container {
margin-top: 12rpx;
}
.chat-icon {
width: 80rpx;
height: 80rpx;
border-radius: 10rpx;
background-color: #ffffff;
}
.chat-content-container {
margin: 0rpx 15rpx;
max-width: 70%;
}
.chat-user-name {
font-size: 26rpx;
color: #888888;
}
.chat-text-container {
//word-break: break-all;
word-wrap:break-word;
background-color: #ffffff;
border-radius: 10rpx;
padding: 20rpx 20rpx;
margin-top: 5rpx;
font-size: 32rpx;
}
.chat-text-container-me {
background-color: #95ec69;
}
.emoji {
width: 40rpx !important;
height: 40rpx !important;
position: relative;
top: 10rpx;
}
//语音信息样式
.content-audio-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 25rpx 20rpx;
margin-top: 5rpx;
/* #ifndef APP-NVUE */
max-width: 500rpx;
/* #endif */
display: flex;
flex-direction: row;
align-items: center;
.voice_icon {
height: 34rpx;
width: 34rpx;
background-repeat: no-repeat;
background-size: 100%;
}
.voice_icon_right {
background-image: url('@/static/images/chat/voice/voice-left-3.png');
margin-left: 10rpx;
}
.voice_icon_left {
background-image: url('@/static/images/chat/voice/voice-right-3.png');
margin-right: 10rpx;
}
.voice_icon_right_an {
animation: voiceAn_right 1s linear alternate infinite;
}
.voice_icon_left_an {
animation: voiceAn_left 1s linear alternate infinite;
}
@keyframes voiceAn_right {
0% {
background-image: url('@/static/images/chat/voice/voice-left-1.png');
}
50% {
background-image: url('@/static/images/chat/voice/voice-left-2.png');
}
100% {
background-image: url('@/static/images/chat/voice/voice-left-3.png');
}
}
@keyframes voiceAn_left {
0% {
background-image: url('@/static/images/chat/voice/voice-right-1.png');
}
50% {
background-image: url('@/static/images/chat/voice/voice-right-2.png');
}
100% {
background-image: url('@/static/images/chat/voice/voice-right-3.png');
}
}
}
//我的语音信息样式
.chat-audio-container-me {
background-color: #95ec69;
flex-direction: row-reverse;
}
//文件信息样式
.contentType-file {
width: 450rpx;
padding: 0;
border-radius: 10rpx;
border: 1rpx solid #e4e7ed;
background-color: #ffffff !important;
}
//红包
.contentType-redbag {
padding: 20rpx 30rpx;
padding-bottom: 6rpx;
border-radius: 10rpx;
background-color: #f29100;
color: #ffffff;
}
//位置
.contentType-location {
width: 500rpx;
padding: 0rpx 10rpx;
border-radius: 10rpx;
border: 1rpx solid #e4e7ed;
background-color: #ffffff !important;
}
//组合信息
.contentType-fixed {
border-radius: 10rpx;
font-size: 32rpx;
word-break: break-word;
padding: 20rpx;
background-color: #95ec69 !important;
border: 1rpx solid #e4e7ed;
max-width: 400rpx;
.img {
width: 200rpx;
height: auto;
max-width: 300rpx;
max-height: 400rpx;
}
}
.u-flex-reserve {
flex-direction: row-reverse;
}
.u-text-reserve {
text-align: left;
}
</style>
File diff suppressed because it is too large Load Diff
+441
View File
@@ -0,0 +1,441 @@
<template>
<view class="zhuanfa-container">
<template v-if="moreFlag==false">
<view>
<u-navbar :is-back="false"
back-icon-color="#333333"
title=""
:border-bottom="false"
:background="{ background: '#f0f0f0'}"
z-index="1001">
<view class="slot-wrap u-flex u-row-between u-col-center u-font-32">
<view @click="goback()">
<text>关闭</text>
</view>
<view style="font-weight: bold;font-size: 34rpx;color: #000000;">
<text>选择一个聊天</text>
</view>
<view @click="changeMoreFlag(1)">
<text>多选</text>
</view>
</view>
</u-navbar>
<view>
<view style="background-color: #f0f0f0;" class="u-p-30">
<view class="u-flex u-row-center u-col-center"
style="background-color: #ffffff;height:70rpx;border-radius: 10rpx;color: #c0c0c0;">
<view class="u-m-r-20">
<u-icon class="u-clear-icon" top="6rpx" :size="40" name="search" color="#c0c0c0"></u-icon>
</view>
<view style="color: #c0c0c0;font-size: 34rpx;">搜索</view>
</view>
<view class="u-m-t-40 u-p-b-20" v-if="latestZhuanFa.length>0">
<view style="font-size: 30rpx;font-weight: bold;">
<text>最近转发</text>
</view>
<view class="u-flex u-row-left u-col-center u-m-t-20" style="text-align: center;">
<view class="u-m-r-40" v-for="(lastestItem,index) in latestZhuanFa" :key="index">
<view class="u-flex u-row-center u-col-center">
<view style="height: 100rpx;width: 100rpx;">
<u-image :src="lastestItem.avatar"
:width="100" :height="100" :border-radius="12"></u-image>
</view>
</view>
<view class="u-line-2 u-tips-color"
style="width: 100rpx;height: 64rpx;line-height: 30rpx;font-size: 26rpx;padding:8rpx;">
<text>{{lastestItem.nickName}}</text>
</view>
</view>
</view>
</view>
</view>
<view class="u-p-30" style="background-color: #ffffff;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;">
<view class="u-flex u-row-between u-col-center u-font-30">
<view style="color: #000000;font-weight: bold;">
<text>最近聊天</text>
</view>
<view style="color:#36648b;">
<text>创建聊天</text>
</view>
</view>
<view v-if="lastestChatUsers.length>0" class="u-m-t-30">
<view v-for="(user,uIndex) in lastestChatUsers" :key="uIndex"
class="u-flex u-row-left u-col-center u-p-t-16 u-p-b-16">
<view style="width:90rpx;" class="u-flex u-row-left u-col-center">
<view>
<u-image :src="user.avatar" :width="76" :height="76" border-radius="8rpx"></u-image>
</view>
</view>
<view style="width: 600rpx;"
class="u-flex u-row-between u-col-center u-p-20 u-border-bottom">
<view style="text-align: left;">
<view class="u-line-1" style="font-size: 32rpx;color: #000000;">
<text>{{user.nickName}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<template v-if="moreFlag==true">
<view>
<u-navbar :is-back="false"
back-icon-color="#333333"
title=""
:border-bottom="false"
:background="{ background: '#f0f0f0'}"
z-index="1001">
<view class="slot-wrap u-flex u-row-between u-col-center u-font-32">
<view @click="changeMoreFlag(0)">
<text>取消</text>
</view>
<view style="font-weight: bold;font-size: 34rpx;color: #000000;">
<text>选择多个聊天</text>
</view>
<view>
<view v-if="checkedUsers.length<1" style="border-radius: 10rpx;background-color: #dddddd;color: #909399;padding: 10rpx 20rpx;">
<text>完成</text>
</view>
<view v-if="checkedUsers.length>0"
@click="openZhuanFa()"
style="border-radius: 10rpx;background-color: #19be6b;color: #ffffff;padding: 10rpx 20rpx;">
<text>完成({{checkedUsers.length}})</text>
</view>
</view>
</view>
</u-navbar>
<view style="background-color: #f0f0f0;">
<view v-if="checkedUsers.length<1" class="u-p-30">
<view class="u-flex u-row-center u-col-center"
style="background-color: #ffffff;height:70rpx;border-radius: 10rpx;color: #c0c0c0;">
<view class="u-m-r-20">
<u-icon class="u-clear-icon" top="6rpx" :size="40" name="search" color="#c0c0c0"></u-icon>
</view>
<view style="color: #c0c0c0;font-size: 34rpx;">搜索</view>
</view>
</view>
<view v-else class="u-p-30">
<view class="u-flex u-row-left u-col-center"
style="background-color: #ffffff;border-radius: 10rpx;color: #c0c0c0;">
<view class="u-p-20" style="width: 400rpx;">
<scroll-view class="hidden-scroll-bar"
:scroll-into-view="scrollIntoViewId"
:scroll-with-animation="true"
:scroll-y="false" :scroll-x="true" style="width:400rpx;">
<view class="u-flex u-row-left u-col-center">
<view class="u-m-l-20"
v-for="(checkeItem,index) in checkedUsers"
:key="index">
<view :id="'u-'+checkeItem.chatNumber"
class="u-flex u-row-center u-col-center">
<view>
<u-image :src="checkeItem.avatar"
:width="80" :height="80" :border-radius="12"></u-image>
</view>
</view>
</view>
<view class="u-p-l-30" v-if="checkedUsers.length<4" style="color: #909399;font-size: 34rpx;">
<text>搜索</text>
</view>
</view>
</scroll-view>
</view>
<view v-if="checkedUsers.length>=4" class="u-p-l-30" style="color: #909399;font-size: 34rpx;" >
<text>搜索</text>
</view>
</view>
</view>
<view class="u-p-30" v-if="latestZhuanFa.length>0">
<view style="font-size: 30rpx;font-weight: bold;">
<text>最近转发</text>
</view>
<view class="u-flex u-row-left u-col-center u-m-t-20" style="text-align: center;">
<view class="u-m-r-40" v-for="(lastestItem,index) in latestZhuanFa" :key="index">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image :src="lastestItem.avatar"
:width="100" :height="100" :border-radius="12"></u-image>
</view>
</view>
<view class="u-line-2 u-tips-color"
style="width: 100rpx;height: 64rpx;line-height: 30rpx;font-size: 26rpx;padding: 8rpx;">
<text>{{lastestItem.nickName}}</text>
</view>
</view>
</view>
</view>
<view class="u-p-30"
style="background-color: #ffffff;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;">
<view class="u-flex u-row-between u-col-center u-font-30">
<view style="color: #000000;font-weight: bold;">
<text>最近聊天</text>
</view>
<view style="color:#36648b;">
<text>从通讯录选择</text>
</view>
</view>
<view v-if="lastestChatUsers.length>0" class="u-m-t-30">
<view v-for="(user,uIndex) in lastestChatUsers" :key="uIndex"
class="u-flex u-row-left u-col-center u-m-b-20">
<view>
<u-checkbox :size="46" v-model="user.checked" @click.native="checkChange(user)"
shape="circle" active-color="#19be6b"></u-checkbox>
</view>
<view class="u-flex u-row-left u-col-center u-p-b-20">
<view style="width:90rpx;" class="u-flex u-row-center u-col-center">
<view>
<u-image :src="user.avatar" :width="76" :height="76" border-radius="8rpx"></u-image>
</view>
</view>
<view class="u-flex u-row-between u-col-center u-p-20 u-border-bottom">
<view style="text-align: left;">
<view class="u-line-1" style="font-size: 32rpx;color: #000000;width: 480rpx;">
<text>{{user.nickName}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<u-popup v-model="openZhuanFaFlag" mode="center" border-radius="16"
:mask-close-able="false"
width="625rpx" :height="checkedUsers.length>3?'600rpx':'520rpx'">
<view class="u-p-30">
<view style="font-size: 34rpx;font-weight: bold;">
<text>分别发送给:</text>
</view>
<view class="u-m-t-30">
<view class="u-flex u-flex-wrap u-row-left u-col-center">
<view v-for="(checkeItem,index) in checkedUsers" class="u-m-r-16 u-m-t-10"
:key="index">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image :src="checkeItem.avatar"
:width="80" :height="80" :border-radius="12"></u-image>
</view>
</view>
</view>
</view>
</view>
<view class="u-flex u-row-between u-col-center u-m-t-30 u-p-t-30 u-p-b-10 u-tips-color u-border-top">
<view>
<text>[逐条转发]{{selectedMessages.length>0?selectedMessages.length:2}}条信息</text>
</view>
<view>
<u-icon name="arrow-right" size="32"></u-icon>
</view>
</view>
<view class="u-m-t-20 u-p-b-20">
<view style="background-color: #f7f7f7;width: 550rpx;padding:16rpx 20rpx;text-align: left;color: #909399;font-size: 30rpx;">
<text>给朋友留言</text>
</view>
</view>
<view style="position: absolute;width: 560rpx;bottom:30rpx;"
class="u-flex u-row-between u-col-center u-font-34 u-p-t-30 u-border-top">
<view style="color: #000000;text-align: center;width: 50%;">
<view @click="cancelZhuanFa()">
<text>取消</text>
</view>
</view>
<view style="color: #36648b;text-align: center;width: 50%;">
<view @click="confirmSend()">
<text>发送({{checkedUsers.length}})</text>
</view>
</view>
</view>
</view>
</u-popup>
<u-popup v-model="maxLengthFlag" mode="center" border-radius="16"
:mask-close-able="false" height="300rpx"
width="620rpx">
<view style="text-align: center;font-weight: bold;font-size: 34rpx;">
<view class="u-flex u-row-center u-col-center" style="width: 100%; height: 200rpx;">
<view>
<text>最多只能选择9个聊天</text>
</view>
</view>
<view @click="maxLengthFlag=false"
style="color: #36648b;padding-top:30rpx;padding-bottom: 30rpx; width: 100%;" class="u-border-top">
<text>我知道了</text>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
moreFlag:false,
scrollHidden:false,
checkNum:0,
latestZhuanFa:[],
checkedUsers:[],
scrollIntoViewId:"",
lastestChatUsers:[],
openZhuanFaFlag:false,
maxLengthFlag:false,
selectedMessages:[],
};
},
onPageScroll:function(e){
let top= e.scrollTop;
let pageHeight= this.$u.sys().windowHeight;
if((top/pageHeight)>0.25){
console.log("隐藏");
this.scrollHidden=true;
}else{
this.scrollHidden=false;
}
},
onLoad:function(option){
if(option.checkedMessages){
this.selectedMessages=JSON.parse(decodeURIComponent(option.checkedMessages));
this.selectedMessages[0].showTimeFlag=true;
};
this.checkedUsers=[];
this.latestZhuanFa=this.vuex_lastestZhuanFaUsers;
this.latestZhuanFa.map(function(item){
item.checked=false;
});
this.lastestChatUsers=this.vuex_yyyFriendList.concat(this.latestZhuanFa);
this.lastestChatUsers.map(function(item){
item.checked=false;
});
},
methods:{
goback:function(){
uni.navigateBack();
},
changeMoreFlag:function(value){
this.moreFlag=value;
},
checkChange:function(user){
let that=this;
let isExist = this.checkedUsers.some(item=>item.chatNumber===user.chatNumber);
if(!isExist){
if(that.checkedUsers.length>=9){
this.maxLengthFlag=true;
return;
};
this.checkedUsers.push(user);
this.$nextTick(function(){
that.scrollIntoViewId="u-"+user.chatNumber;
})
}else{
this.checkedUsers = this.checkedUsers.filter(function(item) {
return item.chatNumber!=user.chatNumber
});
}
},
openZhuanFa:function(){
this.openZhuanFaFlag=true;
},
confirmSend:function(){
let that=this;
console.log("===选择的用户===",that.checkedUsers);
console.log("===转发的信息===",that.selectedMessages);
let lastMsg=that.selectedMessages[that.selectedMessages.length-1];
let friendList=that.vuex_yyyFriendList;
for (var i = 0; i < friendList.length; i++) {
let friend= friendList[i];
friend.checked=false;
let isExist = that.checkedUsers.some(item=>item.chatNumber===friend.chatNumber);
if(isExist){
that.setLastMsgContent(friend,lastMsg,that.selectedMessages)
}
};
that.$nextTick(function(){
that.$u.vuex("vuex_yyyFriendList",friendList);
that.openZhuanFaFlag=false;
uni.navigateBack();
});
},
cancelZhuanFa:function(){
this.openZhuanFaFlag=false;
},
setLastMsgContent:function(friend,message){
let that=this;
let formatContent="";
let contentType=message.contentType;
let contentObj=message.content;
switch (contentType+""){
case "1":
formatContent=contentObj.text;
formatContent=formatContent.replace(/face\[([^\s\[\]]+?)]/g, function(face) {
return face.replace(/^face/g, '')
});
break;
case "2":
formatContent="[图片]";
break;
case "3":
formatContent="[视频]";
break;
case "4":
formatContent="[语音]";
break;
case "7":
formatContent="[红包]";
break;
case "10":
formatContent="[聊天记录]";
break;
case "11":
formatContent="[图文]";
break;
case "12":
formatContent="[视频文字]";
break;
default:
formatContent="[其他]";
break;
};
console.log("最后一条信息",formatContent);
console.log("群号",friend.chatNumber);
if(friend.chatNumber=="000000"){
let obj={
"lastMsgContent":formatContent,
"messageList":that.selectedMessages,
"lastMsgTime":message.createTime,
};
this.$u.vuex("vuex_fileAssist",obj);
}else{
friend.lastMsgContent=formatContent;
friend.sendTimeStr=message.createTime;
friend.messageList=that.selectedMessages;
}
},
},
}
</script>
<style lang="scss" scoped>
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1;
/* 如果您想让slot内容与导航栏左右有空隙 */
padding: 0 30rpx;
}
</style>
+239
View File
@@ -0,0 +1,239 @@
<template>
<view>
<view>
<u-navbar :custom-back="goback" title=" " :background="{ background: '#ffffff' }" :border-bottom="false">
<view class="slot-wrap" @click="toDetail()">
<view>
<u-icon name="more-dot-fill" color="#000000" :size="35"></u-icon>
</view>
</view>
</u-navbar>
</view>
<view class="friendInfo">
<view class="img">
<u-image :src="friendInfo.avatar"
mode="aspectFill" width="120" height="120" border-radius="12">
<u-loading slot="loading"></u-loading>
<view slot="error"
class="u-flex u-row-center u-col-center u-p-t-10"
style="width: 90rpx;height: 90rpx;background-color: #f1f1f1;border-radius: 12rpx;">
<view>
<image src="/static/image/default/default-user/default-user.png"
style="width: 64rpx;height: 64rpx;"></image>
</view>
</view>
</u-image>
</view>
<view class="friendInfo-desc">
<view class="friendInfo-desc-name u-flex u-row-left u-col-center">
<view class="u-line-2" style="font-size:42rpx;max-width: 400rpx;">
<text>{{friendInfo.nickName}}</text>
</view>
<view class="u-m-l-10 u-flex u-row-center u-col-center u-p-b-10">
<view>
<u-image v-if="friendInfo.sex==1" src="/static/image/chat/addFriend/woman.png" width="34rpx" height="34rpx"></u-image>
<u-image v-if="friendInfo.sex==0" src="/static/image/chat/addFriend/man.png" width="34rpx" height="34rpx"></u-image>
</view>
</view>
</view>
<view class="friendInfo-desc-gray u-line-1 u-m-b-4" style="max-width: 500rpx;">微信号{{friendInfo.chatNumber}}</view>
<view v-if="friendInfo.address&&friendInfo.address!=0&&friendInfo.address.length>0" class="friendInfo-desc-gray">地区{{friendInfo.address}}</view>
</view>
</view>
<u-cell-group>
<u-cell-item title="备注和标签" :title-style="titleStyle"></u-cell-item>
<u-cell-item :border-bottom="false" title="朋友权限"
:title-style="titleStyle" @click="setFiendPermission"></u-cell-item>
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
<u-cell-item :title-style="titleStyle">
<view slot="title" class="u-flex u-row-left u-col-center">
<view>
<text>朋友圈</text>
</view>
<view class="u-flex u-row-left u-col-center u-m-l-50"
v-if="friendInfo.friendCircle&&friendInfo.friendCircle.length>0">
<template v-for="(circle,index) in friendInfo.friendCircle.length">
<view class="u-m-l-10" v-if="circle!=circle&&circle.length>0">
<u-image :src="circle" :width="90" :height="90"></u-image>
</view>
</template>
</view>
</view>
</u-cell-item>
<u-cell-item title="视频号" :title-style="titleStyle"></u-cell-item>
<u-cell-item :border-bottom="false" title="更多信息" :title-style="titleStyle" @click="linkToMoreInfoMation"></u-cell-item>
</u-cell-group>
<u-gap height="20" bg-color="#eee" margin-top="0" margin-bottom="1"></u-gap>
<view style="background-color: #ffffff;">
<view class="u-flex u-row-center u-col-center u-p-30"
style="font-size: 32rpx;color: #335f83;">
<view class="u-m-r-20">
<!-- width="36rpx" height="36rpx" -->
<u-image src="/static/image/chat/sms-send.png" mode="aspectFit" width="40rpx" height="40rpx"></u-image>
</view>
<view style="font-weight: 450;">
<text>发信息</text>
</view>
</view>
<u-gap height="1" bg-color="#eee"></u-gap>
<view class="u-flex u-row-center u-col-center u-p-30"
style="font-size: 32rpx;color: #335f83;">
<view class="u-m-r-20">
<!-- src="/static/image/chat/yinshipin.jpg" width="40rpx" height="40rpx"-->
<u-image src="/static/image/chat/video-call.png" mode="aspectFit" width="50rpx" height="50rpx"></u-image>
</view>
<view style="font-weight: 450;">
<text>音视频通话</text>
</view>
</view>
</view>
<u-action-sheet :list="callList" v-model="callShow" @click="callClick"></u-action-sheet>
<u-top-tips ref="uTips"></u-top-tips>
</view>
</template>
<script>
export default {
data() {
return {
titleStyle: {
marginLeft: '10rpx',
color: '#000000',
fontSize: "34rpx",
},
friendInfo: {},
callList:[
{text: '视频通话'},
{text: '语音通话'}
],
callShow:false,
}
},
onLoad(option) {
let that=this;
/* let param=JSON.parse(decodeURIComponent(option.personInfo));
this.friendInfo=param; */
this.friendInfo=this.yyy_current_user;
//往好友里面塞
let arr=JSON.parse(JSON.stringify(this.vuex_yyyFriendList));
let isExist = arr.some(item=>item.chatNumber===this.friendInfo.chatNumber);
if(!isExist){
arr.push(this.friendInfo);
};
this.$u.vuex("vuex_yyyFriendList",arr);
console.log("this.vuex_yyyFriendList=======",this.vuex_yyyFriendList);
},
methods: {
goback(){
console.log("自定义返回");
uni.navigateBack({
delta:3,
animationType:"slide-out-right"
});
},
//创建单聊会话
createSingleChat:function(){
let that=this;
},
//跳转聊天窗口
linkToChatting:function(groupInfo) {
let that=this;
},
//音视频弹窗
toCall() {
return;
},
//确认发起音视频
callClick:function(index){
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
},
//设置标签
setFiendTag() {
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
return;
},
//设置朋友权限
setFiendPermission() {
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
return;
},
//查看朋友的朋友圈
viewHisFiendCircle() {
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
return;
},
//更多信息
linkToMoreInfoMation() {
this.$u.route({
url: "/pages/tabbar/contact/friends/friend-more-info",
params: {
signature: this.friendInfo.signature
}
})
},
toDetail:function(){
this.$u.route({
url: "/pages/tabbar/contact/friends/friend-home-detail",
params: {
friendInfo:encodeURIComponent(JSON.stringify(this.friendInfo))
}
})
}
},
}
</script>
<style scoped lang="scss">
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1;
width: 100%;
/* 如果您想让slot内容与导航栏左右有空隙 */
padding: 0 30rpx;
flex-direction: row;
justify-content: flex-end;
}
.perch {
height: 10rpx;
}
.friendInfo {
display: flex;
justify-content: flex-start;
align-items: flex-start;
padding: 20rpx 30rpx 40rpx 40rpx;
background-color: #FFFFFF;
.img {
display: block;
width: 130rpx;
height: 130rpx;
border-radius: 10rpx;
}
&-desc {
padding-left: 30rpx;
&-name {
font-weight: bold;
font-size: 36rpx;
transform: translateY(-10rpx);
color: #000000;
}
&-gray {
color: #757575;
font-size: 32rpx;
font-weight: 420rpx;
}
}
}
</style>
<style>
page{
background-color: #eeeeee;
}
</style>
+80
View File
@@ -0,0 +1,80 @@
<template>
<view>
<u-navbar :is-back="true"
back-icon-color="#ffffff"
title="摇一摇"
:background="{ background: '#101010'}"
title-color="#ffffff"
:title-bold="true"
title-size="34"
:border-bottom="false"
z-index="1001">
<view slot="right" class="u-p-r-30" @click="toSet()">
<u-icon name="more-dot-fill" color="#ffffff" :size="36"></u-icon>
</view>
</u-navbar>
<view class="u-flex u-row-center u-col-center" style="padding-top: 60%;">
<view>
<u-image src="/static/image/wx/yaoyiyao-1.jpg" :width="200" :height="200"></u-image>
</view>
</view>
<view class="footer-box u-flex u-row-around u-col-center">
<view @click="activeTab=0">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image v-if="activeTab==0" src="/static/image/wx/yaoyiyao-2.jpg" :width="48" :height="48"></u-image>
<u-image v-if="activeTab==1" src="/static/image/wx/yaoyiyao-b.jpg" :width="48" :height="48"></u-image>
</view>
</view>
<view class="u-m-t-8" :style="activeTab==1?'color:#595959;':''">
<text></text>
</view>
</view>
<view @click="activeTab=1">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image v-if="activeTab==0" src="/static/image/wx/yaoyiyao-3.jpg" :width="48" :height="48"></u-image>
<u-image v-if="activeTab==1" src="/static/image/wx/yaoyiyao-c.jpg" :width="48" :height="48"></u-image>
</view>
</view>
<view class="u-m-t-8" :style="activeTab==0?'color:#595959;':''">
<text>歌曲和哼唱</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
activeTab:0,
};
},
methods:{
toSet:function(){
console.log("去摇一摇设置");
uni.$u.route("/pages/find/shake/set");
}
}
}
</script>
<style lang="scss" scoped>
.footer-box{
color: #ffffff;
width: 100%;
position: absolute;
bottom: 80rpx;
padding: 20rpx 100rpx;
text-align: center;
font-size: 22rpx;
}
</style>
<style>
page{
background-color: #101010;
}
</style>
+139
View File
@@ -0,0 +1,139 @@
<template>
<view>
<u-navbar :is-back="true"
back-icon-color="#333333"
title="打招呼的人"
:background="{ background: '#f0f0f0'}"
title-color="#000000"
:title-bold="true"
title-size="34"
:border-bottom="false"
z-index="1001">
<view slot="right" class="u-p-r-30 u-font-34" @click="clear()">
<text :style="linkedUsers.length<1?'color:#909399;':'color:#000000'">清空</text>
</view>
</u-navbar>
<view class="u-p-30">
<view v-if="linkedUsers.length>0">
<view class="u-p-b-20">
<text>近三天</text>
</view>
<view v-for="(user,uIndex) in linkedUsers" :key="uIndex"
class="u-flex u-row-left u-col-center u-p-b-12">
<view style="width:100rpx;" class="u-flex u-row-left u-col-center">
<view @longpress="delUser(user,uIndex)">
<u-image :src="user.avatar" :width="76" :height="76" border-radius="8rpx">
<view slot="error"
class="u-flex u-row-center u-col-center u-p-t-10 "
style="width: 76rpx;height: 76rpx;background-color: #f0f0f0;border-radius: 12rpx;">
<view>
<image src="/static/image/default/default-user/default-user.png"
style="width: 40rpx;height: 40rpx;"></image>
</view>
</view>
</u-image>
</view>
</view>
<view @click="toPersonInfo(user)"
style="width: 600rpx;"
class="u-flex u-row-between u-col-center u-p-t-6 u-p-b-12 u-border-bottom">
<view style="text-align: left;">
<view class="u-line-1" style="font-size: 32rpx;color: #000000;">
<text>{{user.nickName}}</text>
</view>
<view class="u-tips-color u-font-28">
<text>{{user.userRemark}}</text>
</view>
</view>
<template v-if="!idAdd(user)">
<view style="background-color: #f0f0f0;color: #000000;padding: 10rpx 20rpx;border-radius: 6rpx;text-align: center;font-size: 30rpx;">
<text>查看</text>
</view>
</template>
<template v-else>
<view class="u-font-28" style="position:relative;top: -16rpx;color: #595b5f;">
<text>已添加</text>
</view>
</template>
</view>
</view>
</view>
<view v-else style="padding-top: 40%;">
<view style="text-align: center;color: #000000;font-size: 34rpx;">
<text>暂时没有人向你打招呼</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
linkedUsers:[],
};
},
onLoad:function(){
this.linkedUsers=JSON.parse(JSON.stringify(this.vuex_linkedUsers));
},
methods:{
idAdd:function(user){
let that=this;
if(that.vuex_yyyFriendList.length<1){
return false;
}else{
for (var i = 0; i < that.vuex_yyyFriendList.length; i++) {
let item= that.vuex_yyyFriendList[i];
if(item.chatNumber==user.chatNumber){
return true;
}
}
}
return false;
},
clear:function(){
this.$u.vuex("vuex_linkedUsers",[]);
this.$u.vuex("vuex_yyyFriendList",[]);
this.$u.vuex("vuex_lastestZhuanFaUsers",[]);
this.$u.vuex("yyy_current_user",null);
this.linkedUsers=[];
},
toPersonInfo:function(user){
let that=this;
that.$u.vuex("yyy_current_user",user);
this.$u.route({
url:'/pages/tabbar/find/yaoyiyao/yaoyiyao-user-detail',
});
},
delUser:function(user,index){
let that=this;
uni.showModal({
title: '操作',
content: user.sendTimeStr,
cancelText:'删除',
confirmText:'修改时间',
editable:true,
success: function (res) {
if (res.confirm) {
let newTime=res.content;
if(newTime.length>0){
that.linkedUsers[index].sendTimeStr=newTime;
that.$u.vuex("vuex_linkedUsers",that.linkedUsers);
}
return;
} else if (res.cancel) {
that.linkedUsers.splice(index,1);
that.$u.vuex("vuex_linkedUsers",that.linkedUsers);
}
}
});
}
}
}
</script>
<style lang="scss">
</style>
+454
View File
@@ -0,0 +1,454 @@
<template>
<view>
<u-navbar :is-back="true"
back-icon-color="#333333"
title="摇一摇设置"
:background="{ background: '#f0f0f0'}"
title-color="#000000"
:title-bold="true"
title-size="34"
:border-bottom="false"
z-index="1001">
</u-navbar>
<view>
<u-cell-group>
<u-cell-item @click="showNewUserPop()" title="背景图片" :title-style="titleStyle"></u-cell-item>
<u-cell-item title="音效" :title-style="titleStyle" :arrow="false">
<u-switch slot="right-icon" size="48" active-color="#19BE6B" v-model="checked"></u-switch>
</u-cell-item>
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
<u-cell-item title="打招呼的人" :title-style="titleStyle" @click="toLinkedList()"></u-cell-item>
<u-cell-item title="摇到的历史" @click="addAndUpdate()" :title-style="titleStyle"></u-cell-item>
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
<u-cell-item title="摇一摇信息" :title-style="titleStyle" @click="toSetLatestUsers()"></u-cell-item>
</u-cell-group>
</view>
<u-popup v-model="newLatestFlag" mode="right"
safe-area-inset-bottom
:mask-close-able="false"
length="100%">
<scroll-view class="u-p-30 u-p-t-80" scroll-y="true" style="height:85%;width: 700rpx;">
<view>
<u-collapse :head-style="{borderBottom:'1rpx solid #909399'}">
<u-collapse-item :title="'第'+(index+1)+'位'"
v-for="(newUser,index) in lastestZhuanFaUsers"
:key="index">
<view style="border: 1rpx solid #595b5f;padding: 10rpx 20rpx;">
<u-form :model="newUser" :ref="'newUser-'+index"
label-width="300rpx"
label-position="top">
<u-form-item label="姓名">
<u-input v-model="newUser.nickName" />
</u-form-item>
<u-form-item label="微信号">
<u-input v-model="newUser.chatNumber" />
</u-form-item>
<u-form-item label="头像">
<u-input type="textarea" v-model="newUser.avatar" />
</u-form-item>
</u-form>
</view>
</u-collapse-item>
</u-collapse>
</view>
</scroll-view>
<view class="u-flex u-row-between u-col-center u-p-30">
<u-button @click="addNewLatestUserItem()">新增</u-button>
<u-button v-if="lastestZhuanFaUsers.length>1" @click="delNewLatestUser()">删除</u-button>
<u-button type="success" @click="submitAddLatestUsers()">确定</u-button>
</view>
</u-popup>
<u-popup v-model="addAndUpdateFlag" mode="right"
safe-area-inset-bottom
:mask-close-able="false"
length="100%">
<scroll-view class="u-p-30 u-p-t-80" scroll-y="true" style="height:85%;width: 700rpx;">
<view>
<u-collapse :head-style="{borderBottom:'1rpx solid #909399'}">
<u-collapse-item :title="'第'+(index+1)+'位'"
v-for="(newUser,index) in newUsers"
:key="index">
<view style="border: 1rpx solid #595b5f;padding: 10rpx 20rpx;">
<u-form :model="newUser" :ref="'newUser-'+index"
label-width="300rpx"
label-position="top">
<u-form-item label="姓名">
<u-input :maxlength="-1" v-model="newUser.nickName" />
</u-form-item>
<u-form-item label="微信号">
<u-input :maxlength="-1" placeholder="不能与其他重复!" v-model="newUser.chatNumber" />
</u-form-item>
<u-form-item label="头像">
<u-input :maxlength="-1" type="textarea" v-model="newUser.avatar" />
</u-form-item>
<u-form-item label="地区(注意空格)">
<u-input :maxlength="-1" placeholder="注意格式,如: 广东 广州" v-model="newUser.address" />
</u-form-item>
<u-form-item label="个性签名">
<u-input :maxlength="-1" v-model="newUser.signature" />
</u-form-item>
<u-form-item label="给你打招呼的内容">
<u-input :maxlength="-1" type="textarea" v-model="newUser.userRemark" />
</u-form-item>
<u-form-item label="给你打招呼的时间">
<u-input :maxlength="-1" placeholder="注意格式,如: 22:30" v-model="newUser.createTime" />
</u-form-item>
<u-form-item label="你通过好友时间">
<u-input :maxlength="-1" placeholder="注意格式,如: 22:35" v-model="newUser.sendTimeStr" />
</u-form-item>
<u-form-item label="第一条朋友圈">
<u-input type="textarea" :maxlength="-1" v-model="newUser.friendCircle[0]" />
</u-form-item>
<u-form-item label="第二条朋友圈">
<u-input type="textarea" :maxlength="-1" v-model="newUser.friendCircle[1]" />
</u-form-item>
<u-form-item label="第三条朋友圈">
<u-input type="textarea" :maxlength="-1" v-model="newUser.friendCircle[2]" />
</u-form-item>
</u-form>
</view>
</u-collapse-item>
</u-collapse>
</view>
</scroll-view>
<view class="u-flex u-row-between u-col-center u-p-30">
<u-button @click="addNewUserItem()">新增</u-button>
<u-button v-if="newUsers.length>1" @click="delNewUser()">删除</u-button>
<u-button type="success" @click="submitAddUsers()">确定</u-button>
</view>
</u-popup>
<u-popup v-model="newUserPopFlag" mode="right"
safe-area-inset-bottom
:mask-close-able="false"
length="100%">
<view style="padding-top:15%;">
<view class="u-border-top">
<u-field v-model="count"
type="number"
label="本次录入数量" label-width="200rpx"
placeholder="录入数量,建议5-10个"></u-field>
</view>
<view v-if="count<1" class="u-p-30 u-font-32" style="font-weight: bold;">
<view>填入数量决定了下面录入的每项信息的数量 !!!</view>
<view class="u-m-t-10">比如5个,那么必须填入5个人的信息,每个用%%隔开 ! </view>
<view class="u-m-t-10">不能多! 也不能少! 没有信息的填0 !</view>
<view>地址为例: "广东 广州,0,湖北 武汉,四川 城都,福建 厦门" </view>
</view>
</view>
<view v-if="count>0">
<scroll-view class="u-p-30 u-p-t-80"
scroll-y="true" style="height:80%;width: 700rpx;">
<view style="padding:10rpx 20rpx;">
<u-form :model="propArrObj" :border-bottom="false"
label-width="300rpx"
label-position="top">
<u-form-item label="姓名">
<u-input placeholder="格式: (张三%%李四%%王五)"
type="textarea" :maxlength="-1"
:height="300" border
v-model="propArrObj.nickNameStr" />
</u-form-item>
<u-form-item label="微信号">
<u-input placeholder="格式: (666666%%aaaaaa%%zzzzzz)"
type="textarea" :maxlength="-1"
:height="200" border
v-model="propArrObj.chatNumberStr" />
</u-form-item>
<u-form-item label="头像">
<u-input placeholder="格式: (xxx.jpg%%yyy.jpg%%%zzz%%jpg)"
type="textarea" :maxlength="-1"
:height="300" border
v-model="propArrObj.avatarStr" />
</u-form-item>
<u-form-item label="个性签名">
<u-input placeholder="格式: (哈哈哈%%嘻嘻嘻%%哇哇哇)"
type="textarea" :maxlength="-1"
:height="200" border
v-model="propArrObj.signatureStr" />
</u-form-item>
<u-form-item label="打招呼的内容">
<u-input placeholder="格式: (哈喽%%你好%%hello)"
type="textarea" :maxlength="-1"
:height="200" border
v-model="propArrObj.userRemarkStr" />
</u-form-item>
<u-form-item label="地址">
<u-input placeholder="每个值用%%隔开!没有地址的用0代替"
type="textarea" :maxlength="-1"
:height="100" border
v-model="propArrObj.addressStr" />
</u-form-item>
<u-form-item label="打招呼时间">
<u-input placeholder="格式: (12:01%%12:02%%12:03)"
type="textarea" :maxlength="-1"
:height="100" border
v-model="propArrObj.createTimeStr" />
</u-form-item>
<u-form-item label="加好友时间">
<u-input placeholder="格式: (12:01%%12:02%%12:03)"
type="textarea" :maxlength="-1"
:height="100" border
v-model="propArrObj.sendTimeStr" />
</u-form-item>
<u-form-item label="朋友圈">
<u-input placeholder="格式: ([xxx.jpg%%yyy.jpg,zzz.jpg]%%[111.jpg,222.jpg]%%[]%%[333.jpg])"
type="textarea" :maxlength="-1"
:height="300" border
v-model="propArrObj.friendCircleStr" />
</u-form-item>
</u-form>
</view>
</scroll-view>
<view class="u-flex u-row-between u-col-center u-p-30">
<u-button @click="cancelAdd()">取消</u-button>
<u-button type="success" @click="submitAdd()">确定</u-button>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
titleStyle:{
fontSize:"34rpx",
color:'#000000'
},
linkedUsers:[], //摇一摇的人
addAndUpdateFlag:false, //新增
newUsers:[
{
id:new Date().getTime(),
avatar:'',
chatNumber:'',
nickName:'',
signature:'',
userRemark:'',
address:'',
sex:0,
friendPower:0,
forbidSelf:false,
forbidHis:false,
createTime:"",
sendTimeStr:"",
lastMsgContent:'',
delFlag:false,
friendCircle:["","",""],
messageList:[],
},
],
checked:true,
newLatestFlag:false,
lastestZhuanFaUsers:[
{
id:'1',
avatar:'/static/image/default/default-user/1.jpg',
chatNumber:'qwe',
nickName:'猫先生',
}
],
//--------------------------------------
newUserPopFlag:false,
count:5,
propArrObj:{
nickNameStr:"",
chatNumberStr:"",
avatarStr:"",
signatureStr:"",
userRemarkStr:"",
addressStr:"",
createTimeStr:"",
sendTimeStr:"",
friendCircleStr:"",
}
};
},
methods:{
toSetLatestUsers:function(){
if(this.vuex_lastestZhuanFaUsers.length>0){
this.lastestZhuanFaUsers=JSON.parse(JSON.stringify(this.vuex_lastestZhuanFaUsers));
}
this.newLatestFlag=true;
},
addNewLatestUserItem:function(){
let obj={
id:new Date().getTime(),
avatar:'',
chatNumber:'',
nickName:'',
};
this.lastestZhuanFaUsers.push(obj);
},
delNewLatestUser:function(){
this.lastestZhuanFaUsers.splice(this.lastestZhuanFaUsers.length-1,1);
},
submitAddLatestUsers:function(){
let that=this;
this.$u.vuex("vuex_lastestZhuanFaUsers",this.lastestZhuanFaUsers);
this.newLatestFlag=false;
},
addAndUpdate:function(){
let that=this;
that.addAndUpdateFlag=true
},
addNewUserItem:function(){
let oldObj= this.newUsers[this.newUsers.length-1];
let obj={
id:new Date().getTime(),
avatar:'',
chatNumber:'',
nickName:'',
signature:'',
userRemark:'',
address:'',
sex:0,
friendPower:0,
forbidSelf:false,
forbidHis:false,
createTime:oldObj.createTime,
sendTimeStr:oldObj.sendTimeStr,
lastMsgContent:'',
delFlag:false,
friendCircle:["","",""],
messageList:[],
};
//this.newUsers.push(obj);
this.newUsers.unshift(obj);
},
delNewUser:function(){
this.newUsers.splice(this.newUsers.length-1,1);
},
submitAddUsers:function(){
let that=this;
uni.showModal({
title: '确认提示',
content: '请认真检查各项填入内容!',
success: function (res) {
if (res.confirm) {
that.addAndUpdateFlag = false;
that.linkedUsers=that.newUsers.concat(that.linkedUsers);
that.newUsers=[
{
id:new Date().getTime(),
avatar:'',
chatNumber:'',
nickName:'',
signature:'',
userRemark:'',
address:'',
sex:0,
friendPower:0,
forbidSelf:false,
forbidHis:false,
createTime:'',
sendTimeStr:'',
lastMsgContent:'',
delFlag:false,
friendCircle:["","",""],
messageList:[],
},
]
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
toLinkedList:function(){
let arr=JSON.parse(JSON.stringify(this.vuex_linkedUsers));
let newLinkedUsers=this.linkedUsers.concat(arr);
console.log("去摇一摇设置",newLinkedUsers);
this.$u.vuex("vuex_linkedUsers",newLinkedUsers);
this.linkedUsers=[];
this.$u.route("/pages/tabbar/find/yaoyiyao/yaoyiyao-linked-list");
},
//------------------------------------------------------------------------------------------------
showNewUserPop:function(){
this.newUserPopFlag=true;
},
cancelAdd:function(){
this.newUserPopFlag=false;
},
submitAdd:function(){
let that=this;
let keys= Object.keys(that.propArrObj);
for (let i = 0; i < keys.length; i++) {
let key= keys[i];
let keyValue= that.propArrObj[key];
let valueArr= keyValue.split("%%");
if(valueArr.length!=that.count){
this.globalUtil.utilAlert("第"+(i+1)+"项录入信息有误!["+key+"]");
return;
}
}
that.muchCreateUser();
},
muchCreateUser(){
let that=this;
let arr=[];
for (var i = 0; i < this.count; i++) {
let item={
id:"u-"+i,
avatar:that.propArrObj.avatarStr.split("%%")[i],
chatNumber:that.propArrObj.chatNumberStr.split("%%")[i],
nickName:that.propArrObj.nickNameStr.split("%%")[i],
signature:that.propArrObj.signatureStr.split("%%")[i],
userRemark:that.propArrObj.userRemarkStr.split("%%")[i],
address:that.propArrObj.addressStr.split("%%")[i],
createTime:that.propArrObj.createTimeStr.split("%%")[i],
sendTimeStr:that.propArrObj.sendTimeStr.split("%%")[i],
friendCircle:that.propArrObj.friendCircleStr.split("%%")[i],
lastMsgContent:"",
messageList:[],
sex:0,
friendPower:0,
forbidSelf:false,
forbidHis:false,
delFlag:false,
};
arr.push(item);
}
console.log("====arr====",arr);
that.linkedUsers=arr.concat(that.linkedUsers);
this.count=0;
this.propArrObj={
avatarStr:"",
chatNumberStr:"",
nickNameStr:"",
signatureStr:"",
userRemarkStr:"",
addressStr:"",
createTimeStr:"",
sendTimeStr:"",
friendCircleStr:"",
};
that.newUserPopFlag=false;
}
}
}
</script>
<style lang="scss">
</style>
<style>
page{
background-color: #f0f0f0;
}
</style>
+138
View File
@@ -0,0 +1,138 @@
<template>
<view class="u-font-34">
<u-navbar :is-back="true" back-icon-color="#333333" title=""
:background="{ background: '#ffffff'}"
:border-bottom="false" z-index="1001">
<view slot="right" class="u-p-r-30">
<u-icon name="more-dot-fill" color="#000000" :size="38"></u-icon>
</view>
</u-navbar>
<view style="background-color: #ffffff;">
<view class="u-p-30 u-flex u-row-left u-col-center">
<view class="u-p-l-20">
<view>
<u-image :src="personInfo.avatar" width="120rpx" height="120rpx" border-radius="12rpx">
<view slot="error"
class="u-flex u-row-center u-col-center u-p-t-10"
style="width: 90rpx;height: 90rpx;background-color: #f1f1f1;border-radius: 12rpx;">
<view>
<image src="/static/image/default/default-user/default-user.png"
style="width: 64rpx;height: 64rpx;"></image>
</view>
</view>
</u-image>
</view>
</view>
<view class="u-m-l-30 u-p-t-20">
<view class="u-line-2" style="width: 350rpx;line-height: 40rpx;">
<text style="color: #000000;font-size: 44rpx;font-weight: bold;">{{personInfo.nickName}}</text>
<!-- <text></text> -->
</view>
<view v-if="personInfo.address&&personInfo.address!=0&&personInfo.address.length>0"
style="margin-top: 10rpx;color: #757575;font-size: 30rpx;">
<text>地区: </text>
<text>{{personInfo.address}}</text>
</view>
<view style="color: #2d5675;font-size: 32rpx;margin-top: 15rpx;">
<text class="u-m-r-30">备注名</text>
<text>朋友权限</text>
</view>
</view>
</view>
<view class="u-p-l-50 u-p-r-50 u-p-b-50 u-p-t-10">
<view style="font-size: 28rpx;border: 1rpx solid #909399;background-color: #f8f8f8;padding: 30rpx;border-radius: 6rpx;">
<view class="u-tips-color">
<text>{{personInfo.nickName}}: </text>
<text>{{personInfo.userRemark}}</text>
</view>
<view style="color: #2d5675;margin-top: 20rpx;">
<text>回复</text>
</view>
</view>
</view>
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
<view class="u-flex u-row-left u-col-center u-p-l-30 u-p-t-20 u-p-b-20">
<view class="u-m-r-30" style="width: 150rpx;text-align: left;">
<text>个性签名</text>
</view>
<view v-if="personInfo.signature&&personInfo.signature!=0&&personInfo.signature.length>0"
class="u-line-3" style="padding-right: 40rpx;width: 500rpx;color: #757575;">
<text>{{personInfo.signature}}</text>
</view>
</view>
<view class="u-p-l-30">
<u-gap height="1" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
</view>
<view class="u-flex u-row-left u-col-center u-p-l-30 u-p-t-20 u-p-b-20">
<view class="u-m-r-30" style="width: 150rpx;text-align: left;">
<text>来源</text>
</view>
<view class="u-line-3" style="padding-right: 40rpx;width: 500rpx;color: #757575;">
<text>对方通过摇一摇添加</text>
</view>
</view>
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
<view @click="toAgree()" style="text-align: center;padding: 30rpx;color: #2d5675;font-weight: bold;">
<text>前往验证</text>
</view>
</view>
<view class="footer-box u-flex u-row-center u-col-center">
<view>
<text>加入黑名单</text>
</view>
<view class="u-m-l-26 u-m-r-26">
<text>|</text>
</view>
<view>
<text>投诉</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
personInfo:null,
};
},
onLoad:function(option){
this.personInfo=this.yyy_current_user;
/* let param= option.personInfo;
if(param!=null&&param!=undefined){
this.personInfo=JSON.parse(decodeURIComponent(param));
} */
},
methods:{
toAgree:function(){
this.$u.route({
url:'/pages/tabbar/find/yaoyiyao/yaoyiyao-agree-apply-friend',
params:{
personInfo:encodeURIComponent(JSON.stringify(this.personInfo))
}
})
}
}
}
</script>
<style lang="scss" scoped>
.footer-box{
width: 100%;
position: absolute;
bottom: 80rpx;
padding: 20rpx 100rpx;
text-align: center;
font-size: 28rpx;
color: #2d5675;
}
</style>
<style>
page{
background-color: #f0f0f0;
}
</style>
+1 -1
View File
@@ -85,7 +85,7 @@
let system = uni.getSystemInfoSync(); let system = uni.getSystemInfoSync();
const _this = this; const _this = this;
plus.runtime.getProperty(plus.runtime.appid,(inf) => { plus.runtime.getProperty(plus.runtime.appid,(inf) => {
console.log(inf); //console.log(inf);
_this.appversion = inf.version _this.appversion = inf.version
}); });
}, },
+10
View File
@@ -72,6 +72,16 @@
], ],
}; };
}, },
// onShow() {
// const path = plus.io.convertLocalFileSystemURL('/storage/emulated/0/DCIM/Download/oceans.mp4');
// console.log('path:', path);
// const res1 = IMSDK.getVideoCover(path).then(res => {
// console.log('视频封面:', res);
// }).catch(err => {
// console.error('获取视频封面失败:', err);
// });
// console.log('res1:', res1);
// },
methods: { methods: {
...util, ...util,
copy() { copy() {
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

@@ -0,0 +1,186 @@
<template>
<view>
<view class="u-p-40" style="background-color: #ffffff;">
<view class="header u-border-bottom"
style="display: flex;flex-direction: column;justify-content: space-between;align-items: center;padding-bottom: 80rpx;">
<view>
<u-image width="100rpx" height="100rpx" src="./imgs/gaosu.jpg" shape="circle"></u-image>
</view>
<view style="font-size:17px;margin-top: 20rpx;margin-bottom: 26rpx;color: #000000;">{{target}}</view>
<view style="font-size: 28px;color: #000000;font-weight: bold;">{{tradeValue}}</view>
</view>
<view class="center u-p-t-20">
<view>
<u-field class="field-class" v-model="tradeStatus" label="当前状态" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-18">
<u-field class="field-class" v-model="goodName" label="商品" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="company" label="收单机构" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="settleCompany" label="清算机构" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="paytime" label="支付时间" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="payway" label="支付方式" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-m-t-16">
<u-field class="field-class" v-model="tradeDesc" label="支付说明" :label-width="160"
:field-style="fieldTextareaStyle" type="textarea" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
<view style="margin-top: -20rpx;">
<view>
<u-field class="field-class" v-model="tradeCode" label="交易单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-30">
<u-field class="field-class" v-model="shanghu" label="商户单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
</view>
<view class="u-text-center u-m-t-20 u-m-b-30">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image src="./imgs/tiao-code.jpg" height="150rpx" width="480rpx" mode="aspectFill"></u-image>
</view>
</view>
<view>
<text>{{shanghuCode}}</text>
</view>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>账单服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="question-circle" color="#818ba4" label="对订单有疑惑" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="32" name="coupon" color="#818ba4" label="开发票" label-color="#818ba4" margin-left="12"
label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 ">
<view class="">
<u-icon size="32" name="order" color="#818ba4" label="在此商户的交易" label-color="#818ba4"
margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
</view>
</view>
<!-- position: absolute;bottom: 50rpx; -->
<view style="width: 100%;text-align:center;padding:50rpx;color:#909399;">
<text>本服务由财付通提供</text>
</view>
</view>
</template>
<script>
export default {
props:{
recordData:{
required:true,
type:Object,
default:function(){
return null
}
}
},
data() {
return {
fieldStyle: {
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
},
fieldTextareaStyle: {
width:'400rpx',
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
marginBottom:'0rpx',
},
tradeStatus: '支付成功',
paytime: '2022年9月30日20:01:29',
goodName: '高速通行费',
company: '辽宁省高速公路运营管理有限责任公司',
settleCompany: '财付通支付科技有限公司',
payway: '交通银行储蓄卡(7961)',
tradeDesc: '优先支付方式零钱扣款失败,已自动更换支付方式完成支付',
tradeCode: '4200067662202209303339833402',
shanghu:'可在支持的商户扫码退款',
shanghuCode: '893226056885035008',
tradeValue: '-40.00',
target: '辽宁高速'
};
},
mounted(){
console.log("辽宁高速数据",this.recordData);
this.tradeValue="-"+Number(this.recordData.tradeValue).toFixed(2);
this.paytime=this.formatTimeStr(this.recordData.createTime);
if(this.recordData.tradeValue==61){
this.paytime="2023年9月29日 22:09:10";
this.shanghuCode="893226056885031992";
this.tradeCode="4200067662202209303259866205";
}
},
methods:{
formatTimeStr:function(timeStr){
timeStr=timeStr.replace(/-/g,"/");
let cdate=new Date(timeStr);
let year=cdate.getFullYear();
let yearStr=year+"年";
let month= cdate.getMonth()+1;
let day=cdate.getDate();
let hour= cdate.getHours();
let min=cdate.getMinutes();
let s=cdate.getSeconds();
let monthStr=month+"月";
let dayStr=day+"日";
let hourStr=hour+":";
let minStr=min+":";
let sStr=s;
if(hour<10){
hourStr="0"+hour+":";
}
if(min<10){
minStr="0"+min+":";
}
if(s<10){
sStr="0"+s;
}
let formatStr=yearStr+monthStr+dayStr+" "+hourStr+minStr+sStr;
return formatStr;
},
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
@@ -0,0 +1,148 @@
<template>
<view>
<view class="u-p-40" style="background-color: #ffffff;">
<view class="header u-border-bottom"
style="display: flex;flex-direction: column;justify-content: space-between;align-items: center;padding-bottom: 80rpx;">
<view>
<u-image width="100rpx" height="100rpx" src="/static/image/mt.jpg"
shape="circle"></u-image>
</view>
<view style="font-size:17px;margin-top: 20rpx;margin-bottom: 26rpx;color: #000000;">{{target}}</view>
<view style="font-size: 28px;color: #000000;font-weight: bold;">{{tradeValue}}</view>
</view>
<view class="center u-p-t-20">
<view>
<u-field class="field-class" v-model="tradeStatus" label="当前状态" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="paytime" label="支付时间" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-18">
<u-field class="field-class" v-model="goodName" label="商品" :label-width="160"
:field-style="fieldStyle" type="text" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="company" label="商户全称" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="settleCompany" label="收单机构" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
<view style="padding-left: 165rpx;color: #909399;">
<text>由网联清算有限公司提供收款清算服务</text>
</view>
</view>
<view>
<u-field class="field-class" v-model="payway" label="支付方式" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="tradeCode" label="交易单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-30">
<u-field class="field-class" v-model="shanghu" label="商户单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
<view class="u-text-center u-m-t-20 u-m-b-30">
<view class="u-flex u-row-center u-col-center">
<view>
<u-image src="./imgs/tiao-code.jpg" height="150rpx" width="480rpx" mode="aspectFill"></u-image>
</view>
</view>
<view>
<text>{{shanghuCode}}</text>
</view>
</view>
</view>
</view>
<!-- <view class="u-m-t-20 u-p-40 u-flex u-row-between u-col-center"
style="background-color: #ffffff;font-size: 30rpx;">
<view>商家小程序</view>
<view class="u-flex u-row-between u-col-center">
<view class="u-flex u-row-left u-col-center">
<view class="u-m-r-10">
<u-image width="36rpx" height="36rpx" src="/static/image/xiaochengxu.png"></u-image>
</view>
<view style="color: #909399;">
<view class="u-flex u-row-left u-col-center">
<view><text>美团</text></view>
<view class="u-m-r-10 u-m-l-10">
<u-line color="#909399" direction="col" length="30rpx" />
</view>
<view>
<view>外卖美食买菜酒店电影</view>
</view>
</view>
<view>购物</view>
</view>
</view>
<view class="u-m-l-30">
<u-icon name="arrow-right" color="#909399" size="30"></u-icon>
</view>
</view>
</view> -->
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>账单服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="question-circle" color="#818ba4" label="对订单有疑惑" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="32" name="order" color="#818ba4" label="在此商户的交易" label-color="#818ba4"
margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
</view>
<view style="width: 100%;text-align:center;padding:50rpx;color:#909399;">
<text>本服务由财付通提供</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
fieldStyle: {
//width:'460rpx',
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
},
tradeStatus: '支付成功',
goodName: '美团收银909700180095643047',
company: '商户_李敏',
settleCompany: '北京钱袋宝支付技术有限公司',
paytime: '2022年9月30日 12:50:56',
payway: '零钱',
tradeCode: '4200066259202209304888262262',
shanghu:'可在支持的商户扫码退款',
shanghuCode: '0461368604225767873608013',
tradeValue: '-74.08',
target: '万象三顾冒菜'
};
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
@@ -0,0 +1,152 @@
<template>
<view>
<view class="u-p-40" style="background-color: #ffffff;">
<view class="header u-border-bottom"
style="display: flex;flex-direction: column;justify-content: space-between;align-items: center;padding-bottom: 80rpx;">
<view>
<u-image width="100rpx" height="100rpx" src="/static/image/mycenter/default-record-icon.jpg"
shape="circle"></u-image>
</view>
<view style="font-size:17px;margin-top: 20rpx;margin-bottom: 26rpx;color: #000000;">
{{target}}
</view>
<view style="font-size: 28px;color: #000000;font-weight: bold;">{{tradeValue}}</view>
</view>
<view class="center u-p-t-20">
<view>
<u-field class="field-class" v-model="tradeStatus" label="当前状态" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="receiveRemark" label="收款方备注" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="transferWay" label="支付方式" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="transferTime" label="转账时间" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="transferCode" label="转账单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>账单服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="question-circle" color="#818ba4" label="对订单有疑惑" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="22" name="/static/image/bill/shoukuan.png" color="#818ba4" label="发起群收款"
label-color="#818ba4" margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
</view>
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>收款方服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="/static/image/bill/minpian.png" color="#818ba4" label="收款方名片"
label-color="#818ba4" margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
</view>
<view style="width: 30rpx;"> </view>
</view>
</view>
<!-- <view style="width: 100%;text-align:center;padding:50rpx;color:#909399;">
<text>本服务由财付通提供</text>
</view> -->
</view>
</template>
<script>
export default {
props:{
recordData:{
required:true,
type:Object,
default:function(){
return null
}
}
},
data() {
return {
fieldStyle: {
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
},
target: '扫二维码付款-铁东区品江渔斑鱼火锅庄',
tradeValue: '-1500.00',
tradeStatus: '支付成功',
receiveRemark: '二维码收款',
transferWay: '零钱',
transferTime: '2022年09月29日20:02:11',
transferCode: '10000499012022092900281292669093'
};
},
mounted(){
console.log("扫码付款数据",this.recordData);
this.tradeValue="-"+Number(this.recordData.tradeValue).toFixed(2);
this.transferTime=this.formatTimeStr(this.recordData.createTime);
this.target=this.recordData.tradeTitle;
if(this.recordData.tradeValue==10){
this.transferTime="2023年9月30日 14:02:12";
this.transferCode="4200067662202209303259866205";
}
},
methods:{
formatTimeStr:function(timeStr){
timeStr=timeStr.replace(/-/g,"/");
let cdate=new Date(timeStr);
let year=cdate.getFullYear();
let yearStr=year+"年";
let month= cdate.getMonth()+1;
let day=cdate.getDate();
let hour= cdate.getHours();
let min=cdate.getMinutes();
let s=cdate.getSeconds();
let monthStr=month+"月";
let dayStr=day+"日";
let hourStr=hour+":";
let minStr=min+":";
let sStr=s;
if(hour<10){
hourStr="0"+hour+":";
}
if(min<10){
minStr="0"+min+":";
}
if(s<10){
sStr="0"+s;
}
let formatStr=yearStr+monthStr+dayStr+" "+hourStr+minStr+sStr;
return formatStr;
},
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
@@ -0,0 +1,125 @@
<template>
<view>
<view class="u-p-40" style="background-color: #ffffff;">
<view class="header u-border-bottom"
style="display: flex;flex-direction: column;justify-content: space-between;align-items: center;padding-bottom: 80rpx;">
<view>
<u-image width="100rpx" height="100rpx" src="./imgs/shihua.jpg"
shape="circle"></u-image>
</view>
<view style="font-size:17px;margin-top: 20rpx;margin-bottom: 26rpx;color: #000000;">{{target}}</view>
<view style="font-size: 28px;color: #000000;font-weight: bold;">{{tradeValue}}</view>
</view>
<view class="center u-p-t-20">
<view>
<u-field class="field-class" v-model="tradeStatus" label="当前状态" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="paytime" label="支付时间" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-18">
<u-field class="field-class" v-model="goodName" label="商品" :label-width="160"
:field-style="fieldStyle" type="text" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="company" label="商户全称" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="settleCompany" label="收单机构" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
<view style="padding-left: 165rpx;color: #909399;">
<text>由中国银联股份有限公司提供收款清算服务</text>
</view>
</view>
<view>
<u-field class="field-class" v-model="payway" label="支付方式" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="tradeCode" label="交易单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-30">
<u-field class="field-class" v-model="shanghuCode" label="商户单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40 u-flex u-row-between u-col-center"
style="background-color: #ffffff;font-size: 30rpx;">
<view class="u-flex u-row-left u-col-center">
<view>商家订单中心</view>
<view style="margin-left: 30rpx;background-color: #f04131;color: #ffffff;border-radius: 30rpx;padding: 5rpx 18rpx;">
<text>NEW</text>
</view>
</view>
<view>
<view class="u-m-l-30">
<u-icon name="arrow-right" color="#909399" size="30"></u-icon>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>账单服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="question-circle" color="#818ba4" label="对订单有疑惑" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="32" name="order" color="#818ba4" label="在此商户的交易" label-color="#818ba4"
margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
</view>
<view style="width: 100%;text-align:center;padding:50rpx;color:#909399;">
<text>本服务由财付通提供</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
fieldStyle: {
//width:'460rpx',
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
},
tradeStatus: '支付成功',
goodName: '智慧U站215元',
company: '鞍山市中金石油经销有限公司',
settleCompany: '汇元银通(北京)在线支付技术有限公司',
paytime: '2022年9月30日18:36:09',
payway: '交通银行储蓄卡(7961)',
tradeCode: '4200001559202209307401263465',
shanghuCode: '40822093001788196557',
tradeValue: '-215.00',
target: '亚孚石化中金站'
};
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
@@ -0,0 +1,127 @@
<template>
<view>
<view class="u-p-40" style="background-color: #ffffff;">
<view class="header u-border-bottom"
style="display: flex;flex-direction: column;justify-content: space-between;align-items: center;padding-bottom: 80rpx;">
<view>
<u-image width="100rpx" height="100rpx" src="./imgs/xinrun.jpg"
shape="circle"></u-image>
</view>
<view style="font-size:17px;margin-top: 20rpx;margin-bottom: 26rpx;color: #000000;">{{target}}</view>
<view style="font-size: 28px;color: #000000;font-weight: bold;">{{tradeValue}}</view>
</view>
<view class="center u-p-t-20">
<view>
<u-field class="field-class" v-model="tradeStatus" label="当前状态" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="paytime" label="支付时间" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-18">
<u-field class="field-class" v-model="goodName" label="商品" :label-width="160"
:field-style="fieldStyle" type="text" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="company" label="商户全称" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="settleCompany" label="收单机构" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="payway" label="支付方式" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="tradeCode" label="交易单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view class="u-p-r-30">
<u-field class="field-class" v-model="shanghuCode" label="商户单号" :label-width="160"
:field-style="fieldStyle" type="textarea" :border-bottom="false" :clearable="false"
placeholder=" "></u-field>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40 u-flex u-row-between u-col-center"
style="background-color: #ffffff;font-size: 30rpx;">
<view>商家小程序</view>
<view class="u-flex u-row-between u-col-center">
<view class="u-flex u-row-left u-col-center">
<view class="u-m-r-10">
<u-image width="36rpx" height="36rpx" src="/static/image/xiaochengxu.png"></u-image>
</view>
<view style="color: #909399;">
<view class="u-flex u-row-left u-col-center">
<view><text>润欣商业发展鞍山有限公司</text></view>
</view>
</view>
</view>
<view class="u-m-l-30">
<u-icon name="arrow-right" color="#909399" size="30"></u-icon>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>账单服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="question-circle" color="#818ba4" label="对订单有疑惑" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="32" name="order" color="#818ba4" label="在此商户的交易" label-color="#818ba4"
margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
</view>
<view style="width: 100%;text-align:center;padding:50rpx;color:#909399;">
<text>本服务由财付通提供</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
fieldStyle: {
//width:'460rpx',
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
},
tradeStatus: '支付成功',
goodName: '小程序-停车场支付',
company: '润欣商业发展(鞍山) 有限公司',
settleCompany: '财付通支付科技有限公司',
paytime: '2022年9月30日13:33:13',
payway: '零钱',
tradeCode: '4200001569202209306188471713',
shanghuCode: 'ASTCWX16645159870220d5eb1578fe70',
tradeValue: '-8.00',
target: '润欣商业发展 (鞍山) 有限公司'
};
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
@@ -0,0 +1,110 @@
<template>
<view>
<view class="u-p-40" style="background-color: #ffffff;">
<view class="header u-border-bottom"
style="display: flex;flex-direction: column;justify-content: space-between;align-items: center;padding-bottom: 80rpx;">
<view>
<u-image width="100rpx" height="100rpx" :src="recordData.tradeIcon"
shape="circle"></u-image>
</view>
<view style="font-size:17px;margin-top: 20rpx;margin-bottom: 26rpx;color: #000000;">
{{target}}
</view>
<view style="font-size: 28px;color: #000000;font-weight: bold;">{{tradeValue}}</view>
</view>
<view class="center u-p-t-20">
<view>
<u-field class="field-class" v-model="tradeStatus" label="当前状态" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="receiveRemark" label="转账说明" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="transferTime" label="转账时间" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="transferWay" label="支付方式" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
<view>
<u-field class="field-class" v-model="transferCode" label="转账单号" :label-width="160"
:field-style="fieldStyle" :border-bottom="false" :clearable="false" placeholder=" "></u-field>
</view>
</view>
</view>
<view class="u-m-t-20 u-p-40" style="background-color: #ffffff;font-size: 30rpx;">
<view style="padding-bottom: 30rpx;">
<text>账单服务</text>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30 u-border-top">
<view>
<u-icon size="32" name="question-circle" color="#818ba4" label="对订单有疑惑" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="34" name="chat" color="#818ba4" label="定位到聊天位置"
label-color="#818ba4" margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
<view class="u-flex u-row-between u-col-center u-p-t-30">
<view>
<u-icon size="32" name="star" color="#818ba4" label="申请转账电子凭证" label-color="#818ba4"
margin-left="12" top="4" label-size="30" label-pos="right"></u-icon>
</view>
<view class="">
<u-icon size="34" name="rmb-circle" color="#818ba4" label="查看往来转账"
label-color="#818ba4" margin-left="12" label-size="30" label-pos="right"></u-icon>
</view>
<view style="width: 30rpx;"> </view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
recordData:{
required:true,
type:Object,
default:function(){
return null
}
}
},
data() {
return {
fieldStyle: {
color: '#000000',
padding: '0rpx',
margin: '0rpx',
height: '70rpx',
},
target: '转账-转给祁晶 华润质量',
tradeValue: '-1800.00',
tradeStatus: '对方已收钱',
receiveRemark: '微信转账',
transferWay: '交通银行储蓄卡(7961)',
transferTime: '2022年9月30日11:04:09',
transferCode: '1000050001202209300712408714345'
};
},
mounted(){
console.log("转账付款数据",this.recordData);
this.target=this.recordData.tradeTitle;
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
+74
View File
@@ -0,0 +1,74 @@
<template>
<view>
<u-navbar :is-back="true" title=" " :title-bold="true" :title-size="34" :background="{ background: '#ffffff'}"
back-icon-name="close" back-icon-size="32" title-color="#404133" :border-bottom="false">
</u-navbar>
<template v-if="recordData.tradeTitle.indexOf('辽宁高速')!=-1">
<liaoning-gaosu :recordData="recordData"></liaoning-gaosu>
</template>
<template v-else-if="recordData.tradeTitle.indexOf('三顾冒菜')!=-1">
<sangumaocai></sangumaocai>
</template>
<template v-else-if="recordData.tradeTitle.indexOf('亚孚石化')!=-1">
<shihua></shihua>
</template>
<template v-else-if="recordData.tradeTitle.indexOf('润欣')!=-1">
<xinrun></xinrun>
</template>
<template v-else-if="recordData.tradeTitle.indexOf('转账')!=-1">
<zhuanzhang :recordData="recordData"></zhuanzhang>
<view style="width: 100%;text-align:center;padding:50rpx;color:#909399;position: absolute;bottom: 50rpx;">
<text>本服务由财付通提供</text>
</view>
</template>
<!-- v-if="recordData.tradeTitle.indexOf('扫二维码')!=-1" -->
<template v-else>
<saoma :recordData="recordData"></saoma>
<view style="width: 100%;text-align:center;padding:50rpx;color:#909399;position: absolute;bottom: 50rpx;">
<text>本服务由财付通提供</text>
</view>
</template>
</view>
</template>
<script>
import saoma from './components/saoma.vue';
import liaoningGaosu from './components/liaoning-gaosu.vue';
import sangumaocai from './components/sangumaocai.vue';
import shihua from './components/shihua.vue';
import xinrun from './components/xinrunshangye.vue';
import zhuanzhang from './components/zhuanzhang.vue';
export default {
components:{
saoma,liaoningGaosu,sangumaocai,shihua,xinrun,zhuanzhang
},
data() {
return {
recordData:null,
};
},
onLoad(option) {
let that=this;
let paramVal= option.record;
if(paramVal!=null&&paramVal!=undefined&&paramVal.length>0){
that.recordData=JSON.parse(decodeURIComponent(paramVal));
console.log("recordData",that.recordData);
}
}
}
</script>
<style lang="scss" scoped>
.field-class {
color: #909399 !important;
font-size: 28rpx !important;
margin: 0rpx !important;
padding: 0rpx !important;
}
</style>
<style>
page {
background-color: #efefef;
}
</style>
+360
View File
@@ -0,0 +1,360 @@
<template>
<view>
<u-navbar :background="{ background: '#efefef'}" :border-bottom="true" :is-back="false">
<view style=" display: flex;flex-direction: row;justify-content: space-between;align-items: center; flex: 1; padding: 0 30rpx; ">
<view style="width: 150rpx;" @click="goBack()">
<u-icon name="close" :size="32"></u-icon>
</view>
<view @click="addRecord()" style="color:#404133;font-size: 34rpx;font-weight: bold;text-align: center;">
<text>账单</text>
</view>
<view style="width: 150rpx;">
<text style="font-size: 34rpx;color: #000000;" @click="serviceCenter()">客服中心</text>
</view>
</view>
</u-navbar>
<view>
<view class="u-flex u-row-between u-col-center u-border-bottom"
style="padding:34rpx 30rpx;">
<view @click="openTradeTypePop()" style="background-color:#e3e3e3;height:60rpx;line-height: 50rpx; border-radius: 30rpx;padding: 0rpx 16rpx;">
<u-icon name="arrow-down-fill" size="16" color="#666666"
label="全部账单" label-size="26rpx" label-pos="left" margin-right="6rpx">
</u-icon>
</view>
<view @click="toBillStatistics()">
<u-icon name="arrow-right" color="#acb0b7"
label="统计" label-color="#acb0b7" label-pos="left"></u-icon>
</view>
</view>
<view style="padding:34rpx 30rpx;background-color:#efefef;width:100%;"
class="u-flex u-row-between u-col-center">
<view >
<u-icon name="arrow-down" size="24" color="#333333" @click="openTimePicker"
:label="activeMonthObj.currentYear+'年'+activeMonthObj.currentMonth+'月'"
label-color="#333333"
label-size="30rpx" label-pos="left"
margin-right="6rpx">
</u-icon>
</view>
<view class="u-flex u-row-left u-col-center" style="color:#acb0b7;" @click="openUpdateModel()">
<view class="u-m-r-16">支出¥{{Number(activeMonthObj.outputAmount).toFixed(2)}}</view>
<view>收入¥{{Number(activeMonthObj.inputAmount).toFixed(2)}}</view>
</view>
</view>
</view>
<view style="background-color:#ffffff;width: 100%;">
<scroll-view :scroll-x="false" :scroll-y="true" class="hidden-scroll-bar"
:style="'width: 100%;height:'+scrollviewHeight+'px'"
:scroll-into-view="scrollIntoViewId"
@scrolltoupper="scrolltoUpper"
@scrolltolower="scrolltolower">
<template v-if="activeMonthObj.recordList&&activeMonthObj.recordList.length>0">
<view v-for="(record,index) in activeMonthObj.recordList" :key="index"
:id="'record_'+index"
class="u-flex u-row-between u-col-center"
style="width: 100%;">
<view style="width: 18%;padding: 30rpx 20rpx 30rpx 30rpx;">
<u-image :src="record.tradeIcon" width="90rpx" height="90rpx"
shape="circle" bg-color="#909399"></u-image>
</view>
<view style="width: 82%;padding: 30rpx 30rpx 30rpx 0rpx"
class="u-flex u-row-between u-col-center u-border-bottom">
<view @click="showUpdatePop(record,index)">
<view style="font-size: 34rpx;font-weight: 500;width:400rpx" class="u-line-1">{{record.tradeTitle}}</view>
<view style="font-size: 28rpx;color: #909399;margin-top:6rpx;">{{formatTimeStr(record.createTime)}}</view>
</view>
<view class="u-p-b-40" @click="toDetail(record)">
<text v-if="record.tradeDirection=='out'"
style="color: #000000;font-weight: bold;font-size: 32rpx;">{{"-"+Number(record.tradeValue).toFixed(2)}}</text>
<text v-if="record.tradeDirection=='in'"
style="color: #f29100;font-weight: bold;font-size: 32rpx;">{{"+"+Number(record.tradeValue).toFixed(2)}}</text>
</view>
</view>
</view>
</template>
</scroll-view>
</view>
<!-- 当前月份统计信息修改 -->
<u-popup v-model="currentMonthPopFlag" mode="center" :mask-close-able="false" negative-top="200" closeable>
<view class="u-p-30">
<view class="u-m-t-30">
<u-form :model="activeMonthObj" ref="activeMonthObj" label-width="150rpx">
<u-form-item label="当前年度">
<u-input v-model="activeMonthObj.currentYear" type="number" placeholder="月份"/>
</u-form-item>
<u-form-item label="当前月份">
<u-input v-model="activeMonthObj.currentMonth" type="number" placeholder="月份"/>
</u-form-item>
<u-form-item label="当月收入">
<u-input v-model="activeMonthObj.inputAmount" type="number" placeholder="本月收入"/>
</u-form-item>
<u-form-item label="当月支出">
<u-input v-model="activeMonthObj.outputAmount" type="number" placeholder="本月支出"/>
</u-form-item>
</u-form>
</view>
<view class="u-p-30">
<view>
<u-button type="success" @click="submitUpdate">确定</u-button>
</view>
</view>
</view>
</u-popup>
<!-- 月份查询筛选-->
<u-picker mode="time" v-model="timePickerShow" :params="timeParams"
confirm-color="#3c2e55" confirm-text="确定" @confirm="timePickerConfirm"
:show-time-tag="false"></u-picker>
<!-- 新增或者修改时间选择器 -->
<!-- 消费类型 -->
<u-popup v-model="tradeTypePopFlag" mode="bottom"
:border-radius="16" close-icon-color="#000000"
:closeable="true" close-icon-pos="top-left">
<view style="width: 100%;padding: 20rpx;background-color: #f0f0f0;">
<view style="margin-top: 20rpx; text-align: center;font-weight: bold;">选择筛选项</view>
<view style="margin-top: 50rpx;text-align: center;padding: 0rpx 20rpx;margin-bottom: 100rpx;">
<u-row>
<u-col :span="4" v-for="(tradeTypeItem,index) in tradeTypeList" :key="index">
<view v-if="index==4"
class="trade-type trade-type-4"
:class="currentTradeType.value==tradeTypeItem.value?'trade-type trade-type-4 trade-type-active':'trade-type trade-type-4'"
@click="selectTradeType(tradeTypeItem)">
{{tradeTypeItem.title}}
</view>
<view v-else @click="selectTradeType(tradeTypeItem)"
:class="currentTradeType.value==tradeTypeItem.value?'trade-type trade-type-active':'trade-type'">
{{tradeTypeItem.title}}
</view>
</u-col>
</u-row>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import billList from '@/util/billList';
export default {
data() {
return {
scrollviewHeight:0,
scrollIntoViewId:'',
currentMonthIndex:new Date().getMonth()+1, //当前月份
currentYearIndex: new Date().getFullYear(),//当期年份
currentMonthPopFlag:false,//当前月份信息修改弹窗控制器
//当前月份数据
activeMonthObj:{
currentYear:2022,
currentMonth:5,
outputAmount:0.00,
inputAmount:0.00,
recordList:[]
},
timePickerShow:false, //时间选择器开关
//时间参数
timeParams:{
year: true,
month: true,
day: false,
hour: false,
minute: false,
second: false,
timestamp: true,
},
tradeTypePopFlag:false,
tradeTypeList:[
{"title":"全部",value:"0"},{"title":"红包",value:"1"},{"title":"转账",value:"2"},
{"title":"群收款",value:"3"},{"title":"二维码收付款",value:"4"},{"title":"商户消费",value:"5"},
{"title":"充值提现",value:"6"},{"title":"信用卡还款",value:"7"},{"title":"有退款",value:"8"},
],
currentTradeType:{title:'全部',value:"0"}
};
},
onLoad:function(){
let that=this;
this.scrollviewHeight= that.$u.sys().windowHeight*0.76; // 0.828
this.getRecordList();
},
methods:{
goBack(){
uni.navigateBack();
},
openTimePicker:function(){
let that=this;
that.timePickerShow=true;
},
timePickerConfirm:function(obj){
let year=obj.year;
let monthStr=obj.month;
let month= (new Date(obj.timestamp*1000)).getMonth()+1;
console.log("选择的月份",month);
this.currentMonthIndex=month;
this.currentYearIndex=year;
this.getRecordList();
},
//获取缓存记录
getRecordList:function(){
this.activeMonthObj.recordList=[];
this.activeMonthObj.inputAmount=0.00;
this.activeMonthObj.outputAmount=0.00;
this.activeMonthObj.currentMonth=this.currentMonthIndex;
this.activeMonthObj.currentYear=this.currentYearIndex;
let month=this.currentMonthIndex<10?("0"+this.currentMonthIndex):this.currentMonthIndex;
let param={
timeDuring:this.currentYearIndex+"-"+month,
tradeType:this.currentTradeType.value=='0'?'':this.currentTradeType.value,
}
console.log("获取账单记录参数",param);
this.activeMonthObj=JSON.parse(JSON.stringify(billList.tempBillList[0]));
console.log("this.activeMonthObj",this.activeMonthObj);
this.$forceUpdate();
return;
/* this.$u.api.imUser.getUserAccountRecordList(param).then(res => {
if(res.code==200&&res.data){
this.activeMonthObj.recordList=res.data.recordList;
this.activeMonthObj.inputAmount=res.data.monthAccountInfo.inputAmount;
this.activeMonthObj.outputAmount=res.data.monthAccountInfo.outputAmount;
console.log("获取账单记录结果",this.activeMonthObj);
}else{
}
}) */
},
//打开修改弹窗
openUpdateModel:function(){
this.currentMonthPopFlag=true;
},
//提交修改
submitUpdate:function(){
this.currentMonthPopFlag=false;
},
//打开新增记录弹窗
addRecord:function(){
let that=this;
that.addPopFlag=true;
},
serviceCenter(){
this.$u.route({
url:'/pages/tabbar/my/service/my-bill-question',
});
},
toDetail:function(record){
let that=this;
this.$u.route({
url:'/pages/tabbar/my/service/my-bill-detail',
params:{
record:encodeURIComponent(JSON.stringify(record))
}
});
},
scrolltoUpper:function(){
this.currentMonthIndex=new Date().getMonth()+1; //当前月份
this.currentYearIndex=new Date().getFullYear();//当期年份
this.getRecordList();
},
//监听滚动
scrolltolower:function(){
let that=this;
console.log("监听到页面滚动到底部");
this.currentMonthIndex=this.currentMonthIndex-1;
let month=this.currentMonthIndex<10?"0"+this.currentMonthIndex:this.currentMonthIndex;
let param={
timeDuring:this.currentYearIndex+"-"+month,
tradeType:this.currentTradeType.value=='0'?'6':this.currentTradeType.value,
}
console.log("获取上一个月的账单记录参数",param);
that.getRecordList();
return;
this.$u.api.imUser.getUserAccountRecordList(param).then(res => {
console.log("获取上一个月的账单记录结果",res);
if(res.code==200&&res.data){
let recordList=res.data.recordList;
if(recordList!=null&&recordList.length>0){
that.activeMonthObj.recordList=that.activeMonthObj.recordList.concat(recordList);
that.activeMonthObj.inputAmount=res.data.monthAccountInfo.inputAmount;
that.activeMonthObj.outputAmount=res.data.monthAccountInfo.outputAmount;
that.activeMonthObj.currentMonth=this.currentMonthIndex;
}
}else{
this.currentMonthIndex=this.currentMonthIndex+1;
}
})
},
formatTimeStr:function(timeStr){
//console.log("timeStr",timeStr);
timeStr=timeStr.replace(/-/g,"/");
let cdate=new Date(timeStr);
let month= cdate.getMonth()+1;
//console.log("month",month);
let day=cdate.getDate();
let hour= cdate.getHours();
let min=cdate.getMinutes();
let monthStr=month+"月";
let dayStr=day+"日";
let hourStr=hour+":";
let minStr=min;
/* if(month<10){
monthStr="0"+month+"月";
}
if(day<10){
dayStr="0"+day+"日";
} */
if(hour<10){
hourStr="0"+hour+":";
}
if(min<10){
minStr="0"+min;
}
let formatStr=monthStr+dayStr+" "+hourStr+minStr;
//console.log("formatStr",formatStr);
return formatStr;
},
openTradeTypePop:function(){
let that=this;
that.tradeTypePopFlag=true;
},
selectTradeType:function(tradeItem){
this.currentTradeType=tradeItem;
this.tradeTypePopFlag=false;
this.getRecordList();
},
toBillStatistics:function(){
this.$u.route({
url:'/pages/tabbar/my/service/my-bill-statistics',
});
},
}
}
</script>
<style lang="scss" scoped>
::v-deep .u-picker-view{
background-color: #f3f4f6;
}
.trade-type{
height: 120rpx;
padding:40rpx 30rpx 0rpx 30rpx;
margin-bottom: 16rpx;
background-color: #e2e2e2;
border-radius: 10rpx;
text-align: center;
color: #000000;
}
.trade-type-4{
padding:25rpx 30rpx 0rpx 30rpx;
}
.trade-type-active{
background-color: rgb(232,248,238);
border:1rpx solid #18b566;
font-weight: bold;
color:#18b566;
}
</style>
<style>
page{
background-color: #efefef;
}
</style>
+108
View File
@@ -0,0 +1,108 @@
<template>
<view>
<u-navbar :is-back="true" title=" " :title-bold="true" :title-size="34"
:background="{ background: '#57ab6d'}"
back-icon-name="arrow-left" :back-icon-size="34" back-icon-color="#f0f0f0"
:border-bottom="false">
</u-navbar>
<!-- 这里背景好像是图片 -->
<scroll-view :scroll-x="false" :scroll-y="true" class="hidden-scroll-bar"
:style="'width: 100%;background-color: #ffffff;height:'+scrollviewHeight+'px'">
<view style="padding:20rpx;background-color:#57ab6d;height:230rpx;">
<view style="color: #ffffff;font-size: 22px;">协助你解决</view>
<view style="color: #ffffff;font-size: 22px;">账单相关问题</view>
</view>
<view style="margin-top: -40rpx; padding: 0rpx 30rpx;">
<view style="border-radius: 20rpx;background-color: #f9f9f9;padding: 40rpx;">
<u-row>
<u-col :span="5">
<view class="u-flex u-row-center u-col-center">
<view>
<u-icon name="checkmark-circle-fill" :size="40"></u-icon>
</view>
<view class="u-m-l-10" @click="toDownLoadOrder()">
<text style="font-size: 32rpx;">下载账单</text>
</view>
</view>
</u-col>
<u-col :span="2">
<view class="u-flex u-row-center">
<u-line color="#a3a6ad" direction="col" length="70rpx" :hair-line="false"></u-line>
</view>
</u-col>
<u-col :span="5">
<view class="u-flex u-row-center u-col-center">
<view>
<u-icon name="file-text-fill" :size="40"></u-icon>
</view>
<view class="u-m-l-10">
<text style="font-size: 32rpx;">银行支出查询</text>
</view>
</view>
</u-col>
</u-row>
</view>
</view>
<view class="u-p-30 u-flex u-row-between u-col-center">
<view style="font-size: 20px;color: #000000;">常见问题</view>
<view class="u-flex u-row-around u-col-center"
style="padding: 12rpx 20rpx;border-radius: 14rpx;border: 1rpx solid #adb1b8;">
<view>
<u-icon name="search" :size="32" :top="2"></u-icon>
</view>
<view class="u-tips-color u-p-l-10 u-font-30">
<text>搜索</text>
</view>
</view>
</view>
<view>
<u-cell-item icon="order" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="如何快速查询历史账单"></u-cell-item>
<u-cell-item icon="order" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="如何查看注销前账单"></u-cell-item>
<u-cell-item icon="question-circle" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="微信支付账单如何删除"></u-cell-item>
<u-cell-item icon="rmb-circle" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="交易遇到问问如何联系商家"></u-cell-item>
<u-cell-item icon="heart" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="未成年人充值/平台消费"></u-cell-item>
<u-cell-item icon="question-circle" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="申请交易明细证明常见问题"></u-cell-item>
<u-cell-item icon="rmb-circle" :title-style="titleStyle" :border-bottom="false" :border-top="true" title="微信支付账户被莫名扣费"></u-cell-item>
<u-cell-item icon="order" :title-style="titleStyle" :border-bottom="true" :border-top="true" title="账单号'收入/支出'的统计说明"></u-cell-item>
</view>
<!-- 不要删,占位 -->
<view class="u-p-30" style="background-color: #f8f8f8;"></view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
scrollviewHeight:0, //页面高度
titleStyle:{
fontSize:"32rpx",
color:"#000000",
margin:"16rpx 0rpx"
}
};
},
onLoad:function(){
let that=this;
this.scrollviewHeight= that.$u.sys().windowHeight*0.895; // 0.828
//this.getData();
},
methods:{
toDownLoadOrder:function(){
this.$u.route({
url:"/pages/my/service/download-bill-order/download-bill-order"
})
}
}
}
</script>
<style lang="scss">
</style>
+563
View File
@@ -0,0 +1,563 @@
<template>
<view>
<u-navbar :is-back="true" title=" " :title-bold="true" :title-size="34"
:background="{ background: '#57ab6d'}"
back-icon-name="close" back-icon-size="34" back-icon-color="#f0f0f0"
:border-bottom="false">
</u-navbar>
<view>
<scroll-view :scroll-x="false" :scroll-y="true" class="hidden-scroll-bar"
style="'width: 100%;background-color: #ffffff;height:88.5vh">
<!-- 头部块 -->
<view style="padding-bottom: 20rpx;background-color:#57ab6d;">
<view class="u-flex u-row-center u-col-center">
<!-- 年度账单/月度账单 -->
<view style="width: 500rpx;">
<u-tabs :list="tabList" :is-scroll="false" :current="currentTab" @change="tabChange"
:font-size="32" :height="90" :bar-width="100"
active-color="#ffffff" inactive-color="#d6d6d6" bg-color="#57ab6d"></u-tabs>
</view>
</view>
<!-- 月份,年份,类型 -->
<view style="padding:40rpx;width:100%;padding-bottom: 30rpx;"
class="u-flex u-row-between u-col-center">
<view style="width: 50%;" v-if="currentTab==0">
<u-icon name="arrow-down" size="24" color="#ffffff" @click="openTimePicker('month')"
:label="currentBillObj.year+'年'+currentBillObj.month+'月'"
label-color="#ffffff"
label-size="30rpx" label-pos="left"
margin-right="6rpx">
</u-icon>
</view>
<view style="width: 50%;" v-if="currentTab==1">
<u-icon name="arrow-down" size="24" color="#ffffff" @click="openTimePicker('year')"
:label="currentBillObj.year+'年'"
label-color="#ffffff"
label-size="30rpx" label-pos="left"
margin-right="6rpx">
</u-icon>
</view>
<view class="u-flex u-row-between u-col-center" style="color:#d6d6d6;width: 50%;">
<view :class="currentBillObj.currentbillTitle==0?'active-bill-type':'bill-type'" @click="changebillTitle(0)">支出</view>
<view :class="currentBillObj.currentbillTitle==1?'active-bill-type':'bill-type'" @click="changebillTitle(1)">收入</view>
<view :class="currentBillObj.currentbillTitle==2?'active-bill-type':'bill-type'" @click="changebillTitle(2)">其他</view>
</view>
</view>
<!-- 支付类型摘要信息 -->
<view v-if="currentBillObj.currentbillTitle!=2"
style="padding:40rpx;background-color:#57ab6d;width:100%;padding-top: 20rpx;">
<view style="color:#d6d6d6;font-size: 26rpx;">
{{currentBillObj.currentbillTitle==0?'支出':'收入'}}{{currentBillObj.tradeCount}}合计
</view>
<view class="u-flex u-row-left u-col-top"
style="color: #ffffff;font-size: 26px;margin-top: 20rpx;font-weight: bold;">
<view style="margin-right:16rpx;font-size: 22px;margin-top: 4rpx;">¥</view>
<view class="u-m-l-10">{{Number(currentBillObj.tradeAmount).toFixed(2)}}</view>
</view>
</view>
</view>
<!-- 白色块 -->
<view class="u-p-20" v-show="currentTab==0"
style="background-color: #ffffff;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;">
<view class="u-flex u-row-between u-col-center u-p-30"
style="background-color: #f0f0f0;border-radius: 20rpx;">
<view class="u-flex u-row-left u-col-center">
<view class="u-m-r-20">
<u-icon name="red-packet-fill" color="#57ab6d" size="32"></u-icon>
</view>
<view>
<view class="u-line-2" style="color:#909399;">使用记账本查看分类统计(餐饮交通等)</view>
</view>
</view>
<view>
<u-icon name="arrow-right" color="#909399" size="32"></u-icon>
</view>
</view>
<view v-show="currentBillObj.currentbillTitle!=2" >
<!-- 图表 -->
<view class="u-p-20">
<view class="u-font-34 ">{{currentBillObj.currentbillTitle==0?'每月支出':'每月收入'}}对比</view>
<view style="height: 500rpx;">
<l-echart ref="chart"></l-echart>
</view>
</view>
<!-- 排行榜 -->
<view class="u-p-20">
<view class="u-m-b-50">{{currentBillObj.currentbillTitle==0?'支出':'收入'}}排行榜</view>
<view class="u-flex u-row-between u-col-center u-m-b-30"
v-for="(rankItem,index) in monthRankingkList" :key="index">
<view class="u-flex u-row-left u-col-center">
<view class="u-m-r-30" style="width: 40rpx;">{{rankItem.id}}</view>
<view class="u-flex u-row-left u-col-center">
<view>
<u-image width="60rpx" height="60rpx" shape="circle" :src="rankItem.iconSrc"></u-image>
</view>
<view class="u-m-l-20 u-line-1" style="width: 350rpx;">{{rankItem.billTitle}}</view>
</view>
</view>
<view>
<view class="u-flex u-row-left u-col-center">
<view style="color: #000000;font-weight: bold;width: 150rpx;text-align: right;">
<text>¥</text>
<text>{{Number(rankItem.amountValue).toFixed(2)}}</text>
</view>
<view class="u-m-l-20">
<u-icon name="arrow-right" color="#909399"></u-icon>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-show="currentBillObj.currentbillTitle==2">
<view style="padding-top: 20%;">
<!-- 可以给src图片 -->
<u-empty text="无其他资金流转记录" mode="data" :icon-size="100"></u-empty>
</view>
</view>
</view>
<view class="u-p-40" v-show="currentTab==1"
style="background-color: #ffffff;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;">
<view v-if="currentBillObj.currentbillTitle!=2">
<view class="u-font-34">
{{currentBillObj.currentbillTitle==0?'支出':'收入'}}构成
</view>
<view class="u-m-t-40" v-for="(yearBillItem,index) in yearBillBuildArr" :key="index">
<u-row>
<u-col :span="4">
<view class="u-flex u-row-left u-col-center">
<view>
<u-image :src="yearBillItem.iconSrc" :width="36" :height="36"></u-image>
</view>
<view class="u-m-l-20 u-line-1"
style="width: 70%;font-size: 28rpx;">
{{yearBillItem.billTitle}}
</view>
</view>
</u-col>
<u-col :span="4">
<view>
<u-line-progress :show-percent="false" :height="16"
:active-color="yearBillItem.color"
:percent="yearBillItem.percentValue"></u-line-progress>
</view>
</u-col>
<u-col :span="4">
<view style="width: 100%;" class="u-flex u-row-right u-col-center">
<view style="text-align: right;font-weight: bold;color:#000000;font-size: 26rpx;">
¥{{Number(yearBillItem.amountValue).toFixed(2)}}
</view>
<view class="u-m-l-10">
<u-icon name="arrow-right" color="#909399"></u-icon>
</view>
</view>
</u-col>
</u-row>
</view>
</view>
<view v-if="currentBillObj.currentbillTitle==2">
<view class="u-font-34">
<view class="u-flex u-row-left u-col-center">
<view> 个人资金流转</view>
<view class="u-m-l-16">
<u-icon name="info-circle" color="#909399"></u-icon>
</view>
</view>
</view>
<view class="u-m-t-40">
<view class="u-flex u-row-between u-col-center u-m-t-40"
v-for="(otherItem,otherIndex) in yearBillBuildOtherArr" :key="otherIndex">
<view class="u-flex u-row-left u-col-center">
<view>
<u-icon name="rmb-circle" color="#ff9900" size="40"></u-icon>
</view>
<view class="u-m-l-20 u-font-32">{{otherItem.title}}</view>
</view>
<view class="u-flex u-row-left u-col-center">
<view style="font-weight: bold;">¥{{Number(otherItem.amountValue).toFixed(2)}}</view>
<view class="u-m-l-10">
<u-icon name="arrow-right" color="#909399"></u-icon>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 月份查询筛选-->
<u-picker mode="time" v-model="monthPickerShow" :params="monthTimeParams" end-year="2026"
confirm-color="#3c2e55" confirm-text="确定" @confirm="monthTimePickerConfirm"
:show-time-tag="false"></u-picker>
<!-- 年度查询筛选-->
<u-picker mode="time" v-model="yearPickerShow" :params="yearTimeParams" end-year="2026"
confirm-color="#3c2e55" confirm-text="确定" @confirm="yearTimePickerConfirm"
:show-time-tag="false"></u-picker>
</view>
</template>
<script>
// #ifdef APP-PLUS
import * as echarts from '@/uni_modules/lime-echart/static/app/echarts.min';
// #endif
// #ifndef APP-PLUS
import * as echarts from '@/uni_modules/lime-echart/static/web/echarts.esm.min';
// #endif
export default {
data() {
return {
//年月tab切换器
tabList:[
{name:"月账单"},{name:"年账单"}
],
//当期年月tab的下标
currentTab:0,
//参数
currentBillObj:{
year:new Date().getFullYear(), //年
month:new Date().getMonth()+1, //月
currentbillTitle:0 ,//0支出 ,1收入 2其他
tradeCount:264,
tradeAmount:216734.8
},
monthPickerShow:false, //月份时间选择器开关
yearPickerShow:false, //年度事件选择器开关
//时间参数-月
monthTimeParams:{
year: true,
month: true,
day: false,
hour: false,
minute: false,
second: false,
timestamp: true,
},
//时间参数-年
yearTimeParams:{
year: true,
month: false,
day: false,
hour: false,
minute: false,
second: false,
timestamp: true,
},
//月度排行榜
monthRankingkList:[],
//年度账单构成
yearBillBuildArr:[
{
billTitle:"转账",
percentValue:70,
amountValue:513080,
color:"#F29100",
iconSrc:"/static/image/bill/zhuanzhang.jpg"
},
{
billTitle:"消费支出",
percentValue:20,
amountValue:231160.58,
color:"#2979ff",
iconSrc:"/static/image/bill/xiaofei.jpg"
},
{
billTitle:"发红包",
percentValue:10,
amountValue:44650,
color:"#fa3534",
iconSrc:"/static/image/bill/hongbao.jpg"
}
],
//年度账单其他类型的数据结构
yearBillBuildOtherArr:[],
//图表插件 :https://ext.dcloud.net.cn/plugin?id=4899
//图表的配置 参考:https://echarts.apache.org/zh/option.html#xAxis.axisLine.lineStyle.join
chartOption: {
xAxis: {
type: 'category',
data: ['7月', '8月', '9月', '10月', '11月', '12月'],
axisLabel: {
color: '#909399',
fontSize:10,
},
axisLine:{
lineStyle:{
color:'rgb(172, 233, 189)'
}
}
},
yAxis: {
type: 'value',
show:false,
},
series: [{
data: [0,0,0,0,0,0],
type: 'bar',//柱状
showBackground:false,//是否显示阴影
color:'rgb(172, 233, 189)',//柱体颜色
borderColor:'#fff',//柱体背景颜色
barWidth:20,//柱条的宽度,
label:{
show:true,
position:'top',
fontSize:9,
color:'inherit',
formatter:function(params){
//console.log(params);
let val= params.value;
//console.log("数值",val);
if(val<10000){
return "¥"+val.toFixed(2);
}else{
return "¥"+(val/10000).toFixed(1)+""
}
}
},
}]
}
};
},
mounted:function(){
let that=this;
that.$refs.chart.init(echarts, chart=> {
that.getMonthData();
chart.on('click',function(params){
that.listenerChartClick(params.dataIndex)
})
});
},
methods:{
//年账单,月账单切换事件
tabChange:function(index){
this.currentTab = index;
if(index==1){
this.getYearBillData();
}else{
//获取月度数据,以图表为例
this.getMonthData();
}
},
//打开时间选择器
openTimePicker:function(type){
let that=this;
if(type=='month'){
that.monthPickerShow=true;
}
if(type=='year'){
that.yearPickerShow=true;
}
},
//选择时间变化-月度
monthTimePickerConfirm:function(obj){
let year=obj.year;
let monthStr=obj.month;
let month= (new Date(obj.timestamp*1000)).getMonth()+1;
console.log("选择的月份",month);
this.currentBillObj.month=month;
this.currentBillObj.year=year;
this.getMonthData();
},
//选择时间变化-年度
yearTimePickerConfirm:function(obj){
let year=obj.year;
this.currentBillObj.year=year;
this.getYearBillData();
},
//改变账单类型 0支出 1收入 2其他
changebillTitle:function(index){
this.currentBillObj.currentbillTitle=index;
//年度账单
if(this.currentTab==1){
this.getYearBillData();
}
//获取月度数据,以图表为例
if(this.currentTab==0&&index!=2){
this.getMonthData();
}
},
//获取图表数据
getMonthData:function(){
let that=this;
let param={
currentTab:this.currentTab, //0月度 1年度
currentBillType:this.currentBillObj.currentbillTitle,//0支出 1收入 2其他
year:this.currentBillObj.year, //当前年度
month:this.currentBillObj.month //当前月度(如果当前选择是年度,month参数要忽略的)
};
console.log("获取月度账单参数",param);
if(this.currentTab==0){
if(this.currentBillObj.currentbillTitle==1){
//下面数据临时写死,实际后端请求要得到柱状图的的x,y坐标系的数据以及月度排行数据
let xData=['6月', '7月', '8月', '9月', '10月', '11月'];
let currentMonthIndex= xData.findIndex(item=>item.indexOf(that.currentBillObj.month)!=-1);
//console.log("currentMonthIndex",currentMonthIndex);
let dataArr=[21000,84000,16000,98000,102000,216743];
let currentMonthValue= dataArr[currentMonthIndex];
dataArr[currentMonthIndex]={
value:currentMonthValue,
itemStyle:{
color:"#19bE6B"
}
}
that.chartOption.xAxis.data=xData;
that.chartOption.series[0].data=dataArr;
that.$refs.chart.setOption(this.chartOption);
//模拟后台数据
that.currentBillObj.tradeCount=267;//交易记录次数
that.currentBillObj.tradeAmount=318962.2;//交易记录总额
//月度排行数据
that.monthRankingkList=[
{id:1,iconSrc:"/static/image/bill/zhuanzhang.jpg",billTitle:"转账",amountValue:182204.3},
{id:2,iconSrc:"/static/image/bill/xiaofei.jpg",billTitle:"二维码收付款",amountValue:21523.5},
{id:3,iconSrc:"/static/image/bill/hongbao.jpg",billTitle:"微信红包",amountValue:8550},
];
}else{
let xData=['6月', '7月', '8月', '9月', '10月', '11月'];
let currentMonthIndex= xData.findIndex(item=>item.indexOf(that.currentBillObj.month)!=-1);
//console.log("currentMonthIndex",currentMonthIndex);
let dataArr=[55000,102000,38000,116000,114000,265400];
let currentMonthValue= dataArr[currentMonthIndex];
dataArr[currentMonthIndex]={
value:currentMonthValue,
itemStyle:{
color:"#19bE6B"
}
}
that.chartOption.xAxis.data=xData;
this.chartOption.series[0].data=dataArr;//模拟后台数据
this.$refs.chart.setOption(this.chartOption);
that.currentBillObj.tradeCount=324;//交易记录次数
that.currentBillObj.tradeAmount=216734.8;//交易记录总额
that.monthRankingkList=[
{id:1,iconSrc:"/static/image/bill/zhuanzhang.jpg",billTitle:"转账",amountValue:182204.3},
{id:2,iconSrc:"/static/image/bill/xiaofei.jpg",billTitle:"二维码收付款",amountValue:21523.5},
{id:3,iconSrc:"/static/image/bill/hongbao.jpg",billTitle:"微信红包",amountValue:8550},
];
}
}
},
//获取年账单
getYearBillData:function(){
let that=this;
let param={
currentTab:this.currentTab, //0月度 1年度
currentBillType:this.currentBillObj.currentbillTitle,//0支出 1收入 2其他
year:this.currentBillObj.year, //当前年度
month:this.currentBillObj.month //当前月度(如果当前选择是年度,month参数要忽略的)
};
console.log("获取年度度账单参数",param);
if(this.currentTab==1){
that.currentBillObj.currentbillTitle;
//收入
if(that.currentBillObj.currentbillTitle==0){
that.currentBillObj.tradeCount=3120;
that.currentBillObj.tradeAmount=3816734.8;
this.yearBillBuildArr=[
{
billTitle:"转账",
percentValue:78,
amountValue:that.currentBillObj.tradeAmount*0.78,
color:"#F29100",
iconSrc:"/static/image/bill/zhuanzhang.jpg"
},
{
billTitle:"消费支出",
percentValue:21,
amountValue:that.currentBillObj.tradeAmount*0.21,
color:"#2979ff",
iconSrc:"/static/image/bill/xiaofei.jpg"
},
{
billTitle:"发红包",
percentValue:1,
amountValue:that.currentBillObj.tradeAmount*0.01,
color:"#fa3534",
iconSrc:"/static/image/bill/hongbao.jpg"
}
];
}
//支出
if(that.currentBillObj.currentbillTitle==1){
that.currentBillObj.tradeCount=3878;
that.currentBillObj.tradeAmount=4201384.68;
this.yearBillBuildArr=[
{
billTitle:"收转账",
percentValue:80,
amountValue:that.currentBillObj.tradeAmount*0.8,
color:"#F29100",
iconSrc:"/static/image/bill/zhuanzhang.jpg"
},
{
billTitle:"二维码收款",
percentValue:10,
amountValue:that.currentBillObj.tradeAmount*0.1,
color:"#fa3534",
iconSrc:"/static/image/bill/hongbao.jpg"
},
{
billTitle:"收红包",
percentValue:5,
amountValue:that.currentBillObj.tradeAmount*0.05,
color:"#fa3534",
iconSrc:"/static/image/bill/hongbao.jpg"
},
{
billTitle:"退款",
percentValue:3,
amountValue:that.currentBillObj.tradeAmount*0.03,
color:"#2979ff",
iconSrc:"/static/image/bill/xiaofei.jpg"
},
{
billTitle:"其他",
percentValue:2,
amountValue:that.currentBillObj.tradeAmount*0.02,
color:"#2979ff",
iconSrc:"/static/image/bill/hongbao.jpg"
}
];
}
//其他
if(that.currentBillObj.currentbillTitle==2){
this.yearBillBuildOtherArr=[
{title:"零钱提现",amountValue:1001},
{title:"零钱提现",amountValue:430}
];
}
}
},
//监听柱状图点击事件
listenerChartClick(dataIndex){
console.log("dataIndex",dataIndex);
let monthIndex= this.chartOption.xAxis.data[dataIndex];
this.currentBillObj.month=monthIndex.replace('月','');
this.getMonthData();
},
}
}
</script>
<style lang="scss" scoped>
.bill-type{
border-radius: 30rpx;
padding: 4rpx 16rpx;
color: #ffffff;
}
.active-bill-type{
border: 1rpx solid #fff;
border-radius: 30rpx;
padding: 4rpx 16rpx;
color: #ffffff;
}
</style>
+268
View File
@@ -0,0 +1,268 @@
<template>
<view class="service-home-page">
<u-navbar :is-back="true" title="服务" :title-bold="true" :title-size="34" :background="{background: '#f1f1f1'}"
title-color="#404133" :border-bottom="false" z-index="1001">
<view slot="right" class="u-m-r-20" @click="modelShow=true">
<u-icon name="more-dot-fill" size="48"></u-icon>
</view>
</u-navbar>
<view class="u-p-20">
<view class="u-flex u-row-around u-col-center" style="background-color:rgb(87,171,109);border-radius: 16rpx;height: 280rpx;
font-size: 32rpx;color: #f8f8f8;text-align: center;">
<view style="height: 150rpx;">
<view style="height: 100rpx;">
<u-icon name="/static/image/wx/services/shoufukuan.png" color="#ffffff" size="90rpx"></u-icon>
</view>
<view style="font-weight: bold;">收付款</view>
</view>
<view @click="toWallet()" style="height: 150rpx;">
<view style="height: 100rpx;padding-top:20rpx;">
<u-icon name="/static/image/wx/services/qianbao.png" color="#ffffff" size="70rpx"></u-icon>
</view>
<view>
<view style="font-weight: bold;">钱包</view>
<view style="color: #dbdbdb;;font-size:24rpx;font-weight: bold;">
<text v-if="userAccount.accountBalance"> ¥ {{amountFormat()}}</text>
<text v-else>¥ 0.00</text>
</view>
</view>
</view>
</view>
<view
style="background-color: #ffffff;border-radius: 10rpx;padding: 30rpx;margin: 20rpx 0rpx;font-size: 30rpx;">
<view class="u-m-b-30" style="color:#606266">金融理财</view>
<u-row style="color: #000000;font-size: 28rpx;padding: 30rpx 0rpx;">
<u-col :span="3" v-for="(service,index) in financeServiceList" :key="index">
<view style="text-align: center;margin-bottom: 10rpx;">
<u-icon :name="service.iconPath" :size="70"></u-icon>
</view>
<view style="text-align: center;">
{{service.title}}
</view>
</u-col>
</u-row>
</view>
<view
style="background-color: #ffffff;border-radius: 10rpx;padding: 30rpx;margin: 20rpx 0rpx;font-size: 30rpx;">
<view class="u-m-b-30" style="color:#606266">生活服务</view>
<u-row style="color: #000000;font-size: 28rpx;">
<u-col style="margin: 30rpx 0rpx;" :span="3" v-for="(service,index) in lifeServiceList"
:key="index">
<view style="text-align: center;margin-bottom: 10rpx;">
<u-icon :name="service.iconPath" :size="70"></u-icon>
</view>
<view style="text-align: center;">
<view>{{service.title}}</view>
</view>
</u-col>
</u-row>
</view>
<view
style="background-color: #ffffff;border-radius: 10rpx;padding: 30rpx;margin: 20rpx 0rpx;font-size: 30rpx;">
<view class="u-m-b-30" style="color:#606266">交通出行</view>
<u-row style="color: #000000;font-size: 28rpx;">
<u-col style="margin: 30rpx 0rpx;" :span="3" v-for="(service,index) in jiaotongServiceList"
:key="index">
<view style="text-align: center;margin-bottom: 10rpx;">
<u-icon :name="service.iconPath" :size="70"></u-icon>
</view>
<view style="text-align: center;">
<view>{{service.title}}</view>
</view>
</u-col>
</u-row>
</view>
<view
style="background-color: #ffffff;border-radius: 10rpx;padding: 30rpx;margin: 20rpx 0rpx;font-size: 30rpx;">
<view class="u-m-b-30" style="color:#606266">购物消费</view>
<u-row style="color: #000000;font-size: 28rpx;">
<u-col style="margin: 30rpx 0rpx;" :span="3" v-for="(service,index) in shopList" :key="index">
<view style="text-align: center;margin-bottom: 10rpx;">
<u-icon :name="service.iconPath" :size="70"></u-icon>
</view>
<view style="text-align: center;">
<view>{{service.title}}</view>
</view>
</u-col>
</u-row>
</view>
</view>
<u-action-sheet :list="actionList" v-model="modelShow" @click="toServiceSet"
border-radius="20"></u-action-sheet>
</view>
</template>
<script>
export default {
data() {
return {
userAccount: {},
financeServiceList: [{
iconPath: '/static/image/wx/services/xinyongka.png',
title: '信用卡还款'
},
{
iconPath: '/static/image/wx/services/weilidai.png',
title: '微粒贷借钱'
},
{
iconPath: '/static/image/wx/services/licai.png',
title: '理财通'
},
{
iconPath: '/static/image/wx/services/baoxianfuwu.png',
title: '保险服务'
},
],
lifeServiceList: [{
iconPath: '/static/image/wx/services/shoujichongzhi.png',
title: '手机充值'
},
{
iconPath: '/static/image/wx/services/shenghuojiaofei.png',
title: '生活缴费'
},
{
iconPath: '/static/image/wx/services/qq.png',
title: 'Q币充值'
},
{
iconPath: '/static/image/wx/services/city.png',
title: '城市服务'
},
{
iconPath: '/static/image/wx/services/gongyi.png',
title: '腾讯公益'
},
{
iconPath: '/static/image/wx/services/yiliaojiankang.png',
title: '医疗健康'
},
],
jiaotongServiceList: [{
iconPath: '/static/image/wx/services/chuxing.png',
title: '出行服务'
},
{
iconPath: '/static/image/wx/services/huoche.png',
title: '火车票机票'
},
{
iconPath: '/static/image/wx/services/didi.png',
title: '滴滴出行'
},
{
iconPath: '/static/image/wx/services/jiudian.png',
title: '酒店'
},
],
shopList: [{
iconPath: '/static/image/wx/services/pinpai.png',
title: '品牌发现'
},
{
iconPath: '/static/image/wx/services/jingdong.png',
title: '京东购物'
},
{
iconPath: '/static/image/wx/services/waimai.png',
title: '美团外卖'
},
{
iconPath: '/static/image/wx/services/dianying.png',
title: '电影演出'
},
{
iconPath: '/static/image/wx/services/meituantejia.png',
title: '美团特价'
},
{
iconPath: '/static/image/wx/services/pinduoduo.png',
title: '拼多多'
},
{
iconPath: '/static/image/wx/services/weipinhui.png',
title: '唯品会特卖'
},
{
iconPath: '/static/image/wx/services/zhuanzhuan.png',
title: '转转二手'
},
{
iconPath: '/static/image/wx/services/beike.png',
title: '贝壳找房'
},
],
modelShow: false,
actionList: [{
text: '服务管理',
fontSize: 30,
color: '#000000',
subText: ''
}, ],
};
},
onShow: function() {
this.getAccountInfo();
},
methods: {
getAccountInfo: function() {
let that = this;
that.$u.api.imUser.getUserAccountInfo({}).then(res => {
if (res.code == 200) {
that.userAccount = res.data;
this.$u.vuex("vuex_userAccountInfo", that.userAccount);
}
})
},
amountFormat: function() {
let that = this;
if (that.userAccount != null && that.userAccount != {} && that.userAccount.accountBalance != null &&
that.userAccount != undefined) {
let value = this.userAccount.accountBalance ? this.userAccount.accountBalance.toString() : '0.00';
var arrayNum = value.split(".");
if (arrayNum.length == 1) {
return value.toString() + ".00";
} else {
if (arrayNum.length > 1) {
//小数点右侧 如果小于两位则补一个0
if (arrayNum[1].length < 2) {
return value.toString() + "0";
}
return value;
}
}
}
return "0.00";
},
toWallet: function() {
this.$u.route("/pages/tabbar/my/service/wallat");
},
toServiceSet: function(index) {
console.log(`点击了第${index + 1}项,内容为:${this.actionList[index].text}`)
},
}
}
</script>
<style lang="scss" scoped>
.service-home-page {
}
</style>
<style>
page {
background-color: #f1f1f1;
}
</style>
+95
View File
@@ -0,0 +1,95 @@
<template>
<view>
<u-navbar :is-back="true" title="支付管理" :title-bold="true" :title-size="34" :background="{ background: '#f1f1f1' }"
title-color="#404133" :border-bottom="false" z-index="1001">
</u-navbar>
<view style="width: 100%;">
<u-cell-item title="修改支付密码" @click="toUpdatePayPwd"></u-cell-item>
</view>
<u-popup v-model="passwordPopFlag" mode="bottom" border-radius="14" length="70%"
:mask-close-able="false">
<view class="u-p-30">
<view>
<view class="u-flex u-row-between">
<view style="width: 100rpx;" @click="closePwdPop">
<u-icon name="close"></u-icon>
</view>
<view v-if="pwdErrorTips.length>0"
style="text-align: center;color: #FC5531;font-size: 34rpx">
{{pwdErrorTips}}
</view>
<view v-else style="text-align: center;font-weight: bold;font-size: 32rpx;">
<text>请输入支付密码</text>
</view>
<view style="width: 100rpx;">
<text></text>
</view>
</view>
</view>
<view class="u-m-t-50">
<u-message-input :breathe="true" :maxlength="6" :dot-fill="true"
@change="inputChange" @finish="inputFinish" :focus="pwdFocus">
</u-message-input>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
passwordPopFlag:false,
pwdErrorTips:'',
pwdFocus:false,
};
},
methods:{
toUpdatePayPwd:function(){
this.passwordPopFlag=true;
this.pwdFocus=true;
},
closePwdPop:function(){
this.pwdErrorTips="";
this.passwordPopFlag=false;
this.pwdFocus=false;
},
inputChange(e){
this.pwdErrorTips="";
},
inputFinish(e) {
let that=this;
console.log('输入结束,当前值为:' + e);
let param={
tradePwd:e
};
that.$u.api.chatGroup.updateTradePwd(param).then(res => {
console.log("交易密码校验结果",res);
if(res.code==200){
this.globalUtil.utilAlert("修改成功");
this.closePwdPop();
setTimeout(function(){
uni.navigateBack();
},2000);
return;
}else{
let message=res.message?res.message:'支付密码错误';
this.globalUtil.utilAlert(message);
this.pwdErrorTips=message;
this.closePwdPop();
return;
}
})
},
}
}
</script>
<style lang="scss">
</style>
+106
View File
@@ -0,0 +1,106 @@
<template>
<view class="wallat-page">
<u-navbar :is-back="true" title="钱包" :title-bold="true" :title-size="34" :background="{ background: '#f1f1f1' }"
title-color="#404133" :border-bottom="false" z-index="1001">
<view slot="right" style="margin-right: 20rpx;" @click="toMyBill()">
<text style="font-size: 34rpx;color: #000000;">账单</text>
</view>
</u-navbar>
<view>
<template v-for="(item,index) in cellItemList">
<u-cell-item :title-style="titleStyle" :title="item.title"
@click="itemClick(item)"
style="padding: 36rpx 30rpx;"
:value="item.value?item.value:' '"
:value-style="valueStyle" bg-color="#ffffff">
<view slot="icon" class="u-m-r-16">
<u-icon :name="item.iconPath" :color="item.iconColor" :size="40" top="6"></u-icon>
</view>
</u-cell-item>
<u-gap v-if="index==2||index==4" height="16" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
</template>
</view>
<view style="position: absolute;bottom: 60rpx;text-align: center;width: 100%;">
<view style="color: #36648b;font-weight: bold;margin-bottom: 10rpx;">帮助中心</view>
<view style="font-size: 24rpx;color: #909399;">本服务由财务通提供</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
titleStyle:{
fontSize:'32rpx',
color:'#000000',
},
valueStyle:{
fontSize:'32rpx',
color:'#000000',
},
cellItemList:[
{title:'零钱',value:'¥105242.12',iconPath:'rmb-circle',iconColor:'#f29100'},
{title:'零钱通',value:'',iconPath:'integral',iconColor:'#f29100'},
{title:'银行卡',value:'',iconPath:'zhuanfa',iconColor:'#5788f2'},
{title:'支付分',value:'',iconPath:'coupon',iconColor:'#f29100'},
{title:'亲属卡',value:'',iconPath:'grid',iconColor:'#f29100'},
{title:'身份信息',value:'',iconPath:'fingerprint',iconColor:'#5788f2'},
/* {title:'安全保障',value:'',iconPath:'integral-fill',iconColor:'#5788f2'}, */
{title:'支付设置',value:'',iconPath:'setting',iconColor:'#5788f2'}
]
};
},
onLoad:function(){
console.log("this.vuex_userAccountInfo",this.vuex_userAccountInfo);
if(this.vuex_userAccountInfo!=null){
this.cellItemList[0].value= this.amountFormat(this.vuex_userAccountInfo.accountBalance);
}
},
methods:{
amountFormat:function(accountBalance){
let that=this;
if(accountBalance!=null&&accountBalance!=undefined){
let value=accountBalance?accountBalance.toString():'0.00';
var arrayNum = value.split(".");
if (arrayNum.length == 1) {
return value.toString()+".00";
}
else{
if (arrayNum.length>1) {
//小数点右侧 如果小于两位则补一个0
if (arrayNum[1].length<2) {
return value.toString()+"0" ;
}
return value;
}
}
}
return "0.00";
},
itemClick:function(item){
console.log("item",item);
if(item.title=='零钱'){
this.$u.route("/pages/tabbar/my/service/walletOption");
}
if(item.title=="支付设置"){
this.$u.route("/pages/tabbar/my/service/paySet");
}
},
toMyBill:function(){
this.$u.route("/pages/tabbar/my/service/my-bill");
}
}
}
</script>
<style lang="scss">
.wallat-page{
}
</style>
<style>
page{
background-color: #f1f1f1;
}
</style>
+93
View File
@@ -0,0 +1,93 @@
<template>
<view>
<u-navbar :is-back="true" title=" "
:background="{ background: '#f1f1f1' }"
:border-bottom="false">
<view slot="right" style="margin-right: 20rpx;">
<text style="font-size: 34rpx;color: #000000;">零钱明细</text>
</view>
</u-navbar>
<view style="display: flex;flex-direction: column;justify-content: space-around;align-items: center;">
<view class="u-m-t-80">
<u-icon name="rmb-circle-fill" size="120" color="#f2b007"></u-icon>
</view>
<view class="u-m-t-30 u-font-34">
<view style="text-align: center;">
<text>我的零钱</text>
</view>
<view style="font-size: 36px;font-weight: bold;text-align: center;margin-top: 20rpx;"> ¥ {{amountFormat()}}</view>
<view style="color: #f29100;font-size: 32rpx;text-align: center;margin-top: 20rpx;">
转入零钱通能赚又能花<u-icon name="arrow-right" color="#f29100" size="30"></u-icon>
</view>
</view>
</view>
<view class="u-m-t-80" style="padding:25%;">
<view>
<u-button @click="toPay()" type="success">充值</u-button>
</view>
<view class="u-m-t-30">
<u-button @click="toCashOut()" type="default" class="custom-style" :hair-line="false">
提现
</u-button>
</view>
</view>
<view style="position: absolute;bottom: 60rpx;text-align: center;width: 100%;">
<view style="color: #36648b;font-weight: bold;margin-bottom: 10rpx;">常见问题</view>
<view style="font-size: 24rpx;color: #909399;">本服务由财务通提供</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods:{
amountFormat:function(){
let that=this;
if(that.vuex_userAccountInfo!=null&&that.vuex_userAccountInfo.accountBalance!=null&&that.vuex_userAccountInfo!=undefined){
let value=this.vuex_userAccountInfo.accountBalance?this.vuex_userAccountInfo.accountBalance.toString():'0.00';
var arrayNum = value.split(".");
if (arrayNum.length == 1) {
return value.toString()+".00";
}
else{
if (arrayNum.length>1) {
//小数点右侧 如果小于两位则补一个0
if (arrayNum[1].length<2) {
return value.toString()+"0" ;
}
return value;
}
}
}
return "0.00";
},
toPay:function(){
this.$u.route("/pages/tabbar/my/service/wallet-pay");
},
toCashOut:function(){
},
}
}
</script>
<style lang="scss" scoped>
.custom-style{
background-color: #e0e0e0 !important;
color: #19be6b !important;
border:#f1f1f1 !important;
}
</style>
<style>
page{
background-color: #f1f1f1;
}
</style>
+251
View File
@@ -0,0 +1,251 @@
<template>
<view class="red-bag-page">
<u-navbar back-icon-name="close" :back-icon-size="36" back-icon-color="#333333" :border-bottom="false"
title="充值" title-color="#000000" :title-size="36" :title-bold="true">
<view slot="right">
<view class="u-m-r-20">
<u-icon name="more-dot-fill" color="#333333" :size="36"></u-icon>
</view>
</view>
</u-navbar>
<u-top-tips ref="uTips" :navbar-height="statusBarHeight + navbarHeight" type="error"></u-top-tips>
<view class="u-m-30" style="background-color: #ffffff;color: #000000;font-size: 34rpx;border-radius: 10rpx;">
<view class="u-flex u-row-between u-col-center u-p-20" :style="payValue>maxPayLimit?'color:#fa3534':''">
<view>
<text>金额</text>
</view>
<view>
<u-input input-align="right" v-model="payValue" :border="false"
@input="amountInputChange" type="digit"
:custom-style="{color:payValue>maxPayLimit?'#fa3534':'#000000',fontSize:'34rpx'}"
placeholder="¥0.00" placeholder-style="color:#cccccc;font-size:34rpx;" :clearable="false"/>
</view>
</view>
</view>
<view class="u-m-30" style="background-color: #ffffff;color: #000000;font-size: 34rpx;border-radius: 10rpx;">
<view class="u-flex u-row-between u-col-center"
style="width: 100%;padding: 30rpx 20rpx;" @click="selectPayWay">
<view>
<text>充值方式</text>
</view>
<view>
<u-icon color="#606266" name="arrow-right"
label-pos="left" label-color="#000000" label-size="32rpx"
:label="selectedPayWay.text"></u-icon>
</view>
</view>
</view>
<view :style="payValue>maxPayLimit?'color:#fa3534;text-align: center;margin-top: 120rpx;':'text-align: center;margin-top: 120rpx;'"
class="u-flex u-row-center u-col-center">
<view style="font-size:36px;margin-right: 10rpx;font-weight: 500;margin-bottom: 10rpx;">¥</view>
<view style="font-size:50px;font-weight: 400;">{{valueFormat()}}</view>
</view>
<view class="u-flex u-row-center u-col-center u-m-t-30">
<view @click="showPwdPop"
style="font-size: 36rpx; background-color:#19be6b;color:#ffffff;border-radius: 16rpx;text-align: center;padding: 26rpx 100rpx;">充值</view>
</view>
<!-- 支付方式 -->
<u-action-sheet :tips="tips" :list="payWaylist" @click="payWayClick" v-model="payWayshow"></u-action-sheet>
<u-popup v-model="passwordPopFlag" mode="bottom" border-radius="14" length="70%"
:mask-close-able="false">
<view class="u-p-30">
<view>
<view class="u-flex u-row-between">
<view style="width: 100rpx;" @click="closePwdPop">
<u-icon name="close"></u-icon>
</view>
<view v-if="pwdErrorTips.length>0"
style="text-align: center;color: #FC5531;font-size: 34rpx">
{{pwdErrorTips}}
</view>
<view v-else style="text-align: center;font-weight: bold;font-size: 32rpx;">
<text>请输入支付密码</text>
</view>
<view style="width: 100rpx;">
<text></text>
</view>
</view>
</view>
<view class="u-m-t-30 u-p-b-30 u-border-bottom" style="text-align: center;font-size: 18px;">
<view>充值到零钱</view>
<view style="font-weight: bold;">
<text style="margin-right: 6rpx;">¥</text><text style="font-size: 26px;">{{valueFormat()}}</text>
</view>
</view>
<view class="u-m-t-50">
<u-message-input :breathe="true" :maxlength="6" :dot-fill="true"
@change="inputChange" @finish="inputFinish" :focus="pwdFocus">
</u-message-input>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
payValue:"",
redBagRemark:"",
// 状态栏高度,H5中,此值为0,因为H5不可操作状态栏
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
// 导航栏内容区域高度,不包括状态栏高度在内
navbarHeight: 44,
chatGroupId:'',
passwordPopFlag:false,
pwdFocus:false,
pwdErrorTips:'',
payWayshow:false,
maxPayLimit:100000,
payWaylist:[
{
text: '银行卡1',
color:'#19be6b',
fontSize:32,
subText:'推荐',
payID:1
},
{
text: '银行卡2',
color:'#2979ff',
fontSize:32,
payID:2
}
],
tips: {
text: '选择充值方式',
color: '#000000',
fontSize: 36
},
selectedPayWay:{
text: '请选择',
payID:0
}
};
},
onLoad:function(option){
this.chatGroupId=option.chatGroupId;
},
methods:{
valueFormat:function(){
if(this.payValue.length<1){
return "0.00"
}
if(this.payValue.toString().indexOf(".")==-1){
return this.payValue+'.00';
}else{
return this.payValue;
}
},
amountInputChange:function(e){
console.log(e);
if(Number(e)>this.maxPayLimit){
this.showTips("单次充值金额不可超过"+this.maxPayLimit+"元");
this.payValue="";
}
},
selectPayWay:function(){
let that=this;
that.payWayshow=true;
},
payWayClick:function(index){
//console.log(`点击了第${index + 1}项`,this.payWaylist[index]);
this.selectedPayWay=this.payWaylist[index];
},
showPwdPop:function(){
let that=this;
if(this.payValue.length<1||this.payValue<=0){
this.showTips("未填写[金额]");
return;
}
if(this.payValue>this.maxPayLimit){
this.showTips("单次充值金额不可超过"+this.maxPayLimit+"元");
return;
}
if(this.selectedPayWay.payID<1){
this.showTips("请选择充值方式");
return;
}
this.passwordPopFlag=true;
this.pwdErrorTips="";
setTimeout(function(){
that.pwdFocus=true;
},1000)
},
closePwdPop:function(){
this.pwdErrorTips="";
this.passwordPopFlag=false;
this.pwdFocus=false;
},
inputChange(e){
this.pwdErrorTips="";
},
inputFinish(e) {
//this.pwdFocus=fasle;
let that=this;
console.log('输入结束当前值为' + e);
let param={
accountBalance:this.payValue,
tradePwd:e
};
that.$u.api.imUser.validatePayTradePwd(param).then(res => {
console.log("交易密码校验结果",res);
if(res.code==200){
this.submit();
}else{
let message=res.message?res.message:'支付密码错误';
this.globalUtil.utilAlert(message);
this.pwdErrorTips=message;
return;
}
})
},
submit:function(){
let that=this;
let param={
payValue:Number(this.payValue).toFixed(2),
payWay:this.selectedPayWay.payID,
}
that.$u.api.imUser.toPayUserBalance(param).then(res =>{
if(res.code==200){
that.userAccount=res.data;
this.$u.vuex("vuex_userAccountInfo",that.userAccount);
this.closePwdPop();
this.globalUtil.utilAlert("充值成功!",3000);
setTimeout(function(){
uni.navigateBack();
},2000)
}
})
console.log("充值参数",param);
},
showTips(title) {
this.$refs.uTips.show({
title: title?title:'未填写[金额]',
type:'error'
});
}
}
}
</script>
<style lang="scss" scoped>
.red-bag-page{
background-color: #f1f1f1;
}
</style>
<style>
page{
background-color: #f1f1f1;
}
</style>
@@ -0,0 +1,140 @@
<template>
<view>
<u-navbar :is-back="true" title="银行卡" :title-bold="true" :title-size="34"
:background="{background: '#f1f1f1'}"
title-color="#404133" :border-bottom="false" z-index="1001">
<view slot="right" class="u-m-r-20">
<u-icon name="more-dot-fill" size="48"></u-icon>
</view>
</u-navbar>
<template v-if="imgList.arr.length>0">
<view class="yinhangitem" v-for="item in imgList.arr" :style="{backgroundImage:'url( '+ item.bg2x_url +' )'}"
:key="item.bank_type">
<image class="itemlogo1" :src="item.logo1x_url" mode=""></image>
<view class="info">
<view class="itemtitle">{{item.bank_desc}}<br><span>储蓄卡</span></view>
<view class="itemnum"><span>·</span><span>·</span><span>·</span><span>· &nbsp;</span>
<span>·</span><span>·</span><span>·</span><span>· &nbsp;</span>
<span>·</span><span>·</span><span>·</span><span>· &nbsp;</span>
{{item.bank_type}}
</view>
</view>
<image class="itemlogo" :src="item.wl1x_url" mode="heightFix"></image>
</view>
</template>
<view class="add">
<span class="iconfont icon-jia"></span>
<span>添加银行卡</span>
<view>绑新卡送立减金</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imgList:{
arr:[]
}
};
},
onLoad() {
let that=this;
plus.io.resolveLocalFileSystemURL('/static/xml/tu.xml', (entry) => {
entry.file(function(file) {
const fileReader = new plus.io.FileReader()
fileReader.onloadend = (evt) => {
const data = JSON.parse(evt.target.result);
that.imgList.arr = data.bank_urls_list;
}
fileReader.readAsText(file, 'utf-8')
})
}, (err) => {
console.log("发生了错误", err)
})
}
}
</script>
<style lang="scss" scoped>
.add {
height: 140rpx;
width: calc(100% - 36rpx);
background-color: #ffffff;
border-radius: 16rpx;
margin: 10rpx auto;
padding: 30rpx;
box-sizing: border-box;
display: flex;
align-items: center;
.iconfont {
font-size: 40rpx;
margin-right: 16rpx;
font-weight: 700;
}
div {
color: #cea337;
font-size: 24rpx;
padding: 0 14rpx;
}
}
.yinhangitem {
background-repeat: no-repeat;
background-size: 200%;
background-position: center;
position: relative;
display: flex;
height: 220rpx;
width: calc(100% - 36rpx);
// background-color: black;
border-radius: 16rpx;
margin: 10rpx auto;
padding: 30rpx;
box-sizing: border-box;
.itemlogo1 {
width: 80rpx;
height: 80rpx;
}
.info {
padding: 0 18rpx;
box-sizing: border-box;
color: white;
.itemtitle {
span {
font-size: 24rpx;
color: #cbcece;
}
}
.itemnum {
// font-weight: 700;
font-size: 44rpx;
padding-top: 40rpx;
span {
font-weight: 700;
}
}
}
.itemlogo {
position: absolute;
right: 20rpx;
top: 0;
// width: 100rpx;
height: 100%;
}
}
</style>
<style>
page {
background-color: #f1f1f1;
}
</style>
@@ -0,0 +1,55 @@
<template>
<view class="container">
<!-- <u-navbar :is-back="false" title="" :border-bottom="false" :background="{background: 'rgb(99,200,98)'}">
<view class="slot-wrap">
<view @click="goback()">
<u-icon name="close" size="34" color="#ffffff"></u-icon>
</view>
</view>
</u-navbar> -->
<image style="height: 100%;width: 100%;" src="/static/image/wx/wallet/fen-fu-page.jpg"></image>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods:{
goback(){
uni.navigateBack();
}
}
}
</script>
<style lang="scss" scoped>
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1;
/* 如果您想让slot内容与导航栏左右有空隙 */
padding: 0 30rpx;
}
.container{
width: 100%;
height: 100%;
}
.page-image{
width: 100%;
height: 100%;
}
</style>
<style>
/*page{
width: 100%;
height: 100%;
background-image: url('/static/image/wx/wallet/fen-fu-page.jpg');
background-repeat: no-repeat;
background-size: 100% 100%;
} */
</style>
@@ -0,0 +1,52 @@
<template>
<view>
<u-navbar :is-back="false" title="" :border-bottom="false" :background="{background: '#ffffff'}">
<view class="slot-wrap">
<view @click="goback()">
<u-icon name="close" size="34" color="#606266"></u-icon>
</view>
</view>
</u-navbar>
<image class="page-image" src="/static/image/wx/wallet/linqiantong-page.jpg" mode="widthFix"></image>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods:{
handle(){
},
goback(){
uni.navigateBack();
}
}
}
</script>
<style lang="scss" scoped>
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1;
/* 如果您想让slot内容与导航栏左右有空隙 */
padding: 0 30rpx;
}
.page-image{
width: 100%;
margin-top: 30rpx;
}
</style>
<style>
page{
background-color: #ffffff;
}
</style>
@@ -0,0 +1,29 @@
<template>
<view>
<u-navbar :is-back="true" title="" :title-bold="true" :background="{background: '#ffffff'}" :border-bottom="false" z-index="1001">
</u-navbar>
<image class="page-image" src="/static/image/wx/wallet/qinshuka-page.png" mode="widthFix"></image>
</view>
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
<style lang="scss" scoped>
.page-image{
margin-top: 20rpx;
width: 100%;
}
</style>
<style>
page{
background-color: #ffffff;
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

+63
View File
@@ -0,0 +1,63 @@
@font-face {
font-family: "custom-icon";
font-weight: normal;
font-style: normal;
font-display: auto;
/* IE9 */
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAusAAsAAAAAFNgAAAtfAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCELAqaMJRxATYCJAMwCxoABCAFhREHgUUbNBEjkpBWCdlfHBjjbgo6UoZiMJ1gbEJ6Hnp89LLwnnuuuuqqm+OJ/vnu8UDsj3pfWCGZ0zch4SCX4ApHqF6UQr5QhSHc1m2jxyjlI4fRzKgvXjATExs3JKcwXvdR7Ud0tvkA4P/Btn9NWk/aG/KkKoJUbGIOV7hGkNbBv/jEDMKOa1/y+XpTa63eC+YhuYRCipT4Yrt7x9ziLyKLeiI02hOaTr9DVBo0KhmmEyOVTGwksIhuzcPV3lsbgNMJUOoxJVhaWd1KIEYwQI+zp04cIig0iTsyAnlD2rBr3BqaCLjycBR8Blej9w9+WQgEQCiJAG26kVo+SvvM10cN/D/lAQUUy9NC4yPCFGKNudfI3gAUOFmRkuQ4DoBm8dkRXyOlFh4S3bf456uKcNF41A8061yJXClTqNbiDyXStf/wUkCoRsytQMVXXhk5X4MySr6GZWR8jcoo+FrKeXQL5OeMbgPEp5cAgb4PLAH9EFgK+hGU16pim3bpxgzxLiDZjJi9UbBQis8mk53To4V1uLKzn7AthyOTin2VYRyOtwqTLX5+slxPI49ZiVh68dBGeTmk8WsQntR9J/pfu8TVD03zlm4oMCgWRD3tSvete/nitISQcTn+eCFNy1AJEuVUstjkKg/TV5RE0mc33FQ1w+WcgsJ6biIUg1P5qPnJJsYU88PNh9PFli/HHy5O+zsquNkaqaQxsekRv2dBNLKIBd3wy8WcKcUq+Q2ysFQ/XO63/GwBIXK+dC/V7QbG9UGiPfxgdpgupHK8MIu2aS0vW5R80gnKD0efg70rn9d08x1HIhKgMqWq+68p/niT/abVf2Oqcg4hTx6pKq2u9aYxhbiAoK0wJpEWSFIYOjoGnLtUDjnmvTOBjiAhiqOwADZegVDOuxDrJEJR0dksWzJ1uWIzJWk9gsJDlbuxLFPgYzMGplrbSFBfpuToEgH0+uzlOM7bCxgBr7k/5+pC4kkELVm6w2TXVrsqv7RxGNAlYgg3EAMrwSrcWmX1aEK8kxRwvF26OYCtDCVFZ2KYS2pPSIJwFvAyrY/1ESGMJWldFRwSbpPbisGIBBhyKoq3rm6J09Iu0CtDQiAns3K8LukmaB0JHhlCI5asU8dCsdsQYVenZdcY2B86WUu38oXvLGdDAH4QqwyzvzkMrIXvAgBypO+O/LZnxapvBFroKOzWK3Wtp8qv1exfvfJr/eeDFONxX2Y722lHELAT4I4C1ugtLn1XzblXH/yxmX9fHNIPXMv48PDgy85KtGEZc6WnY4eHpzmFXS6eHudW9ijKhLjuxcd6h1QbRn5akPW0ab1Xp2SRqNYQr23VW2m8eTRd3DQGE4YR8e0vH8y6Hbzz4cbRpdfk1TzJW0AUJUFR1p77fb2zd+a9OTdnDFRbKu07QeQ8YT5odv97Tz1GKlPf86SRakVWzaj0wXrrz9g9/uH2cnXYDR90hnYli8Sh9bY/8NlH3/3wyb5O0Lk9vLxsNs8K7nTDmLiQtbw2vdukirfLFGPkLIHoxsDjLBXL7nHlDe1Ag/rDNFV5sOcnSSIPADTy1wxw6++NGFh+jAdsWSSSBvGH/86Gt//ZhOCF/f9rQ2iXKsY0lwHJEIL4mdr874LxRLncxZVGPNnP5VrX+sQu1tcJhpd/2Wzac27RidfOKXiLbg6aPHq+z93IWLDtn4+qHee2rvYgHySFCcLogHOD4+cqQ7GCE9aVlqObqls6yqqOPspQ69JWj62PHdFpo+efda5xDmhpUil5Bdbz+NB1eGcHvwPTTmG7wfd8THxDZdAuaZ2OJZG3nj5WzHtm/rzYgev5KRGFe09STYrLbq9OdUbzguK+WF7cDe895UhDTMS7i7vXruxQcy3jlA4RxQ7dJChhDdtblGN8oKS2Q5dEdZpW4XlgrJGGg30ubc0aXP4MkhfZI79FaAV6VUVS++ibpTfnPS5hJ9/tM3U56Hl9Kbqsqf0ubHvCxQShAk5BMkaGA2TzyEiSHVUh3HIswcbdhVb2PtQfXrocHgD3X76ib8guXZFI8CzLl79s9iXFPgEXg2Jhg28jv4lTHRTDLffd5N3e8a7NvcpBb9EPHBndDHu3cvx8LpkdUyBt+dVyxYYD6+BkX4oNtMsa9Fwff0TuLSlG+MwiBVmwFMWYxUNwfmyaJ/8Lr+kC4s0nF3k8c4vahCR7j/GWe/t6v6KkeFHMNb7p4VDv8Y3V9eIrcU1LKCm6xHWPCIFbZxjdqlt9piDHTiIzDwh3e5wWHYD7zFztlkaJTnvsFsb05S9aD/c/KNjjcUZ4EJl2+CQIP4iFtXg6PVsCAnbVmZwXGYm0+EOC3LP4Ss+dUuAzYIjovBRcwPzMALMsVAYZJtwGCMG7C54zQ2v0Er2/CfNc0B3ndLepc/PU1mZXEl7Gpu4uK/QqUmjT9Xl5VnUPOeVFycsgloUNYjO2uQzm5WmEz5ih1XqpXpZyq3bT8XtY1Xl5IavuvwCKQF/kpBzI4xsD0LVvv9tKPhPm6Uoi94ZkEjlriqN0PYTPSLc1AU2s3ylTxs9rEn2lWZYelJ4xdm0cY2MNUfuInJDMfVFT7PjyruMzBqXTRUW01rf98DyeLJb/TcS7xgWKx4h8lU6nyq9wWZ02BeWmWEvpONTsA32BVKLXP4ja9RKpc4mHe/aCQgsVDpDyhXLSzlec6zd9Tei0T2tCci1xegU949iqVyDBMeQAFUfMyAlnZHUjHuPHtvOfBwIeKcfEd0hZ7jR8+hWl1JSet7coHmgTkAbN9gGlCBGafPW7YblPx6Z5R7OdtA4tHZhUuxRUpZejH/vIXMD3c+s2rc3fX5R3VZZuiPh4/VRWG1Df9/cgpdFcv/84KuSFV6L+TmJgjpCyy+uisnOiapfJchU5C4gS77GZnZyNXq+mT/f/vNihCxtY0T4hUpjaNlGVlPNiji5avp/4kzSlrl+n8bCrU/e2ke0taahn4M109q1o1BhMJgmq0ganr6CIpcu0BSWaKFtqGvFiu6Yu4QBHFNiJ6Qaizs85NXv74FHRvBReB+/VD8RNp2a6B8kHHmX39a4MeLx9Mtsn8JX1+E1O6xbxHGxBL3RD25EDsfnokSChdNkg444g5aYWQ6IDW9Ak2thm1EDMEbcAk3hJNnh9LmA5F7ywDZjcR/xBDFKuaIGIb5c+3UCQ812FZ+eYTfWmlh8SWYc1mfU55FLwV1OBrVN4dHd5Q0k6MOA/Kv6faC4SD7I50/A7YEeW4c9RzKeZd+GHRe1b+AbHK3weUUnZZUNw/5UhEIwj8IgfodVAwc8bc6ukPb4K0O/PqDtH+Ntl+39i9Xr1AnAbgKbyn5zmRL416qmKmsWxDUGnKpuyJ2fnij0k0sJAIpPH/OCYFe6tg1EOlgUALSi0fBgfno9A+Qs4MRECboxGwItJzRcJVhCJ8tAfgoRYaAwyCfmQVnbnwyQuAqQp5j7gIOYrxU0JUAEvRpUvUhTEHhLlF4wTJTjJGoasw2tZ3GykHZQ7kBEZ3S6GtquLc+eTJretxqmPTT1FpNNlRjQeToQ1hFJIB+lc3hauXqYIhqFwyknb8eQFn4202Wi8wUlbSCND1DNMQ7fQUKppS8JI24FIAidSDSYoXgdXi61tZkRzoPgYIkZuLoxjtlN3fZx8JBM3mxrO7ilI3iIkp47M0tLgwhHChglSJJANnXAbSZdeTCKmXgYF95CTZ8Qlb7WWZBN+Gq6heSULkhGDUM/wNugmVJqOGoqI9TL224ABF+sktL04gCEE4kBciAfxIQEk/CvYExJDGBCdc7vMRrXV3USnO9jNJregwVbDqs0OkywmaAeppuhLQm+sR0udnTWOOtouz1w2s4vpUI6XlWlBamhsxOIhDpIha1wkOg82m2vsZq2j1W2i3QAA') format('woff2');
/* iOS 4.1- */
}
.custom-icon-play-ing:before {
content: "\e611";
}
.custom-icon-play-one-foreach:before {
content: "\e6a3";
}
.custom-icon-play-random:before {
content: "\e6a0";
}
.custom-icon-play-list-foreach:before {
content: "\e6a2";
}
.custom-icon {
font-family: "custom-icon" !important;
position: relative;
display: flex;
font: normal normal normal 14px/1 "uicon-iconfont";
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.custom-icon::before {
display: flex;
align-items: center;
}
.custom-icon-music-kuwo:before {
content: "\e613";
}
.custom-icon-music-migu:before {
content: "\e644";
}
.custom-icon-music-qq:before {
content: "\e600";
}
.custom-icon-music-netease:before {
content: "\e603";
}
.custom-icon-music-xiami:before {
content: "\e601";
}
.custom-icon-music-kugou:before {
content: "\e60a";
}
.custom-icon-music-list:before {
content: "\e602";
}
+91
View File
@@ -0,0 +1,91 @@
.page-fixed{
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
.btn-active {
&:active {
opacity: 0.8;
}
}
.flex-v-center{
display: flex;
align-items: center;
}
.flex-h-center{
display: flex;
justify-items: center;
justify-content:center;
}
.flex-v-h-center{
display: flex;
justify-items: center;
align-items: center;
justify-content:center;
}
.flex-v{
flex-direction: column;
}
.flex{
display: flex;
}
.flex-space-between {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.flex-flex-end{
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
}
[class*="text-line-"]{
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
.text-line-1{
-webkit-line-clamp: 1;
}
.text-line-2{
-webkit-line-clamp: 2;
}
.text-line-3{
-webkit-line-clamp: 3;
}
.text-line-4{
-webkit-line-clamp: 4;
}
.text-line-5{
-webkit-line-clamp: 5;
}
@keyframes textScrollRun {
0% {
left: 0;
transform: translate(0, 0);
}
100% {
left: 100%;
transform: translate(-100%, 0);
}
}
.text-scroll-content{
white-space: nowrap;
display: inline-block;
}
.text-scroll-run{
animation: textScrollRun 15s infinite alternate linear;
}
.text-scroll{
width: 100%;
white-space: nowrap;
overflow: hidden;
}
+1 -1
View File
@@ -31,7 +31,7 @@ const actions = {
}, },
async getFriendCircleInfo({ commit, state}) { async getFriendCircleInfo({ commit, state}) {
uni.$u.http.get('/friendcircle/info').then(data=>{ uni.$u.http.get('/friendcircle/info').then(data=>{
console.log("获取朋友圈信息",data); //console.log("获取朋友圈信息",data);
commit("SET_UNREAD_COUNT", data.unread_count); commit("SET_UNREAD_COUNT", data.unread_count);
commit("SET_TOP_UNREAD_ITEMS", data.top_unread_items); commit("SET_TOP_UNREAD_ITEMS", data.top_unread_items);
commit("SET_SETTINGS", data.settings); commit("SET_SETTINGS", data.settings);
+8 -5
View File
@@ -1,8 +1,6 @@
import { import {v4 as uuidv4} from "uuid";
v4 as uuidv4
} from "uuid";
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill";
import conversation from "./conversation";
const state = { const state = {
friendList: [], friendList: [],
blackList: [], blackList: [],
@@ -160,7 +158,7 @@ const actions = {
commit("SET_FRIEND_LIST", [...tmpList, friendInfo]); commit("SET_FRIEND_LIST", [...tmpList, friendInfo]);
} }
}, },
updateFriendInfo({commit,state}, { friendInfo,isRemove = false}) { updateFriendInfo({commit,state,dispatch }, { friendInfo,isRemove = false}) {
const tmpList = [...state.friendList]; const tmpList = [...state.friendList];
const idx = tmpList.findIndex((item) => item.userID === friendInfo.userID); const idx = tmpList.findIndex((item) => item.userID === friendInfo.userID);
@@ -174,6 +172,11 @@ const actions = {
} }
commit("SET_FRIEND_LIST", tmpList); commit("SET_FRIEND_LIST", tmpList);
} }
if (isRemove) {
const conversationID = friendInfo.userID ? `si_${friendInfo.ownerUserID}_${friendInfo.userID}` : `si_${friendInfo.groupID}`;
dispatch('conversation/deleteConversation',conversationID, { root: true });
}
}, },
pushNewBlack({ commit, state}, blackInfo) { pushNewBlack({ commit, state}, blackInfo) {
const tmpList = [...state.blackList]; const tmpList = [...state.blackList];
+15 -3
View File
@@ -103,13 +103,25 @@ const actions = {
commit("SET_CURRENT_MEMBER_IN_GROUP", memberInfo); commit("SET_CURRENT_MEMBER_IN_GROUP", memberInfo);
} }
}, },
resetConversationState({ resetConversationState({commit}) {
commit
}) {
commit("SET_CURRENT_MEMBER_IN_GROUP", {}); commit("SET_CURRENT_MEMBER_IN_GROUP", {});
commit("SET_CURRENT_GROUP", {}); commit("SET_CURRENT_GROUP", {});
commit("SET_CURRENT_CONVERSATION", {}); commit("SET_CURRENT_CONVERSATION", {});
}, },
deleteConversation({state,commit},conversationID) {
return new Promise((reject,resolve)=>{
IMSDK.asyncApi('deleteConversationAndDeleteAllMsg',uuidv4(), conversationID).then(res=>{
const list = state.conversationList.filter((item)=>{
return item.conversationID != conversationID;
});
commit("SET_CONVERSATION_LIST", [...list]);
resolve();
}).catch((e)=>{
console.error(e);
reject(e);
})
})
},
}; };
export default { export default {
+1 -1
View File
@@ -81,7 +81,7 @@ const actions = {
resetMessageState({commit}) { resetMessageState({commit}) {
commit("SET_HISTORY_MESSAGE_LIST", []); commit("SET_HISTORY_MESSAGE_LIST", []);
commit("SET_HAS_MORE_MESSAGE", true); commit("SET_HAS_MORE_MESSAGE", true);
}, }
}; };
export default { export default {
+2 -2
View File
@@ -38,7 +38,7 @@ const mutations = {
}; };
const actions = { const actions = {
async getSelfInfo({ commit }) { async getSelfInfo({commit}) {
//#ifndef APP //#ifndef APP
return []; return [];
//#endif //#endif
@@ -57,7 +57,7 @@ const actions = {
uni.$u.toast("获取个人信息失败"); uni.$u.toast("获取个人信息失败");
} }
}, },
async updateBusinessInfo({ commit, state }) { async updateBusinessInfo({commit,state}) {
try { try {
const res = await businessGetUserInfo(state.selfInfo.userID); const res = await businessGetUserInfo(state.selfInfo.userID);
const businessData = res.data[0] ?? {}; const businessData = res.data[0] ?? {};
+234
View File
@@ -0,0 +1,234 @@
## 2.0.72026-02-05
- fix: 修复非web无法缩放问题
## 2.0.62025-12-13
- feat: 修复类型问题
## 2.0.52025-12-12
- fix: 修复uniappx 微信小程序模糊问题
## 2.0.42025-12-12
- fix: 修复uniapp vue2 app引入依赖报错问题
## 2.0.32025-12-04
- feat: autoHideTooltip默认为false
## 2.0.22025-11-24
- feat: 增加`autoHideTooltip`属性
## 2.0.12025-10-28
- chore: 更新文档
## 2.0.02025-10-28
- feat: 基于 Vue 3 Composition API 重构 uni-app 端组件,提升代码可维护性和性能
- feat: 升级内置 ECharts 至 v6 版本,支持最新图表特性和性能优化
## 1.0.42025-05-16
- fix: 修复uniappx ios尺寸
## 1.0.32025-05-10
- fix: 修复nvue缺少`isDisposed`
## 1.0.22025-03-21
- fix: 修复词云无法设置字体大小的问题
## 1.0.12025-03-14
- fix: 修复抖音小程序不显示问题
## 1.0.02025-02-27
- fix: 修复uniappx微信小程序不显示问题
## 0.9.92025-02-24
- feat: 更新v4
## 0.9.82024-12-20
- fix: 修复 APP 无法放大问题
## 0.9.72024-12-02
- feat: uniapp 增加`landscape`,当`landscape``true`时旋转90deg达到横屏效果。
- feat: 支持uniapp x 微信小程序
## 0.9.62024-07-23
- fix: 修复 uni is not defined
## 0.9.52024-07-19
- chore: 鸿蒙`measureText`为异步,异步字体不正常,使用模拟方式。
## 0.9.42024-07-18
- chore: 更新文档
## 0.9.32024-07-16
- feat: 鸿蒙 canvas 事件缺失,待官方修复,如何在鸿蒙使用请看文档`常见问题 vue3`
## 0.9.22024-07-12
- chore: 删除多余文件
## 0.9.12024-07-12
- fix: 修复 安卓5不显示图表问题
## 0.9.02024-06-13
- chore: 合并nvue和uvue
## 0.8.92024-05-19
- chore: 更新文档
## 0.8.82024-05-13
- chore: 更新文档和uvue示例
## 0.8.72024-04-26
- fix: uniapp x需要HBX 4.13以上
## 0.8.62024-04-10
- feat: 支持 uniapp x ios
## 0.8.52024-04-03
- fix: 修复 nvue `reset`传值不生效问题
- feat: 支持 uniapp x web
## 0.8.42024-01-27
- chore: 更新文档
## 0.8.32024-01-21
- chore: 更新文档
## 0.8.22024-01-21
- feat: 支持 `uvue`
## 0.8.12023-08-24
- fix: app 的`touch`事件为`object` 导致无法显示 `tooltip`
## 0.8.02023-08-22
- fix: 离屏 报错问题
- fix: 微信小程序PC无法使用事件
- chore: 更新文档
## 0.7.92023-07-29
- chore: 更新文档
## 0.7.82023-07-29
- fix: 离屏 报错问题
## 0.7.72023-07-27
- chore: 更新文档
- chore: lime-echart 里的示例使用自定tooltips
- feat: 对支持离屏的使用离屏创建(微信、字节、支付宝)
## 0.7.62023-06-30
- fix: vue3 报`width`的错
## 0.7.52023-05-25
- chore: 更新文档 和 demo, 使用`lime-echart`这个标签即可查看示例
## 0.7.42023-05-22
- chore: 增加关于钉钉小程序上传时提示安全问题的说明及修改建议
## 0.7.32023-05-16
- chore: 更新 vue3 非微信小程序平台可能缺少`wx`的说明
## 0.7.22023-05-16
- chore: 更新 vue3 非微信小程序平台的可以缺少`wx`的说明
## 0.7.12023-04-26
- chore: 更新demo,使用`lime-echart`这个标签即可查看示例
- chore:微信小程序的`tooltip`文字有阴影,怀疑是微信的锅,临时解决方法是`tooltip.shadowBlur = 0`
## 0.7.02023-04-24
- fix: 修复`setAttribute is not a function`
## 0.6.92023-04-15
- chore: 更新文档,vue3请使用echarts esm的包
## 0.6.82023-03-22
- feat: mac pc无法使用canvas 2d
## 0.6.72023-03-17
- feat: 更新文档
## 0.6.62023-03-17
- feat: 微信小程序PC已经支持canvas 2d,故去掉判断PC
## 0.6.52022-11-03
- fix: 某些手机touches为对象,导致无法交互。
## 0.6.42022-10-28
- fix: 优化点击事件的触发条件
## 0.6.32022-10-26
- fix: 修复 dataZoom 拖动问题
## 0.6.22022-10-23
- fix: 修复 飞书小程序 尺寸问题
## 0.6.12022-10-19
- fix: 修复 PC mousewheel 事件 鼠标位置不准确的BUG,不兼容火狐!
- feat: showLoading 增加传参
## 0.6.02022-09-16
- feat: 增加PC的mousewheel事件
## 0.5.42022-09-16
- fix: 修复 nvue 动态数据不显示问题
## 0.5.32022-09-16
- feat: 增加enableHover属性, 在PC端时当鼠标进入显示tooltip,不必按下。
- chore: 更新文档
## 0.5.22022-09-16
- feat: 增加enableHover属性, 在PC端时当鼠标进入显示tooltip,不必按下。
## 0.5.12022-09-16
- fix: 修复nvue报错
## 0.5.02022-09-15
- feat: init(echarts, theme?:string, opts?:{}, callback: function(chart))
## 0.4.82022-09-11
- feat: 增加 @finished
## 0.4.72022-08-24
- chore: 去掉 stylus
## 0.4.62022-08-24
- feat: 增加 beforeDelay
## 0.4.52022-08-12
- chore: 更新文档
## 0.4.42022-08-12
- fix: 修复 resize 无参数时报错
## 0.4.32022-08-07
# 评论有说本插件对新手不友好,让我做不好就不要发出来。 还有的说跟官网一样,发出来做什么,给我整无语了。
# 所以在此提醒一下准备要下载的你,如果你从未使用过 echarts 请不要下载 或 谨慎下载。
# 如果你确认要下载,麻烦看完文档。还有请注意插件是让echarts在uniapp能运行,API 配置请自行去官网查阅!
# 如果你不会echarts 但又需要图表,市场上有个很优秀的图表插件 uchart 你可以去使用这款插件,uchart的作者人很好,也热情。
# 每个人都有自己的本职工作,如果你能力强可以自行兼容,如果使用了他人的插件也麻烦尊重他人的成果和劳动时间。谢谢。
# 为了心情愉悦,本人已经使用插件屏蔽差评。
- chore: 更新文档
## 0.4.22022-07-20
- feat: 增加 resize
## 0.4.12022-06-07
- fix: 修复 canvasToTempFilePath 不生效问题
## 0.4.02022-06-04
- chore 为了词云 增加一个canvas 标签
- 词云下载地址[echart-wordcloud](https://ext.dcloud.net.cn/plugin?id=8430)
## 0.3.92022-06-02
- chore: 更新文档
- tips: lines 不支持 `trailLength`
## 0.3.82022-05-31
- fix: 修复 因mouse事件冲突tooltip跳动问题
## 0.3.72022-05-26
- chore: 更新文档
- chore: 设置默认宽高300px
- fix: 修复 vue3 微信小程序 拖影BUG
- chore: 支持PC
## 0.3.52022-04-28
- chore: 更新使用方式
- 🔔 必须使用hbuilderx 3.4.8-alpha以上
## 0.3.42021-08-03
- chore: 增加 setOption的参数值
## 0.3.32021-07-22
- fix: 修复 径向渐变报错的问题
## 0.3.22021-07-09
- chore: 统一命名规范,无须主动引入组件
## [代码示例站点1](https://limeui.qcoon.cn/#/echart-example)
## [代码示例站点2](http://liangei.gitee.io/limeui/#/echart-example)
## 0.3.12021-06-21
- fix: 修复 app-nvue ios is-enable 无效的问题
## [代码示例站点1](https://limeui.qcoon.cn/#/echart-example)
## [代码示例站点2](http://liangei.gitee.io/limeui/#/echart-example)
## 0.3.02021-06-14
- fix: 修复 头条系小程序 2d 报 JSON.stringify 的问题
- 目前 头条系小程序 2d 无法在开发工具上预览,划动图表页面无法滚动,axisLabel 字体颜色无法更改,建议使用非2d。
## 0.2.92021-06-06
- fix: 修复 头条系小程序 2d 放大的BUG
- 头条系小程序 2d 无法在开发工具上预览,也存在划动图表页面无法滚动的问题。
## [代码示例:http://liangei.gitee.io/limeui/#/echart-example](http://liangei.gitee.io/limeui/#/echart-example)
## 0.2.82021-05-19
- fix: 修复 微信小程序 PC 显示过大的问题
## 0.2.72021-05-19
- fix: 修复 微信小程序 PC 不显示问题
## [代码示例:http://liangei.gitee.io/limeui/#/echart-example](http://liangei.gitee.io/limeui/#/echart-example)
## 0.2.62021-05-14
- feat: 支持 `image`
- feat: props 增加 `ec.clear`,更新时是否先删除图表样式
- feat: props 增加 `isDisableScroll` ,触摸图表时是否禁止页面滚动
- feat: props 增加 `webviewStyles` webview 的样式, 仅nvue有效
## 0.2.52021-05-13
- docs: 插件用到了css 预编译器 [stylus](https://ext.dcloud.net.cn/plugin?name=compile-stylus) 请安装它
## 0.2.42021-05-12
- fix: 修复 百度平台 多个图表ctx 和 渐变色 bug
- ## [代码示例:http://liangei.gitee.io/limeui/#/echart-example](http://liangei.gitee.io/limeui/#/echart-example)
## 0.2.32021-05-10
- feat: 增加 `canvasToTempFilePath` 方法,用于生成图片
```js
this.$refs.chart.canvasToTempFilePath({success: (res) => {
console.log('tempFilePath:', res.tempFilePath)
}})
```
## 0.2.22021-05-10
- feat: 增加 `dispose` 方法,用于销毁实例
- feat: 增加 `isClickable` 是否派发点击
- feat: 实验性的支持 `nvue` 使用要慎重考虑
- ## [代码示例:http://liangei.gitee.io/limeui/#/echart-example](http://liangei.gitee.io/limeui/#/echart-example)
## 0.2.12021-05-06
- fix:修复 微信小程序 json 报错
- chore: `reset` 更改为 `setChart`
- feat: 增加 `isEnable` 开启初始化 启用这个后 无须再使用`init`方法
```html
<l-echart ref="chart" is-enable />
```
```js
// 显示加载
this.$refs.chart.showLoading()
// 使用实例回调
this.$refs.chart.setChart(chart => ...code)
// 直接设置图表配置
this.$refs.chart.setOption(data)
```
## 0.2.02021-05-05
- fix:修复 头条 百度 偏移的问题
- docs: 更新文档
## [代码示例:http://liangei.gitee.io/limeui/#/echart-example](http://liangei.gitee.io/limeui/#/echart-example)
## 0.1.02021-05-02
- chore: 第一次上传,基本全端兼容,使用方法与官网一致。
- 已知BUG:非2d 无法使用背景色,已反馈官方
- 已知BUG:头条 百度 有许些偏移
- 后期计划:兼容nvue
@@ -0,0 +1,399 @@
import {getDeviceInfo} from './utils';
const cacheChart = {}
const fontSizeReg = /([\d\.]+)px/;
class EventEmit {
constructor() {
this.__events = {};
}
on(type, listener) {
if (!type || !listener) {
return;
}
const events = this.__events[type] || [];
events.push(listener);
this.__events[type] = events;
}
emit(type, e) {
if (type.constructor === Object) {
e = type;
type = e && e.type;
}
if (!type) {
return;
}
const events = this.__events[type];
if (!events || !events.length) {
return;
}
events.forEach((listener) => {
listener.call(this, e);
});
}
off(type, listener) {
const __events = this.__events;
const events = __events[type];
if (!events || !events.length) {
return;
}
if (!listener) {
delete __events[type];
return;
}
for (let i = 0, len = events.length; i < len; i++) {
if (events[i] === listener) {
events.splice(i, 1);
i--;
}
}
}
}
class Image {
constructor() {
this.currentSrc = null
this.naturalHeight = 0
this.naturalWidth = 0
this.width = 0
this.height = 0
this.tagName = 'IMG'
}
set src(src) {
this.currentSrc = src
uni.getImageInfo({
src,
success: (res) => {
this.naturalWidth = this.width = res.width
this.naturalHeight = this.height = res.height
this.onload()
},
fail: () => {
this.onerror()
}
})
}
get src() {
return this.currentSrc
}
}
class OffscreenCanvas {
constructor(ctx, com, canvasId) {
this.tagName = 'canvas'
this.com = com
this.canvasId = canvasId
this.ctx = ctx
}
set width(w) {
this.com.offscreenWidth = w
}
set height(h) {
this.com.offscreenHeight = h
}
get width() {
return this.com.offscreenWidth || 0
}
get height() {
return this.com.offscreenHeight || 0
}
getContext(type) {
return this.ctx
}
getImageData() {
return new Promise((resolve, reject) => {
this.com.$nextTick(() => {
uni.canvasGetImageData({
x:0,
y:0,
width: this.com.offscreenWidth,
height: this.com.offscreenHeight,
canvasId: this.canvasId,
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
},
}, this.com)
})
})
}
}
export class Canvas {
constructor(ctx, com, isNew, canvasNode={}) {
cacheChart[com.canvasId] = {ctx}
this.canvasId = com.canvasId;
this.chart = null;
this.isNew = isNew
this.tagName = 'canvas'
this.canvasNode = canvasNode;
this.com = com;
if (!isNew) {
this._initStyle(ctx)
}
this._initEvent();
this._ee = new EventEmit()
}
getContext(type) {
if (type === '2d') {
return this.ctx;
}
}
setAttribute(key, value) {
if(key === 'aria-label') {
this.com['ariaLabel'] = value
}
}
setChart(chart) {
this.chart = chart;
}
createOffscreenCanvas(param){
if(!this.children) {
// this.com.isOffscreenCanvas = true
// this.com.offscreenWidth = param.width||300
// this.com.offscreenHeight = param.height||300
// const com = this.com
// const canvasId = this.com.offscreenCanvasId
// const context = uni.createCanvasContext(canvasId, this.com)
// this._initStyle(context)
// this.children = new OffscreenCanvas(context, com, canvasId)
}
return this.children
}
appendChild(child) {
console.log('child', child)
}
dispatchEvent(type, e) {
if(typeof type == 'object') {
this._ee.emit(type.type, type);
} else {
this._ee.emit(type, e);
}
return true
}
attachEvent() {
}
detachEvent() {
}
addEventListener(type, listener) {
this._ee.on(type, listener)
}
removeEventListener(type, listener) {
this._ee.off(type, listener)
}
_initCanvas(zrender, ctx) {
// zrender.util.getContext = function() {
// return ctx;
// };
// zrender.util.$override('measureText', function(text, font) {
// ctx.font = font || '12px sans-serif';
// return ctx.measureText(text, font);
// });
}
_initStyle(ctx, child) {
const styles = [
'fillStyle',
'strokeStyle',
'fontSize',
'globalAlpha',
'opacity',
'textAlign',
'textBaseline',
'shadow',
'lineWidth',
'lineCap',
'lineJoin',
'lineDash',
'miterLimit',
// #ifdef H5 || APP
'font',
// #endif
];
const colorReg = /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])\b/g;
styles.forEach(style => {
Object.defineProperty(ctx, style, {
set: value => {
// #ifdef H5 || APP
if (style === 'font' && fontSizeReg.test(value)) {
const match = fontSizeReg.exec(value);
ctx.setFontSize(match[1]);
return;
}
// #endif
if (style === 'opacity') {
ctx.setGlobalAlpha(value)
return;
}
if (style !== 'fillStyle' && style !== 'strokeStyle' || value !== 'none' && value !== null) {
// #ifdef H5 || APP-PLUS || MP-BAIDU
if(typeof value == 'object') {
if (value.hasOwnProperty('colorStop') || value.hasOwnProperty('colors')) {
ctx['set' + style.charAt(0).toUpperCase() + style.slice(1)](value);
}
return
}
// #endif
// #ifdef MP-TOUTIAO
if(colorReg.test(value)) {
value = value.replace(colorReg, '#$1$1$2$2$3$3')
}
// #endif
ctx['set' + style.charAt(0).toUpperCase() + style.slice(1)](value);
}
}
});
});
if(!this.isNew && !child) {
ctx.uniDrawImage = ctx.drawImage
ctx.drawImage = (...a) => {
a[0] = a[0].src
ctx.uniDrawImage(...a)
}
}
if(!ctx.createRadialGradient) {
ctx.createRadialGradient = function() {
return ctx.createCircularGradient(...[...arguments].slice(-3))
};
}
// 字节不支持
if (!ctx.strokeText) {
ctx.strokeText = (...a) => {
ctx.fillText(...a)
}
}
// 钉钉不支持 , 鸿蒙是异步
if (!ctx.measureText || getDeviceInfo().osName == 'harmonyos') {
ctx._measureText = ctx.measureText
const strLen = (str) => {
let len = 0;
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) {
len++;
} else {
len += 2;
}
}
return len;
}
ctx.measureText = (text, font) => {
let fontSize = ctx?.state?.fontSize || 12;
if (font) {
fontSize = parseInt(font.match(/([\d\.]+)px/)[1])
}
fontSize /= 2;
let isBold = fontSize >= 16;
const widthFactor = isBold ? 1.3 : 1;
// ctx._measureText(text, (res) => {})
return {
width: strLen(text) * fontSize * widthFactor
};
}
}
}
_initEvent(e) {
this.event = {};
const eventNames = [{
wxName: 'touchStart',
ecName: 'mousedown'
}, {
wxName: 'touchMove',
ecName: 'mousemove'
}, {
wxName: 'touchEnd',
ecName: 'mouseup'
}, {
wxName: 'touchEnd',
ecName: 'click'
}];
eventNames.forEach(name => {
this.event[name.wxName] = e => {
const touch = e.touches[0];
this.chart.getZr().handler.dispatch(name.ecName, {
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
zrY: name.wxName === 'tap' ? touch.clientY : touch.y
});
};
});
}
set width(w) {
this.canvasNode.width = w
}
set height(h) {
this.canvasNode.height = h
}
get width() {
return this.canvasNode.width || 0
}
get height() {
return this.canvasNode.height || 0
}
get ctx() {
return cacheChart[this.canvasId]['ctx'] || null
}
set chart(chart) {
cacheChart[this.canvasId]['chart'] = chart
}
get chart() {
return cacheChart[this.canvasId]['chart'] || null
}
}
export function dispatch(name, {x,y, wheelDelta}) {
this.dispatch(name, {
zrX: x,
zrY: y,
zrDelta: wheelDelta,
preventDefault: () => {},
stopPropagation: () =>{}
});
}
export function setCanvasCreator(echarts, {canvas, node}) {
if(echarts && !echarts.registerPreprocessor) {
return console.warn('echarts 版本不对或未传入echartsvue3请使用esm格式')
}
echarts.registerPreprocessor(option => {
if (option && option.series) {
if (option.series.length > 0) {
option.series.forEach(series => {
series.progressive = 0;
});
} else if (typeof option.series === 'object') {
option.series.progressive = 0;
}
}
});
function loadImage(src, onload, onerror) {
let img = null
if(node && node.createImage) {
img = node.createImage()
img.onload = onload.bind(img);
img.onerror = onerror.bind(img);
img.src = src;
return img
} else {
img = new Image()
img.onload = onload.bind(img)
img.onerror = onerror.bind(img);
img.src = src
return img
}
}
if(echarts.setPlatformAPI) {
echarts.setPlatformAPI({
loadImage: canvas.setChart ? loadImage : null,
createCanvas(){
const key = 'createOffscreenCanvas'
return uni.canIUse(key) && uni[key] ? uni[key]({type: '2d'}) : canvas
}
})
} else if(echarts.setCanvasCreator) {
echarts.setCanvasCreator(() => {
return canvas;
});
}
}
@@ -0,0 +1,322 @@
<template>
<!-- #ifdef APP -->
<web-view class="lime-echart" ref="chartRef" @load="loaded" :style="[lStyle]" :webview-styles="[webviewStyles]"
src="/uni_modules/lime-echart/static/app/uvue.html?v=10112">
</web-view>
<!-- #endif -->
<!-- #ifdef WEB -->
<div class="lime-echart" ref="chartRef"></div>
<!-- #endif -->
<!-- #ifndef WEB || APP-->
<view class="lime-echart">
<canvas style="width:100%; height:100%" v-if="canvasid" :id="canvasid" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas>
</view>
<!-- #endif -->
</template>
<script lang="uts" setup>
// @ts-nocheck
import { echartsProps } from './type';
import { Echarts } from './uvue';
// #ifdef WEB
import { dispatch } from './canvas';
import * as echartsLibrary from '@/uni_modules/lime-echart/static/web/echarts.esm.min.js';
// #endif
// #ifndef APP || WEB
import { Canvas, setCanvasCreator, dispatch } from './canvas';
import { wrapTouch, convertTouchesToArray, devicePixelRatio, sleep, canIUseCanvas2d, getRect } from './utils';
// #endif
type EChartsResolveCallback = (value : Echarts) => void
const emits = defineEmits(['finished'])
const props = withDefaults(defineProps<echartsProps>(), {
isDisableScroll: false,
isClickable: true,
autoHideTooltip: false,
enableHover: false,
landscape: false,
beforeDelay: 30,
})
const instance = getCurrentInstance()!;
const canvasid = `lime-echart-${instance.uid}`
const finished = ref(false)
const initializationQueue = [] as EChartsResolveCallback[]
const callbackQueue = [] as EChartsResolveCallback[]
// let context = null as UniWebViewElement | null
let chartInstance = null as Echarts | null
let chartRef = ref<UniWebViewElement | null>(null)
let canvasNode:any|null = null
const processInitializationQueue = () => {
// #ifdef APP
if (finished.value) {
if (chartInstance == null) {
chartInstance = new Echarts(chartRef.value!)
}
while (initializationQueue.length > 0) {
const resolve = initializationQueue.pop() as EChartsResolveCallback
resolve(chartInstance!)
}
}
// #endif
// #ifndef APP
while (initializationQueue.length > 0) {
if (chartInstance != null) {
const resolve = initializationQueue.pop() as EChartsResolveCallback
resolve(chartInstance!)
}
}
// #endif
if (chartInstance != null) {
while (callbackQueue.length > 0) {
const callback = callbackQueue.pop() as EChartsResolveCallback
callback(chartInstance!)
}
}
}
// #ifdef APP
const loaded = (event : UniWebViewLoadEvent) => {
event.stopPropagation()
event.preventDefault()
nextTick(()=> {
chartRef.value?.getBoundingClientRectAsync()?.then(res => {
if(res.width > 0 && res.height > 0) {
finished.value = true
processInitializationQueue()
emits('finished')
} else {
console.warn('【lime-echart】获取尺寸失败,请检查代码样式')
}
})
})
}
// #endif
const checkInitialization = () : boolean => {
if (chartInstance == null) {
console.warn(`组件还未初始化,请先使用 init`)
return true
}
return false
}
const setOption = (option : UTSJSONObject) => {
if (checkInitialization()) return
chartInstance!.setOption(option);
}
const showLoading = () => {
if (checkInitialization()) return
chartInstance!.showLoading();
}
const hideLoading = () => {
if (checkInitialization()) return
chartInstance!.hideLoading();
}
const clear = () => {
if (checkInitialization()) return
chartInstance!.clear();
}
const dispose = () => {
if (checkInitialization()) return
chartInstance!.dispose();
}
const resize = (size : UTSJSONObject) => {
if (checkInitialization()) return
chartInstance!.resize(size);
}
const canvasToTempFilePath = (opt : UTSJSONObject) => {
if (checkInitialization()) return
// #ifdef APP
chartInstance!.canvasToTempFilePath(opt);
// #endif
// #ifdef WEB
opt.success?.({
// @ts-ignore
tempFilePath: chartInstance!._api.getDataURL()
})
// #endif
// #ifndef WEB || APP
if(canvasNode) {
opt.success?.({
tempFilePath: canvasNode.toDataURL()
})
} else {
uni.canvasToTempFilePath({
...opt,
canvasId
}, instance.proxy);
}
// #endif
}
// #ifdef APP
function init(callback : ((chartInstance : Echarts) => void) | null) : Promise<Echarts> {
if (callback != null) {
callbackQueue.push(callback)
}
return new Promise<Echarts>((resolve) => {
initializationQueue.push(resolve)
processInitializationQueue()
})
}
// #endif
// #ifndef APP
// #ifndef WEB
let use2dCanvas = canIUseCanvas2d()
const getContext = async () => {
return new Promise((resolve, reject)=>{
uni.createCanvasContextAsync({
id: canvasid,
component: instance.proxy!,
success: (context : CanvasContext) => {
canvasNode = context
const canvasContext = context.getContext('2d')!;
const canvas = canvasContext.canvas;
let uniCanvas;
const width = canvas.offsetWidth
const height = canvas.offsetHeight
// 处理高清屏逻辑
const dpr = devicePixelRatio//uni.getDeviceInfo().devicePixelRatio ?? 1;
canvas.width = canvas.offsetWidth * dpr;
canvas.height = canvas.offsetHeight * dpr;
canvasContext.scale(dpr, dpr); // 仅需调用一次,当调用 reset 方法后需要再次 scale
if(use2dCanvas) {
uniCanvas = new Canvas(canvasContext, instance.proxy, true, context);
} else {
uniCanvas = new Canvas(canvasContext, instance.proxy, false);
}
resolve({ canvas: uniCanvas, width, height, devicePixelRatio: dpr, node: context});
},
fail(err) {
reject(err)
console.log('err', err)
}
})
})
}
// #endif
const getTouch = (e) => {
const touches = e.touches[0]
// #ifdef WEB
// @ts-ignore
const rect = chart!.getZr().dom.getBoundingClientRect();
const touch = {
x: touches.clientX - rect.left,
y: touches.clientY - rect.top
}
// #endif
// #ifndef WEB
const touch = {
x: touches.x,
y: touches.y
}
// #endif
return touch
}
const handleTouchStart = (e) => {
if (chartInstance == null) return
const handler = chartInstance.getZr().handler;
const touch = getTouch(e)
dispatch.call(handler, 'mousedown', touch)
dispatch.call(handler, 'mousemove', touch)
handler.processGesture(wrapTouch(e), 'start');
}
const handleTouchMove = (e) => {
if (chartInstance == null) return
const handler = chartInstance.getZr().handler;
const touch = getTouch(e)
dispatch.call(handler, 'mousemove', touch)
handler.processGesture(wrapTouch(e), 'change');
}
const handleTouchEnd = (e) => {
if (chartInstance == null) return
const handler = chartInstance.getZr().handler;
const touch = e.changedTouches ? e.changedTouches[0] : {}
handler.processGesture(wrapTouch(e), 'end');
dispatch.call(handler, 'mouseup', touch)
dispatch.call(handler, 'click', touch)
}
async function init(echarts : any, ...args : any[]) : Promise<Echarts> {
const library = echarts || echartsLibrary
if (library == null) {
console.error('请确保已经引入了 ECharts 库');
return Promise.reject('请确保已经引入了 ECharts 库');
}
let theme : string | null = null
let opts = {}
let callback : Function | null = null;
args.forEach(item => {
if (typeof item === 'function') {
callback = item
} else if (['string'].includes(typeof item)) {
theme = item
} else if (typeof item === 'object') {
opts = item
}
})
// #ifdef WEB
library.env.domSupported = true
library.env.hasGlobalWindow = true
library.env.node = false
library.env.pointerEventsSupported = false
library.env.svgSupported = true
library.env.touchEventsSupported = true
library.env.transform3dSupported = true
library.env.transformSupported = true
library.env.worker = false
library.env.wxa = false
chartInstance = library.init(chartRef.value, theme, opts)
// window.addEventListener('touchstart', touchstart)
// window.addEventListener('touchmove', touchmove)
// window.addEventListener('touchend', touchend)
// #endif
// #ifndef WEB
let config = await getContext();
setCanvasCreator(library, config)
chartInstance = library.init(config.canvas, theme, Object.assign({}, config, opts))
// #endif
if (callback != null && typeof callback == 'function') {
callbackQueue.push(callback)
}
return new Promise<Echarts>((resolve) => {
initializationQueue.push(resolve)
processInitializationQueue()
})
}
onMounted(() => {
nextTick(() => {
finished.value = true
processInitializationQueue()
emits('finished')
})
})
onUnmounted(() => {
// #ifdef WEB
// window.removeEventListener('touchstart', touchstart)
// window.removeEventListener('touchmove', touchmove)
// window.removeEventListener('touchend', touchend)
// #endif
})
// #endif
defineExpose({
init,
setOption,
showLoading,
hideLoading,
clear,
dispose,
resize,
canvasToTempFilePath
})
</script>
<style lang="scss">
.lime-echart {
flex: 1;
width: 100%;
}
</style>
@@ -0,0 +1,484 @@
<template>
<!-- #ifndef APP-NVUE || WEB -->
<view class="lime-echart"
:style="[lStyle]"
v-if="canvasId"
ref="chartContainer"
:aria-label="'图表'">
<canvas class="lime-echart__canvas"
type="2d"
:style="[styles]"
:id="canvasId"
:disable-scroll="isDisableScroll"
:canvas-id="canvasId"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd">
</canvas>
</view>
<!-- #endif -->
<!-- #ifdef WEB -->
<div class="lime-echart" ref="chartContainer" :style="[styles, lStyle]"></div>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view class="lime-echart" :style="[lStyle]">
<web-view class="lime-echart__canvas"
:webview-styles="webviewStyles"
:style="[styles]"
ref="chartContainer"
src="/uni_modules/lime-echart/static/app/uvue.html?v=1"
@pagefinish="isInitialized = true"
@onPostMessage="handleWebviewMessage"></web-view>
</view>
<!-- #endif -->
</template>
<script lang="ts">
// @ts-nocheck
import { defineComponent, getCurrentInstance, ref, onMounted, nextTick, onBeforeUnmount, watch, computed } from './vue'
import echartProps from './props'
// #ifndef APP-NVUE || WEB
import { Canvas, setCanvasCreator, dispatch } from './canvas';
import { wrapTouch, convertTouchesToArray, devicePixelRatio ,sleep, canIUseCanvas2d, getRect, getDeviceInfo } from './utils';
// #endif
// #ifdef APP-NVUE
import { base64ToPath, sleep } from './utils';
import { Echarts } from './nvue'
// #endif
// #ifdef WEB
import * as echartsLibrary from '@/uni_modules/lime-echart/static/web/echarts.esm.min.js';
// #endif
// #ifdef APP-VUE
// #ifdef VUE3
import '@/uni_modules/lime-echart/static/app/echarts.min.js';
const echartsLibrary = globalThis.echarts
// #endif
// #ifdef VUE2
import * as echartsLibrary from '@/uni_modules/lime-echart/static/web/echarts.esm.min.js';
// #endif
// #endif
export default defineComponent({
props: echartProps,
emits: ['finished'],
setup(props, { emit, expose }) {
// #ifndef APP-NVUE || WEB || APP-VUE
let echartsLibrary = null
// #endif
const instance = getCurrentInstance()!;
const canvasId = `lime-echart-${instance.uid}`
const isInitialized = ref(false)
const chartContainer = ref(null)
type ChartOptions = Record<string, any>
type EChartsInstance = typeof echartsLibrary
type EChartsResolveCallback = (value: EChartsInstance) => void
const initializationQueue = [] as EChartsResolveCallback[]
const callbackQueue = [] as EChartsResolveCallback[]
let chartInstance: null | EChartsInstance = null
const styles = computed(()=> {
if(props.landscape) {
return {
transform: 'translate(-50%,-50%) rotate(90deg)',
top: '50%',
left: '50%',
}
}
return {}
})
const checkInitialization = (): boolean => {
if(chartInstance) return false
console.warn(`组件还未初始化,请先使用 init`)
return true
}
const setOption = (options: ChartOptions) => {
if (checkInitialization()) return
chartInstance!.setOption(options);
}
const hideLoading = () => {
if (checkInitialization()) return
chartInstance!.showLoading();
}
const showLoading = () => {
if (checkInitialization()) return
chartInstance!.hideLoading();
}
const clear = () => {
if (checkInitialization()) return
chartInstance!.clear();
}
const dispose = () => {
if (checkInitialization()) return
chartInstance!.dispose();
}
const processInitializationQueue = () => {
while (initializationQueue.length > 0) {
if (chartInstance != null) {
const resolve = initializationQueue.pop() as EChartsResolveCallback
resolve(chartInstance!)
}
}
if (chartInstance != null) {
while (callbackQueue.length > 0) {
const callback = callbackQueue.pop() as EChartsResolveCallback
callback(chartInstance!)
}
}
}
const resize = (dimensions?: { width?: number; height?: number }) => {
if (checkInitialization()) return
// #ifdef APP-NVUE || WEB
chartInstance!.resize(dimensions);
// #endif
// #ifndef APP-NVUE || WEB
getRect(`#${canvasId}`, instance.proxy).then(res => {
chartInstance!.resize({width: res.width, height: res.height});
})
// #endif
}
// #ifdef APP-NVUE
let chartFile = ref(null);
const handleWebviewMessage = (e) => {
const detail = e?.detail?.data[0] || null;
const data = detail?.data
const key = detail?.event
const options = data?.options
const event = data?.event
const file = detail?.file
if (key == 'log' && data) {
console.log(data)
}
if(event) {
chartInstance.dispatchAction(event.replace(/"/g,''), options)
}
if(file) {
chartFile.value = file
}
}
const canvasToTempFilePath = (options: ChartOptions) => {
if (checkInitialization()) return
chartContainer.value.evalJs(`canvasToTempFilePath()`);
watch(chartFile, async (file) =>{
if(!file) return
const tempFilePath = await base64ToPath(file)
options.success({tempFilePath})
})
}
const getContext = () => {
if(isInitialized.value) {
return Promise.resolve(isInitialized.value)
}
return new Promise(resolve => {
watch(isInitialized, (val) =>{
if(!val) return
resolve(val)
})
})
}
const init = async (echarts, ...args) => {
let theme: string | null = null
let config:Record<string, any> = {}
let callback: Function | null = null;
args.forEach(item => {
if (typeof item === 'function') {
callback = item
} else if (typeof item === 'string') {
theme = item
} else if (typeof item === 'object') {
config = item
}
})
if(props.beforeDelay) {
await sleep(props.beforeDelay)
}
await getContext();
chartInstance = new Echarts(chartContainer.value)
chartContainer.value.evalJs(`init(null, null, ${JSON.stringify(config)}, ${theme})`)
if (callback && typeof callback === 'function') {
callbackQueue.push(callback)
}
return new Promise<EChartsInstance>((resolve) => {
nextTick(()=>{
initializationQueue.push(resolve)
processInitializationQueue()
})
})
}
// #endif
// #ifndef APP-NVUE || WEB
let canvasNode;
const canvasToTempFilePath = (options: ChartOptions) => {
if (checkInitialization()) return
if(canvasNode) {
options.success?.({
tempFilePath: canvasNode.toDataURL()
})
} else {
uni.canvasToTempFilePath({
...options,
canvasId
}, instance.proxy);
}
}
const getContext = () => {
return getRect(`#${canvasId}`, instance.proxy).then(res => {
let dpr = devicePixelRatio
let {width, height, node} = res
let canvas: Canvas | null = null;
if(!(width || height)) {
return Promise.reject('no rect')
}
if(node && node.getContext) {
const ctx = node.getContext('2d');
canvas = new Canvas(ctx, instance.proxy, true, node);
canvasNode = node
} else {
dpr = 1
const ctx = uni.createCanvasContext(canvasId, instance.proxy);
canvas = new Canvas(ctx, instance.proxy, false);
}
return { canvas, width, height, devicePixelRatio: dpr, node }
})
}
const getTouch = (e) => {
const touches = e.touches[0]
const touch = props.landscape
? {
x: touches.y,
y: touches.x
}
: {
x: touches.x,
y: touches.y
}
return touch
}
const handleTouchStart = (e) => {
if (chartInstance == null) return
const handler = chartInstance.getZr().handler;
const touch = getTouch(e)
dispatch.call(handler, 'mousedown', touch)
dispatch.call(handler, 'mousemove', touch)
handler.processGesture(wrapTouch(e), 'start');
}
const handleTouchMove = (e) => {
if (chartInstance == null) return
const handler = chartInstance.getZr().handler;
const touch = getTouch(e)
dispatch.call(handler, 'mousemove', touch)
handler.processGesture(wrapTouch(e), 'change');
}
const handleTouchEnd = (e) => {
if (chartInstance == null) return
const handler = chartInstance.getZr().handler;
const touch = e.changedTouches ? e.changedTouches[0] : {}
handler.processGesture(wrapTouch(e), 'end');
dispatch.call(handler, 'mouseup', touch)
dispatch.call(handler, 'click', touch)
}
const init = async (echartsLib: EChartsInstance = echartsLibrary, ...args: any[]): Promise<EChartsInstance> => {
const library = echartsLib || echartsLibrary
if (!library) {
console.error('ECharts library is required');
return Promise.reject('ECharts library is required');
}
let theme: string | null = null
let config:Record<string, any> = {}
let callback: Function | null = null;
args.forEach(item => {
if (typeof item === 'function') {
callback = item
} else if (typeof item === 'string') {
theme = item
} else if (typeof item === 'object') {
config = item
}
})
if(props.beforeDelay) {
await sleep(props.beforeDelay)
}
let options = await getContext();
setCanvasCreator(library, options)
chartInstance = library.init(options.canvas, theme, Object.assign({}, options, config))
if (callback && typeof callback === 'function') {
callbackQueue.push(callback)
}
return new Promise<EChartsInstance>((resolve) => {
initializationQueue.push(resolve)
processInitializationQueue()
})
}
// #endif
// #ifdef WEB
const canvasToTempFilePath = (options: ChartOptions) => {
if (checkInitialization()) return
options.success?.({
tempFilePath: chartInstance._api.getDataURL()
})
}
const init = async (echarts: EChartsInstance = echartsLibrary, ...args: any[]): Promise<EChartsInstance> => {
const library = echarts || echartsLibrary
if (!library) {
console.error('ECharts library is required');
return Promise.reject('ECharts library is required');
}
let theme: string | null = null
let config = {}
let callback: Function | null = null;
args.forEach(item => {
if (typeof item === 'function') {
callback = item
} else if (typeof item === 'string') {
theme = item
} else if (typeof item === 'object') {
config = item
}
})
// Configure ECharts environment
library.env.domSupported = true
library.env.hasGlobalWindow = true
library.env.node = false
library.env.pointerEventsSupported = false
library.env.svgSupported = true
library.env.touchEventsSupported = true
library.env.transform3dSupported = true
library.env.transformSupported = true
library.env.worker = false
library.env.wxa = false
chartInstance = library.init(chartContainer.value, theme, config)
if (callback != null && typeof callback === 'function') {
callbackQueue.push(callback)
}
return new Promise<EChartsInstance>((resolve) => {
initializationQueue.push(resolve)
processInitializationQueue()
})
}
// #endif
onMounted(() => {
nextTick(() => {
// #ifndef APP-NVUE
isInitialized.value = true
// #endif
emit('finished')
processInitializationQueue()
})
})
onBeforeUnmount(()=> {
clear()
dispose()
})
// #ifdef VUE3
expose({
init,
setOption,
hideLoading,
showLoading,
clear,
dispose,
resize,
canvasToTempFilePath
})
// #endif
return {
canvasId,
chartContainer,
styles,
// #ifndef WEB || APP-NVUE
handleTouchStart,
handleTouchMove,
handleTouchEnd,
// #endif
// #ifdef APP-NVUE
handleWebviewMessage,
isInitialized,
// #endif
// #ifdef VUE2
init,
setOption,
hideLoading,
showLoading,
clear,
dispose,
resize,
canvasToTempFilePath,
// #endif
}
}
})
</script>
<style>
.lime-echart {
position: relative;
/* #ifndef APP-NVUE */
width: 100%;
height: 100%;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
}
.lime-echart__canvas {
/* #ifndef APP-NVUE */
width: 100%;
height: 100%;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
}
/* #ifndef APP-NVUE */
.lime-echart__mask {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 1;
}
/* #endif */
</style>
@@ -0,0 +1,56 @@
export class Echarts {
eventMap = new Map()
constructor(webview) {
this.webview = webview
this.options = null
}
setOption() {
this.options = arguments
console.log('setOption1')
this.webview.evalJs(`setOption(${JSON.stringify(arguments)})`);
}
getOption() {
return this.options
}
showLoading() {
this.webview.evalJs(`showLoading(${JSON.stringify(arguments)})`);
}
hideLoading() {
this.webview.evalJs(`hideLoading()`);
}
clear() {
this.webview.evalJs(`clear()`);
}
dispose() {
this.webview.evalJs(`dispose()`);
}
resize(size) {
if(size) {
this.webview.evalJs(`resize(${JSON.stringify(size)})`);
} else {
this.webview.evalJs(`resize()`);
}
}
on(type, ...args) {
const query = args[0]
const useQuery = query && typeof query != 'function'
const param = useQuery ? [type, query] : [type]
const key = `${type}${useQuery ? JSON.stringify(query): '' }`
const callback = useQuery ? args[1]: args[0]
if(typeof callback == 'function'){
this.eventMap.set(key, callback)
}
this.webview.evalJs(`on(${JSON.stringify(param)})`);
console.warn('nvue 暂不支持事件')
}
dispatchAction(type, options){
const handler = this.eventMap.get(type)
if(handler){
handler(options)
}
}
// 不让报错 无实际作用
isDisposed() {
return !!this.webview
}
}
@@ -0,0 +1,27 @@
export default {
// #ifdef MP-WEIXIN || MP-TOUTIAO
type: {
type: String,
default: '2d'
},
// #endif
// #ifdef APP-NVUE
webviewStyles: Object,
// #endif
lStyle: String,
isDisableScroll: Boolean,
isClickable: {
type: Boolean,
default: true
},
enableHover: Boolean,
beforeDelay: {
type: Number,
default: 30
},
landscape: Boolean,
autoHideTooltip: {
type: Boolean,
default: false
}
}
@@ -0,0 +1,11 @@
// @ts-nocheck
export interface echartsProps {
webviewStyles?: UTSJSONObject,
lStyle?: string | UTSJSONObject
isDisableScroll: boolean;
isClickable: boolean;
enableHover: boolean;
beforeDelay: number;
landscape: boolean;
autoHideTooltip: boolean;
}
@@ -0,0 +1,181 @@
// @ts-nocheck
/**
* 获取设备基础信息
*
* @see [uni.getDeviceInfo](https://uniapp.dcloud.net.cn/api/system/getDeviceInfo.html)
*/
export function getDeviceInfo() {
if (uni.getDeviceInfo || uni.canIUse('getDeviceInfo')) {
return uni.getDeviceInfo();
} else {
return uni.getSystemInfoSync();
}
}
/**
* 获取窗口信息
*
* @see [uni.getWindowInfo](https://uniapp.dcloud.net.cn/api/system/getWindowInfo.html)
*/
export function getWindowInfo() {
if (uni.getWindowInfo || uni.canIUse('getWindowInfo')) {
return uni.getWindowInfo();
} else {
return uni.getSystemInfoSync();
}
}
/**
* 获取APP基础信息
*
* @see [uni.getAppBaseInfo](https://uniapp.dcloud.net.cn/api/system/getAppBaseInfo.html)
*/
export function getAppBaseInfo() {
if (uni.getAppBaseInfo || uni.canIUse('getAppBaseInfo')) {
return uni.getAppBaseInfo();
} else {
return uni.getSystemInfoSync();
}
}
// #ifndef APP-NVUE
// 计算版本
export function compareVersion(v1, v2) {
v1 = v1.split('.')
v2 = v2.split('.')
const len = Math.max(v1.length, v2.length)
while (v1.length < len) {
v1.push('0')
}
while (v2.length < len) {
v2.push('0')
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i], 10)
const num2 = parseInt(v2[i], 10)
if (num1 > num2) {
return 1
} else if (num1 < num2) {
return -1
}
}
return 0
}
// const systemInfo = uni.getSystemInfoSync();
function gte(version) {
// 截止 2023-03-22 mac pc小程序不支持 canvas 2d
// let {
// SDKVersion,
// platform
// } = systemInfo;
const { platform } = getDeviceInfo();
let { SDKVersion } = getAppBaseInfo();
// #ifdef MP-ALIPAY
SDKVersion = my.SDKVersion
// #endif
// #ifdef MP-WEIXIN
return platform !== 'mac' && compareVersion(SDKVersion, version) >= 0;
// #endif
return compareVersion(SDKVersion, version) >= 0;
}
export function canIUseCanvas2d() {
// #ifdef MP-WEIXIN
return gte('2.9.0');
// #endif
// #ifdef MP-ALIPAY
return gte('2.7.0');
// #endif
// #ifdef MP-TOUTIAO
return gte('1.78.0');
// #endif
return false
}
export function convertTouchesToArray(touches) {
// 如果 touches 是一个数组,则直接返回它
if (Array.isArray(touches)) {
return touches;
}
// 如果touches是一个对象,则转换为数组
if (typeof touches === 'object' && touches !== null) {
return Object.values(touches);
}
// 对于其他类型,直接返回它
return touches;
}
export function wrapTouch(event) {
event.touches = convertTouchesToArray(event.touches)
for (let i = 0; i < event.touches.length; ++i) {
const touch = event.touches[i];
touch.offsetX = touch.x;
touch.offsetY = touch.y;
}
return event;
}
// export const devicePixelRatio = uni.getSystemInfoSync().pixelRatio
export const devicePixelRatio = getWindowInfo().pixelRatio;
// #endif
// #ifdef APP-NVUE
export function base64ToPath(base64) {
return new Promise((resolve, reject) => {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
bitmap.loadBase64Data(base64, () => {
if (!format) {
reject(new Error('ERROR_BASE64SRC_PARSE'))
}
const time = new Date().getTime();
const filePath = `_doc/uniapp_temp/${time}.${format}`
bitmap.save(filePath, {},
() => {
bitmap.clear()
resolve(filePath)
},
(error) => {
bitmap.clear()
console.error(`${JSON.stringify(error)}`)
reject(error)
})
}, (error) => {
bitmap.clear()
console.error(`${JSON.stringify(error)}`)
reject(error)
})
})
}
// #endif
export function sleep(time) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true)
}, time)
})
}
export function getRect(selector, context) {
return new Promise((resolve, reject) => {
const dom = uni.createSelectorQuery().in(context).select(selector);
const result = (rect) => {
if (rect) {
resolve(rect)
} else {
reject()
}
}
dom.fields({
node: true,
size: true,
rect: true
}, result).exec()
});
};
@@ -0,0 +1,136 @@
// @ts-nocheck
// #ifdef APP
type EchartsEventHandler = (event: UTSJSONObject)=>void
// type EchartsTempResolve = (obj : UTSJSONObject) => void
// type EchartsTempOptions = UTSJSONObject
export class Echarts {
options: UTSJSONObject = {} as UTSJSONObject
context: UniWebViewElement
eventMap: Map<string, EchartsEventHandler> = new Map()
private temp: UTSJSONObject[] = []
constructor(context: UniWebViewElement){
this.context = context
this.init()
}
init(){
this.context.evalJS(`init(null, null, ${JSON.stringify({})})`)
this.context.addEventListener('message', (e : UniWebViewMessageEvent) => {
// event.stopPropagation()
// event.preventDefault()
const detail = e.detail.data[0]
const file = detail.getString('file')
const data = detail.get('data')
const key = detail.getString('event')
const options = typeof data == 'object' ? (data as UTSJSONObject).getJSON('options'): null
const event = typeof data == 'object' ? (data as UTSJSONObject).getString('event'): null
if (key == 'log' && data != null) {
console.log(data)
}
if (event != null && options != null) {
this.dispatchAction(event.replace(/"/g,''), options)
}
if(file != null){
while (this.temp.length > 0) {
const opt = this.temp.pop()
const success = opt?.get('success')
if(typeof success == 'function'){
success as (res: UTSJSONObject) => void
success({tempFilePath: file})
}
}
}
})
}
setOption(option: UTSJSONObject){
this.options = option;
this.context.evalJS(`setOption(${JSON.stringify([option])})`)
}
setOption(option: UTSJSONObject, notMerge: boolean = false, lazyUpdate: boolean = false){
this.options = option;
this.context.evalJS(`setOption(${JSON.stringify([option, notMerge, lazyUpdate])})`)
}
setOption(option: UTSJSONObject, notMerge: UTSJSONObject){
this.options = option;
this.context.evalJS(`setOption(${JSON.stringify([option, notMerge])})`)
}
getOption(): UTSJSONObject {
return this.options
}
showLoading(){
this.context.evalJS(`showLoading(${JSON.stringify([] as any[])})`);
}
showLoading(type: string, opts: UTSJSONObject){
this.context.evalJS(`showLoading(${JSON.stringify([type, opts])})`);
}
hideLoading(){
this.context.evalJS(`hideLoading()`);
}
clear(){
this.context.evalJS(`clear()`);
}
dispose(){
this.context.evalJS(`dispose()`);
}
resize(size:UTSJSONObject){
setTimeout(()=>{
this.context.evalJS(`resize(${JSON.stringify(size)})`);
},0)
}
resize(){
setTimeout(()=>{
this.context.evalJS(`resize()`);
},10)
}
on(type:string, query: any, callback: EchartsEventHandler) {
const key = `${type}${JSON.stringify(query)}`
if(typeof callback == 'function'){
this.eventMap.set(key, callback)
}
this.context.evalJS(`on(${JSON.stringify([type, query])})`);
console.warn('uvue 暂不支持事件')
}
on(type:string, callback: EchartsEventHandler) {
const key = `${type}`
if(typeof callback == 'function'){
this.eventMap.set(key, callback)
}
this.context.evalJS(`on(${JSON.stringify([type])})`);
console.warn('uvue 暂不支持事件')
}
dispatchAction(type:string, options: UTSJSONObject){
const handler = this.eventMap.get(type)
if(handler!=null){
handler(options)
}
}
canvasToTempFilePath(opt: UTSJSONObject){
// this.context.evalJS(`on(${JSON.stringify(opt)})`);
this.context.evalJS(`canvasToTempFilePath(${JSON.stringify(opt)})`);
this.temp.push(opt)
}
isDisposed():boolean {
return false
}
}
// #endif
// #ifndef APP
export class Echarts {
constructor() {}
setOption(option: UTSJSONObject): void
isDisposed(): boolean;
clear(): void;
resize(size:UTSJSONObject): void;
resize(): void;
canvasToTempFilePath(opt : UTSJSONObject): void;
dispose(): void;
showLoading(cfg?: UTSJSONObject): void;
showLoading(name?: string, cfg?: UTSJSONObject): void;
hideLoading(): void;
getZr(): any
}
// #endif
@@ -0,0 +1,16 @@
// @ts-nocheck
// #ifdef VUE3
export * from 'vue';
// #endif
// #ifndef VUE3
export * from '@vue/composition-api';
// #ifdef APP-NVUE
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
// #endif
// #endif
@@ -0,0 +1,227 @@
<template>
<view>
<view style="height: 750rpx; position: relative">
<l-echart ref="chart" @finished="init"></l-echart>
<view
class="customTooltips"
:style="{ left: position[0] + 'px', top: position[1] + 'px' }"
v-if="params.length && position.length && showTip"
>
<view>这是个自定的tooltips</view>
<view>{{ params[0]['axisValue'] }}</view>
<view v-for="item in params">
<view>
<text>{{ item.seriesName }}</text>
<text>{{ item.value }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
// nvue 不需要引入
// #ifdef VUE2
import * as echarts from '@/uni_modules/lime-echart/static/echarts.min'
// #endif
// #ifdef VUE3
// #ifdef MP
// 由于vue3 使用vite 不支持umd格式的包,小程序依然可以使用,但需要使用require
const echarts = require('../../static/echarts.min')
// #endif
// #ifndef MP
// 由于 vue3 使用vite 不支持umd格式的包,故引入npm的包
import * as echarts from 'echarts/dist/echarts.esm'
// #endif
// #endif
export default {
data() {
return {
showTip: false,
position: [],
params: [],
option: {
tooltip: {
trigger: 'axis',
// shadowBlur: 0,
textStyle: {
textShadowBlur: 0,
},
renderMode: 'richText',
position: (point, params, dom, rect, size) => {
// 假设自定义的tooltips尺寸
const box = [170, 170]
// 偏移
const offsetX = point[0] < size.viewSize[0] / 2 ? 20 : -box[0] - 20
const offsetY = point[1] < size.viewSize[1] / 2 ? 20 : -box[1] - 20
const x = point[0] + offsetX
const y = point[1] + offsetY
this.position = [x, y]
this.params = params
},
formatter: (params, ticket, callback) => {},
},
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
},
yAxis: {
type: 'value',
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210],
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 232, 201, 154, 190, 330, 410],
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 332, 301, 334, 390, 330, 320],
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
},
}
},
methods: {
init() {
// init(echarts, theme?:string, opts?:{}, chart => {})
// echarts 必填, 非nvue必填,nvue不用填
// theme 可选,应用的主题,目前只支持名称,如:'dark'
// opts = { // 可选
// locale?: string // 从 `5.0.0` 开始支持
// }
// chart => {} callback 返回图表实例
// setTimeout(()=>{
// this.$refs.chart.init(echarts, chart => {
// chart.setOption(this.option);
// });
// },300)
this.$refs.chart.init(echarts, (chart) => {
chart.setOption(this.option)
// 监听tooltip显示事件
chart.on('showTip', (params) => {
this.showTip = true
console.log('showTip::')
})
chart.on('hideTip', (params) => {
setTimeout(() => {
this.showTip = false
}, 300)
})
setTimeout(() => {
const option = {
tooltip: {
trigger: 'axis',
// shadowBlur: 0,
textStyle: {
textShadowBlur: 0,
},
renderMode: 'richText',
},
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
},
yAxis: {
type: 'value',
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [1120, 132, 101, 134, 90, 230, 210],
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 632, 201, 154, 190, 330, 410],
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [820, 332, 301, 334, 390, 330, 320],
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
}
chart.setOption(option)
}, 1000)
})
},
save() {
this.$refs.chart.canvasToTempFilePath({
success(res) {
console.log('res::::', res)
},
})
},
},
}
</script>
<style>
.customTooltips {
position: absolute;
background-color: rgba(255, 255, 255, 0.8);
padding: 20rpx;
}
</style>
@@ -0,0 +1,159 @@
<template>
<view style="width: 100%; height: 408px;">
<l-echart ref="chartRef" @finished="init"></l-echart>
</view>
</template>
<script>
export default {
data() {
return {
showTip: false,
option: {
tooltip: {
trigger: 'axis',
// shadowBlur: 0,
textStyle: {
textShadowBlur: 0
},
renderMode: 'richText',
},
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
}
}
},
mounted() {
console.log('lime echarts nvue')
},
methods: {
init() {
const chartRef = this.$refs['chartRef']
chartRef.init(chart => {
chart.setOption(this.option);
setTimeout(()=>{
const option = {
tooltip: {
trigger: 'axis',
// shadowBlur: 0,
textStyle: {
textShadowBlur: 0
},
renderMode: 'richText',
},
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
}
chart.setOption(option);
},1000)
})
},
save() {
// this.$refs.chart.canvasToTempFilePath({
// success(res) {
// console.log('res::::', res)
// }
// })
}
}
}
</script>
<style>
</style>
@@ -0,0 +1,158 @@
<template>
<view style="width: 100%; height: 408px;">
<l-echart ref="chartRef" @finished="init"></l-echart>
</view>
</template>
<script lang="uts" setup>
// #ifdef MP
// 引入小程序依赖包,require只能是当前文件的相对路径
const echarts = require('../../../../static/echarts.min.js')
// #endif
// #ifndef MP
// 非小程序不需要引入
const echarts = null
// #endif
const chartRef = ref<LEchartComponentPublicInstance|null>(null)
const option = {
tooltip: {
trigger: 'axis',
// shadowBlur: 0,
textStyle: {
textShadowBlur: 0
},
renderMode: 'richText',
},
// formatter: async (params: any) => {
// console.log('params', params)
// return 1
// },
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
},
// grid: {
// left: '3%',
// right: '4%',
// bottom: '3%',
// containLabel: true
// },
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
}
const init = async () =>{
if(chartRef.value== null) return
const chart = await chartRef.value!.init(echarts)
chart.setOption(option)
// chart.on('mouseover', function (params) {
// console.log('params', params);
// });
// setTimeout(()=> {
// const option1 = {
// tooltip: {
// trigger: 'axis',
// // shadowBlur: 0,
// textStyle: {
// textShadowBlur: 0
// },
// renderMode: 'richText',
// },
// legend: {
// data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
// },
// grid: {
// left: '3%',
// right: '4%',
// bottom: '3%',
// containLabel: true
// },
// xAxis: {
// type: 'category',
// boundaryGap: false,
// data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
// },
// yAxis: {
// type: 'value'
// },
// series: [
// {
// name: '邮件营销',
// type: 'line',
// stack: '总量',
// data: [820, 132, 101, 134, 90, 230, 210]
// },
// {
// name: '联盟广告',
// type: 'line',
// stack: '总量',
// data: [220, 182, 191, 234, 290, 330, 310]
// },
// {
// name: '视频广告',
// type: 'line',
// stack: '总量',
// data: [950, 232, 201, 154, 190, 330, 410]
// },
// {
// name: '直接访问',
// type: 'line',
// stack: '总量',
// data: [320, 332, 301, 334, 390, 330, 320]
// },
// {
// name: '搜索引擎',
// type: 'line',
// stack: '总量',
// data: [820, 932, 901, 934, 1290, 1330, 1320]
// }
// ]
// }
// chart.setOption(option1)
// },1000)
}
</script>
<style>
</style>
@@ -0,0 +1,152 @@
<template>
<view>
<view style="height: 750rpx; position: relative">
<l-echart ref="chart" @finished="init"></l-echart>
<view class="customTooltips" :style="{ left: position[0] + 'px', top: position[1] + 'px' }"
v-if="params.length && position.length && showTip">
<view>这是个自定的tooltips</view>
<view>{{ params[0]['axisValue'] }}</view>
<view v-for="item in params">
<view>
<text>{{ item.seriesName }}</text>
<text>{{ item.value }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
// #ifdef MP
// 引入小程序依赖包,require只能是当前文件的相对路径
const echarts = require('../../../../static/echarts.min.js');
// #endif
// #ifndef MP
// 非小程序不需要引入
const echarts = null
// #endif
export default {
data() {
return {
showTip: false,
position: [],
params: [],
option: {
tooltip: {
trigger: 'axis',
// shadowBlur: 0,
textStyle: {
textShadowBlur: 0,
},
renderMode: 'richText',
position: (point, params, dom, rect, size) => {
// 假设自定义的tooltips尺寸
const box = [170, 170]
// 偏移
const offsetX = point[0] < size.viewSize[0] / 2 ? 20 : -box[0] - 20
const offsetY = point[1] < size.viewSize[1] / 2 ? 20 : -box[1] - 20
const x = point[0] + offsetX
const y = point[1] + offsetY
this.position = [x, y]
this.params = params
},
formatter: (params, ticket, callback) => {},
},
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
},
// grid: {
// left: '3%',
// right: '4%',
// bottom: '3%',
// containLabel: true,
// },
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
},
yAxis: {
type: 'value',
},
series: [{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210],
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 232, 201, 154, 190, 330, 410],
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 332, 301, 334, 390, 330, 320],
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
},
}
},
methods: {
async init() {
// init(echarts, theme?:string, opts?:{}, chart => {})
// echarts 必填, 非nvue必填,nvue不用填
// theme 可选,应用的主题,目前只支持名称,如:'dark'
// opts = { // 可选
// locale?: string // 从 `5.0.0` 开始支持
// }
// chart => {} callback 返回图表实例
// setTimeout(()=>{
// this.$refs.chart.init(echarts, chart => {
// chart.setOption(this.option);
// });
// },300)
const chart = await this.$refs.chart.init(echarts)
chart.setOption(this.option)
// 监听tooltip显示事件
chart.on('showTip', (params) => {
this.showTip = true
console.log('showTip::')
})
chart.on('hideTip', (params) => {
setTimeout(() => {
this.showTip = false
}, 300)
})
},
save() {
this.$refs.chart.canvasToTempFilePath({
success(res) {
console.log('res::::', res)
},
})
},
},
}
</script>
<style>
.customTooltips {
position: absolute;
background-color: rgba(255, 255, 255, 0.8);
padding: 20rpx;
}
</style>
+111
View File
@@ -0,0 +1,111 @@
{
"id": "lime-echart",
"displayName": "lime-echart echarts图表",
"version": "2.0.7",
"description": "lime-echart 为 UniApp 和 UniAppX 提供 ECharts 图表兼容支持, 使 ECharts 图表能在H5、小程序、App中运行",
"keywords": [
"echarts",
"canvas",
"图表",
"可视化"
],
"repository": "https://gitee.com/liangei/lime-echart",
"engines": {
"HBuilderX": "^3.6.4",
"uni-app": "^4.65",
"uni-app-x": "^4.71"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "",
"type": "component-vue",
"darkmode": "x",
"i18n": "x",
"widescreen": "x"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "x",
"aliyun": "x",
"alipay": "x"
},
"client": {
"uni-app": {
"vue": {
"vue2": "√",
"vue3": "√"
},
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"vue": "√",
"nvue": "√",
"android": {
"extVersion": "",
"minVersion": "21"
},
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√",
"alipay": "√",
"toutiao": "√",
"baidu": "√",
"kuaishou": "√",
"jd": "√",
"harmony": "-",
"qq": "√",
"lark": "√",
"xhs": "-"
},
"quickapp": {
"huawei": "-",
"union": "-"
}
},
"uni-app-x": {
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"android": {
"extVersion": "",
"minVersion": "21"
},
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√"
}
}
}
}
},
"dependencies": {
"echarts": "^5.4.1",
"zrender": "^5.4.3"
}
}
+499
View File
@@ -0,0 +1,499 @@
# lime-echart 📊
为 UniApp 和 UniAppX 提供 ECharts 图表兼容支持,使 ECharts 图表能在 H5、小程序、App 等多端环境中正常运行。
## 特性 ✨
- 📱 **跨平台兼容**:支持 H5、微信小程序、支付宝小程序、App 等多端
- 🎯 **简单易用**:统一 API,使用方式与原生 ECharts 基本一致
- ⚡ **性能优化**:针对不同平台进行了渲染优化
- 🔄 **双框架支持**:同时支持 uni-app 和 uni-app-x
## 文档与示例 📚
更多详细文档与示例:
- [lime-echart 组件文档](https://limeui.qcoon.cn/#/echart)
- [在线示例](https://limeui.qcoon.cn/#/echart-example)
- [ECharts 官方示例](https://echarts.apache.org/examples/zh/index.html)
- [lime-echart 组件文档2](https://limex.qcoon.cn/components/echart.html) (将来用到,目前未上线)
## 安装方法 📦
### 插件市场安装
1. 在uni-app插件市场中搜索并导入`lime-echart`
2. 导入后重新编译项目
3. 在页面中直接使用 `l-echart` 组件
### CLI 项目安装
```bash
# 下载插件到项目的 src/uni_modules 目录
mkdir -p src/uni_modules
# 将插件解压到上述目录
```
## 前置依赖 ⚙️
### 小程序平台(重点说明)
小程序平台必须下载并引入 ECharts 自定义构建包:
1. 小程序中引入ECharts方式:
- **本地构建文件**
- 访问 [ECharts 在线构建](https://echarts.apache.org/zh/builder.html) 下载所需图表类型的精简版
- 注意:在线构建工具**仅支持生成UMD格式**(默认,`echarts.min.js`),通过 `require` 引入
- 建议只勾选项目所需的图表类型和组件,以减小文件体积
2. **文件放置位置**
- 📁 **主包**:将文件放入项目根目录的 `static` 文件夹
- 📁 **分包**:将文件放入对应分包的 `static` 文件夹(如 `pagesB/static/`
3. **相对路径引用示例**
```js
// UMD格式 - 页面位于主包根目录 - 相对路径引用示例(仅在线构建或本地文件使用)
// ├─pages
// │ └─index
// │ └─index.vue
// └─static
const echarts = require('../../static/echarts.min.js')
// UMD格式 - 页面位于主包三层目录 - 相对路径引用示例(仅在线构建或本地文件使用)
// ├─pages
// │ └─user
// │ └─settings
// │ └─profile.vue
// └─static
const echarts = require('../../../static/echarts.min.js')
// UMD格式 - 页面位于分包中 - 相对路径引用示例(仅在线构建或本地文件使用)
// ├─pagesB (分包)
// │ ├─static
// │ └─detail
// │ └─detail.vue
const echarts = require('../static/echarts.min.js')
// ES模块格式
import * as echarts from 'echarts'
```
> 注意:
> - `require` 是小程序平台特有的API,仅在小程序环境下使用
> - 路径是相对于当前页面文件的路径,请根据实际项目结构调整路径
## 使用示例 🎯
### 图表配置项示例
以下是一个柱状图的配置项示例,在后续使用示例中将引用此配置:
```js
// 图表配置项示例 - 柱状图
const chartOption = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
confine: true
},
legend: {
data: ['热度', '正面', '负面']
},
xAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: '#999999'
}
},
axisLabel: {
color: '#666666'
}
}
],
yAxis: [
{
type: 'category',
axisTick: { show: false },
data: ['汽车之家', '今日头条', '百度贴吧', '一点资讯', '微信', '微博', '知乎'],
axisLine: {
lineStyle: {
color: '#999999'
}
},
axisLabel: {
color: '#666666'
}
}
],
series: [
{
name: '热度',
type: 'bar',
label: {
show: true,
position: 'inside'
},
data: [300, 270, 340, 344, 300, 320, 310]
},
{
name: '正面',
type: 'bar',
stack: '总量',
label: {
show: true
},
data: [120, 102, 141, 174, 190, 250, 220]
},
{
name: '负面',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'left'
},
data: [-20, -32, -21, -34, -90, -130, -110]
}
]
}
```
> **说明**:在实际项目中,可以根据需求修改上述配置项。
> - 更多配置选项请参考 [ECharts 官方文档](https://echarts.apache.org/zh/option.html)
> - 查看更多图表样式请访问 [ECharts 官方示例](https://echarts.apache.org/examples/zh/index.html)
### uni-app 使用方式
#### 组合式 API 方式
```html
<template>
<view style="width: 750rpx; height: 750rpx;">
<l-echart ref="chartRef" @finished="initChart"></l-echart>
</view>
</template>
```
```js
import { ref } from 'vue';
const chartRef = ref(null)
// 仅在小程序环境下引入 ECharts
// #ifdef MP
const echarts = require('../../static/echarts.min.js') // 根据实际路径调整
// #endif
// #ifndef MP
const echarts = null // H5 和 App 环境不需要手动引入
// #endif
// 使用上面定义的图表配置项
const option = chartOption
// 初始化图表
const initChart = async () => {
if (!chartRef.value) return
try {
const chart = await chartRef.value.init(echarts)
chart.setOption(option)
} catch (error) {
console.error('图表初始化失败:', error)
}
}
```
#### 选项式 API 方式
```html
<template>
<view style="width: 750rpx; height: 750rpx;">
<l-echart ref="chartRef" @finished="initChart"></l-echart>
</view>
</template>
```
```js
// 仅在小程序环境下引入 ECharts
// #ifdef MP
const echarts = require('../../static/echarts.min.js') // 根据实际路径调整
// #endif
// #ifndef MP
const echarts = null // H5 和 App 环境不需要手动引入
// #endif
export default {
data() {
return {
// 使用上面定义的图表配置项
option: chartOption,
// 图表实例,用于后续操作
chartInstance: null,
}
},
methods: {
// 初始化图表
async initChart() {
if (!this.$refs.chartRef) return
try {
this.chartInstance = await this.$refs.chartRef.init(echarts)
this.chartInstance.setOption(this.option)
} catch (error) {
console.error('图表初始化失败:', error)
}
},
// 更新图表数据
updateChart(newOption) {
if (this.chartInstance) {
this.chartInstance.setOption(newOption)
} else if (this.$refs.chartRef) {
this.$refs.chartRef.setOption(newOption)
}
},
// 调整图表大小
resizeChart() {
if (this.$refs.chartRef) {
this.$refs.chartRef.resize()
}
}
},
// 页面卸载时销毁图表实例
beforeUnmount() {
if (this.$refs.chartRef) {
this.$refs.chartRef.dispose()
}
}
}
```
### uni-app-x 使用方式
```html
<template>
<view style="width: 100%; height: 408px;">
<l-echart ref="chartRef" @finished="initChart"></l-echart>
</view>
</template>
```
```ts
const chartRef = ref<LEchartComponentPublicInstance | null>(null)
// 仅在小程序环境下引入 ECharts
// #ifdef MP
const echarts = require('../../static/echarts.min.js') // 根据实际路径调整
// #endif
// #ifndef MP
const echarts = null
// #endif
// 使用上面定义的图表配置项
const option = chartOption
// 初始化图表
const initChart = async () => {
if (chartRef.value === null) return
try {
const chart = await chartRef.value.init(echarts, null)
chart.setOption(option)
} catch (error) {
console.error('图表初始化失败:', error)
}
}
```
## 高级功能 💪
### 数据更新 🔄
图表支持动态更新数据,有两种常用方式:
#### 方式一:通过组件引用更新
```js
// Vue 3 Composition API
chartRef.value?.setOption(newOption)
// Vue 2 Options API
this.$refs.chart.setOption(newOption)
```
#### 方式二:通过图表实例更新
```js
// 在初始化时保存图表实例
let chartInstance = null
const initChart = async () => {
if (!chartRef.value) return
chartInstance = await chartRef.value.init(echarts)
chartInstance.setOption(option)
}
// 后续更新数据
const updateChart = () => {
if (chartInstance) {
chartInstance.setOption(newData)
}
}
```
### 图表大小调整 📏
当容器大小改变时,可以调用 `resize` 方法重新调整图表尺寸:
```js
// 自动适应容器大小
chartRef.value?.resize()
// 手动指定尺寸
chartRef.value?.resize({
width: 375, // 像素值
height: 375 // 像素值
})
```
**💡 提示**:在窗口大小变化或屏幕旋转时,可以监听相应事件并调用 `resize` 方法。
### Vue 2 兼容配置 🔄
如果您的项目使用 Vue 2,需要先安装并引入 Vue Composition API
```js
// main.js
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
```
详细配置请参考:[Vue Composition API 官方文档](https://uniapp.dcloud.net.cn/tutorial/vue-composition-api.html)
### 组件标签说明 🏷️
| 标签名 | 说明 |
|-------|------|
| `l-echart` | 正式使用的组件标签 |
| `lime-echart` | 演示用组件标签 |
### 快速预览 🚀
导入插件后,可以直接使用演示标签查看效果:
```html
<template>
<view style="width: 100%; height: 400px;">
<!-- 演示组件 -->
<lime-echart />
</view>
</template>
```
## 常见问题与解决方案 🐛
### 平台特殊问题
#### 微信小程序
- **画布层级问题**:微信开发工具中 canvas 可能出现层级过高或不跟随页面滚动的情况,真机环境下通常不受影响
- **Tooltip 阴影**:如需去除文字阴影,可添加配置:`tooltip.shadowBlur = 0`
#### 钉钉小程序
- **文字测量精度**:由于钉钉小程序没有原生 `measureText`,字体粗细测量可能不够精确
- **安全扫描警告**:如遇到 `Uint8Clamped` 安全问题,可按以下方式修改 ECharts 文件:
```js
// 查找类似代码并修改
// 原代码
["Int8","Uint8","Uint8Clamped","Int16","Uint16","Int32","Uint32","Float32","Float64"],(function(t,e){return t["[object "+e+"Array]"]
// 修改为
["Int8","Uint8","Uint8_Clamped","Int16","Uint16","Int32","Uint32","Float32","Float64"],(function(t,e){return t["[object "+e.replace('_','')+"Array]"]
```
### 功能限制 ⚠️
- **Toolbox**:不支持 `saveImage` 功能
- **Lines 图表**:不支持 `trailLength` 属性,请设置为 `0`
- **DataZoom**H5 平台不建议设置 `showDetail` 属性
- **自定义 Tooltips**uvue 和 vue 中不支持 DOM 操作相关的自定义 Tooltips
## API 参考 📝
### Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|--------|------|
| l-style | 自定义样式 | string | - | - |
| type | 指定 canvas 类型(废除) | string | "2d" | - |
| is-disable-scroll | 触摸图表时是否禁止页面滚动 | boolean | false | - |
| beforeDelay | 延迟初始化时间(毫秒) | number | 30 | - |
| enableHover | PC端是否启用鼠标悬浮效果(废除) | boolean | false | - |
| landscape | 是否旋转90度,模拟横屏效果 | boolean | false | - |
| autoHideTooltip | 是否自动隐藏Tooltip | boolean | false | - |
### 组件方法
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| init | `echarts: Object, config?: Object` | `Promise<ChartInstance>` | 初始化图表实例 |
| setOption | `option: Object` | `void` | 设置或更新图表配置项 |
| resize | `size?: {width: number, height: number}` | `void` | 调整图表尺寸 |
| clear | `-` | `void` | 清空图表内容 |
| dispose | `-` | `void` | 销毁图表实例 |
| showLoading | `-` | `void` | 显示加载动画 |
| hideLoading | `-` | `void` | 隐藏加载动画 |
| canvasToTempFilePath | `options: Object` | `Promise<Object>` | 生成图表图片,与 uni-app 官方 API 类似,但无需传入 canvasId |
### 事件
| 事件名 | 参数 | 说明 |
|--------|------|------|
| finished | 无 | 图表准备就绪时触发,此时可调用 init 方法 |
## 其他平台依赖说明 🌐
### uni-app 非 nvue 端
- **推荐使用 `npm` 安装**
- 通过 npm 安装可以获得完整的 ES 模块格式支持
```bash
npm install echarts --save
```
- 安装后可直接在代码中通过 `import` 引入
```js
import * as echarts from 'echarts'
```
### uni-app-x 非 App 端
- **推荐使用 npm 安装**获取 ES 模块格式
```bash
npm install echarts --save
```
- ES 模块格式具有更好的性能和构建优化支持
- 通过 `import` 引入使用
```js
import * as echarts from 'echarts'
```
> 💡 注意:H5 和 App 原生环境通常不需要手动引入 ECharts,组件会自动处理。只有在需要自定义 ECharts 版本或配置时才需要手动引入。
## 技术支持 🆘
如果您在使用过程中遇到问题,可以通过以下方式获取帮助:
1. 查看 [在线文档](https://limeui.qcoon.cn/#/echart) 获取详细使用说明
2. 检查 [常见问题](#常见问题与解决方案) 章节查找解决方案
## 贡献与支持 💙
如果您觉得本插件对您有帮助,欢迎给作者点个赞或提供支持:
| 支付宝 | 微信 |
|--------|------|
| ![支付宝](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/alipay.png) | ![微信](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/wpay.png) |
您的支持是作者持续开发和维护的动力! 🌟
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,184 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style type="text/css">
html,
body {
overflow: hidden;
/* 隐藏滚动条 */
overscroll-behavior: none;
/* 禁止橡皮筋效果 */
}
html,
body,
.canvas {
padding: 0;
margin: 0;
overflow-y: hidden;
background-color: transparent;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="canvas" id="limeChart"></div>
<script type="text/javascript" src="./uni.webview.1.5.5.js"></script>
<script type="text/javascript" src="./echarts.min.js"></script>
<script type="text/javascript" src="./ecStat.min.js"></script>
<!-- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-liquidfill@latest/dist/echarts-liquidfill.min.js"></script> -->
<script>
let chart = null;
let cache = [];
console.log = function() {
emit('log', {
log: arguments,
})
}
function emit(event, data) {
postMessage({
event,
data
})
cache = []
}
function postMessage(data) {
uni.webView.postMessage({
data
})
// window.__uniapp_x_.postMessage(JSON.stringify(data))
};
function stringify(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
return;
}
cache.push(value);
}
return value;
}
function parse(name, callback, options) {
const optionNameReg = /[\w]+\.setOption\(([\w]+\.)?([\w]+)\)/
if (optionNameReg.test(callback)) {
const optionNames = callback.match(optionNameReg)
if (optionNames[1]) {
const _this = optionNames[1].split('.')[0]
window[_this] = {}
window[_this][optionNames[2]] = options
return optionNames[2]
} else {
return null
}
}
return null
}
function init(callback, options, opts, theme) {
if (!chart) {
chart = echarts.init(document.getElementById('limeChart'), theme, opts)
if (options) {
chart.setOption(options)
}
}
}
function on(data) {
if (chart && data.length > 0) {
const [type, query] = data
const key = `${type}${JSON.stringify(query||'')}`
if (query) {
chart.on(type, query, function(options) {
var obj = {};
Object.keys(options).forEach(function(key) {
if (key != 'event') {
obj[key] = options[key];
}
});
emit(key, {
event: key,
options: obj,
});
});
} else {
chart.on(type, function(options) {
var obj = {};
Object.keys(options).forEach(function(key) {
if (key != 'event') {
obj[key] = options[key];
}
});
emit(key, {
event: key,
options: obj,
});
});
}
}
}
function setChart(callback, options) {
if (!callback) return
if (chart && callback && options) {
var r = null
const name = parse('r', callback, options)
if (name) this[name] = options
eval(`r = ${callback};`)
if (r) {
r(chart)
}
}
}
function setOption(data) {
if (chart) chart.setOption(data[0], data[1])
}
function showLoading(data) {
if (chart) chart.showLoading(data[0], data[1])
}
function hideLoading() {
if (chart) chart.hideLoading()
}
function clear() {
if (chart) chart.clear()
}
function dispose() {
if (chart) chart.dispose()
}
function resize(size) {
if (chart) chart.resize(size)
}
function canvasToTempFilePath(opt) {
if (chart) {
delete opt.success
const src = chart.getDataURL(opt)
postMessage({
// event: 'file',
file: src
})
}
}
document.addEventListener('touchmove', () => {
})
</script>
</body>
</html>
File diff suppressed because one or more lines are too long
+898
View File
@@ -0,0 +1,898 @@
//---------------start----------------------账单列表---------------------start-------------------
var billData=[
{
"currentYear": 2025,
"currentMonth": 9,
"outputAmount": 1100,
"inputAmount": 11000,
"recordList":[
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "转账-来自莉莉-11",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType":"6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "转账给莉莉-11",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "微信红包-发给莉-11",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
}
]
},
{
"currentYear": 2025,
"currentMonth": 8,
"outputAmount": 1000,
"inputAmount": 10000,
"recordList": [
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
}
]
},
{
"currentYear": 2025,
"currentMonth": 7,
"outputAmount": 900,
"inputAmount": 9000,
"recordList": [
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2025-09-03 14:59:00",
"createTime": "2025-09-03 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2025-09-03 12:15:00",
"createTime": "2025-09-03 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
}
]
}
]
function getRecordList(year,month,tradeType){
console.log("=======year"+year+"====month==="+month+"=====type==="+tradeType);
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find(item=>(item.currentYear==year&&item.currentMonth==month));
console.log("recordItem===",recordItem);
if(recordItem!=undefined&&recordItem!=null){
recordItem.recordList=recordItem.recordList.filter(item=>item.tradeType==tradeType);
return recordItem;
}else{
return {
"currentYear": year,
"currentMonth": month,
"outputAmount": 0.00,
"inputAmount": 0.00,
"recordList":[]
};
}
}
function addItem(newItem,callback){
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find((item,index)=>{
return item.currentYear==year&&item.currentMonth==month
})
recordItem.recordList.push(newItem);
billData=tempData;
callback();
}
function deleteItem(delItem,callback){
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find((item,index)=>{
return item.currentYear==year&&item.currentMonth==month
})
recordItem.recordList=recordItem.recordList.filter((item)=>{
return item.createTime!=delItem.createTime;
});
billData=tempData;
callback();
}
function updateItem(updateItem,callback){
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find((item,index)=>{
return item.currentYear==year&&item.currentMonth==month
})
recordItem.recordList=recordItem.recordList.filter((item)=>{
return item.createTime!=delItem.createTime;
});
addItem(updateItem,callback);
}
//---------------end----------------------账单列表---------------------end-------------------
const tempChartData={
"outdata": {
"list": [
{
"id": 3,
"trade_typetxt": "转账",
"sum_value": "65906.00",
"trade_icon": "/assets/icon/zd3.png",
"sum_count": 18,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd3.png",
"billTitle": "转账",
"amountValue": "65906.00"
},
{
"id": 2,
"trade_typetxt": "二维码收付款",
"sum_value": "1348.40",
"trade_icon": "/assets/icon/zd1.png",
"sum_count": 17,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd1.png",
"billTitle": "二维码收付款",
"amountValue": "1348.40"
},
{
"id": 1,
"trade_typetxt": "微信红包",
"sum_value": "326.00",
"trade_icon": "/assets/icon/sh19.png",
"sum_count": 2,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh19.png",
"billTitle": "微信红包",
"amountValue": "326.00"
}
],
"money": 81127.53,
"count": 54,
"month_list": {
"month": [
"06月",
"07月",
"08月",
"09月",
"10月",
"11月"
],
"money": [
136253.37,
140794.18,
140792.95,
136254.18,
140792.97,
81127.53
],
"list": [
{
"money": 136253.37,
"month": "06月"
},
{
"money": 140794.18,
"month": "07月"
},
{
"money": 140792.95,
"month": "08月"
},
{
"money": 136254.18,
"month": "09月"
},
{
"money": 140792.97,
"month": "10月"
},
{
"money": 81127.53,
"month": "11月"
}
]
}
},
"indata": {
"list": [
{
"id": 1,
"trade_typetxt": "二维码收付款",
"sum_value": "62803.00",
"trade_icon": "/assets/icon/zd1.png",
"sum_count": 24,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd1.png",
"billTitle": "二维码收付款",
"amountValue": "62803.00"
},
{
"id": 3,
"trade_typetxt": "转账",
"sum_value": "5591.00",
"trade_icon": "/assets/icon/zd3.png",
"sum_count": 10,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd3.png",
"billTitle": "转账",
"amountValue": "5591.00"
},
{
"id": 2,
"trade_typetxt": "微信红包",
"sum_value": "137.00",
"trade_icon": "/assets/icon/sh19.png",
"sum_count": 4,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh19.png",
"billTitle": "微信红包",
"amountValue": "137.00"
}
],
"money": 119630,
"count": 46,
"month_list": {
"month": [
"06月",
"07月",
"08月",
"09月",
"10月",
"11月"
],
"money": [
137061,
130787,
152473,
120999,
157692,
119630
],
"list": [
{
"money": 137061,
"month": "06月"
},
{
"money": 130787,
"month": "07月"
},
{
"money": 152473,
"month": "08月"
},
{
"money": 120999,
"month": "09月"
},
{
"money": 157692,
"month": "10月"
},
{
"money": 119630,
"month": "11月"
}
]
}
},
"otherdata": {
"list": [
{
"id": 3,
"trade_typetxt": "零钱充值",
"sum_value": "50850.00",
"trade_icon": "/assets/icon/sh20.png",
"sum_count": 7,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh20.png",
"billTitle": "零钱充值",
"amountValue": "50850.00"
},
{
"id": 1,
"trade_typetxt": "零钱提现",
"sum_value": "13000.00",
"trade_icon": "/assets/icon/sh20.png",
"sum_count": 9,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh20.png",
"billTitle": "零钱提现",
"amountValue": "13000.00"
},
{
"id": 2,
"trade_typetxt": "信用卡还款",
"sum_value": "249.00",
"trade_icon": "/assets/icon/sh8.png",
"sum_count": 1,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh8.png",
"billTitle": "信用卡还款",
"amountValue": "249.00"
}
]
},
"sumoutdata": {
"list": [
{
"id": 3,
"trade_typetxt": "转账",
"sum_value": "817456.00",
"trade_icon": "/assets/icon/nzz.png",
"sum_count": 190,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nzz.png",
"billTitle": "转账",
"amountValue": "817456.00",
"percentValue": 95.81,
"color": "#0ABF5E"
},
{
"id": 1,
"trade_typetxt": "消费支出",
"sum_value": "18745.78",
"trade_icon": "/assets/icon/nxfzc.png",
"sum_count": 263,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nxfzc.png",
"billTitle": "消费支出",
"amountValue": "18745.78",
"percentValue": 2.2,
"color": "#57A3F9"
},
{
"id": 2,
"trade_typetxt": "发红包",
"sum_value": "4024.00",
"trade_icon": "/assets/icon/nfhb.png",
"sum_count": 43,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nfhb.png",
"billTitle": "发红包",
"amountValue": "4024.00",
"percentValue": 0.47,
"color": "#fa3534"
}
],
"money": 853225.78,
"count": 505
},
"sumindata": {
"list": [
{
"id": 1,
"trade_typetxt": "二维码收款",
"sum_value": "724802.00",
"trade_icon": "/assets/icon/newm.png",
"sum_count": 274,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/newm.png",
"billTitle": "二维码收款",
"amountValue": "724802.00",
"percentValue": 81.22,
"color": "#D7B746"
},
{
"id": 3,
"trade_typetxt": "收转账",
"sum_value": "114567.00",
"trade_icon": "/assets/icon/nzz.png",
"sum_count": 91,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nzz.png",
"billTitle": "收转账",
"amountValue": "114567.00",
"percentValue": 12.84,
"color": "#0ABF5E"
},
{
"id": 2,
"trade_typetxt": "收红包",
"sum_value": "1966.00",
"trade_icon": "/assets/icon/nfhb.png",
"sum_count": 33,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nfhb.png",
"billTitle": "收红包",
"amountValue": "1966.00",
"percentValue": 0.22,
"color": "#fa3534"
}
],
"money": 892434,
"count": 406
},
"sumotherdata": {
"list": [
{
"id": 3,
"trade_typetxt": "零钱充值",
"sum_value": "50850.00",
"trade_icon": "/assets/icon/nlq.png",
"sum_count": 7,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nlq.png",
"billTitle": "零钱充值",
"title": "零钱充值",
"amountValue": "50850.00",
"percentValue": 7,
"color": "#be8913"
},
{
"id": 1,
"trade_typetxt": "零钱提现",
"sum_value": "13000.00",
"trade_icon": "/assets/icon/nlq.png",
"sum_count": 9,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nlq.png",
"billTitle": "零钱提现",
"title": "零钱提现",
"amountValue": "13000.00",
"percentValue": 9,
"color": "#3d7a25"
},
{
"id": 2,
"trade_typetxt": "信用卡还款",
"sum_value": "249.00",
"trade_icon": "/assets/icon/nxyk.png",
"sum_count": 1,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nxyk.png",
"billTitle": "信用卡还款",
"title": "信用卡还款",
"amountValue": "249.00",
"percentValue": 1,
"color": "#a254e0"
}
]
}
}
//---------------start----------------------账单统计数据---------------------start-------------------
function getChartData(param){
console.log("=======获取图表数据参数======",param);
console.log("----------------------!!!!!!!!!!注意!!!!!!!!!!!!!这里只模拟了一组数据!!!!!!!!注意!!!!!!!!!!=============");
return tempChartData;
};
//
module.exports = {
tempBillList:billData,
tempChartData:tempChartData,
queryRecordList:function(year,month,tradeType){
return getRecordList(year,month,tradeType)
},
addItem:function(newItem,callback){
return addItem(newItem,callback)
},
updateItem:function(newItem,callback){
return updateItem(newItem,callback)
},
deleteItem:function(newItem,callback){
return deleteItem(newItem,callback)
},
getChartData:function(param){
return getChartData(param)
},
}
+333
View File
@@ -0,0 +1,333 @@
const emojiUrl = 'https://web.sdk.qcloud.com/im/assets/emoji/';
const emojiMap = {
'[NO]': 'emoji_0@2x.png',
'[OK]': 'emoji_1@2x.png',
'[下雨]': 'emoji_2@2x.png',
'[么么哒]': 'emoji_3@2x.png',
'[乒乓]': 'emoji_4@2x.png',
'[便便]': 'emoji_5@2x.png',
'[信封]': 'emoji_6@2x.png',
'[偷笑]': 'emoji_7@2x.png',
'[傲慢]': 'emoji_8@2x.png',
'[再见]': 'emoji_9@2x.png',
'[冷汗]': 'emoji_10@2x.png',
'[凋谢]': 'emoji_11@2x.png',
'[刀]': 'emoji_12@2x.png',
'[删除]': 'emoji_13@2x.png',
'[勾引]': 'emoji_14@2x.png',
'[发呆]': 'emoji_15@2x.png',
'[发抖]': 'emoji_16@2x.png',
'[可怜]': 'emoji_17@2x.png',
'[可爱]': 'emoji_18@2x.png',
'[右哼哼]': 'emoji_19@2x.png',
'[右太极]': 'emoji_20@2x.png',
'[右车头]': 'emoji_21@2x.png',
'[吐]': 'emoji_22@2x.png',
'[吓]': 'emoji_23@2x.png',
'[咒骂]': 'emoji_24@2x.png',
'[咖啡]': 'emoji_25@2x.png',
'[啤酒]': 'emoji_26@2x.png',
'[嘘]': 'emoji_27@2x.png',
'[回头]': 'emoji_28@2x.png',
'[困]': 'emoji_29@2x.png',
'[坏笑]': 'emoji_30@2x.png',
'[多云]': 'emoji_31@2x.png',
'[大兵]': 'emoji_32@2x.png',
'[大哭]': 'emoji_33@2x.png',
'[太阳]': 'emoji_34@2x.png',
'[奋斗]': 'emoji_35@2x.png',
'[奶瓶]': 'emoji_36@2x.png',
'[委屈]': 'emoji_37@2x.png',
'[害羞]': 'emoji_38@2x.png',
'[尴尬]': 'emoji_39@2x.png',
'[左哼哼]': 'emoji_40@2x.png',
'[左太极]': 'emoji_41@2x.png',
'[左车头]': 'emoji_42@2x.png',
'[差劲]': 'emoji_43@2x.png',
'[弱]': 'emoji_44@2x.png',
'[强]': 'emoji_45@2x.png',
'[彩带]': 'emoji_46@2x.png',
'[彩球]': 'emoji_47@2x.png',
'[得意]': 'emoji_48@2x.png',
'[微笑]': 'emoji_49@2x.png',
'[心碎了]': 'emoji_50@2x.png',
'[快哭了]': 'emoji_51@2x.png',
'[怄火]': 'emoji_52@2x.png',
'[怒]': 'emoji_53@2x.png',
'[惊恐]': 'emoji_54@2x.png',
'[惊讶]': 'emoji_55@2x.png',
'[憨笑]': 'emoji_56@2x.png',
'[手枪]': 'emoji_57@2x.png',
'[打哈欠]': 'emoji_58@2x.png',
'[抓狂]': 'emoji_59@2x.png',
'[折磨]': 'emoji_60@2x.png',
'[抠鼻]': 'emoji_61@2x.png',
'[抱抱]': 'emoji_62@2x.png',
'[抱拳]': 'emoji_63@2x.png',
'[拳头]': 'emoji_64@2x.png',
'[挥手]': 'emoji_65@2x.png',
'[握手]': 'emoji_66@2x.png',
'[撇嘴]': 'emoji_67@2x.png',
'[擦汗]': 'emoji_68@2x.png',
'[敲打]': 'emoji_69@2x.png',
'[晕]': 'emoji_70@2x.png',
'[月亮]': 'emoji_71@2x.png',
'[棒棒糖]': 'emoji_72@2x.png',
'[汽车]': 'emoji_73@2x.png',
'[沙发]': 'emoji_74@2x.png',
'[流汗]': 'emoji_75@2x.png',
'[流泪]': 'emoji_76@2x.png',
'[激动]': 'emoji_77@2x.png',
'[灯泡]': 'emoji_78@2x.png',
'[炸弹]': 'emoji_79@2x.png',
'[熊猫]': 'emoji_80@2x.png',
'[爆筋]': 'emoji_81@2x.png',
'[爱你]': 'emoji_82@2x.png',
'[爱心]': 'emoji_83@2x.png',
'[爱情]': 'emoji_84@2x.png',
'[猪头]': 'emoji_85@2x.png',
'[猫咪]': 'emoji_86@2x.png',
'[献吻]': 'emoji_87@2x.png',
'[玫瑰]': 'emoji_88@2x.png',
'[瓢虫]': 'emoji_89@2x.png',
'[疑问]': 'emoji_90@2x.png',
'[白眼]': 'emoji_91@2x.png',
'[皮球]': 'emoji_92@2x.png',
'[睡觉]': 'emoji_93@2x.png',
'[磕头]': 'emoji_94@2x.png',
'[示爱]': 'emoji_95@2x.png',
'[礼品袋]': 'emoji_96@2x.png',
'[礼物]': 'emoji_97@2x.png',
'[篮球]': 'emoji_98@2x.png',
'[米饭]': 'emoji_99@2x.png',
'[糗大了]': 'emoji_100@2x.png',
'[红双喜]': 'emoji_101@2x.png',
'[红灯笼]': 'emoji_102@2x.png',
'[纸巾]': 'emoji_103@2x.png',
'[胜利]': 'emoji_104@2x.png',
'[色]': 'emoji_105@2x.png',
'[药]': 'emoji_106@2x.png',
'[菜刀]': 'emoji_107@2x.png',
'[蛋糕]': 'emoji_108@2x.png',
'[蜡烛]': 'emoji_109@2x.png',
'[街舞]': 'emoji_110@2x.png',
'[衰]': 'emoji_111@2x.png',
'[西瓜]': 'emoji_112@2x.png',
'[调皮]': 'emoji_113@2x.png',
'[象棋]': 'emoji_114@2x.png',
'[跳绳]': 'emoji_115@2x.png',
'[跳跳]': 'emoji_116@2x.png',
'[车厢]': 'emoji_117@2x.png',
'[转圈]': 'emoji_118@2x.png',
'[鄙视]': 'emoji_119@2x.png',
'[酷]': 'emoji_120@2x.png',
'[钞票]': 'emoji_121@2x.png',
'[钻戒]': 'emoji_122@2x.png',
'[闪电]': 'emoji_123@2x.png',
'[闭嘴]': 'emoji_124@2x.png',
'[闹钟]': 'emoji_125@2x.png',
'[阴险]': 'emoji_126@2x.png',
'[难过]': 'emoji_127@2x.png',
'[雨伞]': 'emoji_128@2x.png',
'[青蛙]': 'emoji_129@2x.png',
'[面条]': 'emoji_130@2x.png',
'[鞭炮]': 'emoji_131@2x.png',
'[风车]': 'emoji_132@2x.png',
'[飞吻]': 'emoji_133@2x.png',
'[飞机]': 'emoji_134@2x.png',
'[饥饿]': 'emoji_135@2x.png',
'[香蕉]': 'emoji_136@2x.png',
'[骷髅]': 'emoji_137@2x.png',
'[麦克风]': 'emoji_138@2x.png',
'[麻将]': 'emoji_139@2x.png',
'[鼓掌]': 'emoji_140@2x.png',
'[龇牙]': 'emoji_141@2x.png'
};
const emojiName = [
'[龇牙]',
'[调皮]',
'[流汗]',
'[偷笑]',
'[再见]',
'[敲打]',
'[擦汗]',
'[猪头]',
'[玫瑰]',
'[流泪]',
'[大哭]',
'[嘘]',
'[酷]',
'[抓狂]',
'[委屈]',
'[便便]',
'[炸弹]',
'[菜刀]',
'[可爱]',
'[色]',
'[害羞]',
'[得意]',
'[吐]',
'[微笑]',
'[怒]',
'[尴尬]',
'[惊恐]',
'[冷汗]',
'[爱心]',
'[示爱]',
'[白眼]',
'[傲慢]',
'[难过]',
'[惊讶]',
'[疑问]',
'[困]',
'[么么哒]',
'[憨笑]',
'[爱情]',
'[衰]',
'[撇嘴]',
'[阴险]',
'[奋斗]',
'[发呆]',
'[右哼哼]',
'[抱抱]',
'[坏笑]',
'[飞吻]',
'[鄙视]',
'[晕]',
'[大兵]',
'[可怜]',
'[强]',
'[弱]',
'[握手]',
'[胜利]',
'[抱拳]',
'[凋谢]',
'[米饭]',
'[蛋糕]',
'[西瓜]',
'[啤酒]',
'[瓢虫]',
'[勾引]',
'[OK]',
'[爱你]',
'[咖啡]',
'[月亮]',
'[刀]',
'[发抖]',
'[差劲]',
'[拳头]',
'[心碎了]',
'[太阳]',
'[礼物]',
'[皮球]',
'[骷髅]',
'[挥手]',
'[闪电]',
'[饥饿]',
'[咒骂]',
'[折磨]',
'[抠鼻]',
'[鼓掌]',
'[糗大了]',
'[左哼哼]',
'[打哈欠]',
'[快哭了]',
'[吓]',
'[篮球]',
'[乒乓]',
'[NO]',
'[跳跳]',
'[怄火]',
'[转圈]',
'[磕头]',
'[回头]',
'[跳绳]',
'[激动]',
'[街舞]',
'[献吻]',
'[左太极]',
'[右太极]',
'[闭嘴]',
'[猫咪]',
'[红双喜]',
'[鞭炮]',
'[红灯笼]',
'[麻将]',
'[麦克风]',
'[礼品袋]',
'[信封]',
'[象棋]',
'[彩带]',
'[蜡烛]',
'[爆筋]',
'[棒棒糖]',
'[奶瓶]',
'[面条]',
'[香蕉]',
'[飞机]',
'[左车头]',
'[车厢]',
'[右车头]',
'[多云]',
'[下雨]',
'[钞票]',
'[熊猫]',
'[灯泡]',
'[风车]',
'[闹钟]',
'[雨伞]',
'[彩球]',
'[钻戒]',
'[沙发]',
'[纸巾]',
'[手枪]',
'[青蛙]',
];
const faceUrl = 'https://web.sdk.qcloud.com/im/assets/face-elem/';
const bigEmojiList = [
{
icon: 'yz00',
list: ['yz00', 'yz01', 'yz02', 'yz03', 'yz04', 'yz05', 'yz06', 'yz07', 'yz08',
'yz09', 'yz10', 'yz11', 'yz12', 'yz13', 'yz14', 'yz15', 'yz16', 'yz17']
},
{
icon: 'ys00',
list: ['ys00', 'ys01', 'ys02', 'ys03', 'ys04', 'ys05', 'ys06', 'ys07', 'ys08',
'ys09', 'ys10', 'ys11', 'ys12', 'ys13', 'ys14', 'ys15']
},
{
icon: 'gcs00',
list: ['gcs00', 'gcs01', 'gcs02', 'gcs03', 'gcs04', 'gcs05', 'gcs06', 'gcs07',
'gcs08', 'gcs09', 'gcs10', 'gcs11', 'gcs12', 'gcs13', 'gcs14', 'gcs15', 'gcs16'],
},
];
function splitEmojiList() {
let self = this;
let length = Math.ceil(emojiName.length / 24);
let arr = new Array(length);
for (let j = 0; j < length; j++) {
let subArr = [];
for (var i = j * 24; i < 24 * (j + 1); i++) {
if (i > emojiName.length - 1) {
break;
}
subArr.push(emojiName[i]);
}
arr[j] = subArr;
}
//console.log("分割",arr);
return arr;
}
module.exports = {
emojiUrl:emojiUrl,
emojiMap:emojiMap,
emojiName:emojiName,
bigEmojiList:bigEmojiList,
faceUrl:faceUrl,
splitEmojiList:function(){
return splitEmojiList();
}
}
+40 -18
View File
@@ -7,12 +7,16 @@ import {getVideoInfo} from "@/util/common";
import {downloadFile} from "@/uni_modules/network-manage"; import {downloadFile} from "@/uni_modules/network-manage";
// #endif // #endif
export const imapi = (method,data)=>{ export const imapi = (method,data)=>{
console.log(method);
console.log(data);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
IMSDK.asyncApi(method,IMSDK.uuid(),data) IMSDK.asyncApi(method,IMSDK.uuid(),data)
.then(res=>{ .then(res=>{
console.log(res);
return resolve(res); return resolve(res);
}) })
.catch(e=>{ .catch(e=>{
console.log(e);
return reject(e); return reject(e);
}) })
}); });
@@ -64,7 +68,14 @@ export const getPurePath = (path)=>{
} }
return path; return path;
} }
export const createVoiceMessage = async (path)=>{ export const createVoiceMessage = (path,duration)=>{
return new Promise(async(resolve, reject) => {
const message = await imapi(IMMethods.CreateSoundMessageFromFullPath,{
soundPath:getPurePath(path),
duration:duration
});
return resolve(message);
});
}; };
export const createFileMessage = async (path)=>{ export const createFileMessage = async (path)=>{
}; };
@@ -83,11 +94,26 @@ export const getVideoCover = async (path)=>{
}; };
export const createVideoMessage = (path)=>{ export const createVideoMessage = (path)=>{
return new Promise(async(resolve, reject) => { return new Promise(async(resolve, reject) => {
const realVideoPath = await getPurePath(path);
console.log('处理后的可用路径', realVideoPath);
const info = await getVideoInfo(realVideoPath);
//const cover = await getVideoCover(path);
const res1 = await IMSDK.getVideoCover(path);
//console.log(res1.path);
const videoParams = {
videoPath: realVideoPath,
videoType: "mp4",
duration: info.duration,
snapshotPath: getPurePath(res1.path),
//snapshotPath: getPurePath(cover),
};
console.log('videoParams', videoParams);
const message = await imapi(IMMethods.CreateVideoMessageFromFullPath,videoParams);
return resolve(message);
//不想通过imsdk上传了,想自己上传,结果发现imsdk的上传接口不支持视频,所以只能通过imsdk上传了
console.log('处理前的可用路径', path); console.log('处理前的可用路径', path);
//const realVideoPath = await copyFileToTempPath(path); //const realVideoPath = await copyFileToTempPath(path);
const realVideoPath = await getPurePath(path);
//console.log('处理后的可用路径', realVideoPath); //console.log('处理后的可用路径', realVideoPath);
const info = await getVideoInfo(realVideoPath);
console.log('info', info); console.log('info', info);
const cover = await getVideoCover(realVideoPath); const cover = await getVideoCover(realVideoPath);
console.log('cover', cover); console.log('cover', cover);
@@ -140,23 +166,28 @@ export const createVideoMessage = (path)=>{
//const cover = await getVideoCover(path); //const cover = await getVideoCover(path);
//const res1 = await IMSDK.getVideoCover(path); //const res1 = await IMSDK.getVideoCover(path);
//console.log(res1.path); //console.log(res1.path);
const videoParams = { const videoParams1 = {
videoPath: realVideoPath, videoPath: realVideoPath,
videoType: "mp4", videoType: "mp4",
duration: info.duration, duration: info.duration,
snapshotPath: getPurePath(res1.path), snapshotPath: getPurePath(res1.path),
//snapshotPath: getPurePath(cover), //snapshotPath: getPurePath(cover),
}; };
console.log('videoParams', videoParams); console.log('videoParams', videoParams1);
message = await IMSDK.asyncApi( const message1 = await IMSDK.asyncApi(
IMMethods.CreateVideoMessageFromFullPath, IMMethods.CreateVideoMessageFromFullPath,
IMSDK.uuid(), IMSDK.uuid(),
videoParams videoParams
); );
return resolve(message);
}); });
}; };
export const createImageMessage = async (path)=>{ export const createImageMessage = async (path)=>{
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const message = await IMSDK.asyncApi(IMMethods.CreateImageMessageFromFullPath,IMSDK.uuid(),getPurePath(path));
console.log(message);
return resolve(message);
//通过自己上传的方法实现的
const result = await upload(path,{savePath: "msg"}); const result = await upload(path,{savePath: "msg"});
if(result.code !=0){ if(result.code !=0){
uni.$u.toast(result.msg); uni.$u.toast(result.msg);
@@ -171,23 +202,14 @@ export const createImageMessage = async (path)=>{
url: result.data[0].file_url url: result.data[0].file_url
}; };
const message = await IMSDK.asyncApi(IMMethods.CreateImageMessageByURL,IMSDK.uuid(),{ const message1 = await IMSDK.asyncApi(IMMethods.CreateImageMessageByURL,IMSDK.uuid(),{
sourcePicture: picBaseInfo, sourcePicture: picBaseInfo,
bigPicture: picBaseInfo, bigPicture: picBaseInfo,
snapshotPicture: picBaseInfo, snapshotPicture: picBaseInfo,
sourcePath: result.data[0].file_url sourcePath: result.data[0].file_url
}); });
console.log('message', message); console.log('message', message1);
return resolve(message); return resolve(message1);
const tempPath = await copyFileToTempPath(path);
console.log(tempPath);
imapi(IMMethods.CreateImageMessageFromFullPath,getPurePath(tempPath)).then(res=>{
console.log(res);
resolve(res);
}).catch(err=>{
console.log(err);
reject(err);
})
}); });
} }
export const sendMessage = (message, user_id, group_id) => { export const sendMessage = (message, user_id, group_id) => {
+120
View File
@@ -0,0 +1,120 @@
/**
* 秒数转时长 1 00:01
*/
export function secondToDuration(second, fixed = 0) {
var sec = (second % 60).toFixed(fixed);
var min = Math.floor(second / 60);
if (min.toString().length < 2) {
min = '0' + min;
}
if (sec < 10) {
sec = '0' + sec;
}
return min + ':' + sec
}
/**
* 判断两个对象是否相等
* @param {Object} o1
* @param {Object} o2
*/
export function objEquals(o1,o2){
if(o1 && o2){
return o1.platform == o2.platform && o1.id == o2.id;
}else{
return false;
}
}
export function isExist(list,obj){
for (let itemIndex in list) {
const item = list[itemIndex];
if (objEquals(item,obj)) {
return true;
}
}
return false;
}
export function findIndex(list,obj){
for (let itemIndex in list) {
const item = list[itemIndex];
if (objEquals(item,obj)) {
return parseInt(itemIndex);
}
}
return -1;
}
export function findObj(list,obj){
const index = findIndex(list,obj);
if(inde != -1){
return list[index];
}
return null;
}
export function isFind(list,obj){
const index = findIndex(list,obj);
if(index != -1){
return true;
}
return false;
}
export function showToast(title,duration = 2000,icon="none",position="bottom"){
uni.showToast({
title,
icon,
duration,
position
});
}
/**
* 格式化歌词
* @param {String} lrcStr 歌词文本
* @param {String} mode 格式 object 对象模式array 数组模式
*/
export function formatLrc(lrcStr,mode = 'object'){
const reg = /\[\d*:\d*(\.|:)\d*]/g
const timeReg = /\[(\d{2,})\:(\d{2})(?:\.(\d{1,3}))?\]/g; // eslint-disable-line no-useless-escape
let timeResult = [];
let index = 0;
if(mode == 'object'){
let lrcs = {};
lrcStr.split("\n").forEach(item => {
const timeRegAry = item.match(reg);
if (timeRegAry) {
const time = timeRegAry[0];
const min = parseInt(time.match(/\[\d*/i).toString().slice(1))
const sec = parseInt(time.match(/\:\d*/i).toString().slice(1))
const second = min * 60 + sec
const content = item.replace(timeRegAry, "")
lrcs[second] = {
time,
content
};
}
})
return lrcs;
}else{
let lrcs = [];
lrcStr.split("\n").forEach(item => {
const timeRegAry = item.match(reg);
if (timeRegAry) {
const time = timeRegAry[0];
const min = parseInt(time.match(/\[\d*/i).toString().slice(1))
const sec = parseInt(time.match(/\:\d*/i).toString().slice(1))
const second = min * 60 + sec
const content = item.replace(timeRegAry, "")
lrcs.push({
second,
time,
content
});
}
})
return lrcs;
}
}
+134
View File
@@ -0,0 +1,134 @@
const storage_constants = {
searchHistory:'searchHistory',
paramSongList:'paramSongList',
mySongList:'mySongList',
playList:'playList',
playMode:'playMode',
progress:'progress',
playSeconds:'playSeconds',
playDuration:'playDuration',
playIndex:'playIndex',
isFirstRun:'isFirstRun',
recentlyPlayList:'recentlyPlayList'
}
function set(key, value) {
try {
uni.setStorageSync(key, value);
return true;
} catch (e) {
return false;
}
}
function get(key) {
try {
return uni.getStorageSync(key);
} catch (e) {
return null;
}
}
function getDefault(key, defaultVal) {
try {
let val = uni.getStorageSync(key);
if(val || val == 0){
return val;
}else{
val = defaultVal;
return val;
}
} catch (e) {
return defaultVal;
}
}
function getObj(key) {
try {
const val = uni.getStorageSync(key);
if (val) {
return val;
}
return null;
} catch (e) {
return null;
}
}
function getObjDefault(key, defaultVal) {
try {
const val = uni.getStorageSync(key);
if (val) {
return val;
}
return defaultVal;
} catch (e) {
return defaultVal;
}
}
function getArray(key) {
try {
const val = uni.getStorageSync(key);
if (val) {
return val;
}
return [];
} catch (e) {
return [];
}
}
function getArrayDefault(key, defaultVal) {
try {
const val = uni.getStorageSync(key);
if (val) {
return val;
}
return defaultVal;
} catch (e) {
return defaultVal;
}
}
function clearStorage(){
uni.clearStorage();
let item = {
coverImg:"/static/mylike.png",
name:`我喜欢的音乐`,
id:"mylike",
url:null,
singer:"我喜欢的音乐",
desc:null,
platform:'local',
album:null,
list:[]
}
let allSongList = [];
allSongList.push(item);
set(storage_constants.mySongList,allSongList)
}
function remove(key){
uni.removeStorageSync(key);
}
const storage = {
set,
get,
getDefault,
getObj,
getObjDefault,
getArray,
getArrayDefault,
clearStorage,
remove
}
export {
storage,
storage_constants
}
+10
View File
@@ -0,0 +1,10 @@
export const playModeConfig = {
list:{id:'list',icon:'play-list-foreach',name:'列表循环'},
random:{id:'random',icon:'play-random',name:'随机播放'},
single:{id:'single',icon:'play-one-foreach',name:'单曲循环'}
}
export const config = {
playModel:playModeConfig
}
+278
View File
@@ -0,0 +1,278 @@
import Vue from 'vue'
import Store from './store.js'
import {
playModeConfig
} from './config.js';
import {
storage,
storage_constants
} from "./StorageUtil.js"
import * as util from "./BaseUtil.js"
export default {
extends: Store,
data() {},
methods: {
initMusic() {
let audioPlayer = null;
/* #ifdef H5 */
audioPlayer = uni.createInnerAudioContext();
/* #endif */
/* #ifdef APP-PLUS */
audioPlayer = uni.getBackgroundAudioManager();
/* #endif */
audioPlayer.autoplay = false;
audioPlayer.onTimeUpdate((e) => {
this.setPlaySeconds(audioPlayer.currentTime);
let progress = (audioPlayer.currentTime / audioPlayer.duration) * 100;
if (progress) {
this.setProgress(progress);
}
this.updateLrc(false);
});
audioPlayer.onCanplay(() => {
this.setMusicIsReady(true);
})
audioPlayer.onError(()=>{
util.showToast('播放错误,即将播放下一首');
this.next();
})
audioPlayer.onEnded(() => {
if (playModeConfig.single.id == this.playMode.id) {
this.setMusic(this.playIndex, null, () => {
this.play();
this.setPlayState(true);
});
} else if (playModeConfig.random.id == this.playMode.id) {
const index = parseInt((this.playList.length - 1) * Math.random())
this.setMusic(index, null, () => {
this.play();
this.setPlayState(true);
});
} else {
this.next();
}
})
Vue.prototype.audioPlayer = audioPlayer;
Vue.prototype.prev = this.prev;
Vue.prototype.next = this.next;
Vue.prototype.stop = this.stop;
Vue.prototype.pause = this.pause;
Vue.prototype.play = this.play;
Vue.prototype.loadLrc = this.loadLrc;
Vue.prototype.setMusic = this.setMusic;
// Vue.prototype.getMusicPlayUrl = this.musicApi.getPlayUrl;
// Vue.prototype.getLrc = this.musicApi.getLrc;
// Vue.prototype.getMusicOtherInfo = this.musicApi.getMusicOtherInfo
const playMode = storage.get(storage_constants.playMode);
if (!playMode) {
this.setPlayMode(playModeConfig.list);
}
const mySongList = storage.getArrayDefault(storage_constants.mySongList, []);
/**
* 初始化歌词
*/
if (this.playList && this.playIndex >= 0) {
let music = this.playList[this.playIndex];
if (music) {
this.loadLrc(music, () => {
this.updateLrc(true);
});
}
}
},
/**
* 设置音乐
* @param {Object} index
* @param {type} progress
* @param {Object} call
*/
setMusic(index, progress, call) {
if (this.playList && this.playList.length > 0) {
if (index == null) {
index = 0
}
// 停止播放
this.audioPlayer.stop();
// 更新播放状态
this.setPlayState(false);
if (progress) {
// 重置进度条
this.setProgress(progress.progress || 0)
// 重置播放秒数
this.setPlaySeconds(progress.playSeconds || 0)
} else {
// 重置进度条
this.setProgress(0)
// 重置播放秒数
this.setPlaySeconds(0)
}
// 重置总秒数
this.setTotalSeconds(0)
// 音乐状态为未准备
this.setMusicIsReady(false)
let music = this.playList[index];
/* this.getMusicOtherInfo(music,(musicOtherInfo)=>{
music = musicOtherInfo;
}) */
const oldPlayMusic = this.playList[this.playIndex];
if (!util.objEquals(oldPlayMusic, music)) {
// 重置歌词
this.setLrcs([{
time: '[00:00.00]',
content: '歌词加载中'
}]);
this.setLrc({
time: '[00:00.00]',
content: '歌词加载中'
})
}
this.setPlayIndex(index);
// 加载歌词
this.loadLrc(music);
// 获取播放地址
Vue.prototype.getMusicPlayUrl && Vue.prototype.getMusicPlayUrl(music).then(playUrl => {
console.log(`播放地址:${playUrl}`)
this.audioPlayer.src = playUrl;
this.audioPlayer.title = music.name;
this.audioPlayer.singer = music.singer;
this.audioPlayer.coverImgUrl = music.coverImg;
let timer = setInterval(() => {
if (this.musicIsReady) {
this.setTotalSeconds(this.audioPlayer.duration)
if (this.playSeconds > 0) {
this.audioPlayer.seek(this.playSeconds)
}
this.setMusicIsReady(false)
clearInterval(timer);
if (call) {
call();
}
}
}, 200);
})
}
},
getMusicOtherInfo(music, call) {
if (music.loadOtherInfo) {
Vue.prototype.getMusicOtherInfo && Vue.prototype.getMusicOtherInfo(music).then(musicResult => {
call(musicResult)
})
}
},
/**
* 加载歌词
*/
loadLrc(music, call) {
Vue.prototype.getLrc && Vue.prototype.getLrc(music).then(lrcStr => {
if (lrcStr) {
this.setLrcStr(lrcStr)
if (call) {
call();
}
} else {
this.setLrcStr('[00:00.00]无歌词')
}
})
},
/**
* 更新当前歌词
* @param {Object} isInit
*/
updateLrc(isInit) {
if (this.lrcs) {
const sec = parseInt(this.playSeconds);
let index = sec + 1;
let line = this.lrcs[index];
if (line) {
this.setLrc(line);
} else {
if (isInit) {
for (var i = index; i >= 0; i--) {
let initLine = this.lrcs[i];
if (initLine) {
this.setLrc(initLine);
break;
}
}
}
}
}
},
/**
* 播放
*/
play() {
this.audioPlayer.play();
this.setPlayState(true);
const music = this.playList[this.playIndex];
this.pushRecentlyPlayList(music);
},
/**
* 暂停
*/
pause() {
this.audioPlayer.pause();
this.setPlayState(false);
},
/**
* 停止
*/
stop() {
this.audioPlayer.stop();
this.setPlayState(false);
this.setProgress(0);
this.setPlaySeconds(0)
},
/**
* 下一曲
*/
next() {
const length = this.playList.length;
let index = -1;
if (this.playIndex == length - 1) {
index = 0;
} else {
index = this.playIndex + 1;
}
this.setMusic(index, null, () => {
this.play();
this.setPlayState(true);
});
},
/**
* 上一曲
*/
prev() {
const length = this.playList.length;
let index = this.playIndex;
if (index == 0) {
index = length - 1;
} else {
index = index - 1;
}
this.setMusic(index, null, () => {
this.play();
this.setPlayState(true);
});
},
pushRecentlyPlayList(music){
let recentlyPlayList = storage.getArrayDefault(storage_constants.recentlyPlayList, []);
let index = util.findIndex(recentlyPlayList,music);
if(index >= 0){
recentlyPlayList.splice(index,1)
}
recentlyPlayList.splice(0,0,music)
this.setRecentlyPlayList(recentlyPlayList);
this.$forceUpdate()
}
}
}
+70
View File
@@ -0,0 +1,70 @@
/* #ifdef H5 */
const bgAudioManager = uni.createInnerAudioContext();
/* #endif */
/* #ifdef APP-PLUS */
const bgAudioManager = uni.getBackgroundAudioManager();
/* #endif */
bgAudioManager.autoplay = false;
function initPlayer(that){
if(that.currentPlaySong){
that.$u.vuex("currentPlayer",{
playState:false,
progress:0,
musicId:that.currentPlaySong.id,
});
bgAudioManager.title = that.currentPlaySong.songName;
bgAudioManager.singer = that.currentPlaySong.artist;
bgAudioManager.coverImgUrl = that.currentPlaySong.pic;
bgAudioManager.src = that.currentPlaySong.playSrc;
console.log("播放器初始化完成");
bindOnControllerPlay(that);
}
}
function bindOnControllerPlay(that){
let playState=that.currentPlayer.playState;
console.log("that.currentPlayer.progress",that.currentPlayer.progress);
if(playState){
bgAudioManager.pause();
}else{
if(that.currentPlayer.canPlay==false){
initPlayer(that);
return;
}else{
bgAudioManager.play();
that.$u.vuex("currentPlayer.canPlay",true);
}
}
playState=!playState;
console.log("当前播放状态===",playState);
that.$u.vuex("currentPlayer.playState",playState);
that.$u.vuex("currentPlayer.canPlay",true);
bgAudioManager.onTimeUpdate((e) => {
let progress = (bgAudioManager.currentTime / bgAudioManager.duration) * 100;
if (progress) {
that.$u.vuex("currentPlayer.progress",progress);
}
});
bgAudioManager.onError(()=>{
resetPlayer(that);
});
bgAudioManager.onEnded(() => {
resetPlayer(that);
});
}
function resetPlayer(that,player){
bgAudioManager.stop();
that.$u.vuex("currentPlayer.playState",false);
that.$u.vuex("currentPlayer.progress",0);
that.$u.vuex("currentPlayer.canPlay",false);
}
module.exports = {
initPlayer,
bindOnControllerPlay,
resetPlayer,
bgAudioManager
}
+88
View File
@@ -0,0 +1,88 @@
import {
mapState,
mapMutations
} from 'vuex'
import * as util from './BaseUtil.js'
export default {
computed: {
...mapState(['totalSeconds', 'totalDuration', 'playSeconds', 'playDuration', 'progress', 'playState',
'playMode', 'musicIsReady', 'playList', 'playIndex', 'lrcStr', 'lrcs', 'lrc', 'recentlyPlayList'
]),
...mapState(['paramSongList', 'isFirstRun', 'showPlayBar'])
},
methods: {
...mapMutations(['setPlayIndex', 'setTotalSeconds', 'setPlaySeconds', 'setProgress', 'setPlayState',
'setPlayMode', 'setMusicIsReady', 'setPlayList', 'setLrcStr', 'setLrcs', 'setLrc', 'setRecentlyPlayList'
]),
...mapMutations(['setParamSongList', 'setIsFirstRun', 'setShowPlayBar']),
like(music) {
this.songListService.like(music)
this.$forceUpdate();
},
unLike(music) {
this.songListService.unLike(music);
this.$forceUpdate();
},
isLike(music) {
return this.musicService.isLike(music);
},
controllerPlay(type) {
if (type == 'play') {
if (this.playState) {
this.pause();
} else {
if (this.isFirstRun) {
const progress = {
progress: this.progress,
playSeconds: this.playSeconds
}
this.setMusic(this.playIndex, progress, () => {
this.play();
})
} else {
this.play();
}
}
} else if (type == 'next') {
this.next();
} else if (type == 'prev') {
this.prev();
}
},
playMusicByMusic(music) {
let playList = this.playList;
const index = util.findIndex(playList, music);
let playIndex = null;
if (index == -1) {
playList.push(music);
this.setPlayList(playList);
playIndex = playList.length - 1;
} else {
playIndex = index;
}
this.setMusic(playIndex, null, () => {
this.play();
})
},
nextPlay(music) {
const playIndex = this.playIndex;
let playList = this.playList;
const musicIndex = util.findIndex(playList, music);
if (musicIndex != -1) {
if (playList.length - 1 == playIndex) {
playList.push(music);
} else {
let index = playIndex + 1;
playList[musicIndex] = playList.splice(index, 1, playList[musicIndex])[0];
}
} else {
const index = playIndex + 1;
playList.splice(index, 0, music);
}
this.setPlayList(playList);
}
}
}
+286
View File
@@ -0,0 +1,286 @@
// 手机权限js
/// null = 未请求,1 = 已允许,0 = 拒绝|受限, 2 = 系统未开启
var isIOS
function album() {
var result = 0;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
function camera() {
var result = 0;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
function location() {
var result = 0;
var cllocationManger = plus.ios.import("CLLocationManager");
var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
if (!enable) {
result = 2;
} else if (status === 0) {
result = null;
} else if (status === 3 || status === 4) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(cllocationManger);
return result;
}
function push() {
var result = 0;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
if (enabledTypes == 0) {
result = 0;
console.log("推送权限没有开启");
} else {
result = 1;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
result = 3;
console.log("推送权限没有开启!");
} else {
result = 4;
console.log("已经开启推送功能!")
}
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
function contact() {
var result = 0;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(CNContactStore);
return result;
}
function record() {
var result = null;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var status = avaudio.recordPermission();
console.log("permissionStatus:" + status);
if (status === 1970168948) {
result = null;
} else if (status === 1735552628) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(avaudiosession);
return result;
}
function calendar() {
var result = null;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = 1;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
function memo() {
var result = null;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = 1;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
function requestIOS(permissionID) {
return new Promise((resolve, reject) => {
switch (permissionID) {
case "push":
resolve(push());
break;
case "location":
resolve(location());
break;
case "record":
resolve(record());
break;
case "camera":
resolve(camera());
break;
case "album":
resolve(album());
break;
case "contact":
resolve(contact());
break;
case "calendar":
resolve(calendar());
break;
case "memo":
resolve(memo());
break;
default:
resolve(0);
break;
}
});
}
function requestAndroid(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);
},
function(error) {
console.log('result error: ' + error.message)
resolve({
code: error.code,
message: error.message
});
}
);
});
}
function gotoAppPermissionSetting() {
if (permission.isIOS) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
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);
}
}
function gotoiOSPermissionSetting() {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("App-prefs:root=General");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
}
function openAndroidPushSetting() {
var mainActivity = plus.android.runtimeMainActivity();
var pkName = mainActivity.getPackageName();
var uid = mainActivity.getApplicationInfo().plusGetAttribute("uid");
var Intent = plus.android.importClass('android.content.Intent');
var Build = plus.android.importClass("android.os.Build");
if (Build.VERSION.SDK_INT >= 26) {
//android 8.0引导
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", pkName, null);
intent.setData(uri);
}
// 跳转到该应用的系统通知设置页
mainActivity.startActivity(intent);
}
const permission = {
get isIOS(){
return typeof isIOS === 'boolean' ? isIOS : (isIOS = uni.getSystemInfoSync().platform === 'ios')
},
requestIOS: requestIOS,
requestAndroid: requestAndroid,
gotoAppSetting: gotoAppPermissionSetting,
gotoiOSSetting: gotoiOSPermissionSetting,
openAndroidPushSetting:openAndroidPushSetting
}
module.exports = permission
+898
View File
@@ -0,0 +1,898 @@
//---------------start----------------------账单列表---------------------start-------------------
var billData=[
{
"currentYear": 2023,
"currentMonth": 11,
"outputAmount": 1100,
"inputAmount": 11000,
"recordList":[
{
"tradeDirection": "in",
"finishTime": "2023-11-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "转账-来自莉莉-11",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType":"6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "转账给莉莉-11",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "微信红包-发给莉-11",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "11微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
}
]
},
{
"currentYear": 2023,
"currentMonth": 10,
"outputAmount": 1000,
"inputAmount": 10000,
"recordList": [
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "10-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
}
]
},
{
"currentYear": 2023,
"currentMonth": 9,
"outputAmount": 900,
"inputAmount": 9000,
"recordList": [
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-09-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-09-07 12:15:00",
"createTime": "2023-09-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-09-07 14:59:00",
"createTime": "2023-11-07 15:00:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账-来自莉莉",
"tradeCode": "TJTC_1721784520610545664",
"tradeValue": 10000,
"id": 1635,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-07 12:15:00",
"createTime": "2023-11-07 12:15:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-转账给莉莉",
"tradeCode": "TJTC_1721743291227176960",
"tradeValue": 500,
"id": 1630,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "out",
"finishTime": "2023-11-06 14:44:00",
"createTime": "2023-11-06 14:44:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-发给莉",
"tradeCode": "TJTC_1721780784832053248",
"tradeValue": 200,
"id": 1633,
"userId": 554,
"tradeType": "6"
},
{
"tradeDirection": "in",
"finishTime": "2023-11-05 14:55:00",
"createTime": "2023-11-05 14:55:00",
"tradeIcon": "/static/image/mycenter/default-record-icon.jpg",
"tradeStatus": "2",
"tradeTitle": "9-微信红包-来自莉莉",
"tradeCode": "TJTC_1721783502145454080",
"tradeValue": 200,
"id": 1634,
"userId": 554,
"tradeType": "6"
}
]
}
]
function getRecordList(year,month,tradeType){
console.log("=======year"+year+"====month==="+month+"=====type==="+tradeType);
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find(item=>(item.currentYear==year&&item.currentMonth==month));
console.log("recordItem===",recordItem);
if(recordItem!=undefined&&recordItem!=null){
recordItem.recordList=recordItem.recordList.filter(item=>item.tradeType==tradeType);
return recordItem;
}else{
return {
"currentYear": year,
"currentMonth": month,
"outputAmount": 0.00,
"inputAmount": 0.00,
"recordList":[]
};
}
}
function addItem(newItem,callback){
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find((item,index)=>{
return item.currentYear==year&&item.currentMonth==month
})
recordItem.recordList.push(newItem);
billData=tempData;
callback();
}
function deleteItem(delItem,callback){
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find((item,index)=>{
return item.currentYear==year&&item.currentMonth==month
})
recordItem.recordList=recordItem.recordList.filter((item)=>{
return item.createTime!=delItem.createTime;
});
billData=tempData;
callback();
}
function updateItem(updateItem,callback){
let tempData=JSON.parse(JSON.stringify(billData));
let recordItem= tempData.find((item,index)=>{
return item.currentYear==year&&item.currentMonth==month
})
recordItem.recordList=recordItem.recordList.filter((item)=>{
return item.createTime!=delItem.createTime;
});
addItem(updateItem,callback);
}
//---------------end----------------------账单列表---------------------end-------------------
const tempChartData={
"outdata": {
"list": [
{
"id": 3,
"trade_typetxt": "转账",
"sum_value": "65906.00",
"trade_icon": "/assets/icon/zd3.png",
"sum_count": 18,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd3.png",
"billTitle": "转账",
"amountValue": "65906.00"
},
{
"id": 2,
"trade_typetxt": "二维码收付款",
"sum_value": "1348.40",
"trade_icon": "/assets/icon/zd1.png",
"sum_count": 17,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd1.png",
"billTitle": "二维码收付款",
"amountValue": "1348.40"
},
{
"id": 1,
"trade_typetxt": "微信红包",
"sum_value": "326.00",
"trade_icon": "/assets/icon/sh19.png",
"sum_count": 2,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh19.png",
"billTitle": "微信红包",
"amountValue": "326.00"
}
],
"money": 81127.53,
"count": 54,
"month_list": {
"month": [
"06月",
"07月",
"08月",
"09月",
"10月",
"11月"
],
"money": [
136253.37,
140794.18,
140792.95,
136254.18,
140792.97,
81127.53
],
"list": [
{
"money": 136253.37,
"month": "06月"
},
{
"money": 140794.18,
"month": "07月"
},
{
"money": 140792.95,
"month": "08月"
},
{
"money": 136254.18,
"month": "09月"
},
{
"money": 140792.97,
"month": "10月"
},
{
"money": 81127.53,
"month": "11月"
}
]
}
},
"indata": {
"list": [
{
"id": 1,
"trade_typetxt": "二维码收付款",
"sum_value": "62803.00",
"trade_icon": "/assets/icon/zd1.png",
"sum_count": 24,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd1.png",
"billTitle": "二维码收付款",
"amountValue": "62803.00"
},
{
"id": 3,
"trade_typetxt": "转账",
"sum_value": "5591.00",
"trade_icon": "/assets/icon/zd3.png",
"sum_count": 10,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/zd3.png",
"billTitle": "转账",
"amountValue": "5591.00"
},
{
"id": 2,
"trade_typetxt": "微信红包",
"sum_value": "137.00",
"trade_icon": "/assets/icon/sh19.png",
"sum_count": 4,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh19.png",
"billTitle": "微信红包",
"amountValue": "137.00"
}
],
"money": 119630,
"count": 46,
"month_list": {
"month": [
"06月",
"07月",
"08月",
"09月",
"10月",
"11月"
],
"money": [
137061,
130787,
152473,
120999,
157692,
119630
],
"list": [
{
"money": 137061,
"month": "06月"
},
{
"money": 130787,
"month": "07月"
},
{
"money": 152473,
"month": "08月"
},
{
"money": 120999,
"month": "09月"
},
{
"money": 157692,
"month": "10月"
},
{
"money": 119630,
"month": "11月"
}
]
}
},
"otherdata": {
"list": [
{
"id": 3,
"trade_typetxt": "零钱充值",
"sum_value": "50850.00",
"trade_icon": "/assets/icon/sh20.png",
"sum_count": 7,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh20.png",
"billTitle": "零钱充值",
"amountValue": "50850.00"
},
{
"id": 1,
"trade_typetxt": "零钱提现",
"sum_value": "13000.00",
"trade_icon": "/assets/icon/sh20.png",
"sum_count": 9,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh20.png",
"billTitle": "零钱提现",
"amountValue": "13000.00"
},
{
"id": 2,
"trade_typetxt": "信用卡还款",
"sum_value": "249.00",
"trade_icon": "/assets/icon/sh8.png",
"sum_count": 1,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/sh8.png",
"billTitle": "信用卡还款",
"amountValue": "249.00"
}
]
},
"sumoutdata": {
"list": [
{
"id": 3,
"trade_typetxt": "转账",
"sum_value": "817456.00",
"trade_icon": "/assets/icon/nzz.png",
"sum_count": 190,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nzz.png",
"billTitle": "转账",
"amountValue": "817456.00",
"percentValue": 95.81,
"color": "#0ABF5E"
},
{
"id": 1,
"trade_typetxt": "消费支出",
"sum_value": "18745.78",
"trade_icon": "/assets/icon/nxfzc.png",
"sum_count": 263,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nxfzc.png",
"billTitle": "消费支出",
"amountValue": "18745.78",
"percentValue": 2.2,
"color": "#57A3F9"
},
{
"id": 2,
"trade_typetxt": "发红包",
"sum_value": "4024.00",
"trade_icon": "/assets/icon/nfhb.png",
"sum_count": 43,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nfhb.png",
"billTitle": "发红包",
"amountValue": "4024.00",
"percentValue": 0.47,
"color": "#fa3534"
}
],
"money": 853225.78,
"count": 505
},
"sumindata": {
"list": [
{
"id": 1,
"trade_typetxt": "二维码收款",
"sum_value": "724802.00",
"trade_icon": "/assets/icon/newm.png",
"sum_count": 274,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/newm.png",
"billTitle": "二维码收款",
"amountValue": "724802.00",
"percentValue": 81.22,
"color": "#D7B746"
},
{
"id": 3,
"trade_typetxt": "收转账",
"sum_value": "114567.00",
"trade_icon": "/assets/icon/nzz.png",
"sum_count": 91,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nzz.png",
"billTitle": "收转账",
"amountValue": "114567.00",
"percentValue": 12.84,
"color": "#0ABF5E"
},
{
"id": 2,
"trade_typetxt": "收红包",
"sum_value": "1966.00",
"trade_icon": "/assets/icon/nfhb.png",
"sum_count": 33,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nfhb.png",
"billTitle": "收红包",
"amountValue": "1966.00",
"percentValue": 0.22,
"color": "#fa3534"
}
],
"money": 892434,
"count": 406
},
"sumotherdata": {
"list": [
{
"id": 3,
"trade_typetxt": "零钱充值",
"sum_value": "50850.00",
"trade_icon": "/assets/icon/nlq.png",
"sum_count": 7,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nlq.png",
"billTitle": "零钱充值",
"title": "零钱充值",
"amountValue": "50850.00",
"percentValue": 7,
"color": "#be8913"
},
{
"id": 1,
"trade_typetxt": "零钱提现",
"sum_value": "13000.00",
"trade_icon": "/assets/icon/nlq.png",
"sum_count": 9,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nlq.png",
"billTitle": "零钱提现",
"title": "零钱提现",
"amountValue": "13000.00",
"percentValue": 9,
"color": "#3d7a25"
},
{
"id": 2,
"trade_typetxt": "信用卡还款",
"sum_value": "249.00",
"trade_icon": "/assets/icon/nxyk.png",
"sum_count": 1,
"iconSrc": "http://weadmin1.fyhcard.com/assets/icon/nxyk.png",
"billTitle": "信用卡还款",
"title": "信用卡还款",
"amountValue": "249.00",
"percentValue": 1,
"color": "#a254e0"
}
]
}
}
//---------------start----------------------账单统计数据---------------------start-------------------
function getChartData(param){
console.log("=======获取图表数据参数======",param);
console.log("----------------------!!!!!!!!!!注意!!!!!!!!!!!!!这里只模拟了一组数据!!!!!!!!注意!!!!!!!!!!=============");
return tempChartData;
};
//
module.exports = {
tempBillList:billData,
tempChartData:tempChartData,
queryRecordList:function(year,month,tradeType){
return getRecordList(year,month,tradeType)
},
addItem:function(newItem,callback){
return addItem(newItem,callback)
},
updateItem:function(newItem,callback){
return updateItem(newItem,callback)
},
deleteItem:function(newItem,callback){
return deleteItem(newItem,callback)
},
getChartData:function(param){
return getChartData(param)
},
}