进入uniapp
8
im-uniapp/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/.hbuilderx/
|
||||
/node_modules/
|
||||
/unpackage/dist/
|
||||
/package-lock.json
|
||||
/unpackage/release/
|
||||
/unpackage/cache/
|
||||
/json/
|
||||
/unpackage/debug/
|
||||
99
im-uniapp/App.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<script>
|
||||
import {
|
||||
version,
|
||||
name
|
||||
} from './package.json'
|
||||
import {
|
||||
versionName
|
||||
} from '@/manifest.json'
|
||||
import {appInit} from "@/common/utils.js"
|
||||
import consoleImgs from '@/common/consoleImgs.js'
|
||||
// #ifdef APP-PLUS
|
||||
import appUpgrade from '@/common/appUpgrade.js';
|
||||
const TUICalling = uni.requireNativePlugin("TUICallingUniPlugin-TUICallingModule");
|
||||
// #endif
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
localStorage.setItem("appId",10000)
|
||||
|
||||
appInit(500).then((res)=>{
|
||||
console.log("获取到token,创建长链接")
|
||||
this.$store.dispatch('getAddressList');
|
||||
setTimeout(()=>{
|
||||
this.$socketTask.connectSocket()
|
||||
uni.setStorageSync("initReady",1)
|
||||
},1000)
|
||||
}).then((error)=>{
|
||||
console.log("未获取到IM的token")
|
||||
console.log(error)
|
||||
})
|
||||
|
||||
|
||||
console.log(consoleImgs.fz)
|
||||
// todo 下列两行
|
||||
uni.setStorageSync('device', 'H5');
|
||||
uni.setStorageSync('version', versionName);
|
||||
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
|
||||
uni.getStorage({
|
||||
key: 'call',
|
||||
success: (res) => {
|
||||
var callx=res.data
|
||||
if(callx){
|
||||
var call=JSON.parse(callx)
|
||||
function getInervalHour(startDate) {//获取两个时间之间的小时
|
||||
if (!startDate) {
|
||||
return '0秒'
|
||||
}
|
||||
var ms = new Date().getTime() - startDate;
|
||||
if (ms < 0) return '0秒';
|
||||
if((ms/1000)<60){
|
||||
return Math.floor(ms / 1000)+'秒';
|
||||
}else{
|
||||
return Math.floor(ms / 1000 /60)+'分';
|
||||
}
|
||||
}
|
||||
var msgType=''
|
||||
if(call.type=='audio'){
|
||||
msgType='TRTC_VOICE_END'
|
||||
}
|
||||
if(call.type=='video'){
|
||||
msgType='TRTC_VIDEO_END'
|
||||
}
|
||||
this.$fc.pushOutMsg({
|
||||
msgContent:getInervalHour(call.startTime),
|
||||
msgType:msgType,
|
||||
windowType:'SINGLE',
|
||||
userId:call.userId,
|
||||
})
|
||||
uni.removeStorageSync('call')
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/*每个页面公共css */
|
||||
@import '@/uni_modules/uni-scss/index.scss';
|
||||
@import "@/static/styles/animation.css";
|
||||
/* #ifndef APP-NVUE */
|
||||
@import '@/static/customicons.css';
|
||||
|
||||
// 设置整个项目的背景色
|
||||
page {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
// 以下内容最好转移到单页
|
||||
|
||||
</style>
|
||||
373
im-uniapp/LICENSE
Normal file
@@ -0,0 +1,373 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
70
im-uniapp/README.md
Normal file
@@ -0,0 +1,70 @@
|
||||
#### 一、项目简介
|
||||
+ 一直以来都有一个社交梦,想做一款IM应用,看了很多优秀的开源项目,但是没有合适自己的。于是利用休息时间自己写了这么一套系统。
|
||||
+ 项目第一个版本历时2个月,前端使用`uniapp`,后端使用`SpringBoot`。
|
||||
+ 页面设计后期会出`独立UI`。
|
||||
+ 手机端使用`uniapp`实现,目前仅支持`安卓端`、`iOS端`和`H5端`,后期会继续适配`小程序端`、`桌面端`(windows、mac)和`web端`。
|
||||
+ 您的支持,就是我们`【生发的动力】`,请手动点个`star`吧。
|
||||
+ 前端源码地址:[https://gitee.com/lakaola/im-uniapp](https://gitee.com/lakaola/im-uniapp)
|
||||
+ 后端源码地址:[https://gitee.com/lakaola/im-platform](https://gitee.com/lakaola/im-platform)
|
||||
+ 下载体验地址:[https://im.q3z3.com/](https://im.q3z3.com/)
|
||||
+ 加入QQ群:
|
||||
[](https://jq.qq.com/?_wv=1027&k=etm5kfCT)(60559794)
|
||||
[](https://jq.qq.com/?_wv=1027&k=9VJv8p2I)(671590862)(已满)
|
||||
[](https://jq.qq.com/?_wv=1027&k=PQMnFugm)(535099683)(已满)
|
||||
|
||||
#### 二、使用须知
|
||||
+ 仅允许`技术学习`使用
|
||||
+ 不允许`本产品及其衍生品`进行任何形式`商业使用`
|
||||
+ 请自觉遵守本开源协议(MPL-2.0),再次开源请注明出处
|
||||
+ 推荐Watch、Star项目,获取项目第一时间更新,同时也是对项目最好的支持
|
||||
+ 希望大家多多支持本开源作品
|
||||
|
||||
#### 三、技术使用
|
||||
+ 推送:uniPush + websocket
|
||||
+ 资源:阿里OSS(图片、声音、视频、文件等)
|
||||
+ 音视频:TRTC
|
||||
+ 地图:高德地图
|
||||
+ 短信:阿里云短信
|
||||
+ 后端:Hutool、MyBatis-Plus、shiro、sharding-jdbc、接口版本控制等
|
||||
+ 前端:uniapp(Vue3)
|
||||
|
||||
#### 四、演示效果
|
||||
<img src="https://img.alicdn.com/imgextra/i2/87413133/O1CN01mD2wwN1Z0xctYYdAA_!!87413133.jpg" width="200">
|
||||
<img src="https://img.alicdn.com/imgextra/i3/87413133/O1CN01bZSz2q1Z0xco96F1t_!!87413133.jpg" width="200">
|
||||
<img src="https://img.alicdn.com/imgextra/i3/87413133/O1CN01Pe8G6S1Z0xcmQluDI_!!87413133.jpg" width="200">
|
||||
<img src="https://img.alicdn.com/imgextra/i1/87413133/O1CN012JP8VW1Z0xccuWKzM_!!87413133.jpg" width="200">
|
||||
<img src="https://img.alicdn.com/imgextra/i4/87413133/O1CN01fMUNJA1Z0xck1w0kt_!!87413133.jpg" width="200">
|
||||
<img src="https://img.alicdn.com/imgextra/i3/87413133/O1CN01n8MZhZ1Z0xctYZEbM_!!87413133.jpg" width="200">
|
||||
|
||||
|
||||
#### 五、项目计划
|
||||
+ 适配android端(已完成)
|
||||
+ 适配iOS端(已完成)
|
||||
+ 适配H5端(已完成)
|
||||
+ 适配PC端[Windows]
|
||||
+ 适配PC端[Mac]
|
||||
+ 适配WEB端[后台管理集成通信]
|
||||
+ 增加后台管理端[管理后台]
|
||||
+ 更换手机端UI[独立UI]
|
||||
+ 增加通知栏消息展示[当app后台挂起,通知栏展示消息]
|
||||
+ 各大应用市场上架
|
||||
+ 后端优化,支持大并发
|
||||
+ ...
|
||||
|
||||
#### 六、版本迭代
|
||||
+ 1.2.0
|
||||
1、修复群名称、昵称显示问题
|
||||
2、修复性别显示问题
|
||||
3、修复部分手机日期显示问题
|
||||
4、修改消息滚动问题
|
||||
+ 1.1.0
|
||||
1、适配H5端
|
||||
2、集成WebSocket通讯
|
||||
3、修改注册后不跳转至登录页问题
|
||||
4、修改长按消息弹出方式
|
||||
5、修改群聊个人头像点击跳转无信息问题
|
||||
6、修改附近的人显示问题
|
||||
7、修改摇一摇显示问题
|
||||
8、修改其他问题
|
||||
+ 1.0.0
|
||||
1、首版震撼发布
|
||||
213
im-uniapp/common/appUpgrade.js
Normal file
@@ -0,0 +1,213 @@
|
||||
var _maskView, _contentView, _downloadTask, _loadingProgress, _screenHeight, _screenWidth, _config = {
|
||||
forceUpgrade: false,
|
||||
titleText: "版本更新",
|
||||
content: "",
|
||||
contentAlign: "left",
|
||||
loadingColor: "#329EEE",
|
||||
cancelText: "暂不升级",
|
||||
cancelColor: "#666",
|
||||
confirmText: "立即升级",
|
||||
confirmColor: "#329EEE",
|
||||
windowHeight: 380,
|
||||
packageUrl: "",
|
||||
browser: false,
|
||||
maskColor: "rgba(0,0,0,0.3)"
|
||||
},
|
||||
_calculatePosition = function() {
|
||||
return {
|
||||
top: (_screenHeight - _config.windowHeight) / 2,
|
||||
left: _screenWidth * .05,
|
||||
width: _screenWidth * .9,
|
||||
right: _screenWidth * .05,
|
||||
height: _config.windowHeight
|
||||
}
|
||||
},
|
||||
_createMask = function() {
|
||||
_maskView = new plus.nativeObj.View("maskView", {
|
||||
top: "0px",
|
||||
left: "0px",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: _config.maskColor
|
||||
})
|
||||
},
|
||||
_createContentView = function() {
|
||||
var calculatePosition = _calculatePosition();
|
||||
_contentView = new plus.nativeObj.View("contentView", {
|
||||
top: calculatePosition.top + "px",
|
||||
left: calculatePosition.left + "px",
|
||||
height: _config.windowHeight + "px",
|
||||
width: calculatePosition.width + "px",
|
||||
overflow: "auto"
|
||||
});
|
||||
_contentView.drawRect({
|
||||
color: "#ffffff",
|
||||
radius: "20px"
|
||||
}, {
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
}, "roundedRect");
|
||||
_contentView.drawText(_config.titleText, {
|
||||
top: "20px",
|
||||
height: "20px",
|
||||
}, {
|
||||
size: "16px",
|
||||
color: "#333",
|
||||
align: "center",
|
||||
}, "titleText");
|
||||
_contentView.drawText(_config.content, {
|
||||
top: "60px",
|
||||
left: "20px",
|
||||
right: "20px",
|
||||
height: _config.windowHeight - 120 + "px",
|
||||
}, {
|
||||
size: "16px",
|
||||
color: "#666",
|
||||
align: _config.contentAlign,
|
||||
verticalAlign: "top",
|
||||
whiteSpace: "normal",
|
||||
overflow: "ellipsis"
|
||||
}, "UpdaterContent");
|
||||
_createLoading(-2);
|
||||
var top = _config.windowHeight - 60 + 15;
|
||||
var fontSize = '16px';
|
||||
if (!_config.forceUpgrade) {
|
||||
_contentView.drawRichText("<font style=\"font-size:" + fontSize + ";\" color=\"" + _config.cancelColor +
|
||||
"\">" + _config
|
||||
.cancelText + "</font>", {
|
||||
width: "50%",
|
||||
top: top + "px",
|
||||
left: "0px"
|
||||
}, {
|
||||
align: "center",
|
||||
onClick: function() {
|
||||
close()
|
||||
}
|
||||
}, "cancel");
|
||||
_contentView.drawRichText("<font color=\"" + _config.confirmColor +
|
||||
"\" style=\"font-size:" + fontSize + ";\">" +
|
||||
_config.confirmText + "</font>", {
|
||||
width: "50%",
|
||||
right: "0px",
|
||||
top: top + "px"
|
||||
}, {
|
||||
align: "center",
|
||||
onClick: function() {
|
||||
_config.packageUrl ? "android" === plus.os.name.toLowerCase() ? _config.browser ? (plus
|
||||
.runtime.openURL(_config.packageUrl)) : _createTask() : plus.runtime.openURL(
|
||||
_config.packageUrl) : uni.showToast({
|
||||
title: "安装包地址为空",
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
}, "submit")
|
||||
} else {
|
||||
_contentView.drawRichText("<font color=\"" + _config.confirmColor + "\" style=\"font-size:" + fontSize +
|
||||
";\">" +
|
||||
_config.confirmText + "</font>", {
|
||||
width: "100%",
|
||||
right: "0px",
|
||||
top: top + "px"
|
||||
}, {
|
||||
align: "center",
|
||||
onClick: function() {
|
||||
_config.packageUrl ? "android" === plus.os.name.toLowerCase() ? _config.browser ? (plus
|
||||
.runtime.openURL(_config.packageUrl)) : _createTask() : plus.runtime.openURL(
|
||||
_config.packageUrl) : uni.showToast({
|
||||
title: "安装包地址为空",
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
}, "submit")
|
||||
}
|
||||
},
|
||||
_createLoading = function(progress) {
|
||||
var calculatePosition = _calculatePosition();
|
||||
var top = _config.windowHeight - 65;
|
||||
var width = 0 <= progress ? (calculatePosition.width - 100) / 100 * progress : 0;
|
||||
width = parseInt(width);
|
||||
var text = 100 <= progress ? "下载完成" : "下载中...";
|
||||
var loadingText = "";
|
||||
loadingText = -1 == progress ? "资源加载中..." : 0 <= progress ? text + "(" + progress + "%)" : "";
|
||||
_contentView.drawRect({
|
||||
color: _config.loadingColor
|
||||
}, {
|
||||
width: width + "px",
|
||||
height: "3px",
|
||||
left: "20px",
|
||||
top: top + "px"
|
||||
}, "loading");
|
||||
_contentView.drawRichText("<font color=\"" + _config.loadingColor + "\">" + loadingText + "</font>", {
|
||||
width: "100px",
|
||||
top: top + "px",
|
||||
left: width + "px"
|
||||
}, {
|
||||
align: "center"
|
||||
}, "loadingText")
|
||||
},
|
||||
_createTask = function() {
|
||||
return _downloadTask ? void console.log("正在下载中") : void(_createLoading(-1),
|
||||
_downloadTask =
|
||||
uni.downloadFile({
|
||||
url: _config.packageUrl,
|
||||
success: function(res) {
|
||||
if (200 === res.statusCode) {
|
||||
var tempFilePath = res.tempFilePath;
|
||||
uni.saveFile({
|
||||
tempFilePath: tempFilePath,
|
||||
success: function(res) {
|
||||
plus.runtime.install(res.savedFilePath, {
|
||||
force: true
|
||||
}, function(res) {
|
||||
console.log('安装包信息' + JSON.stringify(res))
|
||||
}, function(res) {
|
||||
uni.showToast({
|
||||
title: '安装失败,请检查下载链接',
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
});
|
||||
close();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}), _downloadTask.onProgressUpdate(function(res) {
|
||||
_loadingProgress != res.progress && (_loadingProgress = res.progress, _createLoading(res
|
||||
.progress));
|
||||
}))
|
||||
},
|
||||
init = function(option) {
|
||||
_screenHeight = plus.screen.resolutionHeight;
|
||||
_screenWidth = plus.screen.resolutionWidth;
|
||||
_downloadTask = null;
|
||||
option.titleText && (_config.titleText = option.titleText);
|
||||
option.windowHeight && (_config.windowHeight = option.windowHeight);
|
||||
option.forceUpgrade && (_config.forceUpgrade = option.forceUpgrade);
|
||||
option.content && (_config.content = option.content);
|
||||
option.contentAlign && (_config.contentAlign = option.contentAlign);
|
||||
option.loadingColor && (_config.loadingColor = option.loadingColor);
|
||||
option.cancelText && (_config.cancelText = option.cancelText);
|
||||
option.cancelColor && (_config.cancelColor = option.cancelColor);
|
||||
option.confirmText && (_config.confirmText = option.confirmText);
|
||||
option.confirmColor && (_config.confirmColor = option.confirmColor);
|
||||
option.packageUrl && (_config.packageUrl = option.packageUrl);
|
||||
option.browser && (_config.browser = option.browser);
|
||||
option.maskColor && (_config.maskColor = option.maskColor);
|
||||
_createMask();
|
||||
_createContentView();
|
||||
},
|
||||
show = function() {
|
||||
_maskView && _maskView.show();
|
||||
_contentView && _contentView.show();
|
||||
},
|
||||
close = function() {
|
||||
_downloadTask && (_downloadTask.abort(), _downloadTask = null, _createLoading(-2));
|
||||
_maskView && _maskView.hide();
|
||||
_contentView && _contentView.hide();
|
||||
};
|
||||
export default {
|
||||
init: init,
|
||||
show: show,
|
||||
close: close
|
||||
}
|
||||
210
im-uniapp/common/browser.js
Normal file
@@ -0,0 +1,210 @@
|
||||
export default {
|
||||
init: function(options) {
|
||||
this.initWebview(options)
|
||||
this.handleEvent()
|
||||
return this
|
||||
},
|
||||
initWebview: function(options) {
|
||||
var hh=plus.screen.height-44
|
||||
var _self = this
|
||||
_self.webview = plus.webview.create('', 'browser', {
|
||||
scalable:true,
|
||||
height:hh+'px',
|
||||
bottom:'44px',
|
||||
background:'#ff5500',
|
||||
titleNView: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
progress: { //进度条
|
||||
color: '#4678e7',
|
||||
height: '3px'
|
||||
},
|
||||
splitLine: { //底部分割线
|
||||
color: '#cccccc',
|
||||
height: '1px'
|
||||
},
|
||||
buttons: [{ //关闭按钮
|
||||
'float': 'left',
|
||||
fontSrc: '/static/uni.ttf',
|
||||
text: '\ue460',
|
||||
onclick: _self.close.bind(_self)
|
||||
}, { //更多按钮
|
||||
'float': 'right',
|
||||
fontSrc: '/static/uni.ttf',
|
||||
text: '\ue507',
|
||||
onclick: _self.more.bind(_self)
|
||||
}]
|
||||
},
|
||||
additionalHttpHeaders: options.headers || {}
|
||||
})
|
||||
// 配置下拉刷新
|
||||
_self.webview.setPullToRefresh({
|
||||
support: true
|
||||
}, function() {
|
||||
_self.reload()
|
||||
var titleUpdate = function() {
|
||||
setTimeout(function() {
|
||||
_self.webview.endPullToRefresh()
|
||||
_self.webview.removeEventListener('titleUpdate', titleUpdate)
|
||||
}, 300)
|
||||
};
|
||||
_self.webview.addEventListener('titleUpdate', titleUpdate)
|
||||
})
|
||||
|
||||
//绘制返回前进按钮
|
||||
this.navBottom = new plus.nativeObj.View("navBottom", {
|
||||
bottom: '0px',
|
||||
left: '0px',
|
||||
height: '44px',
|
||||
width: '100%',
|
||||
backgroundColor: 'rgb(255,255,255)'
|
||||
})
|
||||
var screenWidth = plus.screen.resolutionWidth
|
||||
var left = screenWidth / 4
|
||||
this.navBottom.draw([{
|
||||
tag: 'font',
|
||||
id: 'back',
|
||||
text: '\ue471',
|
||||
textStyles: {
|
||||
fontSrc: '/static/uni.ttf',
|
||||
size: '24px',
|
||||
color: '#000000'
|
||||
},
|
||||
position: {
|
||||
right: left+48,
|
||||
height: '100%',
|
||||
}
|
||||
},
|
||||
{
|
||||
tag: 'font',
|
||||
id: 'forward',
|
||||
text: '\ue470',
|
||||
textStyles: {
|
||||
fontSrc: '/static/uni.ttf',
|
||||
size: '24px',
|
||||
color: '#000000'
|
||||
},
|
||||
position: {
|
||||
left: left,
|
||||
height: '100%',
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
//点击前进或后退
|
||||
this.navBottom.addEventListener("click", (e) => {
|
||||
if (e.clientX > left && e.clientX < (left + 24)) {
|
||||
_self.back()
|
||||
}
|
||||
if (e.clientX > (screenWidth - left - 12) && e.clientX < (screenWidth - left + 12)) {
|
||||
_self.forward()
|
||||
}
|
||||
})
|
||||
|
||||
//监听页面变化
|
||||
_self.webview.addEventListener('loaded', function() {
|
||||
_self.webview.canBack(function(event) {
|
||||
var canBack = false
|
||||
if (event.canBack) {
|
||||
canBack = true
|
||||
_self.navBottom.show()
|
||||
} else {
|
||||
canBack = false
|
||||
}
|
||||
_self.webview.canForward(function(event) {
|
||||
if (event.canForward) {
|
||||
_self.navBottom.drawText('\ue470', {
|
||||
left: left,
|
||||
height: '100%'
|
||||
}, {
|
||||
color: '#000000',
|
||||
fontSrc: '/static/uni.ttf',
|
||||
size: '24px'
|
||||
}, 'forward')
|
||||
} else {
|
||||
_self.navBottom.drawText('\ue470', {
|
||||
left: left,
|
||||
height: '100%'
|
||||
}, {
|
||||
color: '#EEEEEE',
|
||||
fontSrc: '/static/uni.ttf',
|
||||
size: '24px'
|
||||
}, 'forward')
|
||||
}
|
||||
if (!canBack && !event.canForward) {
|
||||
// _self.navBottom.hide()
|
||||
}
|
||||
})
|
||||
})
|
||||
_self.navBottom.show()
|
||||
}, false)
|
||||
},
|
||||
handleEvent: function(url) {
|
||||
var _self = this
|
||||
plus.key.addEventListener('backbutton', function() {
|
||||
_self.close()
|
||||
return
|
||||
var topWebview = plus.webview.getTopWebview()
|
||||
// 不等于浏览器窗口
|
||||
if (topWebview.id !== 'browser') {
|
||||
// 这里除了浏览器窗口就是首页了,直接退出了;
|
||||
plus.runtime.quit()
|
||||
} else {
|
||||
_self.back()
|
||||
}
|
||||
})
|
||||
},
|
||||
show: function(url) {
|
||||
url = url || 'https://www.baidu.com'
|
||||
this.webview.loadURL(url)
|
||||
this.webview.show('slide-in-right')
|
||||
},
|
||||
more: function() {
|
||||
var _self = this
|
||||
uni.showActionSheet({
|
||||
itemList: ['刷新', '浏览器打开'],
|
||||
success: function(res) {
|
||||
if (res.tapIndex == 0) {
|
||||
_self.reload()
|
||||
} else if (res.tapIndex == 1) {
|
||||
plus.runtime.openURL(_self.webview.getURL())
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
reload: function() {
|
||||
// 刷新
|
||||
this.webview.reload(true)
|
||||
},
|
||||
back: function() {
|
||||
//后退
|
||||
var _self = this
|
||||
_self.webview.canBack(function(event) {
|
||||
if (event.canBack) {
|
||||
_self.webview.back()
|
||||
} else {
|
||||
_self.close()
|
||||
}
|
||||
})
|
||||
},
|
||||
forward: function() {
|
||||
//前进
|
||||
var _self = this
|
||||
_self.webview.canForward(function(event) {
|
||||
if (event.canForward) {
|
||||
_self.webview.forward();
|
||||
} else {
|
||||
plus.nativeUI.toast('没有可前进的地址')
|
||||
}
|
||||
})
|
||||
},
|
||||
close: function() {
|
||||
//关闭
|
||||
// this.navBottom.hide()
|
||||
this.navBottom.close()
|
||||
this.navBottom=null;
|
||||
this.webview.close('browser', 'slide-out-right')
|
||||
this.webview.clear()
|
||||
plus.key.removeEventListener("backbutton", function() {
|
||||
});
|
||||
}
|
||||
}
|
||||
30165
im-uniapp/common/city.js
Normal file
48
im-uniapp/common/config.js
Normal file
@@ -0,0 +1,48 @@
|
||||
export default class config{
|
||||
static prod="online_not"
|
||||
static getZnzqApiUrl(){
|
||||
if(process.env.NODE_ENV === 'development' ){
|
||||
return 'http://work.ii999.live:19002/znzq'
|
||||
}else{
|
||||
if(this.prod=="online"){
|
||||
return 'http://work.ii999.live:19002/znzq'
|
||||
}else{
|
||||
return '/znzq'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static getBaseApiUrl(){
|
||||
//return process.env.NODE_ENV === 'development' ? 'http://119.45.242.222:8989' :'http://172.16.2.3:8989';
|
||||
return process.env.NODE_ENV === 'development' ? 'http://119.45.242.222:8989' :'/base_api';
|
||||
}
|
||||
static getImApiUrl(){
|
||||
//return process.env.NODE_ENV === 'development' ? 'http://119.45.242.222:28000/v1' :'http://172.16.2.3:28000/v1';
|
||||
return process.env.NODE_ENV === 'development' ? 'http://119.45.242.222/im_api/v1' :'/im_api/v1';
|
||||
}
|
||||
static getImAppId(){
|
||||
return 10000;
|
||||
}
|
||||
static getVideoRoomUrl(room,userid,isPublish=0,isPlayer=1,hasVideo=1,uname,tuid){
|
||||
if(process.env.NODE_ENV === 'development' ){
|
||||
return `http://localhost:8080/hd-glasses-app/#/call_room?showInviteConfirmDialog=1&isForce=0&isPublish=${isPublish}&isPlayer=${isPlayer}&uid=${userid}&room=${room}&hasVideo=${hasVideo}&uname=${uname}&tuid=${tuid}`
|
||||
}else{
|
||||
if(this.prod=="online"){
|
||||
return `https://119.45.242.222/hd-glasses-app/#/call_room?showInviteConfirmDialog=1&isForce=0&isPublish=${isPublish}&isPlayer=${isPlayer}&uid=${userid}&room=${room}&hasVideo=${hasVideo}&uname=${uname}&tuid=${tuid}`
|
||||
}else{
|
||||
return `https://172.16.3.18/hd-glasses-app/#/call_room?showInviteConfirmDialog=1&isForce=0&isPublish=${isPublish}&isPlayer=${isPlayer}&uid=${userid}&room=${room}&hasVideo=${hasVideo}&uname=${uname}&tuid=${tuid}`
|
||||
}
|
||||
}
|
||||
}
|
||||
static getSRSUrl(){
|
||||
if(process.env.NODE_ENV === 'development' ){
|
||||
return 'webrtc://119.45.242.222/'
|
||||
}else{
|
||||
if(this.prod=="online"){
|
||||
return 'webrtc://119.45.242.222/'
|
||||
}else{
|
||||
return 'webrtc://172.16.3.18/'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
im-uniapp/common/consoleImgs.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
fz:' ......................阿弥陀佛......................\n' + ' _oo0oo_ \n' + ' o8888888o \n' + ' 88" . "88 \n' + ' (| -_- |) \n' + ' 0\\ = /0 \n' + ' ___/‘---’\\___ \n' + " .' \\| |/ '. \n" + ' / \\\\||| : |||// \\ \n' + ' / _||||| -卍-|||||_ \\ \n' + ' | | \\\\\\ - /// | | \n' + " | \\_| ''\\---/'' |_/ | \n" + " \\ .-\\__ '-' ___/-. / \n" + " ___'. .' /--.--\\ '. .'___ \n" + ' ."" ‘< ‘.___\\_<|>_/___.’>’ "". \n' + ' | | : ‘- \\‘.;‘\\ _ /’;.’/ - ’ : | | \n' + ' \\ \\ ‘_. \\_ __\\ /__ _/ .-’ / / \n' + ' =====‘-.____‘.___ \\_____/___.-’___.-’===== \n' + ' ‘=---=’ \n' + ' \n' + '....................佛祖保佑 ,永无BUG...................'
|
||||
}
|
||||
47
im-uniapp/common/customHttp.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import Request from 'luch-request' // 使用npm
|
||||
import conf from "@/common/config.js"
|
||||
|
||||
const customHttp = new Request({
|
||||
timeout: 300000, //超时时长5分钟,
|
||||
header: {
|
||||
'Content-Type': 'application/json;charset=UTF-8;'
|
||||
}
|
||||
});
|
||||
|
||||
//请求拦截器
|
||||
customHttp.interceptors.request.use((config) => {
|
||||
if (config.custom.target != undefined) {
|
||||
if (config.custom.target == "znzq") {
|
||||
config.baseURL = conf.getZnzqApiUrl()
|
||||
const token = uni.getStorageSync('token');
|
||||
config.header["X-Access-Token"] = token;
|
||||
console.log("==================customHttp.interceptors.request.use")
|
||||
console.log(config)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(config)
|
||||
return config
|
||||
}, error => {
|
||||
return Promise.resolve(error)
|
||||
})
|
||||
|
||||
// 响应拦截器
|
||||
customHttp.interceptors.response.use((response) => {
|
||||
console.log(response)
|
||||
return response
|
||||
}, (error) => {
|
||||
//未登录时清空缓存跳转
|
||||
if (error.statusCode == 401) {
|
||||
uni.clearStorageSync();
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index.vue"
|
||||
})
|
||||
}
|
||||
return Promise.resolve(error)
|
||||
})
|
||||
|
||||
|
||||
export default {
|
||||
customHttp
|
||||
}
|
||||
2
im-uniapp/common/imSdk/lim-sdk.js
Normal file
1
im-uniapp/common/imSdk/lim-sdk.js.map
Normal file
17
im-uniapp/common/imSdk/sdk-bridge.js
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
function getIM(){
|
||||
// UNIAPP 环境
|
||||
if(typeof uni !== 'undefined'){
|
||||
return {im:uni['im'], im_webtoolkit:uni['im_webtoolkit']};
|
||||
}
|
||||
throw Error(" Couldn't not fetch lim.");
|
||||
}
|
||||
|
||||
|
||||
const lim = {
|
||||
im: getIM().im,
|
||||
};
|
||||
|
||||
export default {
|
||||
lim
|
||||
}
|
||||
259
im-uniapp/common/md5.js
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
* Distributed under the BSD License
|
||||
* See http://pajhome.org.uk/crypt/md5 for more info.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configurable variables. You may need to tweak these to be compatible with
|
||||
* the server-side, but the defaults work in most cases.
|
||||
*/
|
||||
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
|
||||
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
|
||||
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
|
||||
|
||||
/*
|
||||
* These are the functions you'll usually want to call
|
||||
* They take string arguments and return either hex or base-64 encoded strings
|
||||
*/
|
||||
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
|
||||
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
|
||||
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
|
||||
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
|
||||
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
|
||||
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
|
||||
|
||||
/*
|
||||
* Perform a simple self-test to see if the VM is working
|
||||
*/
|
||||
function md5_vm_test()
|
||||
{
|
||||
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the MD5 of an array of little-endian words, and a bit length
|
||||
*/
|
||||
function core_md5(x, len)
|
||||
{
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << ((len) % 32);
|
||||
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
||||
|
||||
var a = 1732584193;
|
||||
var b = -271733879;
|
||||
var c = -1732584194;
|
||||
var d = 271733878;
|
||||
|
||||
for(var i = 0; i < x.length; i += 16)
|
||||
{
|
||||
var olda = a;
|
||||
var oldb = b;
|
||||
var oldc = c;
|
||||
var oldd = d;
|
||||
|
||||
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
|
||||
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
|
||||
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
|
||||
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
|
||||
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
|
||||
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
|
||||
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
|
||||
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
|
||||
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
|
||||
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
|
||||
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
|
||||
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
|
||||
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
|
||||
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
|
||||
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
|
||||
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
|
||||
|
||||
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
|
||||
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
|
||||
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
|
||||
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
|
||||
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
|
||||
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
|
||||
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
|
||||
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
|
||||
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
|
||||
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
|
||||
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
|
||||
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
|
||||
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
|
||||
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
|
||||
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
|
||||
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
|
||||
|
||||
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
|
||||
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
|
||||
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
|
||||
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
|
||||
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
|
||||
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
|
||||
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
|
||||
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
|
||||
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
|
||||
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
|
||||
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
|
||||
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
|
||||
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
|
||||
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
|
||||
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
|
||||
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
|
||||
|
||||
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
|
||||
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
|
||||
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
|
||||
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
|
||||
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
|
||||
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
|
||||
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
|
||||
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
|
||||
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
|
||||
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
|
||||
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
|
||||
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
|
||||
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
|
||||
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
|
||||
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
|
||||
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
|
||||
|
||||
a = safe_add(a, olda);
|
||||
b = safe_add(b, oldb);
|
||||
c = safe_add(c, oldc);
|
||||
d = safe_add(d, oldd);
|
||||
}
|
||||
return Array(a, b, c, d);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions implement the four basic operations the algorithm uses.
|
||||
*/
|
||||
function md5_cmn(q, a, b, x, s, t)
|
||||
{
|
||||
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
|
||||
}
|
||||
function md5_ff(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||
}
|
||||
function md5_gg(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||
}
|
||||
function md5_hh(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
function md5_ii(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the HMAC-MD5, of a key and some data
|
||||
*/
|
||||
function core_hmac_md5(key, data)
|
||||
{
|
||||
var bkey = str2binl(key);
|
||||
if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
|
||||
|
||||
var ipad = Array(16), opad = Array(16);
|
||||
for(var i = 0; i < 16; i++)
|
||||
{
|
||||
ipad[i] = bkey[i] ^ 0x36363636;
|
||||
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
|
||||
return core_md5(opad.concat(hash), 512 + 128);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
||||
* to work around bugs in some JS interpreters.
|
||||
*/
|
||||
function safe_add(x, y)
|
||||
{
|
||||
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
||||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return (msw << 16) | (lsw & 0xFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
function bit_rol(num, cnt)
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string to an array of little-endian words
|
||||
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
|
||||
*/
|
||||
function str2binl(str)
|
||||
{
|
||||
var bin = Array();
|
||||
var mask = (1 << chrsz) - 1;
|
||||
for(var i = 0; i < str.length * chrsz; i += chrsz)
|
||||
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
|
||||
return bin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a string
|
||||
*/
|
||||
function binl2str(bin)
|
||||
{
|
||||
var str = "";
|
||||
var mask = (1 << chrsz) - 1;
|
||||
for(var i = 0; i < bin.length * 32; i += chrsz)
|
||||
str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a hex string.
|
||||
*/
|
||||
function binl2hex(binarray)
|
||||
{
|
||||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
var str = "";
|
||||
for(var i = 0; i < binarray.length * 4; i++)
|
||||
{
|
||||
str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
|
||||
hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a base-64 string
|
||||
*/
|
||||
function binl2b64(binarray)
|
||||
{
|
||||
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var str = "";
|
||||
for(var i = 0; i < binarray.length * 4; i += 3)
|
||||
{
|
||||
var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
|
||||
| (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
|
||||
| ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
|
||||
for(var j = 0; j < 4; j++)
|
||||
{
|
||||
if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
|
||||
else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
export default {
|
||||
hex_md5
|
||||
}
|
||||
245
im-uniapp/common/permission.js
Normal file
@@ -0,0 +1,245 @@
|
||||
/// 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 (cnAuthStatus === 0) {
|
||||
result = null;
|
||||
} else if (cnAuthStatus == 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);
|
||||
}
|
||||
}
|
||||
|
||||
const permission = {
|
||||
get isIOS(){
|
||||
return typeof isIOS === 'boolean' ? isIOS : (isIOS = uni.getSystemInfoSync().platform === 'ios')
|
||||
},
|
||||
requestIOS: requestIOS,
|
||||
requestAndroid: requestAndroid,
|
||||
gotoAppSetting: gotoAppPermissionSetting
|
||||
}
|
||||
|
||||
export default permission
|
||||
142
im-uniapp/common/pinyin.js
Normal file
1100
im-uniapp/common/publicFc.js
Normal file
302
im-uniapp/common/request.js
Normal file
@@ -0,0 +1,302 @@
|
||||
// #ifdef APP-PLUS
|
||||
import appUpgrade from '@/common/appUpgrade.js';
|
||||
// #endif
|
||||
import config from "@/common/config.js"
|
||||
let http = {
|
||||
'setBaseUrl': (url) => {
|
||||
if (url.charAt(url.length - 1) === "/") {
|
||||
url = url.substr(0, url.length - 1)
|
||||
}
|
||||
http.baseUrl = url;
|
||||
},
|
||||
'header': {},
|
||||
'beforeRequestFilter': (config) => {
|
||||
return config
|
||||
},
|
||||
'beforeResponseFilter': (res) => {
|
||||
return res
|
||||
},
|
||||
'afterResponseFilter': (successResult) => {},
|
||||
'get': get,
|
||||
'delete': deletE,
|
||||
'post': post,
|
||||
'put': put,
|
||||
'request': request,
|
||||
'uploadFile': uploadFile,
|
||||
'downloadFile': downloadFile
|
||||
}
|
||||
|
||||
|
||||
function init(con) {
|
||||
//url
|
||||
let url = http.baseUrl;
|
||||
if (url && con.url && !con.url.match(/^(http|https):\/\/([\w.]+\/?)\S*$/)) {
|
||||
if (con.url.charAt(0) !== "/") {
|
||||
con.url = "/" + con.url;
|
||||
}
|
||||
con.url = url.concat(con.url);
|
||||
}
|
||||
//header
|
||||
if (http.header != undefined && http.header != null) {
|
||||
if (!con.header) {
|
||||
con.header = http.header;
|
||||
} else {
|
||||
Object.keys(http.header).forEach(function(key) {
|
||||
con.header[key] = http.header[key]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function request(con) {
|
||||
init(con);
|
||||
let config = { //判断是否有以下属性没有就赋予默认值
|
||||
url: con.url ? con.url : http.baseUrl,
|
||||
data: con.data,
|
||||
header: con.header,
|
||||
method: con.method ? con.method : 'GET',
|
||||
dataType: con.dataType ? con.dataType : 'json',
|
||||
responseType: con.responseType ? con.responseType : 'text',
|
||||
success: con.success ? (res) => {
|
||||
http.afterResponseFilter(con.success(http.beforeResponseFilter(res)));
|
||||
} : null,
|
||||
fail: con.fail ? (res) => {
|
||||
con.fail(res);
|
||||
} : () => {
|
||||
uni.showToast({
|
||||
title: '请检查网络',
|
||||
icon: 'none'
|
||||
});
|
||||
uni.hideLoading();
|
||||
},
|
||||
complete: con.complete ? (res) => {
|
||||
con.complete(res);
|
||||
} : (res) => {
|
||||
if (!res.statusCode) {
|
||||
uni.showToast({
|
||||
title: '请求失败',
|
||||
icon: 'none'
|
||||
});
|
||||
uni.hideLoading();
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
uni.showToast({
|
||||
title: '请求失败',
|
||||
icon: 'none'
|
||||
});
|
||||
uni.hideLoading();
|
||||
}
|
||||
if (res.statusCode == 200) {
|
||||
if (res.data.code == 401) { //登录过期
|
||||
// uni.showToast({
|
||||
// title: '登录已过期,请重新登录',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// uni.hideLoading();
|
||||
// uni.reLaunch({
|
||||
// url:'/pages/wxindex/index'
|
||||
// })
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
if (res.data.code == 601) { //强制拉起升级
|
||||
request({
|
||||
url: '/common/getVersion',
|
||||
success: (res) => {
|
||||
appUpgrade.init({
|
||||
titleText: '版本更新'+res.data.data.version,
|
||||
packageUrl:res.data.data.url,
|
||||
content: res.data.data.content,
|
||||
forceUpgrade:true
|
||||
});
|
||||
appUpgrade.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
else if (res.data.code && res.data.code !== 200) { //这里code是自己的服务器正确标识
|
||||
uni.showToast({
|
||||
title: res.data.msg,
|
||||
icon: 'none',
|
||||
position:'top'
|
||||
});
|
||||
}
|
||||
uni.hideLoading();
|
||||
}
|
||||
uni.stopPullDownRefresh();
|
||||
}
|
||||
}
|
||||
const AUTH_TOKEN = ["Authorization","device","version"];
|
||||
for (var i = 0; i < AUTH_TOKEN.length; i++) {
|
||||
if (uni.getStorageSync(AUTH_TOKEN[i])) {
|
||||
http.header[AUTH_TOKEN[i]] = uni.getStorageSync(AUTH_TOKEN[i]);
|
||||
}
|
||||
}
|
||||
return uni.request(http.beforeRequestFilter(config));
|
||||
}
|
||||
|
||||
function get(url, con, success) {
|
||||
let conf = {};
|
||||
if (con && typeof con == 'function') {
|
||||
if (success && typeof success == 'object') {
|
||||
conf = success;
|
||||
}
|
||||
conf.success = con
|
||||
} else {
|
||||
if (con && typeof con == 'object') {
|
||||
conf = con;
|
||||
}
|
||||
conf.success = success;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
conf.url = url
|
||||
}
|
||||
conf.method = "GET";
|
||||
return request(conf);
|
||||
}
|
||||
|
||||
function deletE(url, con, success) {
|
||||
let conf = {};
|
||||
if (con && typeof con == 'function') {
|
||||
if (success && typeof success == 'object') {
|
||||
conf = success;
|
||||
}
|
||||
conf.success = con
|
||||
} else {
|
||||
if (con && typeof con == 'object') {
|
||||
conf = con;
|
||||
}
|
||||
conf.success = success;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
conf.url = url
|
||||
}
|
||||
conf.method = "DELETE";
|
||||
return request(conf);
|
||||
}
|
||||
|
||||
function post(url, data, con, success) {
|
||||
let conf = {};
|
||||
if (con && typeof con == 'function') {
|
||||
if (success && typeof success == 'object') {
|
||||
conf = success
|
||||
}
|
||||
conf.success = con;
|
||||
} else {
|
||||
if (con && typeof con == 'object') {
|
||||
conf = con;
|
||||
}
|
||||
conf.success = success;
|
||||
}
|
||||
if (url) {
|
||||
conf.url = url
|
||||
}
|
||||
if (data) {
|
||||
conf.data = data
|
||||
}
|
||||
conf.method = "POST";
|
||||
return request(conf);
|
||||
}
|
||||
|
||||
function put(url, data, con, success) {
|
||||
let conf = {};
|
||||
if (con && typeof con == 'function') {
|
||||
if (success && typeof success == 'object') {
|
||||
conf = success
|
||||
}
|
||||
conf.success = con;
|
||||
} else {
|
||||
if (con && typeof con == 'object') {
|
||||
conf = con;
|
||||
}
|
||||
conf.success = success;
|
||||
}
|
||||
if (url) {
|
||||
conf.url = url
|
||||
}
|
||||
if (data) {
|
||||
conf.data = data
|
||||
}
|
||||
conf.method = "PUT";
|
||||
return request(conf);
|
||||
}
|
||||
|
||||
function uploadFile(con) {
|
||||
init(con);
|
||||
console.log("========================")
|
||||
console.log("========================")
|
||||
console.log("========================")
|
||||
console.error(con.url)
|
||||
console.error(con.url)
|
||||
console.error(con.url)
|
||||
console.error(con.url)
|
||||
let config = {
|
||||
url: con.url ? con.url : http.baseUrl,
|
||||
files: con.files,
|
||||
filesType: con.filesType,
|
||||
filePath: con.filePath,
|
||||
name: con.name,
|
||||
header: con.header,
|
||||
formData: con.formData,
|
||||
success: con.success ? (res) => {
|
||||
http.afterResponseFilter(con.success(http.beforeResponseFilter(res)));
|
||||
} : null,
|
||||
fail: con.fail ? (res) => {
|
||||
con.fail(res);
|
||||
} : null,
|
||||
complete: con.complete ? (res) => {
|
||||
con.complete(res);
|
||||
} : null
|
||||
}
|
||||
const AUTH_TOKEN = ["Authorization","device","version"];
|
||||
for (var i = 0; i < AUTH_TOKEN.length; i++) {
|
||||
if (uni.getStorageSync(AUTH_TOKEN[i])) {
|
||||
http.header[AUTH_TOKEN[i]] = uni.getStorageSync(AUTH_TOKEN[i]);
|
||||
}
|
||||
}
|
||||
return uni.uploadFile(http.beforeRequestFilter(config));
|
||||
}
|
||||
|
||||
function downloadFile(con) {
|
||||
init(con);
|
||||
let config = {
|
||||
url: con.url ? con.url : http.baseUrl,
|
||||
header: con.header,
|
||||
success: con.success ? (res) => {
|
||||
http.afterResponseFilter(con.success(http.beforeResponseFilter(res)));
|
||||
} : null,
|
||||
fail: con.fail ? (res) => {
|
||||
con.fail(res);
|
||||
} : null,
|
||||
complete: con.complete ? (res) => {
|
||||
con.complete(res);
|
||||
} : null
|
||||
}
|
||||
return uni.downloadFile(http.beforeRequestFilter(config));
|
||||
}
|
||||
// 使用
|
||||
//POST
|
||||
// this.$http.request({
|
||||
// url: '/xxx',
|
||||
// method: 'POST',
|
||||
// data:JSON.stringify({id:111}),
|
||||
// success: (res) => {
|
||||
// if (res.data.code == 200) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//GET
|
||||
// this.$http.request({
|
||||
// url: '/xxx?id=111',
|
||||
// success: (res) => {
|
||||
// if (res.data.code == 200) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// 地址及配置
|
||||
http.setBaseUrl(config.getBaseApiUrl()); //在线服务器
|
||||
// http.setBaseUrl("http://192.168.0.105:8080"); //离线服务器
|
||||
export default http
|
||||
195
im-uniapp/common/socketTask.js
Normal file
@@ -0,0 +1,195 @@
|
||||
import config from "@/common/config.js"
|
||||
let timer = null
|
||||
let retimer = null
|
||||
import store from '../store'
|
||||
import * as sdk from "@/common/imSdk/lim-sdk.js";
|
||||
import lim from "@/common/imSdk/sdk-bridge.js";
|
||||
|
||||
import publicFc from '@/common/publicFc';
|
||||
import localForage from 'localforage';
|
||||
|
||||
|
||||
export default {
|
||||
socketTask: null,
|
||||
// 连接WebSocket
|
||||
connectSocket() {
|
||||
|
||||
|
||||
const ListenerMap = {
|
||||
onSocketConnectEvent: (option, status, data) => {
|
||||
console.log("已建立连接:" + JSON.stringify(status));
|
||||
},
|
||||
onSocketErrorEvent: (error) => {
|
||||
console.log("连接出现错误:" + userId);
|
||||
},
|
||||
onSocketReConnectEvent: () => {
|
||||
console.log("正在重连:");
|
||||
},
|
||||
onSocketCloseEvent: () => {
|
||||
console.log("连接关闭:");
|
||||
},
|
||||
onSocketReConnectSuccessEvent: () => {
|
||||
console.log("重连成功");
|
||||
},
|
||||
onOfflineMessage: (e) => {
|
||||
// console.log("====================拉取到离线消息")
|
||||
// console.log(e)
|
||||
const userId = uni.getStorageSync("userId")
|
||||
setTimeout(function() {
|
||||
if (e.length > 0) {
|
||||
e.map((msg) => {
|
||||
|
||||
setTimeout(() => {
|
||||
const _data = publicFc.formatMessage(msg)
|
||||
|
||||
console.log(_data)
|
||||
if (_data.fromId != userId) {
|
||||
uni.$emit('onP2PMessage', _data);
|
||||
store.dispatch('onP2PMessage', _data)
|
||||
}
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
}, 500);
|
||||
|
||||
},
|
||||
onTestMessage: (e) => {
|
||||
console.log("onTestMessage :");
|
||||
store.dispatch('onP2PMessage', e)
|
||||
},
|
||||
onP2PMessage: (e) => {
|
||||
console.log("onP2PMessag e :::");
|
||||
console.log(JSON.parse(e))
|
||||
console.log("接收到的ws原始数据")
|
||||
e = JSON.parse(e)
|
||||
console.log(e)
|
||||
console.log("接收到的ws格式化之后数据")
|
||||
const _data = publicFc.formatMessage(e.data)
|
||||
console.log(_data)
|
||||
uni.$emit('onP2PMessage', _data);
|
||||
store.dispatch('onP2PMessage', _data)
|
||||
},
|
||||
onLogin: (uid) => {
|
||||
console.log("用户" + uid + "登陆sdk成功");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
const userId = uni.getStorageSync("userId")
|
||||
|
||||
const imUserSign = uni.getStorageSync("imUserSign")
|
||||
|
||||
var listeners = {};
|
||||
for (const v in ListenerMap) {
|
||||
listeners[v] = ListenerMap[v];
|
||||
}
|
||||
|
||||
console.log(lim)
|
||||
|
||||
// 防止多次建立ws链接,貌似还没有生效,需要检查
|
||||
if (this.socketTask != null) {
|
||||
return false
|
||||
}
|
||||
|
||||
lim.lim.im.init(config.getImApiUrl(), config.getImAppId(), userId, imUserSign, listeners, (
|
||||
sdk) => {
|
||||
if (sdk) {
|
||||
console.warn("====================")
|
||||
this.socketTask = sdk;
|
||||
console.log(this.socketTask)
|
||||
|
||||
console.log('sdk 成功连接的回调, 可以使用 sdk 请求数据了.');
|
||||
|
||||
sdk.getSingleUserInfo(userId).then(res => {
|
||||
console.log("获取到自己的用户信息")
|
||||
console.log(res)
|
||||
if (res.code == 200) {
|
||||
uni.setStorageSync('userInfo', res.data);
|
||||
}
|
||||
})
|
||||
|
||||
// sdk.getAllFriend().then(res => {
|
||||
// console.warn(res)
|
||||
// })
|
||||
// sdk.getUserSequence().then(res => {
|
||||
// console.warn(res)
|
||||
// })
|
||||
|
||||
sdk.getUserConversationList(0).then(res => {
|
||||
console.warn(res)
|
||||
})
|
||||
|
||||
|
||||
} else {
|
||||
console.log('sdk 初始化失败.');
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
|
||||
this.socketTask = uni.connectSocket({
|
||||
url: 'wss://im-api.q3z3.com/ws?Authorization=' + uni.getStorageSync('Authorization'),
|
||||
complete: () => {}
|
||||
});
|
||||
this.socketTask.onOpen(res => {
|
||||
console.log('WebSocket连接已打开!');
|
||||
// 设置心跳
|
||||
timer = setInterval(() => {
|
||||
uni.sendSocketMessage({
|
||||
data: 'isConnact',
|
||||
success: res => {
|
||||
if (res.errMsg == 'sendSocketMessage:ok') {
|
||||
console.log('WebSocket已连接')
|
||||
} else {
|
||||
this.connectSocket()
|
||||
}
|
||||
}
|
||||
})
|
||||
}, 5000)
|
||||
})
|
||||
// 监听接收
|
||||
this.socketTask.onMessage(res => {
|
||||
if (res.data == 'ok') {
|
||||
return
|
||||
}
|
||||
var data = JSON.parse(res.data);
|
||||
fc.getPush(data);
|
||||
console.log('WebSocket接收消息!');
|
||||
})
|
||||
// 监听关闭
|
||||
this.socketTask.onClose(res => {
|
||||
console.log('WebSocket连接已关闭!');
|
||||
let token = uni.getStorageSync('Authorization');
|
||||
if (this.socketTask && token) {
|
||||
this.socketTaskClose()
|
||||
retimer = setTimeout(() => {
|
||||
this.connectSocket()
|
||||
}, 5000)
|
||||
}
|
||||
})
|
||||
// 监听异常
|
||||
this.socketTask.onError(res => {
|
||||
console.log('WebSocket连接打开失败,正在尝试重新打开!');
|
||||
if (this.socketTask) {
|
||||
this.socketTaskClose()
|
||||
retimer = setTimeout(() => {
|
||||
this.connectSocket()
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
});
|
||||
*/
|
||||
|
||||
},
|
||||
// 关闭WebSocket
|
||||
socketTaskClose() {
|
||||
if (this.socketTask) {
|
||||
this.socketTask.close()
|
||||
clearInterval(timer)
|
||||
clearTimeout(retimer)
|
||||
console.log('关闭WebSocket!');
|
||||
}
|
||||
},
|
||||
}
|
||||
56
im-uniapp/common/utils.js
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
export function appInit(ms) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var i = 0;
|
||||
let timer = setInterval(() => {
|
||||
var im_imUserSign = uni.getStorageSync("im_imUserSign")
|
||||
var hd_userId = uni.getStorageSync("hd_userid")
|
||||
if(hd_userId){
|
||||
uni.setStorageSync("userId",hd_userId)
|
||||
|
||||
}else{
|
||||
console.log("============未获取到hd_userid")
|
||||
}
|
||||
var hd_token = localStorage.getItem("hd_token")
|
||||
|
||||
i = 100;
|
||||
if (i < 0) {
|
||||
reject("error")
|
||||
}
|
||||
if (im_imUserSign) {
|
||||
|
||||
uni.setStorageSync("imUserSign",im_imUserSign)
|
||||
uni.setStorageSync("token",hd_token)
|
||||
|
||||
if(uni.getStorageSync("userId")!=null&&uni.getStorageSync("imUserSign")!=null&&uni.getStorageSync("token")!=null){
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
resolve("ok")
|
||||
}
|
||||
|
||||
}else{
|
||||
uni.setStorageSync("initReady",null)
|
||||
}
|
||||
}, ms);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getUrlKey 截取地址栏参数
|
||||
* @param value
|
||||
* @returns {String}
|
||||
*/
|
||||
export function getUrlParam(name) {
|
||||
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
|
||||
let url = window.location.href
|
||||
let search = url.split('?')[1];
|
||||
console.log(search);
|
||||
if (search) {
|
||||
var r = search.substr(0).match(reg);
|
||||
if (r !== null) {
|
||||
return unescape(r[2]);
|
||||
}
|
||||
return null;
|
||||
} else return null;
|
||||
}
|
||||
75
im-uniapp/common/zmmFormCheck.js
Normal file
@@ -0,0 +1,75 @@
|
||||
// 表单验证
|
||||
// zmm2113@qq.com
|
||||
/**
|
||||
* @property {Object} formData 表单
|
||||
* @property {Object} rules 验证规则
|
||||
**/
|
||||
export default {
|
||||
error: '',
|
||||
check: function(formData, rules) {
|
||||
var formDataKeys = Object.keys(formData)
|
||||
for (var i = 0; i < formDataKeys.length; i++) {
|
||||
var key = formDataKeys[i]
|
||||
if (rules[key]) {
|
||||
var itemRules = rules[key].rules
|
||||
var itemValue = formData[key]
|
||||
for (var j = 0; j < itemRules.length; j++) {
|
||||
var rule = itemRules[j]
|
||||
switch (rule.checkType){
|
||||
case 'required'://必填项
|
||||
if(!itemValue) {this.error = rule.errorMsg; return false;}
|
||||
break;
|
||||
|
||||
case 'phone'://手机号码验证
|
||||
var reg = /^1[0-9]{10,10}$/;
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'email'://邮箱验证
|
||||
var reg = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'idcard'://15-18位身份证验证
|
||||
var reg = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'url'://网址验证
|
||||
var reg = /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?$/;
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'reg'://正则验证 checkRule必填
|
||||
if(!rule.checkRule){
|
||||
this.error=key+' 校验失败'
|
||||
console.warn(key+' checkRule规则未填写')
|
||||
return false;
|
||||
}
|
||||
var reg = rule.checkRule;
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'number'://数字
|
||||
var reg = /^\d+$/;
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'same'://是否相同 checkRule必填
|
||||
if(!rule.checkRule){
|
||||
this.error=key+' 校验失败'
|
||||
console.warn(key+' checkRule规则未填写')
|
||||
return false;
|
||||
}
|
||||
if (itemValue!==formData[rule.checkRule]) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
case 'string'://字符串 checkRule必填
|
||||
if(!rule.checkRule){
|
||||
this.error=key+' 校验失败'
|
||||
console.warn(key+' checkRule规则未填写')
|
||||
return false;
|
||||
}
|
||||
var reg = new RegExp('^.{' + rule.checkRule + '}$');
|
||||
if (!reg.test(itemValue)) { this.error = rule.errorMsg; return false; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,620 @@
|
||||
<template>
|
||||
<view class="friendsCircle-content-item">
|
||||
<image class="friendsCircle-content-avatar" :src="content.avatar" mode="aspectFill"></image>
|
||||
<view class="friendsCircle-content-right">
|
||||
<view class="friendsCircle-content-nikeName">{{ content.nikeName }}</view>
|
||||
<view class="friendsCircle-content-text">{{ content.text }}</view>
|
||||
<view class="friendsCircle-content-imgs" v-if="content.topicType=='IMAGE'&&content.files.length>0">
|
||||
<image v-for="(item, ii) in content.files" :key="ii" class="friendsCircle-content-img" :class="'fci' + content.files.length" :src="item.url" mode="aspectFill" @click="pimgs(content.files,ii)"></image>
|
||||
</view>
|
||||
<view class="friendsCircle-content-video" @click="openVideo(content.files[0].videoUrl)" v-if="content.topicType=='VIDEO'&&content.files.length>0">
|
||||
<image class="friendsCircle-content-video-icon" src="../../static/img/bf.png" mode="aspectFill"></image>
|
||||
<image class="friendsCircle-content-video-img" :src="content.files[0].url" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view v-if="content.location" class="friendsCircle-content-location" @click="goMap(content.location)">{{ content.location.name }}</view>
|
||||
<view class="friendsCircle-content-tools">
|
||||
<view class="friendsCircle-content-time">{{ content.time }}</view>
|
||||
<view class="friendsCircle-content-tool" :class="{ 'tabon': tabToolIndex }">
|
||||
<view class="wxfont caidan" @click="tabTool(i)"></view>
|
||||
<view class="friendsCircle-content-tool-absolute">
|
||||
<view class="friendsCircle-popup">
|
||||
<view class="friendsCircle-popup-item" @click="zan(content)">
|
||||
<view class="friendsCircle-popup-icon wxfont zan"></view>
|
||||
<view class="friendsCircle-popup-text" v-if="content.like=='Y'">取消</view>
|
||||
<view class="friendsCircle-popup-text" v-else>赞</view>
|
||||
</view>
|
||||
<view class="friendsCircle-popup-item" @click="comment(content)">
|
||||
<view class="friendsCircle-popup-icon wxfont pinglun"></view>
|
||||
<view class="friendsCircle-popup-text">评论</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="friendsCircle-content-item-detail">
|
||||
<view class="friendsCircle-content-item-detail-item" v-if="content.likeList&&content.likeList.length>0">
|
||||
<view class="friendsCircle-like-icon wxfont zan"></view>
|
||||
<view class="friendsCircle-like">
|
||||
<image class="friendsCircle-like-img" mode="aspectFill" v-for="(z,zindex) in content.likeList" :src="z.portrait"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friendsCircle-content-item-detail-item" v-if="content.replyList&&content.replyList.length>0">
|
||||
<view class="friendsCircle-comment-icon wxfont pinglun"></view>
|
||||
<view class="friendsCircle-comment">
|
||||
<view class="friendsCircle-comment-item" v-for="(c,ci) in content.replyList" :key="ci">
|
||||
<image class="friendsCircle-comment-img" :src="c.portrait" mode="aspectFill"></image>
|
||||
<view class="friendsCircle-comment-item-text">
|
||||
<view class="friendsCircle-comment-item-name">
|
||||
<text class="friendsCircle-comment-text">{{c.nickName}}</text>
|
||||
<text class="friendsCircle-comment-item-time">{{c.createTime}}</text>
|
||||
</view>
|
||||
<view style="width: 100%;" @click="replyclick(c,ci)">
|
||||
<view class="friendsCircle-comment-feedback" v-if="c.replyType=='2'">
|
||||
<text>回复</text>
|
||||
<text class="friendsCircle-comment-text">{{c.toNickName}}</text>
|
||||
</view>
|
||||
<text class="friendsCircle-comment-textx">{{c.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="height: 120rpx;"></view>
|
||||
<view class="zfb-tk-send-tool" :style="{bottom:keyboardHeight+'px'}">
|
||||
<form @submit="sendMsg(msg)">
|
||||
<view class="zfb-tk-send-tool-c">
|
||||
<view class="zfb-tk-send-tool-input-box" @click="msgFocus=true">
|
||||
<textarea class="zfb-tk-send-tool-input" :adjust-position="false" :focus="msgFocus" v-model="msg" :placeholder="placeholder" confirm-type="send" @confirm="sendMsg(msg)" hold-keyboard :maxlength="-1" auto-height />
|
||||
</view>
|
||||
<view class="zfb-tk-send-tool-text" @click="sendMsg(msg)" :style="{ background: msg !== '' ? '#1BC418' : '#F7F7F7', color: msg !== '' ? '#fff' : '#ddd', 'border-color': msg !== '' ? '#1BC418' : '#ddd' }">发送</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
// 朋友圈列表内容区
|
||||
data() {
|
||||
return {
|
||||
timer:null,
|
||||
placeholder:'评论',
|
||||
keyboardHeight:0,
|
||||
msg: '',
|
||||
type:'msg',
|
||||
replydata:'',
|
||||
msgFocus:false,
|
||||
tabToolIndex: false,
|
||||
content:this.detail
|
||||
};
|
||||
},
|
||||
props:{
|
||||
detail:{
|
||||
type:Object
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
detail(v){
|
||||
this.content=v
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
userInfo(){
|
||||
return this.$store.state.userInfo
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.onKeyboardHeightChange(res => {
|
||||
this.keyboardHeight=res.height
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
scrolltoBottom() {
|
||||
this.$nextTick(()=>{
|
||||
this.timer = setTimeout(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 9999999,
|
||||
duration: 10
|
||||
});
|
||||
this.$forceUpdate()
|
||||
}, 100);
|
||||
})
|
||||
},
|
||||
replyclick(e,ci){
|
||||
if(e.canDeleted=='Y'){
|
||||
this.hidenTool()
|
||||
uni.showActionSheet({
|
||||
itemList: ['复制','删除'],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex){
|
||||
case 0:
|
||||
uni.setClipboardData({
|
||||
data: e.content,
|
||||
success: function() {
|
||||
uni.showToast({
|
||||
title: '复制成功',
|
||||
icon: 'none',
|
||||
position: 'bottom'
|
||||
})
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
this.$http.request({
|
||||
url: '/topic/removeReply/'+e.replyId,
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({
|
||||
title:'删除成功',
|
||||
icon:'none'
|
||||
})
|
||||
this.content.replyList.splice(ci,1)
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}else{
|
||||
this.replydata=e
|
||||
this.type='reply'
|
||||
this.placeholder='回复'+e.nickName
|
||||
this.$nextTick(()=>{
|
||||
this.msgFocus=true
|
||||
})
|
||||
}
|
||||
},
|
||||
gofriend(e){
|
||||
uni.navigateTo({
|
||||
url:'../../wx/personInfo/detail?param='+e.userId
|
||||
})
|
||||
},
|
||||
pimgs(arr,ii){
|
||||
var imgs=[]
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
imgs.push(arr[i].url)
|
||||
}
|
||||
this.$fc.previewImages(imgs, ii)
|
||||
},
|
||||
goMap(e) {
|
||||
uni.openLocation({
|
||||
latitude: e.latitude,
|
||||
longitude: e.longitude,
|
||||
success: function() {}
|
||||
});
|
||||
},
|
||||
openVideo(e){
|
||||
this.$fc.plusDownload({onlinePath:e}).then(res=>{
|
||||
this.$fc.plusOpenFile({filePath:res})
|
||||
})
|
||||
},
|
||||
tabTool(e) {
|
||||
this.tabToolIndex=!this.tabToolIndex
|
||||
},
|
||||
comment(e) {
|
||||
this.hidenTool()
|
||||
//评论
|
||||
this.type='msg'
|
||||
this.placeholder='评论'
|
||||
this.$nextTick(()=>{
|
||||
this.msgFocus=true
|
||||
})
|
||||
},
|
||||
zan(e,i){//点赞
|
||||
switch (e.like){
|
||||
case 'N':
|
||||
this.$http.request({
|
||||
url: '/topic/like/'+e.topicId,
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
var like=e.like=='N' ? e.like='Y' : e.like='N'
|
||||
this.content.like=like
|
||||
this.content.likeList.push({
|
||||
userId: this.userInfo.userId,
|
||||
nickName: this.userInfo.nickName,
|
||||
portrait: this.userInfo.portrait
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'Y':
|
||||
this.$http.request({
|
||||
url: '/topic/cancelLike/'+e.topicId,
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
var like=e.like=='N' ? e.like='Y' : e.like='N'
|
||||
this.content.like=like
|
||||
var thisObj=this.$fc.arrFindkey({arr:this.content.likeList,key:'userId',val:this.userInfo.userId})
|
||||
this.content.likeList.splice(thisObj.index,1)
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
sendMsg(e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
var replyId=''
|
||||
var replyType=''
|
||||
if(this.type=='msg'){
|
||||
replyId=this.content.topicId
|
||||
replyType='1'
|
||||
}
|
||||
if(this.type=='reply'){
|
||||
replyId=this.replydata.replyId
|
||||
replyType='2'
|
||||
}
|
||||
this.$http.request({
|
||||
url: '/topic/reply',
|
||||
method: 'POST',
|
||||
data:JSON.stringify({
|
||||
replyId: replyId,
|
||||
replyType: replyType,
|
||||
content: e
|
||||
}),
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.content.replyList.push(res.data.data)
|
||||
this.$nextTick(()=>{
|
||||
this.scrolltoBottom()
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
this.msg=''
|
||||
},
|
||||
hidenTool() {//隐藏选项和输入框
|
||||
this.tabToolIndex = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.zfb-tk-send-tool {
|
||||
background: #f7f7f7;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-c {
|
||||
padding: 16rpx 12rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
border: 1px #ddd solid;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-c .zfb-tk-send-tool-btn {
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool .zfb-tk-send-tool-input {
|
||||
padding:0 24rpx;
|
||||
box-sizing: border-box !important;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-text {
|
||||
white-space: nowrap;
|
||||
padding: 10rpx 24rpx;
|
||||
border-radius: 12rpx;
|
||||
border: 1px #ddd solid;
|
||||
background: #f7f7f7;
|
||||
color: #ddd;
|
||||
}
|
||||
.friendsCircle-content-item{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding:24rpx;
|
||||
}
|
||||
.friendsCircle-content-item-detail{
|
||||
margin:0 24rpx;
|
||||
border-radius: 8rpx;
|
||||
margin-top: 24rpx;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.friendsCircle-content-avatar{
|
||||
border-radius: 10rpx;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
min-width: 90rpx;
|
||||
}
|
||||
.friendsCircle-content-right{
|
||||
display: flex;flex-direction: column;
|
||||
padding-left: 18rpx;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.friendsCircle-content-nikeName{
|
||||
font-size: 32rpx;
|
||||
color: #5F698C;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.friendsCircle-content-text{
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
.friendsCircle-content-imgs{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
.friendsCircle-content-img{
|
||||
max-width: 100%;
|
||||
}
|
||||
.friendsCircle-content-img.fci1{
|
||||
height: 550rpx;
|
||||
max-width: 500rpx;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.friendsCircle-content-img.fci2{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci2:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci3{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci3:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci4{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci4:nth-child(2n){
|
||||
margin-right: 185rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci5{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci5:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci6{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci6:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci7{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci7:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci8{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci8:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci9{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci9:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-location{
|
||||
font-size: 24rpx;
|
||||
color: #5F698C;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
.friendsCircle-content-time{
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.friendsCircle-content-tools{
|
||||
margin-top: 24rpx;
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.friendsCircle-content-tool{
|
||||
padding:4rpx 16rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #F8F8FA;
|
||||
color: #63678C;
|
||||
display: flex;flex-direction: row;
|
||||
position: relative;
|
||||
}
|
||||
.tabon .friendsCircle-content-tool-absolute{
|
||||
display: block;
|
||||
}
|
||||
.friendsCircle-content-tool-absolute{
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: none;
|
||||
}
|
||||
.friendsCircle-popup{
|
||||
margin-right: 24rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
height: 75rpx;
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
padding:0 24rpx;
|
||||
}
|
||||
.friendsCircle-popup-item{
|
||||
color: #fff;
|
||||
padding:0 25rpx;
|
||||
height: 100%;
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.friendsCircle-popup-item:nth-child(1):active .friendsCircle-popup-icon{
|
||||
font-size: 56rpx;
|
||||
}
|
||||
.friendsCircle-popup-icon{
|
||||
font-size: 46rpx;
|
||||
}
|
||||
.friendsCircle-popup-text{
|
||||
white-space: nowrap;
|
||||
}
|
||||
.friendsCircle-like{
|
||||
display: flex;flex-direction: row;align-items: center;flex-wrap: wrap;
|
||||
|
||||
}
|
||||
.friendsCircle-like-icon,.friendsCircle-like-text,.friendsCircle-comment-text{
|
||||
color: #5F698C !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.friendsCircle-comment-feedback .friendsCircle-comment-text{
|
||||
margin:0 6rpx;
|
||||
}
|
||||
.friendsCircle-comment-feedback .friendsCircle-comment-text::after{
|
||||
content: ":";
|
||||
color: #333;
|
||||
}
|
||||
.friendsCircle-comment-item-name{
|
||||
display: flex;flex-direction: row;
|
||||
width: 100%;
|
||||
}
|
||||
.friendsCircle-comment-item-time{
|
||||
margin-left: auto;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
.friendsCircle-like-icon,.friendsCircle-comment-icon{
|
||||
width: 40rpx;
|
||||
min-width: 40rpx;
|
||||
height: 60rpx;
|
||||
display: flex;flex-direction: row;align-items: center;justify-content: center;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.friendsCircle-like-text{
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
.friendsCircle-like-text::after{
|
||||
content: ",";
|
||||
}
|
||||
.friendsCircle-like-text:nth-last-child(1)::after{
|
||||
content: "";
|
||||
}
|
||||
.friendsCircle-comment{
|
||||
background-color: #F7F7F7;
|
||||
border-radius: 8rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.friendsCircle-comment-item{
|
||||
font-size: 28rpx;
|
||||
padding: 12rpx;
|
||||
white-space: pre-wrap;
|
||||
display: flex;flex-direction: row;
|
||||
}
|
||||
.friendsCircle-comment-feedback{
|
||||
display: inline-block;
|
||||
}
|
||||
.friendsCircle-comment-feedback text{
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
.friendsCircle-comment-textx{
|
||||
word-break: break-all;
|
||||
}
|
||||
.friendsCircle-like-img,.friendsCircle-comment-img{
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-left: 10rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.friendsCircle-comment-img{
|
||||
margin-right: 12rpx;
|
||||
margin-left: 0px;
|
||||
}
|
||||
.friendsCircle-content-item-detail-item{
|
||||
display: flex;flex-direction: row;
|
||||
padding: 12rpx;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 4rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: #F7F7F7;
|
||||
}
|
||||
.friendsCircle-comment-item-text{
|
||||
flex: 1;
|
||||
display: flex;flex-direction: column;
|
||||
align-items:flex-start;
|
||||
}
|
||||
.friendsCircle-content-video{
|
||||
height: 550rpx;
|
||||
max-width: 400rpx;
|
||||
position: relative;
|
||||
margin-right: 14rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
.friendsCircle-content-video-img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friendsCircle-content-video-icon{
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 60rpx !important;
|
||||
height: 60rpx !important;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
.zfb-tk-send-tool-input-box{
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
margin: 0 12rpx;
|
||||
min-height: 75rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding-top: 18rpx;
|
||||
max-height: 225rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,558 @@
|
||||
<template>
|
||||
<view class="friendsCircle-content-item" v-for="(v, i) in content" :key="i">
|
||||
<image class="friendsCircle-content-avatar" :src="v.avatar" mode="aspectFill" @click="gofriend(v)"></image>
|
||||
<view class="friendsCircle-content-right">
|
||||
<view class="friendsCircle-content-nickName" @click="gofriend(v)">{{ v.nickName }}</view>
|
||||
<view class="friendsCircle-content-text">{{ v.text }}</view>
|
||||
<view class="friendsCircle-content-imgs" v-if="v.topicType=='IMAGE'&&v.files.length>0">
|
||||
<image v-for="(item, ii) in v.files" :key="ii" class="friendsCircle-content-img" :class="'fci' + v.files.length" :src="item.url" mode="aspectFill" @click="pimgs(v.files,ii)"></image>
|
||||
</view>
|
||||
<view class="friendsCircle-content-video" @click="openVideo(v.files[0].videoUrl)" v-if="v.topicType=='VIDEO'&&v.files.length>0">
|
||||
<image class="friendsCircle-content-video-icon" src="../../static/img/bf.png" mode="aspectFill"></image>
|
||||
<image class="friendsCircle-content-video-img" :src="v.files[0].url" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="friendsCircle-content-location" v-if="v.location.name" @click="goMap(v.location)">{{ v.location.name }}</view>
|
||||
<view class="friendsCircle-content-tools">
|
||||
<view class="friendsCircle-content-time">{{ v.time }}</view>
|
||||
<view class="friendsCircle-content-tool" :class="{ tabon: i == showToolIndex }">
|
||||
<view class="wxfont caidan" @click="showTool(i)"></view>
|
||||
<view class="friendsCircle-content-tool-absolute">
|
||||
<view class="friendsCircle-popup">
|
||||
<view class="friendsCircle-popup-item" @click="zan(v,i)">
|
||||
<view class="friendsCircle-popup-icon wxfont zan"></view>
|
||||
<view class="friendsCircle-popup-text" v-if="v.like=='Y'">取消</view>
|
||||
<view class="friendsCircle-popup-text" v-else>赞</view>
|
||||
</view>
|
||||
<view class="friendsCircle-popup-item" @click="comment(v)">
|
||||
<view class="friendsCircle-popup-icon wxfont pinglun"></view>
|
||||
<view class="friendsCircle-popup-text">评论</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friendsCircle-like" v-if="v.likeList&&v.likeList.length>0">
|
||||
<view class="friendsCircle-like-icon wxfont zan"></view>
|
||||
<text class="friendsCircle-like-text" v-for="(z,zindex) in v.likeList">{{z.nickName}}</text>
|
||||
</view>
|
||||
<view class="friendsCircle-comment" v-if="v.replyList&&v.replyList.length>0">
|
||||
<view class="friendsCircle-comment-item" v-for="(c,ci) in v.replyList" :key="ci">
|
||||
<text class="friendsCircle-comment-text" @click="gofriend(c)">{{c.nickName}}</text>
|
||||
<view class="friendsCircle-comment-feedback" v-if="c.replyType=='2'">
|
||||
回复
|
||||
<text class="friendsCircle-comment-text" @click="gofriend(c)">{{c.toNickName}}</text>
|
||||
</view>
|
||||
<view class="friendsCircle-comment-content" v-if="c.content" @click="replyclick(c,ci,i)">
|
||||
<text>{{c.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="zfb-tk-send-tool" v-if="toggleMsgBox" :style="{bottom:keyboardHeight+'px'}">
|
||||
<form @submit="sendMsg(msg)">
|
||||
<view class="zfb-tk-send-tool-c">
|
||||
<view class="zfb-tk-send-tool-input-box" @click="msgFocus=true">
|
||||
<textarea class="zfb-tk-send-tool-input" :adjust-position="false" :focus="msgFocus" v-model="msg" :placeholder="placeholder" confirm-type="send" @confirm="sendMsg(msg)" hold-keyboard :maxlength="-1" auto-height />
|
||||
</view>
|
||||
<view class="zfb-tk-send-tool-text" @click="sendMsg(msg)" :style="{ background: msg !== '' ? '#1BC418' : '#F7F7F7', color: msg !== '' ? '#fff' : '#ddd', 'border-color': msg !== '' ? '#1BC418' : '#ddd' }">发送</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
// 朋友圈列表内容区
|
||||
data() {
|
||||
return {
|
||||
keyboardHeight:0,
|
||||
msg: '',
|
||||
msgFocus:false,
|
||||
toggleMsgBox: false,
|
||||
showToolIndex: null,
|
||||
chooseUserIndex:null,
|
||||
type:'msg',
|
||||
placeholder:'评论',
|
||||
replydata:''
|
||||
};
|
||||
},
|
||||
props:{
|
||||
content:{
|
||||
type:Array,
|
||||
default:[]
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
userInfo(){
|
||||
return this.$store.state.userInfo
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.onKeyboardHeightChange(res => {
|
||||
this.keyboardHeight=res.height
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
replyclick(e,ci,i){
|
||||
this.chooseUserIndex=i
|
||||
if(e.canDeleted=='Y'){
|
||||
this.hidenTool()
|
||||
uni.showActionSheet({
|
||||
itemList: ['复制','删除'],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex){
|
||||
case 0:
|
||||
uni.setClipboardData({
|
||||
data: e.content,
|
||||
success: function() {
|
||||
uni.showToast({
|
||||
title: '复制成功',
|
||||
icon: 'none',
|
||||
position: 'bottom'
|
||||
})
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
this.$http.request({
|
||||
url: '/topic/removeReply/'+e.replyId,
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({
|
||||
title:'删除成功',
|
||||
icon:'none'
|
||||
})
|
||||
this.content[i].replyList.splice(ci,1)
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}else{
|
||||
this.replydata=e
|
||||
this.type='reply'
|
||||
this.placeholder='回复'+e.nickName
|
||||
this.$nextTick(()=>{
|
||||
this.toggleMsgBox = true;
|
||||
this.msgFocus=true
|
||||
})
|
||||
}
|
||||
},
|
||||
gofriend(e){
|
||||
uni.navigateTo({
|
||||
url:'../../wx/personInfo/detail?param='+e.userId
|
||||
})
|
||||
},
|
||||
pimgs(arr,ii){
|
||||
var imgs=[]
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
imgs.push(arr[i].url)
|
||||
}
|
||||
this.$fc.previewImages(imgs, ii)
|
||||
},
|
||||
goMap(e) {
|
||||
uni.openLocation({
|
||||
latitude: e.latitude,
|
||||
longitude: e.longitude,
|
||||
success: function() {}
|
||||
});
|
||||
},
|
||||
openVideo(e){
|
||||
this.$fc.plusDownload({onlinePath:e}).then(res=>{
|
||||
this.$fc.plusOpenFile({filePath:res})
|
||||
})
|
||||
},
|
||||
returnParse(txt) {
|
||||
return JSON.parse(txt);
|
||||
},
|
||||
showTool(e) {
|
||||
this.chooseUserIndex=e
|
||||
if (this.showToolIndex === e) {
|
||||
this.showToolIndex = null;
|
||||
} else {
|
||||
this.showToolIndex = e;
|
||||
}
|
||||
},
|
||||
comment(e) {
|
||||
//评论
|
||||
this.showToolIndex = null;
|
||||
this.type='msg'
|
||||
this.placeholder='评论'
|
||||
this.$nextTick(()=>{
|
||||
this.toggleMsgBox = true;
|
||||
this.msgFocus=true
|
||||
})
|
||||
},
|
||||
zan(e,i){//点赞
|
||||
switch (e.like){
|
||||
case 'N':
|
||||
this.$http.request({
|
||||
url: '/topic/like/'+e.topicId,
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.hidenTool()
|
||||
var like=e.like=='N' ? e.like='Y' : e.like='N'
|
||||
this.content[this.chooseUserIndex].like=like
|
||||
this.content[this.chooseUserIndex].likeList.push({
|
||||
userId: this.userInfo.userId,
|
||||
nickName: this.userInfo.nickName,
|
||||
portrait: this.userInfo.portrait
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'Y':
|
||||
this.$http.request({
|
||||
url: '/topic/cancelLike/'+e.topicId,
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.hidenTool()
|
||||
var like=e.like=='N' ? e.like='Y' : e.like='N'
|
||||
this.content[this.chooseUserIndex].like=like
|
||||
var thisObj=this.$fc.arrFindkey({arr:this.content[this.chooseUserIndex].likeList,key:'userId',val:this.userInfo.userId})
|
||||
this.content[this.chooseUserIndex].likeList.splice(thisObj.index,1)
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
sendMsg(e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
var replyId=''
|
||||
var replyType=''
|
||||
if(this.type=='msg'){
|
||||
replyId=this.content[this.chooseUserIndex].topicId
|
||||
replyType='1'
|
||||
}
|
||||
if(this.type=='reply'){
|
||||
replyId=this.replydata.replyId
|
||||
replyType='2'
|
||||
}
|
||||
this.$http.request({
|
||||
url: '/topic/reply',
|
||||
method: 'POST',
|
||||
data:JSON.stringify({
|
||||
replyId: replyId,
|
||||
replyType: replyType,
|
||||
content: e
|
||||
}),
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.hidenTool()
|
||||
this.content[this.chooseUserIndex].replyList.push(res.data.data)
|
||||
}
|
||||
}
|
||||
});
|
||||
this.msg=''
|
||||
},
|
||||
hidenTool() {//隐藏选项和输入框
|
||||
this.showToolIndex = null;
|
||||
this.toggleMsgBox = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.zfb-tk-send-tool {
|
||||
background: #f7f7f7;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-c {
|
||||
padding: 16rpx 12rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
border: 1px #ddd solid;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-c .zfb-tk-send-tool-btn {
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool .zfb-tk-send-tool-input {
|
||||
padding:0 24rpx;
|
||||
box-sizing: border-box !important;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-text {
|
||||
white-space: nowrap;
|
||||
padding: 10rpx 24rpx;
|
||||
border-radius: 12rpx;
|
||||
border: 1px #ddd solid;
|
||||
background: #f7f7f7;
|
||||
color: #ddd;
|
||||
}
|
||||
.friendsCircle-content-item{
|
||||
display: flex;flex-direction: row;
|
||||
padding:24rpx 34rpx;
|
||||
border-bottom: 1px #F2F2F2 solid;
|
||||
}
|
||||
.friendsCircle-content-avatar{
|
||||
border-radius: 10rpx;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
min-width: 90rpx;
|
||||
}
|
||||
.friendsCircle-content-right{
|
||||
display: flex;flex-direction: column;
|
||||
padding-left: 18rpx;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.friendsCircle-content-nickName{
|
||||
font-size: 32rpx;
|
||||
color: #5F698C;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.friendsCircle-content-text{
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
.friendsCircle-content-imgs{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
.friendsCircle-content-img{
|
||||
max-width: 100%;
|
||||
}
|
||||
.friendsCircle-content-img.fci1{
|
||||
height: 550rpx;
|
||||
max-width: 500rpx;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.friendsCircle-content-img.fci2{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci2:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci3{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci3:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci4{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci4:nth-child(2n){
|
||||
margin-right: 185rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci5{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci5:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci6{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci6:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci7{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci7:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci8{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci8:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-img.fci9{
|
||||
width: 185rpx;
|
||||
height: 185rpx;
|
||||
margin-right: 5rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.friendsCircle-content-img.fci9:nth-child(3n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friendsCircle-content-location{
|
||||
font-size: 24rpx;
|
||||
color: #5F698C;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
.friendsCircle-content-time{
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.friendsCircle-content-tools{
|
||||
margin-top: 24rpx;
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
margin-bottom: 14rpx;
|
||||
}
|
||||
.friendsCircle-content-tool{
|
||||
padding:4rpx 16rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #F8F8FA;
|
||||
color: #63678C;
|
||||
display: flex;flex-direction: row;
|
||||
position: relative;
|
||||
}
|
||||
.tabon .friendsCircle-content-tool-absolute{
|
||||
display: block;
|
||||
}
|
||||
.friendsCircle-content-tool-absolute{
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: none;
|
||||
}
|
||||
.friendsCircle-popup{
|
||||
margin-right: 24rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
height: 75rpx;
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
padding:0 24rpx;
|
||||
}
|
||||
.friendsCircle-popup-item{
|
||||
color: #fff;
|
||||
padding:0 25rpx;
|
||||
height: 100%;
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.friendsCircle-popup-item:nth-child(1):active .friendsCircle-popup-icon{
|
||||
font-size: 56rpx;
|
||||
}
|
||||
.friendsCircle-popup-icon{
|
||||
font-size: 46rpx;
|
||||
}
|
||||
.friendsCircle-popup-text{
|
||||
white-space: nowrap;
|
||||
}
|
||||
.friendsCircle-like{
|
||||
border-radius: 8rpx;
|
||||
padding: 12rpx;
|
||||
background-color: #F7F7F7;
|
||||
display: flex;flex-direction: row;align-items: center;flex-wrap: wrap;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.friendsCircle-like-icon,.friendsCircle-like-text,.friendsCircle-comment-text{
|
||||
color: #5F698C !important;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.friendsCircle-comment-feedback .friendsCircle-comment-text{
|
||||
margin:0 6rpx;
|
||||
}
|
||||
.friendsCircle-comment-text::after{
|
||||
content: ":";
|
||||
color: #333;
|
||||
}
|
||||
.friendsCircle-like-text{
|
||||
margin-left: 4rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.friendsCircle-like-text::after{
|
||||
content: ",";
|
||||
}
|
||||
.friendsCircle-like-text:nth-last-child(1)::after{
|
||||
content: "";
|
||||
}
|
||||
.friendsCircle-comment{
|
||||
background-color: #F7F7F7;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
.friendsCircle-comment-item{
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
padding: 12rpx;
|
||||
white-space: pre-wrap;
|
||||
display: flex;flex-direction: row;flex-wrap: wrap;
|
||||
}
|
||||
.friendsCircle-comment-feedback{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.friendsCircle-content-video{
|
||||
width: auto;
|
||||
height: 550rpx;
|
||||
max-width: 400rpx;
|
||||
position: relative;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
.friendsCircle-content-video-img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friendsCircle-content-video-icon{
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 80rpx !important;
|
||||
height: 80rpx !important;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
.friendsCircle-comment-content{
|
||||
}
|
||||
.friendsCircle-comment-content text{
|
||||
word-break: break-all;
|
||||
}
|
||||
.zfb-tk-send-tool-input-box{
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
margin: 0 12rpx;
|
||||
min-height: 75rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding-top: 18rpx;
|
||||
max-height: 225rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<view class="friends-circle-person-item" v-for="(v, i) in content" :key="i">
|
||||
<view class="friends-circle-person-item-date"><!-- -->
|
||||
<text class="day">{{returnDate(v.createTime,'d')}}</text>
|
||||
<text class="month">{{returnDate(v.createTime,'m')}}月</text>
|
||||
<view class="year">{{returnDate(v.createTime,'y')}}</view>
|
||||
<view class="year" v-if="v.location.name">{{v.location.name}}</view>
|
||||
</view>
|
||||
<view class="friends-circle-person-view" @click="clickItem(v)">
|
||||
<view class="friends-circle-person-content" v-if="v.topicType=='IMAGE'&&v.files.length>0">
|
||||
<view class="friends-circle-person-imgs">
|
||||
<image v-for="(item, ii) in v.files.slice(0,4)" :key="ii" :class="'fci' + v.files.slice(0,4).length" :src="item.url" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="friends-circle-person-imgs-text">
|
||||
<text>{{v.text}}</text>
|
||||
<view class="friends-circle-person-imgs-total">共{{v.files.length}}张</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friends-circle-person-content" v-if="v.topicType=='VIDEO'&&v.files.length>0">
|
||||
<view class="friendsCircle-content-video">
|
||||
<image class="friendsCircle-content-video-icon" src="../../static/img/bf.png" mode="aspectFill"></image>
|
||||
<image class="friendsCircle-content-video-img" :src="v.files[0].url" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="friends-circle-person-imgs-text">
|
||||
<text>{{v.text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="v.topicType=='TEXT'" class="friends-circle-person-content">
|
||||
<view class="friends-circle-person-text">
|
||||
<text>{{v.text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friends-circle-nodata" v-if="content.length<=0">
|
||||
<view class="friends-circle-nodata-line"></view>
|
||||
<view class="friends-circle-nodata-text">未发布朋友圈</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
// 朋友圈单人列表
|
||||
emits:['clickItem'],
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
props:{
|
||||
content:{
|
||||
type:Array,
|
||||
default:[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
returnDate(e,format){
|
||||
return this.$fc.getNewDate(format,true,e)
|
||||
},
|
||||
clickItem(e){
|
||||
this.$emit('clickItem',e)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.friends-circle-person-item{
|
||||
display: flex;flex-direction: row;
|
||||
margin-bottom: 60rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.friends-circle-person-view{
|
||||
flex: 1;
|
||||
}
|
||||
.friends-circle-person-item-date{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-right: 40rpx;
|
||||
width: 115rpx;
|
||||
min-width: 115rpx;
|
||||
line-height: 60rpx;
|
||||
text-align: right;
|
||||
}
|
||||
.friends-circle-person-item-date .day{
|
||||
flex: 1;
|
||||
font-size: 43rpx;
|
||||
}
|
||||
.friends-circle-person-item-date .month{
|
||||
font-size: 26rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.friends-circle-person-item-date .year{
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
line-height: initial;
|
||||
}
|
||||
.friends-circle-person-content{
|
||||
flex: 1;
|
||||
display: flex;flex-direction: row;
|
||||
}
|
||||
.friends-circle-person-text{
|
||||
padding: 12rpx;
|
||||
background-color: #eee;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
.friends-circle-person-text text{
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.friends-circle-person-imgs{
|
||||
width: 140rpx;
|
||||
min-width: 140rpx;
|
||||
height: 140rpx;
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
.friends-circle-person-imgs image{float: left;}
|
||||
.friends-circle-person-imgs .fci1{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friends-circle-person-imgs .fci2{
|
||||
margin-right: 2%;
|
||||
width: 49%;
|
||||
height: 100%;
|
||||
}
|
||||
.friends-circle-person-imgs .fci2:nth-child(2n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friends-circle-person-imgs .fci3{
|
||||
margin-right: 2%;
|
||||
width: 49%;
|
||||
height: 48%;
|
||||
}
|
||||
.friends-circle-person-imgs .fci3:nth-child(1){
|
||||
height: 98%;
|
||||
}
|
||||
.friends-circle-person-imgs .fci3:nth-child(2){
|
||||
margin-bottom: 2%;
|
||||
}
|
||||
.friends-circle-person-imgs .fci3:nth-child(2),.friends-circle-person-imgs .fci3:nth-child(3){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friends-circle-person-imgs .fci4{
|
||||
margin-right: 2%;
|
||||
width: 49%;
|
||||
height: 49%;
|
||||
margin-bottom: 2%;
|
||||
}
|
||||
.friends-circle-person-imgs .fci4:nth-child(2n){
|
||||
margin-right: 0;
|
||||
}
|
||||
.friends-circle-person-imgs-text{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.friends-circle-person-imgs-text text{
|
||||
line-height: 1.2;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.friends-circle-person-imgs-total{
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.friends-circle-nodata{
|
||||
display: flex;flex-direction: column;
|
||||
}
|
||||
.friends-circle-nodata-line{
|
||||
margin: 50rpx;
|
||||
margin-bottom: 30rpx;
|
||||
height: 1px;
|
||||
position: relative;
|
||||
background-color: #eee;
|
||||
}
|
||||
.friends-circle-nodata-line::after{
|
||||
content: " ";
|
||||
width: 13rpx;
|
||||
height: 13rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #eee;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
.friends-circle-nodata-text{
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
.friendsCircle-content-video{
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
position: relative;
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
.friendsCircle-content-video-img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friendsCircle-content-video-icon{
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 60rpx !important;
|
||||
height: 60rpx !important;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
</style>
|
||||
327
im-uniapp/components/friends-circle-top/friends-circle-top.vue
Normal file
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<view class="friendsCircle-top" :class="{ 'friendsCircle-top-opend': CircleTop, 'friendsCircle-top-type-img': cover.type == 'img' }" :key="ikey">
|
||||
<view style="width: 100%;height: 100%;" v-if="cover.type == 'img'">
|
||||
<image class="friendsCircle-top-img" @click="changeCircleTop" :src="cover.url" mode="aspectFill"></image>
|
||||
<view class="friendsCircle-top-post" @click="changePoster" v-if="showChangePoster">
|
||||
<view class="wxfont tupian"></view>
|
||||
<text class="text">换封面</text>
|
||||
</view>
|
||||
<view class="friendsCircle-top-information" @click="userClick" v-if="userInfo">
|
||||
<view class="friendsCircle-top-information-user">
|
||||
<view class="friendsCircle-top-information-nikeName">{{userInfo.nickName}}</view>
|
||||
<image class="friendsCircle-top-information-avatar" :src="userInfo.portrait" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="friendsCircle-top-information-signature">{{userInfo.intro}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<video v-else class="friendsCircle-top-video" id="videodemo" ref="videodemo" :key="vkey" :autoplay="false" :src="cover.url" :controls="false" :loop="true" :show-center-play-btn="false" object-fit="cover" muted>
|
||||
<cover-view class="friendsCircle-top-video-model-img-box"><cover-image class="friendsCircle-top-video-model-img" :src="cover.screenShot"></cover-image></cover-view>
|
||||
<cover-view class="friendsCircle-top-video-model" @click="changeCircleTop"></cover-view>
|
||||
<cover-view class="friendsCircle-top-post" @click="changePoster" v-if="showChangePoster">
|
||||
<cover-image @click="changePoster" class="friendsCircle-top-post-img" src="../../static/img/f01.png"></cover-image>
|
||||
<cover-view @click="changePoster" class="text">换封面</cover-view>
|
||||
</cover-view>
|
||||
<cover-view class="friendsCircle-top-information" @click="userClick" v-if="userInfo">
|
||||
<cover-view class="friendsCircle-top-information-user">
|
||||
<cover-view class="friendsCircle-top-information-nikeName">{{userInfo.nickName}}</cover-view>
|
||||
<cover-image class="friendsCircle-top-information-avatar" :src="userInfo.portrait" mode="aspectFill"></cover-image>
|
||||
</cover-view>
|
||||
<cover-view class="friendsCircle-top-information-signature">{{userInfo.intro}}</cover-view>
|
||||
</cover-view>
|
||||
</video>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits:['userClick'],
|
||||
data() {
|
||||
return {
|
||||
CircleTop: false,
|
||||
vkey: 0,
|
||||
ikey:0,
|
||||
videodemo: null
|
||||
};
|
||||
},
|
||||
props:{
|
||||
cover:{
|
||||
type:Object,
|
||||
default(){
|
||||
return{
|
||||
type:'img',
|
||||
name:'',
|
||||
url:''
|
||||
}
|
||||
}
|
||||
},
|
||||
userInfo:{
|
||||
type:[Object,String]
|
||||
},
|
||||
showChangePoster:{
|
||||
type:[Boolean],
|
||||
default:true
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
cover(v){
|
||||
this.ikey++
|
||||
this.vkey++;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
userClick(){//前往个人朋友圈
|
||||
this.$emit('userClick',this.cover,this.userInfo)
|
||||
},
|
||||
changeCircleTop() {//顶部预览
|
||||
this.CircleTop = !this.CircleTop;
|
||||
if(this.type=='img'){
|
||||
return
|
||||
}
|
||||
this.videodemo = uni.createVideoContext('videodemo', this);
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.vkey++;
|
||||
this.$nextTick(() => {
|
||||
if (this.CircleTop) {
|
||||
this.videodemo.seek(0);
|
||||
this.videodemo.play();
|
||||
} else {
|
||||
this.videodemo.pause();
|
||||
this.videodemo.seek(0);
|
||||
}
|
||||
});
|
||||
}, 105);
|
||||
});
|
||||
},
|
||||
updateCover(formdata){
|
||||
this.$http.request({
|
||||
url: '/topic/editCover',
|
||||
method: 'POST',
|
||||
data:JSON.stringify({
|
||||
cover:JSON.stringify(formdata)
|
||||
}),
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.$store.dispatch('get_UserInfo')
|
||||
this.changeCircleTop()
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
changePoster() {//修改封面
|
||||
uni.showActionSheet({
|
||||
// itemList: ['图片封面', '视频封面'],
|
||||
itemList: ['图片封面'],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex){
|
||||
case 0:
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album','camera'], //从相册选择
|
||||
success: (res) => {
|
||||
uni.showLoading({
|
||||
title:'上传中'
|
||||
})
|
||||
this.$http.uploadFile({
|
||||
url: '/file/upload',
|
||||
filePath: res.tempFilePaths[0],
|
||||
name: 'file',
|
||||
fileType: 'image',
|
||||
success: (res) => {
|
||||
var data=JSON.parse(res.data)
|
||||
if (data.code == 200) {
|
||||
var formdata={
|
||||
type:'img',
|
||||
name:data.data.fileName,
|
||||
url:data.data.fullPath
|
||||
}
|
||||
this.updateCover(formdata)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
uni.chooseVideo({
|
||||
sourceType: ['camera', 'album'],
|
||||
success: (res) => {
|
||||
uni.showLoading({
|
||||
title:'上传中'
|
||||
})
|
||||
this.$http.uploadFile({
|
||||
url: '/file/uploadVideo',
|
||||
filePath: res.tempFilePath,
|
||||
name: 'file',
|
||||
fileType: 'video',
|
||||
success: (res) => {
|
||||
var data=JSON.parse(res.data)
|
||||
if (data.code == 200) {
|
||||
var formdata={
|
||||
type:'video',
|
||||
name:data.data.fileName,
|
||||
url:data.data.fullPath,
|
||||
screenShot:data.data.screenShot
|
||||
}
|
||||
this.updateCover(formdata)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log(res.errMsg);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.friendsCircle-top{
|
||||
transition: all 0.1s;
|
||||
width: 750rpx;
|
||||
height: 590rpx;
|
||||
position: relative;
|
||||
background-image: linear-gradient( 135deg, #9708CC 10%, #43CBFF 100%);
|
||||
}
|
||||
.friendsCircle-top-type-img{
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.friendsCircle-top-img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friendsCircle-top-opend{
|
||||
height: 80vh;
|
||||
}
|
||||
.friendsCircle-top-post-img{
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.friendsCircle-top-post{
|
||||
text-align: center;
|
||||
z-index:99;
|
||||
position: absolute;
|
||||
bottom: 24rpx;
|
||||
right: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: none;
|
||||
}
|
||||
.friendsCircle-top-post .tupian{
|
||||
color: #f5f5f5;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
.friendsCircle-top-post .text{
|
||||
font-size: 18rpx;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
.friendsCircle-top-video-model-img-box{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 80vh;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.friendsCircle-top-video-model-img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friendsCircle-top-video-model{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
// background-color: rgba(255,0,0,0.3);
|
||||
}
|
||||
.friendsCircle-top-opend .friendsCircle-top-post{
|
||||
display: block;
|
||||
}
|
||||
.friendsCircle-top-video{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.friendsCircle-top-opend .friendsCircle-top-video-model-img-box{
|
||||
display: none;
|
||||
}
|
||||
.friendsCircle-top-opend .friendsCircle-top-video{
|
||||
height: 80vh;
|
||||
}
|
||||
.friendsCircle-top-information{
|
||||
|
||||
}
|
||||
.friendsCircle-top-information-nikeName{
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
margin-top: 20rpx;
|
||||
margin-right: 14rpx;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px 0px 5px rgba(0,0,0,0.9);
|
||||
}
|
||||
.friendsCircle-top-information-avatar{
|
||||
width: 120rpx;
|
||||
min-width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.friendsCircle-top-information{
|
||||
z-index: 99;
|
||||
display: flex;flex-direction: row;flex-wrap: wrap;
|
||||
position: absolute;
|
||||
bottom: -45rpx;
|
||||
right: 24rpx;
|
||||
display: flex;flex-direction: column;
|
||||
}
|
||||
.friendsCircle-top-information-signature{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -45rpx;
|
||||
width: 100%;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
text-align: right;
|
||||
}
|
||||
.friendsCircle-top-information-user{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
// border-radius: 12rpx;
|
||||
// background-color: #f00;
|
||||
}
|
||||
.friendsCircle-top-opend .friendsCircle-top-information{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.friendsCircle-top-video .friendsCircle-top-information{
|
||||
bottom: -65rpx;
|
||||
}
|
||||
.friendsCircle-top-video .friendsCircle-top-information-user{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.friendsCircle-top-video .friendsCircle-top-information-avatar{
|
||||
float: left;
|
||||
}
|
||||
|
||||
.friendsCircle-top-video .friendsCircle-top-information-nikeName{
|
||||
float: left;
|
||||
}
|
||||
.friendsCircle-top-video .friendsCircle-top-information-signature{
|
||||
position: inherit;
|
||||
float: left;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
145
im-uniapp/components/tool-list-wx/tool-list-wx.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<view class="xw-tool-list">
|
||||
<view class="xw-tool-list-content" v-if="type=='list'">
|
||||
<template v-for="(item, i) in list" :key="i">
|
||||
<view class="xw-tool-item" @click="onClick(item,i)" @longpress="onlongpress(item,i)" v-if="item.title">
|
||||
<image v-if="item.icon" class="xw-tool-img" :src="item.icon" mode="aspectFill"></image>
|
||||
<view class="xw-tool-text">
|
||||
<uni-badge v-if="item.type == 'dottext'" text="1" is-dot absolute="rightTop" size="normal">
|
||||
<text>{{ item.title }}</text>
|
||||
</uni-badge>
|
||||
<text v-else>{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="xw-tool-else">
|
||||
<view v-for="(v, index) in item.else" :key="index">
|
||||
<uni-badge v-if="v.type == 'dotimg'" class="xw-tool-badge" text="1" is-dot absolute="rightTop" size="normal"><image :src="v.content" mode="aspectFill"></image></uni-badge>
|
||||
<image v-if="v.type == 'img'" :src="v.content" mode="aspectFill"></image>
|
||||
<uni-badge v-if="v.type == 'dottext'" class="xw-tool-badge" text="1" is-dot absolute="rightTop" size="normal"><view class="text">{{ v.content }}</view></uni-badge>
|
||||
<view class="text" v-if="v.type == 'text'">{{ v.content }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-icons v-if="!item.hideRight" class="xw-tool-right" type="right" size="16" color="#b5b5b5"></uni-icons>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view class="xw-tool-list-content" v-if="type=='btns'">
|
||||
<view class="xw-tool-btn-item" v-for="(item, i) in list" :key="i" @click="onClick(item,i)" @longpress="onlongpress(item,i)">
|
||||
<view class="xw-tool-btn-icon wxfont " :class="item.icon"></view>
|
||||
<view class="xw-tool-btn-text">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'toolListWx', //微信功能列表
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
emits: ['itemClick','onlongpress'],
|
||||
props: {
|
||||
list: {
|
||||
type: Array
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'list' //list列表icon为图片,btns按钮组icon为字体
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onlongpress(e,i){
|
||||
this.$emit('onlongpress', e,i);
|
||||
},
|
||||
onClick(e,i) {
|
||||
this.$emit('itemClick', e,i);
|
||||
if (e.path=='#') {
|
||||
return;
|
||||
}
|
||||
if (!e.path&&!e.hideRight) {
|
||||
uni.showToast({
|
||||
title: '未开通',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: e.path
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.xw-tool-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #ffffff;
|
||||
margin-bottom: 18rpx;
|
||||
}
|
||||
|
||||
.xw-tool-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 26rpx 24rpx;
|
||||
border-bottom: 1px #eee solid;
|
||||
}
|
||||
.xw-tool-item:nth-last-child(1) {
|
||||
border: none;
|
||||
}
|
||||
.xw-tool-img {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.xw-tool-text {
|
||||
white-space: nowrap;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.xw-tool-badge {
|
||||
}
|
||||
|
||||
.xw-tool-else {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.xw-tool-else image {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
.xw-tool-else .text {
|
||||
color: #666;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 520rpx;
|
||||
}
|
||||
.xw-tool-else image,
|
||||
.xw-tool-else .text {
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
.xw-tool-right {
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
.xw-tool-btn-item{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 34rpx 44rpx;
|
||||
border-bottom: 1px #eee solid;
|
||||
font-weight: bold;
|
||||
color: #5F698C;
|
||||
}
|
||||
.xw-tool-btn-icon{
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
</style>
|
||||
156
im-uniapp/components/top-right-tool-wx/top-right-tool-wx.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<view @touchmove.stop.prevent="moveHandle('touchmove')" @click="moveHandle('click')" v-if="show">
|
||||
<view class="top-right-tool-wx" :animation="animationData" :style="{ top: height + 'px' }">
|
||||
<view class="top-right-tool-wx-icon"></view>
|
||||
<view class="top-right-tool-wx-list">
|
||||
<view class="top-right-tool-wx-list-item" @click="groupChat">
|
||||
<view class="top-right-tool-wx-list-item-icon"><view class="wxfont xiaoxi"></view></view>
|
||||
<view class="text">发起群聊</view>
|
||||
</view>
|
||||
<view class="top-right-tool-wx-list-item" @click="goSearchFriends">
|
||||
<view class="top-right-tool-wx-list-item-icon"><view class="wxfont jiahaoyou"></view></view>
|
||||
<view class="text">添加朋友</view>
|
||||
</view>
|
||||
<view class="top-right-tool-wx-list-item" @click="saoyisao">
|
||||
<view class="top-right-tool-wx-list-item-icon"><view class="wxfont saoyisao"></view></view>
|
||||
<view class="text">扫一扫</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="top-right-tool-wx-model"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
height: 0 ,//距离顶部高度
|
||||
show:false,
|
||||
animationData: {}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [{}];
|
||||
}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getstatusBarHeight();
|
||||
var animation = uni.createAnimation({
|
||||
duration: 300,
|
||||
timingFunction: 'linear'
|
||||
});
|
||||
this.animation = animation;
|
||||
},
|
||||
methods: {
|
||||
groupChat(){
|
||||
uni.navigateTo({
|
||||
url:'../../wx/group/createGroup'
|
||||
})
|
||||
},
|
||||
goSearchFriends(){
|
||||
uni.navigateTo({
|
||||
url:'../../wx/search-friends/index'
|
||||
})
|
||||
},
|
||||
saoyisao(){
|
||||
this.$fc.saoyisao()
|
||||
},
|
||||
showAnimation() {
|
||||
this.animation.opacity(1).step();
|
||||
this.animationData = this.animation.export();
|
||||
},
|
||||
hideAnimation() {
|
||||
this.animation.opacity(0).step();
|
||||
this.animationData = this.animation.export();
|
||||
},
|
||||
moveHandle(e) {
|
||||
this.hiddenTab()
|
||||
},
|
||||
showTab(){
|
||||
this.show=true
|
||||
setTimeout(()=>{
|
||||
this.showAnimation()
|
||||
},30)
|
||||
},
|
||||
hiddenTab(){
|
||||
this.show=false
|
||||
this.hideAnimation()
|
||||
},
|
||||
getstatusBarHeight() {
|
||||
var SystemInfo = uni.getSystemInfoSync();
|
||||
// #ifdef H5
|
||||
this.height = SystemInfo.safeArea.top + SystemInfo.windowTop;
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.top-right-tool-wx {
|
||||
width: 300rpx;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
top: -10px;
|
||||
right: 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
opacity: 0;
|
||||
}
|
||||
.top-right-tool-wx-model{
|
||||
background-color: rgba(0,0,0,0);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 9998;
|
||||
}
|
||||
.top-right-tool-wx-icon {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border: 10px solid transparent;
|
||||
border-bottom-color: #4C4C4C;
|
||||
margin-left: auto;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.top-right-tool-wx-list {
|
||||
width: 100%;
|
||||
background-color: #4C4C4C;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.top-right-tool-wx-list-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 0rpx 36rpx;
|
||||
padding-right: 0;
|
||||
}
|
||||
.top-right-tool-wx-list-item-icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
margin-right: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.top-right-tool-wx-list-item-icon .wxfont {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
.top-right-tool-wx-list-item .text {
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border-bottom: 1px #535353 solid;
|
||||
padding: 30rpx 0rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.top-right-tool-wx-list-item:nth-last-child(1) .text{
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="loaded || list.itemIndex < 15" class="xw-book-wrapper">
|
||||
<view v-if="list.items && list.items.length > 0" class="xw-book-sort">{{ list.key }}</view>
|
||||
</view>
|
||||
<view v-if="(loaded || list.itemIndex < 15) && list.items && list.items.length > 0" class="xw-book-userlist">
|
||||
<view v-for="(item, index) in list.items" :key="index">
|
||||
<view class="xw-book-user" @click="onClick(idx, index)">
|
||||
<view v-if="showSelect" class="xw-book-user-checked">
|
||||
<uni-icons :type="item.checked ? 'checkbox-filled' : 'circle'" :color="item.checked ? '#09C160' : '#C0C0C0'" size="28" />
|
||||
</view>
|
||||
<image class="xw-book-user-avatar" :src="item.data.avatar" mode="aspectFill"></image>
|
||||
<view class="xw-book-user-name">{{item.data.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UniIndexedListWX',
|
||||
emits: ['itemClick'],
|
||||
props: {
|
||||
loaded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
idx: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
list: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
showSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick(idx, index) {
|
||||
this.$emit("itemClick", {
|
||||
idx,
|
||||
index
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.xw-book-wrapper {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
width: 100%;
|
||||
/* #endif */
|
||||
}
|
||||
.xw-book-sort {
|
||||
padding: 0 24rpx;
|
||||
flex: 1;
|
||||
line-height: 60rpx;
|
||||
background-color: #fafafa;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.xw-book-userlist {
|
||||
padding: 0 24rpx;
|
||||
padding-right: 0;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0px 0px 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.xw-book-user {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.xw-book-user-avatar {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.xw-book-user-name {
|
||||
font-size: 32rpx;
|
||||
margin-left: 26rpx;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
padding-bottom: 13rpx;
|
||||
padding-top: 13rpx;
|
||||
border-bottom: 1px #f8f8f8 solid;
|
||||
max-width: 560rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.xw-book-user-checked{
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
</style>
|
||||
456
im-uniapp/components/uni-indexed-list-wx/uni-indexed-list-wx.vue
Normal file
@@ -0,0 +1,456 @@
|
||||
<template>
|
||||
<view class="uni-indexed-list" ref="list" id="list">
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<list class="uni-indexed-list__scroll" scrollable="true" show-scrollbar="false">
|
||||
<cell v-for="(list, idx) in lists" :key="idx" :ref="'uni-indexed-list-' + idx">
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y>
|
||||
<view class="xw-book-add" v-if="showAdd">
|
||||
<view class="xw-book-add-item" v-for="(v,i) in addlist" :key="i" @click="gopath(v)">
|
||||
<uni-badge v-if="v.num" :text="v.num+''" absolute="rightTop">
|
||||
<view class="xw-book-add-icon">
|
||||
<view class="wxfont jiahaoyou"></view>
|
||||
</view>
|
||||
</uni-badge>
|
||||
<view v-else class="xw-book-add-icon" :style="{background:v.color}">
|
||||
<view class="wxfont jiahaoyou"></view>
|
||||
</view>
|
||||
<view class="xw-book-add-item-text">{{v.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-for="(list, idx) in lists" :key="idx" :id="'uni-indexed-list-' + idx">
|
||||
<!-- #endif -->
|
||||
<indexed-list-item :list="list" :loaded="loaded" :idx="idx" :showSelect="showSelect"
|
||||
@itemClick="onClick"></indexed-list-item>
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
</cell>
|
||||
|
||||
</list>
|
||||
<!-- #endif -->
|
||||
<view class="uni-indexed-list__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"
|
||||
@touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove"
|
||||
@mouseleave.stop="mouseleave">
|
||||
<view v-for="(list, key) in lists" :key="key" class="uni-indexed-list__menu-item"
|
||||
:class="touchmoveIndex == key ? 'uni-indexed-list__menu--active' : ''">
|
||||
<text class="uni-indexed-list__menu-text"
|
||||
:class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''">{{ list.key }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="touchmove" class="uni-indexed-list__alert-wrapper">
|
||||
<text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import indexedListItem from './uni-indexed-list-item.vue'
|
||||
// #ifdef APP-NVUE
|
||||
const dom = weex.requireModule('dom');
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
function throttle(func, delay) {
|
||||
var prev = Date.now();
|
||||
return function() {
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
var now = Date.now();
|
||||
if (now - prev >= delay) {
|
||||
func.apply(context, args);
|
||||
prev = Date.now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function touchMove(e) {
|
||||
let pageY = e.touches[0].pageY
|
||||
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
|
||||
if (this.touchmoveIndex === index) {
|
||||
return false
|
||||
}
|
||||
let item = this.lists[index]
|
||||
if (item) {
|
||||
// #ifndef APP-NVUE
|
||||
this.scrollViewId = 'uni-indexed-list-' + index
|
||||
this.touchmoveIndex = index
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
dom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {
|
||||
animated: false
|
||||
})
|
||||
this.touchmoveIndex = index
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
const throttleTouchMove = throttle(touchMove, 40)
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* IndexedList 索引列表 微信版
|
||||
* @description 用于展示索引列表
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=375
|
||||
* @property {Boolean} showSelect = [true|false] 展示模式
|
||||
* @value true 展示模式
|
||||
* @value false 选择模式
|
||||
* @property {Object} options 索引列表需要的数据对象
|
||||
* @event {Function} click 点击列表事件 ,返回当前选择项的事件对象
|
||||
* @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>
|
||||
*/
|
||||
export default {
|
||||
name: 'UniIndexedListWX',
|
||||
components: {
|
||||
indexedListItem
|
||||
},
|
||||
emits: ['click'],
|
||||
props: {
|
||||
options: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
showSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showAdd: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
lists: [],
|
||||
winHeight: 0,
|
||||
itemHeight: 0,
|
||||
winOffsetY: 0,
|
||||
touchmove: false,
|
||||
touchmoveIndex: -1,
|
||||
scrollViewId: '',
|
||||
touchmovable: true,
|
||||
loaded: false,
|
||||
isPC: false
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
friendApply() {
|
||||
return this.$store.state.friendApply
|
||||
},
|
||||
addlist(){
|
||||
return [{
|
||||
title:'新的朋友',
|
||||
path:'../../wx/search-friends/index',
|
||||
num:this.$store.state.friendApply.count ? this.$store.state.friendApply.count : '',
|
||||
icon:'jiahaoyou',
|
||||
color:'#FB9E3E'
|
||||
},{
|
||||
title:'群聊',
|
||||
path:'../../wx/groupInfo/grouplist',
|
||||
icon:'qunl',
|
||||
num:'',
|
||||
color:'#0ABF62'
|
||||
}]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler: function() {
|
||||
this.setList()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef H5
|
||||
this.isPC = this.IsPC()
|
||||
// #endif
|
||||
setTimeout(() => {
|
||||
this.setList()
|
||||
}, 50)
|
||||
setTimeout(() => {
|
||||
this.loaded = true
|
||||
}, 300);
|
||||
},
|
||||
methods: {
|
||||
gopath(e){
|
||||
uni.navigateTo({
|
||||
url:e.path
|
||||
})
|
||||
},
|
||||
setList() {
|
||||
let index = 0;
|
||||
this.lists = []
|
||||
this.options.forEach((value, index) => {
|
||||
if (value.data.length === 0) {
|
||||
return
|
||||
}
|
||||
let indexBefore = index
|
||||
let items = value.data.map(item => {
|
||||
let obj = {}
|
||||
obj['key'] = value.letter
|
||||
obj['data'] = item
|
||||
obj['itemIndex'] = index
|
||||
index++
|
||||
obj.checked = item.checked ? item.checked : false
|
||||
return obj
|
||||
})
|
||||
this.lists.push({
|
||||
title: value.letter,
|
||||
key: value.letter,
|
||||
items: items,
|
||||
itemIndex: indexBefore
|
||||
})
|
||||
})
|
||||
// #ifndef APP-NVUE
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('#list')
|
||||
.boundingClientRect()
|
||||
.exec(ret => {
|
||||
this.winOffsetY = ret[0].top
|
||||
this.winHeight = ret[0].height
|
||||
this.itemHeight = this.winHeight / this.lists.length
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
dom.getComponentRect(this.$refs['list'], (res) => {
|
||||
this.winOffsetY = res.size.top
|
||||
this.winHeight = res.size.height
|
||||
this.itemHeight = this.winHeight / this.lists.length
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
touchStart(e) {
|
||||
this.touchmove = true
|
||||
let pageY = this.isPC ? e.pageY : e.touches[0].pageY
|
||||
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
|
||||
let item = this.lists[index]
|
||||
if (item) {
|
||||
this.scrollViewId = 'uni-indexed-list-' + index
|
||||
this.touchmoveIndex = index
|
||||
// #ifdef APP-NVUE
|
||||
dom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {
|
||||
animated: false
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
touchMove(e) {
|
||||
// #ifndef APP-PLUS
|
||||
let pageY = this.isPC ? e.pageY : e.touches[0].pageY
|
||||
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
|
||||
if (this.touchmoveIndex === index) {
|
||||
return false
|
||||
}
|
||||
let item = this.lists[index]
|
||||
if (item) {
|
||||
this.scrollViewId = 'uni-indexed-list-' + index
|
||||
this.touchmoveIndex = index
|
||||
}
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
throttleTouchMove.call(this, e)
|
||||
// #endif
|
||||
},
|
||||
touchEnd() {
|
||||
this.touchmove = false
|
||||
// this.touchmoveIndex = -1
|
||||
},
|
||||
|
||||
/**
|
||||
* 兼容 PC @tian
|
||||
*/
|
||||
|
||||
mousedown(e) {
|
||||
if (!this.isPC) return
|
||||
this.touchStart(e)
|
||||
},
|
||||
mousemove(e) {
|
||||
if (!this.isPC) return
|
||||
this.touchMove(e)
|
||||
},
|
||||
mouseleave(e) {
|
||||
if (!this.isPC) return
|
||||
this.touchEnd(e)
|
||||
},
|
||||
|
||||
// #ifdef H5
|
||||
IsPC() {
|
||||
var userAgentInfo = navigator.userAgent;
|
||||
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
|
||||
var flag = true;
|
||||
for (let v = 0; v < Agents.length - 1; v++) {
|
||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
},
|
||||
// #endif
|
||||
|
||||
|
||||
onClick(e) {
|
||||
let {
|
||||
idx,
|
||||
index
|
||||
} = e
|
||||
let obj = {}
|
||||
for (let key in this.lists[idx].items[index]) {
|
||||
obj[key] = this.lists[idx].items[index][key]
|
||||
}
|
||||
let select = []
|
||||
if (this.showSelect) {
|
||||
this.lists[idx].items[index].checked = !this.lists[idx].items[index].checked
|
||||
this.lists.forEach((value, idx) => {
|
||||
value.items.forEach((item, index) => {
|
||||
if (item.checked) {
|
||||
let obj = {}
|
||||
for (let key in this.lists[idx].items[index]) {
|
||||
obj[key] = this.lists[idx].items[index][key]
|
||||
}
|
||||
select.push(obj)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
this.$emit('click', {
|
||||
item: obj,
|
||||
select: select
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.uni-indexed-list {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.uni-indexed-list__scroll {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.uni-indexed-list__menu {
|
||||
width: 24px;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.uni-indexed-list__menu-item {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-indexed-list__menu-text {
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.uni-indexed-list__menu--active {
|
||||
// background-color: rgb(200, 200, 200);
|
||||
}
|
||||
|
||||
.uni-indexed-list__menu--active {}
|
||||
|
||||
.uni-indexed-list__menu-text--active {
|
||||
border-radius: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
// background-color: #007aff;
|
||||
// color: #fff;
|
||||
}
|
||||
|
||||
.uni-indexed-list__alert-wrapper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.uni-indexed-list__alert {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 80px;
|
||||
text-align: center;
|
||||
line-height: 80px;
|
||||
font-size: 35px;
|
||||
color: #fff;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.h5-buchang{
|
||||
height: 140rpx;
|
||||
display: none;
|
||||
}
|
||||
.uni-scroll-view-content view:nth-last-child(1) .h5-buchang{
|
||||
display: block;
|
||||
}
|
||||
.xw-book-add{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding:0 24rpx;
|
||||
box-sizing: border-box;
|
||||
// height: 120rpx;
|
||||
}
|
||||
.xw-book-add-item{
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
// height: 90rpx;
|
||||
// line-height: 90rpx;
|
||||
padding-bottom: 16rpx;
|
||||
padding-top: 16rpx;
|
||||
// border-bottom: 1px #f8f8f8 solid;
|
||||
}
|
||||
.xw-book-add-icon{
|
||||
background: #FB9E3E;
|
||||
border-radius: 10rpx;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
display: flex;flex-direction: row;align-items: center;justify-content: center;
|
||||
}
|
||||
|
||||
.xw-book-add-icon .wxfont{
|
||||
color: #fff;
|
||||
font-size: 58rpx;
|
||||
}
|
||||
.xw-book-add-item-text{
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
margin-left: 26rpx;
|
||||
// height: 90rpx;
|
||||
// line-height: 90rpx;
|
||||
// border-bottom: 1px #f8f8f8 solid;
|
||||
}
|
||||
</style>
|
||||
173
im-uniapp/components/uni-list-chat-wx/openTool.vue
Normal file
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<view @touchmove.stop.prevent="moveHandle('touchmove')" @click="moveHandle('click')" v-if="show">
|
||||
<view class="openTool-wx" :animation="animationData">
|
||||
<view class="openTool-wx-list" v-if="data">
|
||||
<view class="openTool-wx-list-item" @click="zhiding">
|
||||
<view class="text" v-if="data.top=='Y'">取消置顶</view>
|
||||
<view class="text" v-if="data.top=='N'">置顶该聊天</view>
|
||||
</view>
|
||||
<view class="openTool-wx-list-item" @click="shanchu">
|
||||
<view class="text">删除该聊天</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="openTool-wx-model"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show:false,
|
||||
animationData: {}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
data:{
|
||||
type:[Object,String]
|
||||
},
|
||||
itemKey:{
|
||||
type:[Object,String,Number]
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [{}];
|
||||
}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
chatList() {
|
||||
return this.$store.state.chatlist
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
var animation = uni.createAnimation({
|
||||
duration: 300,
|
||||
timingFunction: 'linear'
|
||||
});
|
||||
this.animation = animation;
|
||||
},
|
||||
methods: {
|
||||
zhiding(){
|
||||
var data=JSON.parse(JSON.stringify(this.data))
|
||||
var yn = data.top=='N' ? 'Y' : 'N';
|
||||
data.top=yn
|
||||
this.$store.dispatch('updateChatListInfoById', {
|
||||
userId: this.data.userId,
|
||||
data: data
|
||||
})
|
||||
this.$store.dispatch('getChatList')
|
||||
if(data.windowType=='GROUP'){
|
||||
var formData = {
|
||||
groupId: this.data.userId,
|
||||
top: yn
|
||||
};
|
||||
this.$http.request({
|
||||
url: '/group/editTop',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(formData),
|
||||
success: res => {
|
||||
if (res.data.code == 200) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if(data.windowType=='SINGLE'){
|
||||
var formData = {
|
||||
userId: this.data.userId,
|
||||
top: yn
|
||||
};
|
||||
this.$http.request({
|
||||
url: '/friend/top',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(formData),
|
||||
success: res => {
|
||||
if (res.data.code == 200) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
shanchu(){
|
||||
delete this.chatList[this.data.userId]
|
||||
this.$store.dispatch('updateChatListInfoById',{
|
||||
userId: this.data.userId,
|
||||
data: {}
|
||||
});
|
||||
this.$store.dispatch('updateChatById', {
|
||||
userId: this.data.userId,
|
||||
data: []
|
||||
});
|
||||
},
|
||||
showAnimation() {
|
||||
this.animation.opacity(1).step();
|
||||
this.animationData = this.animation.export();
|
||||
},
|
||||
hideAnimation() {
|
||||
this.animation.opacity(0).step();
|
||||
this.animationData = this.animation.export();
|
||||
},
|
||||
moveHandle(e) {
|
||||
this.hiddenTab()
|
||||
},
|
||||
showTab(){
|
||||
this.show=true
|
||||
setTimeout(()=>{
|
||||
this.showAnimation()
|
||||
},30)
|
||||
},
|
||||
hiddenTab(){
|
||||
this.show=false
|
||||
this.hideAnimation()
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.openTool-wx {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.openTool-wx-model{
|
||||
background-color: rgba(0,0,0,0);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
.openTool-wx-list {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 0px 10px rgba(0,0,0,0.3);
|
||||
border-radius: 10rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.openTool-wx-list-item {
|
||||
padding: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.openTool-wx-list-item .text {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.openTool-wx-list-item:nth-last-child(1) .text{
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
583
im-uniapp/components/uni-list-chat-wx/uni-list-chat-wx.vue
Normal file
@@ -0,0 +1,583 @@
|
||||
<template>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<cell>
|
||||
<!-- #endif -->
|
||||
<view :hover-class="!clickable && !link ? '' : 'uni-list-chat--hover'" :style="{background:color}" class="uni-list-chat" @longpress="longpressItem($event,itemKey,item)">
|
||||
<openTool class="openTool" :ref="'toolx'+itemKey" :data="item" :itemKey="itemKey"></openTool>
|
||||
<view :class="{ 'uni-list--border': border, 'uni-list-chat--first': isFirstChild }"></view>
|
||||
<view class="uni-list-chat__container" @click="onClick">
|
||||
<view class="uni-list-chat__header-warp">
|
||||
<view v-if="item.windowType=='SINGLE'" class="uni-list-chat__header" :class="{ 'header--circle': avatarCircle }">
|
||||
<image class="uni-list-chat__header-image" :src="item.portrait" mode="aspectFill"></image>
|
||||
</view>
|
||||
<!-- 头像组 -->
|
||||
<view v-if="item.windowType=='GROUP'" class="uni-list-chat__header">
|
||||
<view v-for="(item, index) in avatarList" :key="index" class="uni-list-chat__header-box" :class="computedAvatar"
|
||||
:style="{ width: imageWidth + 'px', height: imageWidth + 'px' }">
|
||||
<image class="uni-list-chat__header-image" :style="{ width: imageWidth + 'px', height: imageWidth + 'px' }" :src="item.url"
|
||||
mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="badgeText && badgePositon === 'left'" class="uni-list-chat__badge uni-list-chat__badge-pos" :class="[isSingle]">
|
||||
<text class="uni-list-chat__badge-text">{{ badgeText === 'dot' ? '' : badgeText }}</text>
|
||||
</view>
|
||||
<view class="uni-list-chat__content">
|
||||
<view class="uni-list-chat__content-main">
|
||||
<text class="uni-list-chat__content-title uni-ellipsis">{{ title }}</text>
|
||||
<text class="uni-list-chat__content-note uni-ellipsis">{{ note }}</text>
|
||||
</view>
|
||||
<view class="uni-list-chat__content-extra">
|
||||
<slot>
|
||||
<text class="uni-list-chat__content-extra-text">{{ time }}</text>
|
||||
<view v-if="badgeText && badgePositon === 'right'" class="uni-list-chat__badge" :class="[isSingle, badgePositon === 'right' ? 'uni-list-chat--right' : '']">
|
||||
<text class="uni-list-chat__badge-text">{{ badgeText === 'dot' ? '' : badgeText }}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
</cell>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import openTool from './openTool.vue'
|
||||
// 头像大小
|
||||
const avatarWidth = 45;
|
||||
|
||||
/**
|
||||
* ListChat 聊天列表
|
||||
* @description 聊天列表,用于创建聊天类列表
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
|
||||
* @property {String} title 标题
|
||||
* @property {String} note 描述
|
||||
* @property {Boolean} clickable = [true|false] 是否开启点击反馈,默认为false
|
||||
* @property {String} badgeText 数字角标内容
|
||||
* @property {String} badgePositon = [left|right] 角标位置,默认为 right
|
||||
* @property {String} link = [false|navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈,默认为false
|
||||
* @value false 不开启
|
||||
* @value navigateTo 同 uni.navigateTo()
|
||||
* @value redirectTo 同 uni.redirectTo()
|
||||
* @value reLaunch 同 uni.reLaunch()
|
||||
* @value switchTab 同 uni.switchTab()
|
||||
* @property {String | PageURIString} to 跳转目标页面
|
||||
* @property {String} time 右侧时间显示
|
||||
* @property {Boolean} avatarCircle = [true|false] 是否显示圆形头像,默认为false
|
||||
* @property {String} avatar 头像地址,avatarCircle 不填时生效
|
||||
* @property {Array} avatarList 头像组,格式为 [{url:''}]
|
||||
* @event {Function} click 点击 uniListChat 触发事件
|
||||
*/
|
||||
export default {
|
||||
components:{
|
||||
openTool
|
||||
},
|
||||
name: 'UniListChatWx',
|
||||
emits:['click','longpressItem'],
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: '#fff'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
note: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
clickable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
link: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
to: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
badgeText: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
badgePositon: {
|
||||
type: String,
|
||||
default: 'right'
|
||||
},
|
||||
time: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
avatarCircle: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
avatar: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// avatarList: {
|
||||
// type: Array,
|
||||
// default () {
|
||||
// return [];
|
||||
// }
|
||||
// },
|
||||
item: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
itemKey: {
|
||||
type: Number
|
||||
},
|
||||
longTapItemKey: {
|
||||
type: [Number,String],
|
||||
default:''
|
||||
}
|
||||
},
|
||||
// inject: ['list'],
|
||||
computed: {
|
||||
isSingle() {
|
||||
if (this.badgeText === 'dot') {
|
||||
return 'uni-badge--dot';
|
||||
} else {
|
||||
const badgeText = this.badgeText.toString();
|
||||
if (badgeText.length > 1) {
|
||||
return 'uni-badge--complex';
|
||||
} else {
|
||||
return 'uni-badge--single';
|
||||
}
|
||||
}
|
||||
},
|
||||
avatarList(){
|
||||
return this.returnAvatar(this.item.portrait)
|
||||
},
|
||||
computedAvatar() {
|
||||
if (this.avatarList.length > 4) {
|
||||
this.imageWidth = avatarWidth * 0.31;
|
||||
return 'avatarItem--3';
|
||||
} else if (this.avatarList.length > 1) {
|
||||
this.imageWidth = avatarWidth * 0.47;
|
||||
return 'avatarItem--2';
|
||||
} else {
|
||||
this.imageWidth = avatarWidth;
|
||||
return 'avatarItem--1';
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isFirstChild: false,
|
||||
border: true,
|
||||
// avatarList: 3,
|
||||
imageWidth: 50
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.list = this.getForm()
|
||||
if (this.list) {
|
||||
if (!this.list.firstChildAppend) {
|
||||
this.list.firstChildAppend = true;
|
||||
this.isFirstChild = true;
|
||||
}
|
||||
this.border = this.list.border;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
returnAvatar(text){
|
||||
var data=JSON.parse(text)
|
||||
var avatars=[]
|
||||
for(var i=0;i<data.length;i++){
|
||||
avatars.push({
|
||||
url:data[i]
|
||||
})
|
||||
}
|
||||
return avatars
|
||||
},
|
||||
longpressItem(e,i,v) {//长按回调
|
||||
this.$emit('longpressItem',e,i,v)
|
||||
if(this.itemKey==this.longTapItemKey){
|
||||
this.$refs['toolx'+this.itemKey].showTab();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取父元素实例
|
||||
*/
|
||||
getForm(name = 'uniList') {
|
||||
let parent = this.$parent;
|
||||
let parentName = parent.$options.name;
|
||||
while (parentName !== name) {
|
||||
parent = parent.$parent;
|
||||
if (!parent) return false
|
||||
parentName = parent.$options.name;
|
||||
}
|
||||
return parent;
|
||||
},
|
||||
onClick() {
|
||||
if (this.to !== '') {
|
||||
this.openPage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.clickable || this.link) {
|
||||
this.$emit('click', {
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
},
|
||||
openPage() {
|
||||
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) {
|
||||
this.pageApi(this.link);
|
||||
} else {
|
||||
this.pageApi('navigateTo');
|
||||
}
|
||||
},
|
||||
pageApi(api) {
|
||||
uni[api]({
|
||||
url: this.to,
|
||||
success: res => {
|
||||
this.$emit('click', {
|
||||
data: res
|
||||
});
|
||||
},
|
||||
fail: err => {
|
||||
this.$emit('click', {
|
||||
data: err
|
||||
});
|
||||
console.error(err.errMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$uni-font-size-lg:16px;
|
||||
$uni-spacing-row-sm: 5px;
|
||||
$uni-spacing-row-base: 10px;
|
||||
$uni-spacing-row-lg: 15px;
|
||||
$background-color: #fff;
|
||||
$divide-line-color: #e5e5e5;
|
||||
$avatar-width: 45px;
|
||||
$avatar-border-radius: 5px;
|
||||
$avatar-border-color: #eee;
|
||||
$avatar-border-width: 1px;
|
||||
$title-size: 16px;
|
||||
$title-color: #3b4144;
|
||||
$title-weight: normal;
|
||||
$note-size: 12px;
|
||||
$note-color: #999;
|
||||
$note-weight: normal;
|
||||
$right-text-size: 12px;
|
||||
$right-text-color: #999;
|
||||
$right-text-weight: normal;
|
||||
$badge-left: 0px;
|
||||
$badge-top: 0px;
|
||||
$dot-width: 10px;
|
||||
$dot-height: 10px;
|
||||
$badge-size: 18px;
|
||||
$badge-font: 12px;
|
||||
$badge-color: #fff;
|
||||
$badge-background-color: #ff5a5f;
|
||||
$badge-space: 6px;
|
||||
$hover: #f5f5f5;
|
||||
.openTool{
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
display: flex;flex-direction: row;justify-content: center;
|
||||
}
|
||||
.uni-list-chat {
|
||||
font-size: $uni-font-size-lg;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
background-color: $background-color;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// .uni-list-chat--disabled {
|
||||
// opacity: 0.3;
|
||||
// }
|
||||
|
||||
.uni-list-chat--hover {
|
||||
background-color: $hover;
|
||||
}
|
||||
|
||||
.uni-list--border {
|
||||
position: relative;
|
||||
margin-left: $uni-spacing-row-lg;
|
||||
/* #ifdef APP-PLUS */
|
||||
border-top-color: $divide-line-color;
|
||||
border-top-style: solid;
|
||||
border-top-width: 0.5px;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-list--border:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
content: '';
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
background-color: $divide-line-color;
|
||||
}
|
||||
|
||||
.uni-list-item--first:after {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.uni-list-chat--first {
|
||||
border-top-width: 0px;
|
||||
}
|
||||
|
||||
.uni-ellipsis {
|
||||
/* #ifndef APP-NVUE */
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
lines: 1;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-ellipsis-2 {
|
||||
/* #ifndef APP-NVUE */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef APP-NVUE */
|
||||
lines: 2;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-list-chat__container {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
padding: $uni-spacing-row-base $uni-spacing-row-lg;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-list-chat__header-warp {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uni-list-chat__header {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
align-content: center;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap-reverse;
|
||||
/* #ifdef APP-NVUE */
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
width: $avatar-width;
|
||||
height: $avatar-width;
|
||||
/* #endif */
|
||||
|
||||
border-radius: $avatar-border-radius;
|
||||
border-color: $avatar-border-color;
|
||||
border-width: $avatar-border-width;
|
||||
border-style: solid;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-list-chat__header-box {
|
||||
/* #ifndef APP-PLUS */
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: $avatar-width;
|
||||
height: $avatar-width;
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* #endif */
|
||||
overflow: hidden;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.uni-list-chat__header-image {
|
||||
margin: 1px;
|
||||
/* #ifdef APP-NVUE */
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
width: $avatar-width;
|
||||
height: $avatar-width;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-list-chat__header-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.avatarItem--1 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.avatarItem--2 {
|
||||
width: 47%;
|
||||
height: 47%;
|
||||
}
|
||||
|
||||
.avatarItem--3 {
|
||||
width: 32%;
|
||||
height: 32%;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.header--circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.uni-list-chat__content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.uni-list-chat__content-main {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding-left: $uni-spacing-row-base;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-list-chat__content-title {
|
||||
font-size: $title-size;
|
||||
color: $title-color;
|
||||
font-weight: $title-weight;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-list-chat__content-note {
|
||||
margin-top: 3px;
|
||||
color: $note-color;
|
||||
font-size: $note-size;
|
||||
font-weight: $title-weight;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-list-chat__content-extra {
|
||||
/* #ifndef APP-NVUE */
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.uni-list-chat__content-extra-text {
|
||||
color: $right-text-color;
|
||||
font-size: $right-text-size;
|
||||
font-weight: $right-text-weight;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-list-chat__badge-pos {
|
||||
position: absolute;
|
||||
/* #ifdef APP-NVUE */
|
||||
left: 55px;
|
||||
top: 3px;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
left: calc(#{$avatar-width} + 10px - #{$badge-space} + #{$badge-left});
|
||||
top: calc(#{$uni-spacing-row-base}/ 2 + 1px + #{$badge-top});
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-list-chat__badge {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100px;
|
||||
background-color: $badge-background-color;
|
||||
}
|
||||
|
||||
.uni-list-chat__badge-text {
|
||||
color: $badge-color;
|
||||
font-size: $badge-font;
|
||||
}
|
||||
|
||||
.uni-badge--single {
|
||||
/* #ifndef APP-NVUE */
|
||||
// left: calc(#{$avatar-width} + 7px + #{$badge-left});
|
||||
/* #endif */
|
||||
width: $badge-size;
|
||||
height: $badge-size;
|
||||
}
|
||||
|
||||
.uni-badge--complex {
|
||||
/* #ifdef APP-NVUE */
|
||||
left: 50px;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
width: auto;
|
||||
/* #endif */
|
||||
height: $badge-size;
|
||||
padding: 0 $badge-space;
|
||||
}
|
||||
|
||||
.uni-badge--dot {
|
||||
/* #ifdef APP-NVUE */
|
||||
left: 60px;
|
||||
top: 6px;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
left: calc(#{$avatar-width} + 15px - #{$dot-width}/ 2 + 1px + #{$badge-left});
|
||||
/* #endif */
|
||||
width: $dot-width;
|
||||
height: $dot-height;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.uni-list-chat--right {
|
||||
/* #ifdef APP-NVUE */
|
||||
left: 0;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
108
im-uniapp/components/uni-list-wx/uni-list-wx.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<view class="uni-list uni-border-top-bottom">
|
||||
<view v-if="border" class="uni-list--border-top"></view>
|
||||
<slot />
|
||||
<view v-if="border" class="uni-list--border-bottom"></view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<list class="uni-list" :class="{ 'uni-list--border': border }" :enableBackToTop="enableBackToTop" loadmoreoffset="15"><slot /></list>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* List 列表
|
||||
* @description 列表组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
|
||||
* @property {String} border = [true|false] 标题
|
||||
*/
|
||||
export default {
|
||||
name: 'uniListWx',
|
||||
'mp-weixin': {
|
||||
options: {
|
||||
multipleSlots: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
enableBackToTop: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
scrollY: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
// provide() {
|
||||
// return {
|
||||
// list: this
|
||||
// };
|
||||
// },
|
||||
created() {
|
||||
this.firstChildAppend = false;
|
||||
},
|
||||
methods: {
|
||||
loadMore(e) {
|
||||
this.$emit('scrolltolower');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
$uni-bg-color:#ffffff;
|
||||
$uni-border-color:#e5e5e5;
|
||||
.uni-list {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
background-color: $uni-bg-color;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.uni-list--border {
|
||||
position: relative;
|
||||
/* #ifdef APP-NVUE */
|
||||
border-top-color: $uni-border-color;
|
||||
border-top-style: solid;
|
||||
border-top-width: 0.5px;
|
||||
border-bottom-color: $uni-border-color;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 0.5px;
|
||||
/* #endif */
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
|
||||
.uni-list--border-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
background-color: $uni-border-color;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.uni-list--border-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
background-color: $uni-border-color;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
</style>
|
||||
140
im-uniapp/components/uni-section/uni-section.vue
Normal file
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<view class="uni-section">
|
||||
<view class="uni-section-header" nvue>
|
||||
<view v-if="type" class="uni-section__head">
|
||||
<view :class="type" class="uni-section__head-tag"/>
|
||||
</view>
|
||||
<view class="uni-section__content">
|
||||
<text :class="{'distraction':!subTitle}" :style="{color:color}" class="uni-section__content-title">{{ title }}</text>
|
||||
<text v-if="subTitle" class="uni-section__content-sub">{{ subTitle }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view :style="{padding: padding ? '10px' : ''}">
|
||||
<slot/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
/**
|
||||
* Section 标题栏
|
||||
* @description 标题栏
|
||||
* @property {String} type = [line|circle] 标题装饰类型
|
||||
* @value line 竖线
|
||||
* @value circle 圆形
|
||||
* @property {String} title 主标题
|
||||
* @property {String} subTitle 副标题
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'UniSection',
|
||||
emits:['click'],
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
color:{
|
||||
type: String,
|
||||
default: '#333'
|
||||
},
|
||||
subTitle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
padding: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
watch: {
|
||||
title(newVal) {
|
||||
if (uni.report && newVal !== '') {
|
||||
uni.report('title', newVal)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
$uni-primary: #2979ff !default;
|
||||
|
||||
.uni-section {
|
||||
background-color: #fff;
|
||||
// overflow: hidden;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.uni-section-header {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 12px 10px;
|
||||
// height: 50px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.uni-section__head {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 12px;
|
||||
background-color: $uni-primary;
|
||||
border-radius: 10px;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-top-right-radius: 50px;
|
||||
border-top-left-radius: 50px;
|
||||
border-bottom-left-radius: 50px;
|
||||
border-bottom-right-radius: 50px;
|
||||
background-color: $uni-primary;
|
||||
}
|
||||
|
||||
.uni-section__content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.uni-section__content-title {
|
||||
font-size: 14px;
|
||||
color: $uni-primary;
|
||||
}
|
||||
|
||||
.distraction {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-section__content-sub {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
line-height: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
</style>
|
||||
20
im-uniapp/components/watermark/watermark.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<zmm-watermark :opacity="0.05" :watermark="watermark"></zmm-watermark>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'watermark',
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
watermark() {
|
||||
return this.$store.state.watermark;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
187
im-uniapp/components/zmm-city-picker/zmm-city-picker.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<view class="zmm-picker-region" :style="{'cursor':disabled ? 'move' : 'default'}">
|
||||
<picker
|
||||
:disabled="disabled"
|
||||
mode="multiSelector"
|
||||
@columnchange="Citycolumnchange($event)"
|
||||
@change="pickerchange"
|
||||
:value="Index"
|
||||
:range="pickerArr"
|
||||
range-key="label"
|
||||
@tap="iconopen"
|
||||
@cancel="opend = false"
|
||||
>
|
||||
<view class="zmm-picker-region-uni-input" :style="{'color':disabled ? '#666' : '#333'}" :class="{ 'zmm-picker-region-placeholder': modelValue == '' }">
|
||||
<text :style="{ 'text-align': textAlign }" v-if="modelValue == ''">{{ placeholder }}</text>
|
||||
<text :style="{ 'text-align': textAlign }" v-else>{{ modelValue }}</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import citydata from '@/common/city.js';
|
||||
export default {
|
||||
emits: ['update:modelValue','change'],
|
||||
data() {
|
||||
return {
|
||||
opend: false,
|
||||
Index: [0,0,0],
|
||||
citydata:citydata.data
|
||||
};
|
||||
},
|
||||
behaviors: ['uni://form-field'], //必须要写不然微信小程序收不到值
|
||||
props: {
|
||||
rangeLeave:{//联动级别
|
||||
type:Number,
|
||||
default:2
|
||||
},
|
||||
textAlign: {
|
||||
type: String,
|
||||
default: 'center'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请点击选择'
|
||||
},
|
||||
modelValue: {
|
||||
type: [String]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
computed:{
|
||||
pickerArr(){
|
||||
var arr=[]
|
||||
function findarr(arrx){
|
||||
var arr=[]
|
||||
for (var i = 0; i < arrx.length; i++) {
|
||||
var item = arrx[i]
|
||||
arr.push({
|
||||
label:item.label,
|
||||
value:item.value,
|
||||
position:item.position
|
||||
})
|
||||
}
|
||||
return arr
|
||||
}
|
||||
for (var i = 0; i < this.rangeLeave; i++) {
|
||||
arr.push([])
|
||||
if(i==0){//一级数据
|
||||
arr[i]=findarr(this.citydata)
|
||||
}
|
||||
if(i==1){//二级数据
|
||||
if(this.citydata[this.Index[0]]){
|
||||
arr[i]=findarr(this.citydata[this.Index[0]]['children'])
|
||||
}else{
|
||||
arr[i]=[]
|
||||
}
|
||||
}
|
||||
if(i==2){//三级数据
|
||||
if(this.citydata[this.Index[0]]&&this.citydata[this.Index[0]]['children'][this.Index[1]]){
|
||||
arr[i]=findarr(this.citydata[this.Index[0]]['children'][this.Index[1]]['children'])
|
||||
}else{
|
||||
arr[i]=[]
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
modelValue:{
|
||||
deep: true,
|
||||
immediate:true,
|
||||
handler(val) {
|
||||
this.iniIndex()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
iniIndex(){
|
||||
var arr=this.modelValue.split(',')
|
||||
function findLabelIndex(arr,label){
|
||||
if(!label){
|
||||
return 0
|
||||
}
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if(arr[i].label==label){
|
||||
return i
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
this.Index[i]=findLabelIndex(this.pickerArr[i],arr[i])
|
||||
}
|
||||
},
|
||||
iconopen() {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
this.opend = true;
|
||||
},
|
||||
pickerchange(e) {
|
||||
var text=[]
|
||||
if(this.rangeLeave==1){
|
||||
text.push(this.pickerArr[0][e.detail.value[0]].label)
|
||||
}
|
||||
if(this.rangeLeave==2){
|
||||
text.push(this.pickerArr[0][e.detail.value[0]].label)
|
||||
text.push(this.pickerArr[1][e.detail.value[1]].label)
|
||||
}
|
||||
if(this.rangeLeave==3){
|
||||
text.push(this.pickerArr[0][e.detail.value[0]].label)
|
||||
text.push(this.pickerArr[1][e.detail.value[1]].label)
|
||||
text.push(this.pickerArr[2][e.detail.value[2]].label)
|
||||
}
|
||||
this.opend = !this.opend;
|
||||
this.$emit('update:modelValue', text.toString());
|
||||
this.$emit('change', text.toString())
|
||||
},
|
||||
Citycolumnchange(e) {
|
||||
if (e.detail.column == 0&&this.rangeLeave>1) {//第一行发生变化重置第二列索引
|
||||
this.Index.splice(1, 1, 0);
|
||||
}
|
||||
if (e.detail.column == 1&&this.rangeLeave>2) {
|
||||
this.Index.splice(2, 1, 0);
|
||||
}
|
||||
this.Index[e.detail.column] = e.detail.value;//设置index
|
||||
this.$forceUpdate();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.zmm-picker-region {
|
||||
}
|
||||
.zmm-picker-region-uni-input {
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.zmm-picker-region-uni-input text {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
padding:0 12rpx;
|
||||
}
|
||||
|
||||
|
||||
.zmm-picker-region-placeholder {
|
||||
width: 100%;
|
||||
}
|
||||
.zmm-picker-region-placeholder text{
|
||||
color: #666;
|
||||
|
||||
}
|
||||
</style>
|
||||
105
im-uniapp/components/zmm-radio-group/zmm-radio-group.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<view>
|
||||
<radio-group class="zmm-radio-group" @change="radioChange">
|
||||
<label class="zmm-radio-group-label" v-for="(item,index) in ranges" :key="index" :class="{'checked':index === current}">
|
||||
<view class="zmm-radio-group-radio">
|
||||
<radio style="transform:scale(0.9)" :value="item.value" :checked="index === current" />
|
||||
</view>
|
||||
<view class="zmm-radio-group-label-text">{{ item.label }}</view>
|
||||
<uni-icons class="zmm-radio-group-label-icon" type="checkmarkempty" color="#09C160" size="20"></uni-icons>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['update:modelValue','change'],
|
||||
data() {
|
||||
return {
|
||||
current: '',
|
||||
val: '',
|
||||
ranges: []
|
||||
};
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: [String]
|
||||
},
|
||||
range: {
|
||||
//数组label value
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
range(v) {
|
||||
this.init();
|
||||
},
|
||||
modelValue(val) {
|
||||
this.init();
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.ranges = JSON.parse(JSON.stringify(this.range));
|
||||
this.getval(this.modelValue);
|
||||
},
|
||||
getval(e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
var val = e;
|
||||
var items = this.ranges;
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
const item = items[i];
|
||||
if (item.value==val) {
|
||||
this.current=i
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
radioChange(e) {
|
||||
this.getval(e.detail.value);
|
||||
this.$emit('update:modelValue', e.detail.value)
|
||||
this.$emit('change', e.detail.value)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.zmm-radio-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.zmm-radio-group-radio{
|
||||
display: none;
|
||||
}
|
||||
.zmm-radio-group-label.checked{
|
||||
}
|
||||
.zmm-radio-group-label-icon{display: none;}
|
||||
.zmm-radio-group-label.checked .zmm-radio-group-label-icon{
|
||||
display: block;
|
||||
}
|
||||
.zmm-radio-group-label {
|
||||
height: 90rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px #eee solid;
|
||||
padding: 24rpx;
|
||||
}
|
||||
.zmm-radio-group-label:nth-last-child(1){
|
||||
margin-right: 0;
|
||||
}
|
||||
.zmm-radio-group-label-text{
|
||||
margin-left: 10rpx;
|
||||
font-size: 28rpx;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
||||
277
im-uniapp/components/zmm-recorder/zmm-recorder.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<view v-if="show">
|
||||
<view class="uni-padding-wrap">
|
||||
<block v-if="!recording && !playing && !hasRecord">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button" @click="startRecord">
|
||||
<image src="@/static/record.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="recording === true">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button" @click="stopRecord">
|
||||
<view class="button-stop-record"></view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasRecord === true && playing === false">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedPlayTime}}</text>
|
||||
<text class="time-small">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button" @click="playVoice">
|
||||
<image src="@/static/play.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button" @click="clear">
|
||||
<image src="@/static/trash.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasRecord === true && playing === true">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedPlayTime}}</text>
|
||||
<text class="time-small">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button" @click="stopVoice">
|
||||
<image src="@/static/stop.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button" @click="clear">
|
||||
<image src="@/static/trash.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
import permision from "@/common/permission.js"
|
||||
// #endif
|
||||
var playTimeInterval = null;
|
||||
var recordTimeInterval = null;
|
||||
var recorderManager = null;
|
||||
var music = null;
|
||||
export default {
|
||||
props:{
|
||||
show:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
}
|
||||
},
|
||||
emits:['recorderStop'],
|
||||
data() {
|
||||
return {
|
||||
recording: false, //录音中
|
||||
playing: false, //播放中
|
||||
hasRecord: false, //是否有了一个
|
||||
tempFilePath: '',
|
||||
recordTime: 0,
|
||||
playTime: 0,
|
||||
formatedRecordTime: '00:00:00', //录音的总时间
|
||||
formatedPlayTime: '00:00:00' //播放录音的当前时间
|
||||
}
|
||||
},
|
||||
beforeDestroy: function() {
|
||||
this.clear();
|
||||
},
|
||||
mounted() {
|
||||
music = uni.createInnerAudioContext();
|
||||
music.onEnded(() => {
|
||||
clearInterval(playTimeInterval)
|
||||
var playTime = 0
|
||||
// console.log('play voice finished')
|
||||
this.playing = false;
|
||||
this.formatedPlayTime = this.formatTime(playTime);
|
||||
this.playTime = playTime;
|
||||
});
|
||||
recorderManager = uni.getRecorderManager();
|
||||
recorderManager.onStart(() => {
|
||||
// console.log('recorder start');
|
||||
this.recording = true;
|
||||
recordTimeInterval = setInterval(() => {
|
||||
this.recordTime += 1;
|
||||
this.formatedRecordTime = this.formatTime(this.recordTime);
|
||||
}, 1000)
|
||||
});
|
||||
recorderManager.onStop((res) => {
|
||||
// console.log('on stop');
|
||||
music.src = res.tempFilePath;
|
||||
this.hasRecord = true;
|
||||
this.recording = false;
|
||||
this.$emit('recorderStop',{
|
||||
formatedRecordTime:this.formatedRecordTime,
|
||||
recordTime:this.recordTime<1 ? this.recordTime+1 : this.recordTime,
|
||||
recordFilePath:res.tempFilePath
|
||||
})
|
||||
this.clear()
|
||||
});
|
||||
recorderManager.onError(() => {
|
||||
console.log('recorder onError');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
formatTime(time) {
|
||||
if (typeof time !== 'number' || time < 0) {
|
||||
return time
|
||||
}
|
||||
|
||||
var hour = parseInt(time / 3600)
|
||||
time = time % 3600
|
||||
var minute = parseInt(time / 60)
|
||||
time = time % 60
|
||||
var second = time
|
||||
|
||||
return ([hour, minute, second]).map(function(n) {
|
||||
n = n.toString()
|
||||
return n[1] ? n : '0' + n
|
||||
}).join(':')
|
||||
},
|
||||
async startRecord() { //开始录音
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
|
||||
// TODO ios 在没有请求过权限之前无法得知是否有相关权限,这种状态下需要直接调用录音,但没有状态或回调判断用户拒绝
|
||||
recorderManager.start({
|
||||
duration:600000,
|
||||
sampleRate:44100,
|
||||
format:'mp3'
|
||||
});
|
||||
},
|
||||
stopRecord() { //停止录音
|
||||
recorderManager.stop();
|
||||
|
||||
},
|
||||
playVoice() {
|
||||
// console.log('play voice');
|
||||
this.playing = true;
|
||||
playTimeInterval = setInterval(() => {
|
||||
this.playTime += 1;
|
||||
this.formatedPlayTime = this.formatTime(this.playTime);
|
||||
}, 1000)
|
||||
music.play();
|
||||
},
|
||||
stopVoice() {
|
||||
clearInterval(playTimeInterval)
|
||||
this.playing = false;
|
||||
this.formatedPlayTime = this.formatTime(0);
|
||||
this.playTime = 0;
|
||||
music.stop();
|
||||
},
|
||||
end() {
|
||||
music.stop();
|
||||
recorderManager.stop();
|
||||
clearInterval(recordTimeInterval)
|
||||
clearInterval(playTimeInterval);
|
||||
this.recording = false, this.playing = false, this.hasRecord = false;
|
||||
this.playTime = 0, this.recordTime = 0;
|
||||
this.formatedRecordTime = "00:00:00", this.formatedRecordTime = "00:00:00";
|
||||
},
|
||||
clear() {
|
||||
this.end();
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
,
|
||||
async checkPermission() {
|
||||
let status = permision.isIOS ? await permision.requestIOS('record') :
|
||||
await permision.requestAndroid('android.permission.RECORD_AUDIO');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else if (status === 2) {
|
||||
uni.showModal({
|
||||
content: "系统麦克风已关闭",
|
||||
confirmText: "确定",
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要麦克风权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return status;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.uni-padding-wrap{}
|
||||
image {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
}
|
||||
|
||||
.page-body-wrapper {
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
margin-bottom: 300rpx;
|
||||
}
|
||||
|
||||
.page-body-time {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.time-big {
|
||||
font-size: 26rpx;
|
||||
margin: 20rpx;
|
||||
}
|
||||
|
||||
.time-small {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.page-body-buttons{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.page-body-button {
|
||||
/* width: 250rpx; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.button-stop-record {
|
||||
box-sizing: border-box;
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
border: 20rpx solid #fff;
|
||||
background-color: #4CD964;
|
||||
border-radius: 50%;
|
||||
animation: colors 1s linear infinite;
|
||||
}
|
||||
@keyframes colors {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: .7;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
158
im-uniapp/components/zmm-upload-avatar/zmm-upload-avatar.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<view>
|
||||
<image class="zmm-upload-avatar" :src="modelValue" :style="{ width: imgSize + 'rpx', height: imgSize + 'rpx', 'border-radius': imgRadius + 'rpx' }" mode="aspectFill" @click="selectImage"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import http from '@/common/request.js';
|
||||
export default {
|
||||
name: 'zmm-upload-avatar',
|
||||
emits: ['update:modelValue','change'],
|
||||
props: {
|
||||
modelValue: {
|
||||
type: [String]
|
||||
},
|
||||
imgSize: {
|
||||
//图片大小
|
||||
type: Number,
|
||||
default: 120
|
||||
},
|
||||
imgRadius: {
|
||||
//图片圆角
|
||||
type: Number,
|
||||
default: 12
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
action: {
|
||||
//后台上传接口
|
||||
type: String,
|
||||
default: http.baseUrl + '/file/upload'
|
||||
},
|
||||
formData: {
|
||||
//上传所附带数据
|
||||
type: Object
|
||||
},
|
||||
header: {
|
||||
//自定义头
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
Authorization: uni.getStorageSync('Authorization'),
|
||||
device: uni.getStorageSync('device'),
|
||||
version: uni.getStorageSync('version')
|
||||
};
|
||||
}
|
||||
},
|
||||
fileKey: {
|
||||
//后端接受的filekey
|
||||
type: String,
|
||||
default: 'file'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDestroyed: false,
|
||||
showUploadProgress: true
|
||||
};
|
||||
},
|
||||
mounted: function() {},
|
||||
destroyed: function() {
|
||||
this.isDestroyed = true;
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
selectImage: function() {
|
||||
var _self = this;
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sourceType: ['album', 'camera'],
|
||||
success: function(e) {
|
||||
var imagePathArr = e.tempFilePaths;
|
||||
//检查服务器地址是否设置,设置即表示图片要上传到服务器
|
||||
if (_self.action) {
|
||||
uni.showToast({
|
||||
title: '上传中',
|
||||
icon: 'none',
|
||||
mask: false
|
||||
});
|
||||
|
||||
var remoteIndexStart = 1 - imagePathArr.length;
|
||||
var promiseWorkList = [];
|
||||
var keyname = _self.fileKey ? _self.fileKey : 'upload-images';
|
||||
var completeImages = 0;
|
||||
|
||||
for (let i = 0; i < imagePathArr.length; i++) {
|
||||
promiseWorkList.push(
|
||||
new Promise((resolve, reject) => {
|
||||
let remoteUrlIndex = remoteIndexStart + i;
|
||||
uni.uploadFile({
|
||||
url: _self.action,
|
||||
fileType: 'image',
|
||||
header: _self.header,
|
||||
formData: _self.formData,
|
||||
filePath: imagePathArr[i],
|
||||
name: keyname,
|
||||
success: function(res) {
|
||||
if (res.statusCode === 200) {
|
||||
if (_self.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
completeImages++;
|
||||
|
||||
if (_self.showUploadProgress) {
|
||||
uni.showToast({
|
||||
title: '上传中',
|
||||
icon: 'none',
|
||||
mask: false,
|
||||
duration: 500
|
||||
});
|
||||
}
|
||||
// console.log('success to upload image: ' + res.data)
|
||||
resolve(res.data);
|
||||
} else {
|
||||
console.log('fail to upload image:' + res.data);
|
||||
reject('fail to upload image:' + remoteUrlIndex);
|
||||
}
|
||||
},
|
||||
fail: function(res) {
|
||||
uni.showToast({
|
||||
title: '上传失败请检查网络',
|
||||
icon: 'none'
|
||||
});
|
||||
console.log('fail to upload image:' + res);
|
||||
reject('fail to upload image:' + remoteUrlIndex);
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(promiseWorkList).then(result => {
|
||||
if (_self.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
var resItem = JSON.parse(result[i]);
|
||||
_self.$emit('update:modelValue', resItem.data.fullPath);
|
||||
_self.$emit('change', resItem.data.fullPath);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_self.$emit('update:modelValue', '../../static/img/avatar/avatar2.jpg');
|
||||
_self.$emit('change', '../../static/img/avatar/avatar2.jpg');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.zmm-upload-avatar {
|
||||
}
|
||||
</style>
|
||||
319
im-uniapp/components/zmm-upload-image/zmm-upload-image-drag.vue
Normal file
@@ -0,0 +1,319 @@
|
||||
<template>
|
||||
<view @touchmove.stop.prevent="moveHandle" class="moveWrap">
|
||||
<movable-area class="movarea" ref="areaBox" id="areaBox" :style="{height:imgSize*rowNum +200+ 'rpx'}">
|
||||
<view class="imgBox" :style="{height:imgSize*rowNum + 'rpx'}">
|
||||
<view :id="'img' + idx" class="imgItem" v-for="(item, idx) in imgList" :key="idx"
|
||||
:style="{transition:addJump?' all 0.5s':'',opacity:idx===selectIdx?'0':'1', width: imgSize + 'rpx', height: imgSize + 'rpx', borderRadius:imgRadius+'rpx',padding:imgPadding+'rpx',left:(hoverImgIdx==='img'+idx?curHoverBoxMove.x+'rpx':''),top:(hoverImgIdx==='img'+idx?curHoverBoxMove.y+'rpx':'')}">
|
||||
<view class="imgItem-img" @tap="itemclick(item,idx)" @touchstart="tstr(idx, $event)" @touchmove="tsmo" @touchend="toend">
|
||||
<image v-if="item.videoUrl" class="imgItem-play" src="../../static/img/bf.png" mode="aspectFill"></image>
|
||||
<image :style="{borderRadius:imgRadius+'rpx' }" :ref="'img' + idx" :src="item.url" mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
<slot></slot>
|
||||
</view>
|
||||
<movable-view v-if="moveSrc" :animation="false" class="moveV" :x="x" :y="y" direction="all"
|
||||
@change="onChange"
|
||||
:style="{ width: imgSize + 'rpx', height: imgSize + 'rpx',padding:imgPadding+'rpx' }">
|
||||
<image v-if="moveSrc.videoUrl" class="imgItem-play" src="../../static/img/bf.png" mode="aspectFill"></image>
|
||||
<image :style="{borderRadius:imgRadius+'rpx' }" :src="moveSrc.url" mode="aspectFill"></image>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
<view v-if="showDelete">
|
||||
<view class="delete" :class="{'deleteType':deleteType}">
|
||||
<text v-if="deleteType">松开删除</text>
|
||||
<text v-else>拖动到此处删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
emits:['itemclick','update:imgList','deleteImage','change','moveEndList'],
|
||||
props: {
|
||||
//图片列表
|
||||
imgList: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
//图片大小
|
||||
imgSize: {
|
||||
type: Number
|
||||
},
|
||||
//图片间距
|
||||
imgPadding: {
|
||||
type: Number
|
||||
},
|
||||
//图片行数
|
||||
rowNum: {
|
||||
type: Number
|
||||
},
|
||||
//图片圆角
|
||||
imgRadius: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
showDelete:false,
|
||||
touchobj:null,
|
||||
deleteType:false,
|
||||
addJump:false,
|
||||
areaBoxInfo: {},
|
||||
x: 0,
|
||||
y: 0,
|
||||
selectIdx: null,
|
||||
moveSrc: null,
|
||||
areaBoxTop: 0,
|
||||
hoverImgIdx: '',
|
||||
inBoxXY: {},
|
||||
curHoverBoxMove: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
hoverImgIdx(e) {
|
||||
let idx = this.selectIdx
|
||||
let hoverIdx = parseInt(e.split('img')[1]);
|
||||
if (this.imgList[idx]) {
|
||||
let selectRow = this.imgList[idx].y / uni.upx2px(this.imgSize)
|
||||
let selectColum= this.imgList[idx].x / uni.upx2px(this.imgSize)
|
||||
let hoverRow = this.imgList[hoverIdx].y / uni.upx2px(this.imgSize)
|
||||
let hoverColum= this.imgList[hoverIdx].x / uni.upx2px(this.imgSize)
|
||||
let left = -(this.imgSize * (hoverColum - selectColum))
|
||||
let top= -(this.imgSize * (hoverRow - selectRow))
|
||||
this.curHoverBoxMove = {
|
||||
x: left,
|
||||
y: top,
|
||||
}
|
||||
}
|
||||
},
|
||||
// imgList(e){
|
||||
// console.log('变化了item')
|
||||
// this.$nextTick(()=>{
|
||||
// this.setImgXy()
|
||||
// })
|
||||
// }
|
||||
imgList: {
|
||||
deep: true,//深度监听可见听对象中的元素变化例:obj.id
|
||||
immediate:false,//在进入页面时,第一次绑定值,不会立刻执行监听,只有数据发生改变才会执行handler中的操作
|
||||
handler(val) {//watch事件
|
||||
// console.log('变化了item')
|
||||
this.$nextTick(()=>{
|
||||
this.setImgXy()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemclick(e,i){
|
||||
this.$emit('itemclick',e,i)
|
||||
},
|
||||
moveHandle() {
|
||||
return;
|
||||
},
|
||||
deleteImage: function(e) {
|
||||
var index = e
|
||||
var deletedImage = this.imgList[index]
|
||||
this.imgList.splice(index, 1)
|
||||
this.$emit('deleteImage', deletedImage)
|
||||
},
|
||||
onChange(e) {
|
||||
var boxHeight=this.imgSize * this.rowNum
|
||||
var deleteHeight=(boxHeight-80)/2
|
||||
if(e.detail.y>deleteHeight){
|
||||
this.deleteType=true
|
||||
}else{
|
||||
this.deleteType=false
|
||||
}
|
||||
this.showDelete=true
|
||||
this.$emit('change',e)
|
||||
},
|
||||
tstr(e, s) {
|
||||
this.touchobj=this.imgList[e]
|
||||
this.addJump=true
|
||||
this.getDomInfo('areaBox', info => {
|
||||
this.areaBoxInfo = info;
|
||||
//获取拖拽区域的上边距和下边距
|
||||
let areaBoxTop = this.areaBoxInfo.top;
|
||||
let areaBoxLeft = this.areaBoxInfo.left;
|
||||
|
||||
// 设置可移动方块的初始位置为当前所选中图片的位置坐标
|
||||
this.x = this.imgList[e].x;
|
||||
this.y = this.imgList[e].y;
|
||||
//显示可移动方块
|
||||
this.moveSrc = this.imgList[e];
|
||||
//保存当前所选择的图片索引
|
||||
this.selectIdx = e;
|
||||
var x = s.changedTouches[0].clientX - areaBoxLeft;
|
||||
var y = s.changedTouches[0].clientY - areaBoxTop;
|
||||
// 保存鼠标在图片内的坐标
|
||||
this.inBoxXY = {
|
||||
x: x - this.imgList[e].x,
|
||||
y: y - this.imgList[e].y,
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
tsmo(e) {
|
||||
let areaBoxTop = this.areaBoxInfo.top;
|
||||
let areaBoxLeft = this.areaBoxInfo.left;
|
||||
let imgSize = this.imgSize;
|
||||
//重置为以拖拽盒子左上角为坐标原点
|
||||
var x = e.changedTouches[0].clientX - areaBoxLeft;
|
||||
var y = e.changedTouches[0].clientY - areaBoxTop;
|
||||
this.x = x - this.inBoxXY.x;
|
||||
this.y = y - this.inBoxXY.y;
|
||||
this.imgList.forEach((item, idx) => {
|
||||
if (x > item.x && x < item.x + imgSize && y > item.y && y < item.y + imgSize) {
|
||||
this.hoverImgIdx = 'img' + idx
|
||||
}
|
||||
});
|
||||
},
|
||||
toend(e) {
|
||||
this.addJump=false
|
||||
if(this.deleteType){
|
||||
this.deleteImage(this.selectIdx)
|
||||
}else{
|
||||
// 移动结束隐藏可移动方块
|
||||
let beforeIdx = this.selectIdx;
|
||||
let afterIdx = parseInt(this.hoverImgIdx.split('img')[1]);
|
||||
if (this.hoverImgIdx !== '' && beforeIdx !== afterIdx) {
|
||||
this.imgList[beforeIdx] = this.imgList[afterIdx];
|
||||
this.imgList[afterIdx] = this.moveSrc;
|
||||
this.$emit('moveEndList', this.imgList);
|
||||
}
|
||||
}
|
||||
this.moveSrc = '';
|
||||
this.hoverImgIdx = ''
|
||||
this.selectIdx = null
|
||||
this.deleteType=false
|
||||
this.showDelete=false
|
||||
this.$nextTick(()=>{
|
||||
this.setImgXy()
|
||||
})
|
||||
},
|
||||
getDomInfo(id, callBack) {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('#' + id)
|
||||
.boundingClientRect()
|
||||
.exec(function(res) {
|
||||
callBack(res[0]);
|
||||
});
|
||||
},
|
||||
setImgXy(){//设置每个图片的基础xy轴
|
||||
this.getDomInfo('areaBox', info => {
|
||||
this.areaBoxInfo = info;
|
||||
// 设置区域内所有图片的左上角坐标
|
||||
this.imgList.forEach((item, idx) => {
|
||||
this.getDomInfo('img' + idx, res => {
|
||||
item.x = res.left - info.left;
|
||||
});
|
||||
this.getDomInfo('img' + idx, res => {
|
||||
item.y = res.top - info.top;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setImgXy()
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.imgItem-play{
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 80rpx !important;
|
||||
height: 80rpx !important;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
.movarea {
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.imgBox {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
.imgItem {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
left: 0;
|
||||
top: 0;
|
||||
box-sizing: border-box;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// transition: all 0.2s;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.moveV {
|
||||
opacity: 0.6;
|
||||
z-index: 0;
|
||||
box-sizing: border-box;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.select {
|
||||
opacity: 0;
|
||||
}
|
||||
.zmm-upload-image-deleteIcon {
|
||||
right: 0rpx;
|
||||
top: 0rpx;
|
||||
position: absolute;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
color: white;
|
||||
font-size: 30rpx;
|
||||
z-index: 2;
|
||||
display: flex;flex-direction: row;align-items: center;justify-content: center;
|
||||
}
|
||||
.delete{
|
||||
position: absolute;
|
||||
bottom: 0rpx;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background: #C04A42;
|
||||
text-align: center;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.delete text{
|
||||
color: #fff;
|
||||
}
|
||||
.deleteType{
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.moveWrap{
|
||||
position: relative;
|
||||
}
|
||||
.imgItem-img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
437
im-uniapp/components/zmm-upload-image/zmm-upload-image.vue
Normal file
@@ -0,0 +1,437 @@
|
||||
<template>
|
||||
<view class="zmm-upload-image" v-if="show">
|
||||
<zmm-upload-image-drag :key="key" :rowNum="rows" :imgRadius="imgRadius" :imgSize="imgSize" :imgPadding="imgPadding" :imgList="fileList" @deleteImage="deleteImage" @itemclick="itemclick">
|
||||
<view v-if="showAdd && fileList.length < limit" @tap="chooseTap" :style="{ width: imgSize + 'rpx', height: imgSize + 'rpx',padding:imgPadding+'rpx' }" class="zmm-upload-image-item-slot">
|
||||
<view class="zmm-upload-image-item-slotIcon">
|
||||
<uni-icons type="plusempty" color="#6E6E6E" size="24" />
|
||||
</view>
|
||||
</view>
|
||||
</zmm-upload-image-drag>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import zmmUploadImageDrag from './zmm-upload-image-drag.vue';
|
||||
import http from '@/common/request.js';
|
||||
import customHttp from "@/common/customHttp.js"
|
||||
import config from "@/common/config.js"
|
||||
export default {
|
||||
components: {
|
||||
zmmUploadImageDrag
|
||||
},
|
||||
name: 'zmm-upload-image',
|
||||
emits: ['update:modelValue', 'deleteImage','allComplete','oneComplete'],
|
||||
props: {
|
||||
modelValue: {
|
||||
type: [Array]
|
||||
},
|
||||
chooseType:{
|
||||
type:String,
|
||||
default:'chooseImage'//chooseImage图片 chooseVideo视频 chooseMedia图片或视频
|
||||
},
|
||||
imgSize: {
|
||||
//图片大小
|
||||
type: Number,
|
||||
default: 214
|
||||
},
|
||||
imgPadding: {
|
||||
//图片间距
|
||||
type: Number,
|
||||
default: 6
|
||||
},
|
||||
imgRadius: {
|
||||
//图片圆角
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
fileList: {
|
||||
//图片数据
|
||||
type: Array,
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
rowNumber: {
|
||||
//一行多少个图片
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
showAdd: {
|
||||
//增加按钮
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
show: {
|
||||
//是否显示
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
fileAction: {
|
||||
//后台文件上传接口
|
||||
type: String,
|
||||
default: config.getImApiUrl() + '/file/upload'
|
||||
},
|
||||
videoAction: {
|
||||
//后台上传接口
|
||||
type: String,
|
||||
default: config.getImApiUrl() + '/file/uploadVideo'
|
||||
},
|
||||
formData: {
|
||||
//上传所附带数据
|
||||
type: Object
|
||||
},
|
||||
header: {
|
||||
//自定义头
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
Authorization: uni.getStorageSync('Authorization'),
|
||||
device: uni.getStorageSync('device'),
|
||||
version: uni.getStorageSync('version')
|
||||
};
|
||||
}
|
||||
},
|
||||
limit: {
|
||||
//图片数量
|
||||
type: Number,
|
||||
default: 9
|
||||
},
|
||||
fileKey: {
|
||||
//后端接受的filekey
|
||||
type: String,
|
||||
default: 'file'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
key:0,
|
||||
isDestroyed: false,
|
||||
showUploadProgress:true
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
console.log(val);
|
||||
},
|
||||
fileList(e){
|
||||
// console.log('变化了list')
|
||||
this.key++
|
||||
},
|
||||
rows(e){
|
||||
this.key++
|
||||
}
|
||||
// fileList: {
|
||||
// deep: true,//深度监听可见听对象中的元素变化例:obj.id
|
||||
// immediate:false,//在进入页面时,第一次绑定值,不会立刻执行监听,只有数据发生改变才会执行handler中的操作
|
||||
// handler(val) {//watch事件
|
||||
// console.log('变化了list')
|
||||
// this.key++
|
||||
// }
|
||||
// }
|
||||
},
|
||||
mounted: function() {},
|
||||
destroyed: function() {
|
||||
this.isDestroyed = true;
|
||||
},
|
||||
computed: {
|
||||
rows() {
|
||||
var buzhu=this.showAdd && this.fileList.length < this.limit ? 1 : 0;
|
||||
var rows=Math.ceil((this.fileList.length+buzhu) / this.rowNumber);
|
||||
return rows
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemclick(e,i){
|
||||
if(!e.videoUrl){
|
||||
var imgs=[]
|
||||
for (var i = 0; i < this.fileList.length; i++) {
|
||||
var item=this.fileList[i]
|
||||
if(!item.videoUrl){
|
||||
imgs.push(item.url)
|
||||
}
|
||||
}
|
||||
this.previewImage(imgs,i)
|
||||
}else{
|
||||
this.$fc.plusDownload({onlinePath:e.videoUrl}).then(res=>{
|
||||
this.$fc.plusOpenFile({filePath:res})
|
||||
})
|
||||
}
|
||||
},
|
||||
chooseTap(){
|
||||
switch (this.chooseType){
|
||||
case 'chooseImage':
|
||||
this.selectImage()
|
||||
break;
|
||||
case 'chooseVideo':
|
||||
this.selectVideo()
|
||||
break;
|
||||
case 'chooseMedia':
|
||||
uni.showActionSheet({
|
||||
itemList: ['图片'],
|
||||
// itemList: ['图片', '视频'],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex){
|
||||
case 0:
|
||||
this.selectImage()
|
||||
break;
|
||||
case 1:
|
||||
this.selectVideo()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
selectImage: function() {
|
||||
var _self = this;
|
||||
if (!_self.fileList) {
|
||||
_self.fileList = [];
|
||||
}
|
||||
uni.chooseImage({
|
||||
count: _self.limit ? _self.limit - _self.fileList.length : 999,
|
||||
sourceType: ['album', 'camera'],
|
||||
sizeType:['original','compressed'],
|
||||
success: function(e) {
|
||||
var imagePathArr = e.tempFilePaths;
|
||||
//如果设置了limit限制,在web上count参数无效,这里做判断控制选择的数量是否合要求
|
||||
//在非微信小程序里,虽然可以选多张,但选择的结果会被截掉
|
||||
//在app里,会自动做选择数量的限制
|
||||
if (_self.limit) {
|
||||
var availableImageNumber = _self.limit - _self.fileList.length;
|
||||
if (availableImageNumber < imagePathArr.length) {
|
||||
uni.showToast({
|
||||
title: '图片总数限制为' + _self.limit + '张,当前还可以选' + availableImageNumber + '张',
|
||||
icon: 'none',
|
||||
mask: false,
|
||||
duration: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//检查服务器地址是否设置,设置即表示图片要上传到服务器
|
||||
if (_self.fileAction) {
|
||||
uni.showToast({
|
||||
title: '上传进度:0/' + imagePathArr.length,
|
||||
icon: 'none',
|
||||
mask: false
|
||||
});
|
||||
|
||||
var remoteIndexStart = _self.fileList.length - imagePathArr.length;
|
||||
var promiseWorkList = [];
|
||||
var keyname = _self.fileKey ? _self.fileKey : 'upload-images';
|
||||
var completeImages = 0;
|
||||
|
||||
for (let i = 0; i < imagePathArr.length; i++) {
|
||||
promiseWorkList.push(
|
||||
new Promise((resolve, reject) => {
|
||||
let remoteUrlIndex = remoteIndexStart + i;
|
||||
uni.uploadFile({
|
||||
url: _self.fileAction,
|
||||
fileType: 'image',
|
||||
header: _self.header,
|
||||
formData: _self.formData,
|
||||
filePath: imagePathArr[i],
|
||||
name: keyname,
|
||||
success: function(res) {
|
||||
if (res.statusCode === 200) {
|
||||
if (_self.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
completeImages++;
|
||||
|
||||
if (_self.showUploadProgress) {
|
||||
uni.showToast({
|
||||
title: '上传进度:' + completeImages + '/' + imagePathArr.length,
|
||||
icon: 'none',
|
||||
mask: false,
|
||||
duration: 500
|
||||
});
|
||||
}
|
||||
// console.log('success to upload image: ' + res.data)
|
||||
var resItem=JSON.parse(res.data)
|
||||
|
||||
console.error(resItem)
|
||||
|
||||
_self.$emit('oneComplete', {
|
||||
name: resItem.data,
|
||||
url: resItem.data,
|
||||
type:'IMAGE'
|
||||
},_self.chooseType);
|
||||
resolve(res.data);
|
||||
} else {
|
||||
console.log('fail to upload image:' + res.data);
|
||||
reject('fail to upload image:' + remoteUrlIndex);
|
||||
}
|
||||
},
|
||||
fail: function(res) {
|
||||
uni.showToast({
|
||||
title: '上传失败请检查网络',
|
||||
icon: 'none'
|
||||
});
|
||||
console.log('fail to upload image:' + res);
|
||||
reject('fail to upload image:' + remoteUrlIndex);
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(promiseWorkList).then(result => {
|
||||
if (_self.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
var fresult=[]
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
var resItem=JSON.parse(result[i])
|
||||
_self.fileList.push({
|
||||
name: resItem.data.fileName,
|
||||
url: resItem.data.fullPath,
|
||||
type:'IMAGE'
|
||||
});
|
||||
fresult.push({
|
||||
name: resItem.data.fileName,
|
||||
url: resItem.data.fullPath,
|
||||
type:'IMAGE'
|
||||
})
|
||||
}
|
||||
_self.$emit('allComplete', fresult,_self.chooseType);
|
||||
});
|
||||
} else {
|
||||
var testImg='图片地址'
|
||||
for (let i = 0; i < imagePathArr.length; i++) {
|
||||
_self.fileList.push({
|
||||
name: 'avatar'+i+'.jpg',
|
||||
url: testImg
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
selectVideo: function() {
|
||||
var _self = this;
|
||||
if (!_self.fileList) {
|
||||
_self.fileList = [];
|
||||
}
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album', 'camera'],
|
||||
compressed:true,
|
||||
success: function(e) {
|
||||
if (_self.showUploadProgress) {
|
||||
uni.showLoading({
|
||||
title:'上传中...'
|
||||
})
|
||||
}
|
||||
uploadVideo(e).then(res=>{
|
||||
uni.hideLoading()
|
||||
_self.fileList.push(res);
|
||||
_self.$emit('allComplete', res ,_self.chooseType);
|
||||
})
|
||||
function uploadVideo(e){
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: _self.videoAction,
|
||||
fileType: 'video',
|
||||
header: _self.header,
|
||||
formData: _self.formData,
|
||||
filePath: e.tempFilePath,
|
||||
name: _self.fileKey,
|
||||
success: function(res) {
|
||||
if (res.statusCode === 200) {
|
||||
if (_self.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
var resItem=JSON.parse(res.data)
|
||||
var fresult={
|
||||
name: resItem.data.fileName,
|
||||
videoUrl: resItem.data.fullPath,
|
||||
url: resItem.data.screenShot,
|
||||
type:'VIDEO'
|
||||
}
|
||||
_self.$emit('oneComplete', {
|
||||
name: resItem.data.fileName,
|
||||
videoUrl: resItem.data.fullPath,
|
||||
url: resItem.data.screenShot,
|
||||
type:'VIDEO'
|
||||
},_self.chooseType);
|
||||
resolve(fresult)
|
||||
} else {
|
||||
reject(res)
|
||||
}
|
||||
},
|
||||
fail: function(res) {
|
||||
uni.showToast({
|
||||
title: '上传失败请检查网络',
|
||||
icon: 'none'
|
||||
});
|
||||
reject(res)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteImage: function(e) {
|
||||
this.$emit('deleteImage', e);
|
||||
},
|
||||
previewImage: function(arr,index) {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
indicator: 'number',
|
||||
loop: true,
|
||||
urls: arr
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.zmm-upload-image {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
/* display: flex;flex-direction: row;justify-content: center; */
|
||||
}
|
||||
|
||||
.zmm-upload-image-list {
|
||||
/* width: 714rpx; */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.zmm-upload-image-item {
|
||||
width: 214rpx;
|
||||
height: 214rpx;
|
||||
margin: 12rpx;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
.zmm-upload-image-item-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
.zmm-upload-image-item-slot{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.zmm-upload-image-item-slotIcon {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
</style>
|
||||
568
im-uniapp/components/zy-search/zy-search.vue
Normal file
@@ -0,0 +1,568 @@
|
||||
<template name="zy-search">
|
||||
<view class="good-search-page" :class="Theme">
|
||||
<view class="good-search-head">
|
||||
|
||||
<input :class="{'clearvalue':clearValuebtn}" :maxlength="maxLength" :style="{'line-height': inputHeight+'px','height': inputHeight+'px'}" :focus="isFocus" type="text" confirm-type="search" @confirm="searchStart()" :placeholder="inputPlaceholder" :confirm-hold="true" v-model="searchText" />
|
||||
<!-- <view v-if="searchText.length>0&&clearValuebtn" class="good-search-icon clearvalue-icon iconfont iconshanchu1" @click="clearvalue()"></view> -->
|
||||
<view class="good-search-icon search-icon2" @click="goback()">取消</view>
|
||||
<view class="good-search-icon search-icon iconfont iconsousuo-copy" @click="searchStart()"></view>
|
||||
<scroll-view class="autocomplay" :style="{'top': inputHeight+5+'px'}" v-if="autocomplaystate" scroll-y>
|
||||
<view class="autocomplay-item" v-for="(item,index) in autocomplayarr" :key="index" @click="tagsClick(item.value)">
|
||||
<rich-text :nodes="item.richtxt"></rich-text>
|
||||
</view>
|
||||
<view style="color: #999;text-align: center;justify-content: center; line-height: 70rpx;" v-if="autocomplayarr.length<1">没有相关信息</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="good-search-body">
|
||||
<view class="search-history" v-if="hList.length > 0">
|
||||
<view class="header">
|
||||
<text>历史记录</text>
|
||||
<view class="good-search-icon delete-icon iconfont iconshanchu" @click="delhistory()"></view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view v-for="(item,index) in hList" :key="index" @click="tagsClick(item)">{{item}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-showhot" v-if="hotList.length>0">
|
||||
<view class="header">
|
||||
<text>猜你想搜的</text>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view v-for="(item,index) in hotList" :key="index" @click="tagsClick(item)">{{item}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
clearValuebtn: { //是否显示清空按钮
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isFocus: { //是否自动获取焦点
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
Theme: { //选择主题class
|
||||
type: String,
|
||||
default: 'good-search-circle'
|
||||
},
|
||||
maxLength: { //字符最大长度
|
||||
type: [String, Number],
|
||||
default: '140'
|
||||
},
|
||||
inputHeight: { //搜索框高度单位px
|
||||
type: [String, Number],
|
||||
default: '35'
|
||||
},
|
||||
inputPlaceholder: { //搜索框默认提示
|
||||
type: String,
|
||||
default: '请输入关键词搜索'
|
||||
},
|
||||
autoComplaylist: { //自动联想数据
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
historyNum: { //历史记录保存数量
|
||||
type: Number,
|
||||
default: 6
|
||||
},
|
||||
hotList: { //推荐列表数据
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
speechEngine: { //语音引擎=>讯飞:iFly,百度:'baidu'
|
||||
type: String,
|
||||
default: 'iFly'
|
||||
},
|
||||
Punctuation: { //是否开启语音识别标点符号
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
callbackTime: { //input回调缓冲时间(不返回500毫秒以内输入的数据,防止每输入一个值就会触发一次)
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
speechengine: this.speechEngine,
|
||||
punctuation: this.Punctuation,
|
||||
historynum: this.historyNum,
|
||||
callbacktime: this.callbackTime,
|
||||
autocomplaylist: this.getcomplaylist(this.autoComplaylist),
|
||||
autocomplayarr: [],
|
||||
autocomplaystate: false,
|
||||
searchText: '',
|
||||
hList: uni.getStorageSync('search_cache'),
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
historyNum: function(val) {
|
||||
this.historynum = val;
|
||||
},
|
||||
speechEngine: function(val) {
|
||||
this.engine = val;
|
||||
},
|
||||
hotList: function(val) {
|
||||
this.hotList = val;
|
||||
},
|
||||
autoComplaylist: function(val) {
|
||||
this.autocomplaylist = this.getcomplaylist(val);
|
||||
if (!this.searchText || this.searchText == '') {
|
||||
this.autocomplaystate = false
|
||||
return
|
||||
}
|
||||
this.autocomplayarr = this.replacekeyword(this.autocomplaylist, this.searchText)
|
||||
this.autocomplaystate = this.autocomplayarr.length > 0 ? true : false;
|
||||
},
|
||||
searchText: function(val) {
|
||||
let _this = this;
|
||||
var searchWords = val.replace(/^ +| +$/g, '');
|
||||
if (!searchWords || searchWords == '') {
|
||||
this.autocomplaystate = false
|
||||
return
|
||||
}
|
||||
if (this.calbacktime) {
|
||||
clearTimeout(_this.calbacktime)
|
||||
}
|
||||
this.calbacktime = setTimeout(function() {
|
||||
_this.inputChange(searchWords)
|
||||
}, _this.callbackTime);
|
||||
this.autocomplayarr = this.replacekeyword(this.autocomplaylist, searchWords)
|
||||
this.autocomplaystate = this.autocomplayarr.length > 0 ? true : false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
goback(){
|
||||
uni.navigateBack({
|
||||
delta:1
|
||||
})
|
||||
},
|
||||
clearvalue() { //删除input值
|
||||
let _this = this;
|
||||
setTimeout(function() { //增加延时解决键盘收回时导致的@input事件
|
||||
_this.searchText = ''
|
||||
}, 20);
|
||||
this.searchText = ''
|
||||
},
|
||||
getcomplaylist(arr) { //初始化自动联想数组
|
||||
var data = []
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
data.push({
|
||||
richtxt: arr[i],
|
||||
value: arr[i]
|
||||
})
|
||||
}
|
||||
return data
|
||||
},
|
||||
replacekeyword(arr, searchWords) { //返回符合关键词的高亮数组
|
||||
var data = []
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i].richtxt.search(searchWords) != -1) {
|
||||
data.push({
|
||||
richtxt: arr[i].richtxt.replace(searchWords, "<span style='color: #333;font-weight:bold'>" + searchWords +
|
||||
"</span>"),
|
||||
value: arr[i].value
|
||||
})
|
||||
}
|
||||
}
|
||||
return data
|
||||
},
|
||||
tagsClick(item) { //标签点击事件
|
||||
let _this = this;
|
||||
setTimeout(function() { //增加延时解决键盘收回时导致的@input事件
|
||||
_this.searchText = item
|
||||
_this.searchStart()
|
||||
}, 20);
|
||||
this.$emit('tagsClick', item)
|
||||
},
|
||||
inputChange(e) { //input回调
|
||||
this.$emit('inputChange', e)
|
||||
},
|
||||
notSupport() { //不支持提醒
|
||||
uni.showToast({
|
||||
title: '该平台暂不支持',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
});
|
||||
},
|
||||
searchStart() { //触发搜索
|
||||
let _this = this;
|
||||
if (_this.searchText == '') {
|
||||
uni.showToast({
|
||||
title: '请输入关键字',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// else {
|
||||
// if(this.autocomplayarr.length<1){
|
||||
// this.autocomplaystate=true
|
||||
// return
|
||||
// }
|
||||
// uni.getStorage({
|
||||
// key: 'search_cache',
|
||||
// success(res) {
|
||||
// let list = res.data;
|
||||
// if (list.length >= _this.historynum) {
|
||||
// for (let item of list) {
|
||||
// if (item == _this.searchText) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// list.pop();
|
||||
// list.unshift(_this.searchText);
|
||||
// } else {
|
||||
// for (let item of list) {
|
||||
// if (item == _this.searchText) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// list.unshift(_this.searchText);
|
||||
// }
|
||||
// _this.hList = list;
|
||||
// uni.setStorage({
|
||||
// key: 'search_cache',
|
||||
// data: _this.hList
|
||||
// });
|
||||
// },
|
||||
// fail() {
|
||||
// _this.hList = [];
|
||||
// _this.hList.push(_this.searchText);
|
||||
// uni.setStorage({
|
||||
// key: 'search_cache',
|
||||
// data: _this.hList
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
this.$emit('clickSearch', _this.searchText)
|
||||
},
|
||||
delhistory() { //清空历史记录
|
||||
this.hList = [];
|
||||
uni.setStorage({
|
||||
key: 'search_cache',
|
||||
data: []
|
||||
});
|
||||
this.$emit('delhHistory')
|
||||
},
|
||||
startRecognize() { //语音输入
|
||||
let _this = this;
|
||||
let options = {};
|
||||
options.engine = _this.speechengine;
|
||||
options.punctuation = _this.punctuation; // 是否需要标点符号
|
||||
options.timeout = 1000;
|
||||
plus.speech.startRecognize(options, function(s) {
|
||||
_this.searchText = _this.searchText + s;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAARsAAsAAAAACTAAAAQeAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDMgqFOIR/ATYCJAMUCwwABCAFhG0HXhshCBEVnP3IfiTGtg+yYk9cckRpaoLn+Ty/c9976WTSnw8NxB3gNgOIO3pXjJjRVmgD9Ab4PpuONYw5YTol8dSz/I/7dt/vpPE4jVIIiZD8//ctbT0e2HotiyTD+1qXxepTJ4rjgALadwoja4DGBsTHZGxxVg7MnJ/5HAI4FKQ80rBxy47YGGidADJs8MDe2B0bZoEj2MbAxFGDrMLCVovVA2Bl8fPyhapig8LS0Na2Axr1o66P31LPSsyiW0ZDfjgPYJ0CDZQHDMiYSd8wdJUrj8YJfs9QF3CwUSgfP9sv7bdMJCBU3ZDBkT5QN/OPp0ECkC4J7Lp5Az6JCAr8bBEE/NKyZX1L2NA60zI4Byq8AakDdnGd+mjadOnkCgUCQZe2JBWQrrOPLDlENBrCKQ7NOhx0lx6dfcRxJB73ZLxDIpGOsVjY60kZ8igzOXw9LgUBGelc6m3cuuVAZsRx5GvKIpG66zZnkSW0fl+aqQyrs2/PC4MqGm3k3o57OnjwGM/GYh13Xl76sMCgA5cKaldtu1A8yVt6VE6qgY0tiXyypWtSP/W45FhtsVi3dUuywx3Tq47MzuWFN8w+ujQr5G1cenhWZsfQenHrt0Nual5cNWf/2RnJgwa45BXXcaVvHjDIwtCj5mC0pbqoUevXj0rVykS01XygQmPGhkWi1q5CD1V4zJiwAgLTK6ixKmnjng+VFzQ3pz5/PqlPaRCoT+KaU6ZLu+LnFx6adKNhoZbr9a1bap1EeNbrdQ2mn6ZhlWmvN9uLq2TsP7U4b5W8FB5bv7F076IbRQtPLDExo9Ibadiy2+o5q1t1pdHrcsP37+hG3bvu21zld1OnSNq6uuWtV79fm/JtF9YYl+plfM3wiugNm1M99VW1huenTU6hsK5/2fz9ay5L1EmqairU5E15Nq0kzL1F8ywu6YspBjsP5znMJAAS1011/YKXvq7rYabb2/VcX9P+QgCB5CWns3um1PxmBw0AT9ymU0Q0kYEv+0/oCeR/Hjmzz4RKslvG701kftwixF9Dp4KSAyQQSufFYQxZ7EYQbLIaUOSgAGhsitMNuzxYBKkOAWzqgEM5PdXpIBlYa8TkBMryFiCk8gFFMpdBk8qXbtg/sMjmDwFSZQ0O4WVcGaSktKcGFplHCXyGVtCklNOfyuYb1mFgtq0suC+0rk1Ckeb9YoUT2kPscLEuvVegLI1wFa/hMBBoSx0Knzbe60uWqakPpYLGxYkGLMR4SAK4GdASyERlo73T4Ps3qBYMGLtAGYi/IMtpJwcKUnIGvdJNLMpLme1EtRLPU/oqxSIj4AoPGmSOAHp6UQcJXkqzQ0a7kGmDFFeXnt4wvsdjgAPNtkSJFiOWBEi7b3fydkLpGqZRkJ7PYym4QEmj2U8UJtGEQ+EtFgsAAA==') format('woff2');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: 'iconfont' !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconcombinedshapecopy:before {
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.iconsousuo-copy:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.iconshanchu:before {
|
||||
content: "\e64c";
|
||||
}
|
||||
|
||||
.iconshanchu1:before {
|
||||
content: "\e628";
|
||||
}
|
||||
|
||||
page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
view {
|
||||
display: flex;
|
||||
font-size: 28upx;
|
||||
line-height: inherit
|
||||
}
|
||||
|
||||
.good-search-page {
|
||||
box-sizing: border-box;
|
||||
width: 750rpx;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.good-search-head {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.good-search-head input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
background-color: #F7F7F7;
|
||||
font-size: 28rpx;
|
||||
border-radius: 50rpx;
|
||||
padding: 0 73rpx;
|
||||
padding-left: 34rpx;
|
||||
padding-right: 160rpx;
|
||||
}
|
||||
.good-search-head input.clearvalue{
|
||||
}
|
||||
.good-search-icon {
|
||||
color: #888;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.good-search-head .good-search-icon {
|
||||
width: 73rpx;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 0rpx;
|
||||
}
|
||||
|
||||
.good-search-head .voice-icon {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.good-search-head .search-icon {
|
||||
width: 63rpx;
|
||||
right: 97rpx;
|
||||
}
|
||||
.good-search-head .search-icon2 {
|
||||
font-size: 28rpx;
|
||||
right: 0;
|
||||
width: 73rpx;
|
||||
padding-right: 24rpx;
|
||||
}
|
||||
.good-search-head .clearvalue-icon {
|
||||
width: auto;
|
||||
right: 146rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.good-search-head .autocomplay {
|
||||
left: 0;
|
||||
top: 80rpx;
|
||||
border-radius: 20rpx;
|
||||
height: 70vh;
|
||||
background: #f7f7f7;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.good-search-head .autocomplay .autocomplay-item {
|
||||
padding: 0 24rpx;
|
||||
line-height: 70rpx;
|
||||
height: 70rpx;
|
||||
border-bottom: 1px #eee solid;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.good-search-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.good-search-page .search-history {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.good-search-page .search-showhot {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 主题1 */
|
||||
.good-search-rect {}
|
||||
|
||||
.good-search-rect .good-search-head input {
|
||||
border-radius: 0;
|
||||
}
|
||||
.good-search-rect .good-search-head input.clearvalue{
|
||||
}
|
||||
.good-search-rect .good-search-head .voice-icon {}
|
||||
|
||||
.good-search-rect .good-search-head .search-icon {}
|
||||
|
||||
.good-search-rect .good-search-head .clearvalue-icon {}
|
||||
|
||||
.good-search-rect .header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 24rpx 0;
|
||||
padding: 0 12rpx;
|
||||
}
|
||||
|
||||
.good-search-rect .header text {
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
.good-search-rect .list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.good-search-rect .list view {
|
||||
display: block;
|
||||
width: 49%;
|
||||
color: #8A8A8A;
|
||||
font-size: 28rpx;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
padding: 20rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
background-color: #F7F7F7;
|
||||
margin: 0.5%;
|
||||
}
|
||||
|
||||
.good-search-rect .search-showhot {}
|
||||
|
||||
/* 主题2 */
|
||||
.good-search-circle {}
|
||||
|
||||
.good-search-circle .good-search-head input {
|
||||
border-radius: 50rpx;
|
||||
}
|
||||
.good-search-circle .good-search-head input.clearvalue{
|
||||
}
|
||||
.good-search-circle .good-search-head .voice-icon {}
|
||||
|
||||
.good-search-circle .good-search-head .search-icon {}
|
||||
|
||||
.good-search-circle .good-search-head .clearvalue-icon {}
|
||||
.good-search-circle .header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 24rpx 0;
|
||||
padding: 0 12rpx;
|
||||
}
|
||||
|
||||
.good-search-circle .header text {
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
.good-search-circle .list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.good-search-circle .list view {
|
||||
display: block;
|
||||
padding: 8rpx 18rpx;
|
||||
margin: 12rpx;
|
||||
margin-top: 0;
|
||||
font-size: 28rpx;
|
||||
color: #8A8A8A;
|
||||
background-color: #F7F7F7;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.good-search-circle .search-showhot {}
|
||||
|
||||
/* 主题3 */
|
||||
.good-search-tb {}
|
||||
|
||||
.good-search-tb .good-search-head input {
|
||||
border-radius: 0;
|
||||
}
|
||||
.good-search-tb .good-search-head input.clearvalue{
|
||||
padding-right: 133rpx;
|
||||
}
|
||||
.good-search-tb .good-search-head .voice-icon {}
|
||||
|
||||
.good-search-tb .good-search-head .search-icon {
|
||||
background: #FF9A33;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.good-search-tb .good-search-head .clearvalue-icon {
|
||||
width: 60rpx;
|
||||
}
|
||||
.good-search-tb .header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 24rpx 0;
|
||||
padding: 0 12rpx;
|
||||
}
|
||||
|
||||
.good-search-tb .header text {
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
.good-search-tb .list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.good-search-tb .list view {
|
||||
display: block;
|
||||
padding: 8rpx 30rpx;
|
||||
margin: 12rpx;
|
||||
margin-top: 0;
|
||||
font-size: 28rpx;
|
||||
color: #8A8A8A;
|
||||
background-color: #F7F7F7;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.good-search-tb .search-showhot {}
|
||||
</style>
|
||||
18
im-uniapp/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script type="text/javascript" src="https://172.16.3.18/static_file/vconsole.min.js"></script>
|
||||
<script>
|
||||
var vConsole = new VConsole();
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
im-uniapp/key/weiliao.keystore
Normal file
69
im-uniapp/main.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import http from '@/common/request'
|
||||
import store from './store'
|
||||
import md5 from "@/common/md5.js";
|
||||
|
||||
|
||||
|
||||
import publicFc from "@/common/publicFc.js";
|
||||
// #ifdef H5
|
||||
import socketTask from "@/common/socketTask.js";
|
||||
// #endif
|
||||
import zmmFormCheck from './common/zmmFormCheck.js';
|
||||
import pinyin from './common/pinyin.js';
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
|
||||
|
||||
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.prototype.$socketTask = socketTask;
|
||||
|
||||
Vue.prototype.$http = http
|
||||
Vue.prototype.$store = store
|
||||
Vue.prototype.$fc = publicFc;
|
||||
Vue.prototype.$md5 = md5
|
||||
Vue.prototype.$zmmFormCheck = zmmFormCheck;
|
||||
Vue.prototype.$pinyin = pinyin;
|
||||
// #ifdef H5
|
||||
|
||||
|
||||
// uni.lim = lim;
|
||||
|
||||
// Vue.prototype.imsdk = lim
|
||||
|
||||
|
||||
// #endif
|
||||
App.mpType = 'app'
|
||||
|
||||
const app = new Vue({
|
||||
...App,
|
||||
store
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import { createSSRApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.config.globalProperties.$socketTask = socketTask
|
||||
|
||||
app.config.globalProperties.$http = http
|
||||
app.config.globalProperties.$fc = publicFc
|
||||
app.config.globalProperties.$md5 = md5
|
||||
app.config.globalProperties.$zmmFormCheck = zmmFormCheck
|
||||
app.config.globalProperties.$pinyin = pinyin
|
||||
// #ifdef H5
|
||||
|
||||
|
||||
// #endif
|
||||
app.use(store);
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
224
im-uniapp/manifest.json
Normal file
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"name" : "IM",
|
||||
"appid" : "__UNI__1A208D0",
|
||||
"description" : "HS-IM",
|
||||
"versionName" : "1.2.1",
|
||||
"versionCode" : 121,
|
||||
"developer" : {
|
||||
"name" : "zmm2113@qq.com",
|
||||
"email" : "zmm2113@qq.com"
|
||||
},
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
/* 5+App特有相关 */
|
||||
"permissions" : {
|
||||
"File" : {
|
||||
"description" : "文件系统"
|
||||
}
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : false,
|
||||
"waiting" : false,
|
||||
"autoclose" : false,
|
||||
"delay" : 0
|
||||
},
|
||||
"modules" : {
|
||||
"Geolocation" : {},
|
||||
"Maps" : {},
|
||||
"Push" : {},
|
||||
"Speech" : {},
|
||||
"VideoPlayer" : {},
|
||||
"iBeacon" : {},
|
||||
"Barcode" : {},
|
||||
"Camera" : {}
|
||||
},
|
||||
/* 模块配置 */
|
||||
"distribute" : {
|
||||
/* 应用发布信息 */
|
||||
"android" : {
|
||||
/* android打包配置 */
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
|
||||
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
|
||||
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>"
|
||||
],
|
||||
"minSdkVersion" : 21
|
||||
},
|
||||
"ios" : {
|
||||
"dSYMs" : false
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"sdkConfigs" : {
|
||||
"geolocation" : {
|
||||
"system" : {
|
||||
"__platform__" : [ "ios", "android" ]
|
||||
},
|
||||
"amap" : {
|
||||
"__platform__" : [ "ios", "android" ],
|
||||
"appkey_ios" : "81cc6c72aeb6a1946510cc1e9f87ee80",
|
||||
"appkey_android" : "81cc6c72aeb6a1946510cc1e9f87ee80"
|
||||
}
|
||||
},
|
||||
"maps" : {
|
||||
"amap" : {
|
||||
"appkey_ios" : "81cc6c72aeb6a1946510cc1e9f87ee80",
|
||||
"appkey_android" : "81cc6c72aeb6a1946510cc1e9f87ee80"
|
||||
}
|
||||
},
|
||||
"push" : {
|
||||
"unipush" : {}
|
||||
},
|
||||
"speech" : {
|
||||
"ifly" : {}
|
||||
},
|
||||
"ad" : {}
|
||||
},
|
||||
"icons" : {
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||
},
|
||||
"ios" : {
|
||||
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||
"ipad" : {
|
||||
"app" : "unpackage/res/icons/76x76.png",
|
||||
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||
"notification" : "unpackage/res/icons/20x20.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||
"settings" : "unpackage/res/icons/29x29.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||
},
|
||||
"iphone" : {
|
||||
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||
}
|
||||
}
|
||||
},
|
||||
"splashscreen" : {
|
||||
"androidStyle" : "default",
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/splash/splash480.9.png",
|
||||
"xhdpi" : "unpackage/res/splash/splash750.9.png",
|
||||
"xxhdpi" : "unpackage/res/splash/splash1080.9.png"
|
||||
}
|
||||
}
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
},
|
||||
"nativePlugins" : {
|
||||
"TUICallingUniPlugin-TUICallingModule" : {
|
||||
"__plugin_info__" : {
|
||||
"name" : "TUICallingUniPlugin-TUICallingModule",
|
||||
"description" : "腾讯云音视频插件",
|
||||
"platforms" : "Android,iOS",
|
||||
"url" : "",
|
||||
"android_package_name" : "",
|
||||
"ios_bundle_id" : "",
|
||||
"isCloud" : false,
|
||||
"bought" : -1,
|
||||
"pid" : "",
|
||||
"parameters" : {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* SDK配置 */
|
||||
"quickapp" : {},
|
||||
/* 快应用特有相关 */
|
||||
"mp-weixin" : {
|
||||
/* 小程序特有相关 */
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"vueVersion" : "3",
|
||||
"uniStatistics" : {
|
||||
"enable" : true,
|
||||
"version" : "1"
|
||||
},
|
||||
"h5" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"maps" : {
|
||||
"qqmap" : {
|
||||
"key" : "3U7BZ-AZZKD-IXC4C-HZA7T-2PGKT-EZFER"
|
||||
}
|
||||
}
|
||||
},
|
||||
"router" : {
|
||||
"base" : "/im-uniapp/",
|
||||
"mode" : "history"
|
||||
},
|
||||
"devServer" : {
|
||||
"https" : false
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-kuaishou" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-lark" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-qq" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
21
im-uniapp/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "hs-im",
|
||||
"version": "1.1.0",
|
||||
"description": "",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git"
|
||||
},
|
||||
"author": "php_echo@163.com",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.5.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"js-base64": "^3.7.5",
|
||||
"localforage": "^1.10.0",
|
||||
"luch-request": "^3.1.1"
|
||||
}
|
||||
}
|
||||
718
im-uniapp/pages.json
Normal file
@@ -0,0 +1,718 @@
|
||||
{
|
||||
"pages": [
|
||||
// {
|
||||
// "path": "wx/tabbar1/index",
|
||||
// "name": "wxtabbar1",
|
||||
// "aliasPath": "/wxtabbar1",
|
||||
// "requireAuth": true,
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "消息",
|
||||
// "app-plus": {
|
||||
// "titleNView": {
|
||||
// "buttons": [{
|
||||
// "text": "\ue657",
|
||||
// "fontSrc": "/static/wx_iconfont.ttf",
|
||||
// "fontSize": "28px"
|
||||
// }, {
|
||||
// "text": "\ue636",
|
||||
// "fontSrc": "/static/wx_iconfont.ttf",
|
||||
// "fontSize": "26px"
|
||||
// }]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
"path": "pages/wxindex/index",
|
||||
"name": "wxindex",
|
||||
"aliasPath": "/wxindex",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "微信首页",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/agreement/index",
|
||||
"name": "agreement",
|
||||
"aliasPath": "/agreement",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "隐私及服务协议",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"navigationBarTextStyle": "black"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8",
|
||||
"app-plus": {
|
||||
"background": "#efeff4"
|
||||
}
|
||||
},
|
||||
"tabBar": { //底部
|
||||
"color": "#999999",
|
||||
"selectedColor": "#09C160",
|
||||
"borderStyle": "black",
|
||||
"backgroundColor": "#ffffff",
|
||||
"list": [{
|
||||
"pagePath": "wx/tabbar1/index",
|
||||
"iconPath": "static/wx/n0.png",
|
||||
"selectedIconPath": "static/wx/n0_on.png",
|
||||
"text": "消息"
|
||||
},
|
||||
{
|
||||
"pagePath": "wx/tabbar2/index",
|
||||
"iconPath": "static/wx/n01.png",
|
||||
"selectedIconPath": "static/wx/n01_on.png",
|
||||
"text": "通讯录"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subPackages": [ //分包,微信小程序单包最大2M
|
||||
{
|
||||
"root": "wx",
|
||||
"pages": [{
|
||||
"path": "login/index",
|
||||
"name": "wxlogin",
|
||||
"aliasPath": "/wxlogin",
|
||||
"requireAuth": false,
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
}, {
|
||||
"path": "register/index",
|
||||
"name": "wxregister",
|
||||
"aliasPath": "/wxregister",
|
||||
"requireAuth": false,
|
||||
"style": {
|
||||
"navigationBarTitleText": "注册"
|
||||
}
|
||||
}, {
|
||||
"path": "forgetPass/index",
|
||||
"name": "wxforgetPass",
|
||||
"aliasPath": "/wxforgetPass",
|
||||
"requireAuth": false,
|
||||
"style": {
|
||||
"navigationBarTitleText": "忘记密码"
|
||||
}
|
||||
}, {
|
||||
"path": "chatWindow/index",
|
||||
"name": "wxchatWindow",
|
||||
"aliasPath": "/wxchatWindow",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "聊天窗口",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "\ue623",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "28px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
, {
|
||||
"path": "tabbar1/index",
|
||||
"name": "wxtabbar1",
|
||||
"aliasPath": "/wxtabbar1",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "消息"
|
||||
}
|
||||
}
|
||||
, {
|
||||
"path": "tabbar2/index",
|
||||
"name": "wxtabbar2",
|
||||
"aliasPath": "/wxtabbar2",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "通讯录"
|
||||
}
|
||||
}, {
|
||||
"path": "tabbar3/index",
|
||||
"name": "wxtabbar3",
|
||||
"aliasPath": "/wxtabbar3",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "发现",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "\ue657",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "28px"
|
||||
}, {
|
||||
"text": "\ue636",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "26px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "tabbar4/index",
|
||||
"name": "wxtabbar4",
|
||||
"aliasPath": "/wxtabbar4",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "我",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "group/createGroup",
|
||||
"name": "wxcreateGroup",
|
||||
"aliasPath": "/wxcreateGroup",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "发起群聊"
|
||||
}
|
||||
}, {
|
||||
"path": "shake/index",
|
||||
"name": "wxshake",
|
||||
"aliasPath": "/wxshake",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "摇一摇",
|
||||
"navigationBarBackgroundColor":"#212121",
|
||||
"navigationBarTextStyle":"white"
|
||||
}
|
||||
}, {
|
||||
"path": "nearby/index",
|
||||
"name": "wxnearby",
|
||||
"aliasPath": "/wxnearby",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "附近的人",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "\ue623",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "28px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "friendsCircle/msglist",
|
||||
"name": "wxfriendsCirclemsglist",
|
||||
"aliasPath": "/wxfriendsCirclemsglist",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "消息",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "清空",
|
||||
"fontSize": "16px",
|
||||
"width":"44px",
|
||||
"fontWeight":"bold"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "system/index",
|
||||
"name": "wxsystem",
|
||||
"aliasPath": "/wxsystem",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置"
|
||||
}
|
||||
}, {
|
||||
"path": "search/index",
|
||||
"name": "wxsearch",
|
||||
"aliasPath": "/wxsearch",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "搜索"
|
||||
}
|
||||
}, {
|
||||
"path": "search-friends/index",
|
||||
"name": "wxsearch-friends",
|
||||
"aliasPath": "/wxsearch-friends",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "新的朋友",
|
||||
"enablePullDownRefresh" : true,
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "添加",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "search-friends/add",
|
||||
"name": "wxsearch-friends-add",
|
||||
"aliasPath": "/search-friends-add",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "朋友验证",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "发送",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/index",
|
||||
"name": "wxpersonDetail",
|
||||
"aliasPath": "/wxpersonDetail",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人信息" //个人中心信息
|
||||
}
|
||||
}, {
|
||||
"path": "personInfo/addFriendsDetail",
|
||||
"name": "wxpersonInfoAddFriendsDetail",
|
||||
"aliasPath": "/wxpersonInfoAddFriendsDetail",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "" //添加好友信息
|
||||
}
|
||||
}, {
|
||||
"path": "personInfo/beizhu",
|
||||
"name": "wxpersonInfobeizhu",
|
||||
"aliasPath": "/wxpersonInfobeizhu",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置备注", //修改备注
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/editNikeName",
|
||||
"name": "wxpersonDetaileditNikeName",
|
||||
"aliasPath": "/wxpersonDetaileditNikeName",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改名称", //修改备注
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/editchatNo",
|
||||
"name": "wxpersonDetaileditchatNo",
|
||||
"aliasPath": "/wxpersonDetaileditchatNo",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改微聊号", //修改备注
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/editIntro",
|
||||
"name": "wxpersonDetaileditIntro",
|
||||
"aliasPath": "/wxpersonDetaileditIntro",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改个性签名",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/editGender",
|
||||
"name": "wxpersonDetaileditGender",
|
||||
"aliasPath": "/wxpersonDetaileditGender",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改性别",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/editAddress",
|
||||
"name": "wxpersonDetaileditAddress",
|
||||
"aliasPath": "/wxpersonDetaileditAddress",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改地区",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/editPass",
|
||||
"name": "wxpersonDetaileditPass",
|
||||
"aliasPath": "/wxpersonDetaileditPass",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置密码",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personInfo/detail",
|
||||
"name": "wxpersonInfoDetail",
|
||||
"aliasPath": "/wxpersonInfoDetail",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "信息", //好友个人信息
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "\ue623",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "28px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/detail",
|
||||
"name": "wxgroupInfoDetail",
|
||||
"aliasPath": "/wxgroupInfoDetail",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "聊天信息" //群信息
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/qunAdd",
|
||||
"name": "wxqunAdd",
|
||||
"aliasPath": "/wxqunAdd",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "选择联系人"
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/qunless",
|
||||
"name": "wxqunless",
|
||||
"aliasPath": "/wxqunless",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "聊天成员"
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/editGroupName",
|
||||
"name": "wxgroupInfoeditGroupName",
|
||||
"aliasPath": "/wxgroupInfoeditGroupName",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改群聊名称", //修改备注
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "完成",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/editGroupNotice",
|
||||
"name": "wxgroupInfoeditGroupNotice",
|
||||
"aliasPath": "/wxgroupInfoeditGroupNotice",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "更改群公告", //修改备注
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "修改",
|
||||
"fontSize": "16px"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/scanCodeDetail",
|
||||
"name": "wxgroupInfoscanCodeDetail",
|
||||
"aliasPath": "/wxgroupInfoscanCodeDetail",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "群聊信息"
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/grouplist",
|
||||
"name": "wxgroupInfogrouplist",
|
||||
"aliasPath": "/wxgroupInfogrouplist",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "群聊"
|
||||
}
|
||||
}, {
|
||||
"path": "personDetail/QRcode",
|
||||
"name": "wxpersonDetailQRcode",
|
||||
"aliasPath": "/wxpersonDetailQRcode",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "二维码名片",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "\ue623",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "28px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "groupInfo/QRcode",
|
||||
"name": "wxgroupInfoQRcode",
|
||||
"aliasPath": "/wxgroupInfoQRcode",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "群二维码",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"text": "\ue623",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "28px"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "personInfo/edit",
|
||||
"name": "wxpersonInfoedit",
|
||||
"aliasPath": "/wxpersonInfoedit",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "资料设置" //好友资料设置
|
||||
}
|
||||
}, {
|
||||
"path": "friendsCircle/index",
|
||||
"name": "wxfriendsCircle",
|
||||
"aliasPath": "/wxfriendsCircle",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "朋友圈",
|
||||
"enablePullDownRefresh" : true,
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"type": "transparent",
|
||||
"titleColor": "#fff",
|
||||
"backgroundColor": "#d1d1d1",
|
||||
"buttons": [{
|
||||
"text": "\ue638",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "24px",
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "friendsCircle/person",
|
||||
"name": "wxfriendsCirclePerson",
|
||||
"aliasPath": "/wxfriendsCirclePerson",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的相册",
|
||||
"enablePullDownRefresh" : true,
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"type": "transparent",
|
||||
"titleColor": "#fff",
|
||||
"backgroundColor": "#d1d1d1",
|
||||
"buttons": [{
|
||||
"text": "\ue6f4",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "24px",
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "friendsCircle/sendMsg",
|
||||
"name": "wxsendMsg",
|
||||
"aliasPath": "/wxsendMsg",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "发朋友圈",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
// "type": "transparent",
|
||||
// "titleColor": "#333333",
|
||||
// "backgroundColor": "#09C160",
|
||||
"buttons": [{
|
||||
"color": "#09C160",
|
||||
"text": "发表",
|
||||
// "fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "16px",
|
||||
"borderRadius": "0px",
|
||||
"background": "#09C160"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "feedback/index",
|
||||
"name": "wxfeedback",
|
||||
"aliasPath": "/wxfeedback",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "建议反馈",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"buttons": [{
|
||||
"color": "#09C160",
|
||||
"text": "发表",
|
||||
"fontSize": "16px",
|
||||
"borderRadius": "0px",
|
||||
"background": "#09C160"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "favorites/index",
|
||||
"name": "wxfavorites",
|
||||
"aliasPath": "/wxfavorites",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "收藏",
|
||||
"enablePullDownRefresh" : true,
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
// "buttons": [{
|
||||
// "text": "\ue657",
|
||||
// "fontSrc": "/static/wx_iconfont.ttf",
|
||||
// "fontSize": "28px"
|
||||
// }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "friendsCircle/detail",
|
||||
"name": "wxfriendsCircledetail",
|
||||
"aliasPath": "/wxfriendsCircledetail",
|
||||
"requireAuth": true,
|
||||
"style": {
|
||||
"navigationBarTitleText": "详情",
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
// "type": "transparent",
|
||||
// "titleColor": "#333333",
|
||||
// "backgroundColor": "#09C160",
|
||||
"buttons": [{
|
||||
"text": "\ue623",
|
||||
"fontSrc": "/static/wx_iconfont.ttf",
|
||||
"fontSize": "24px",
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}],
|
||||
"backButton": {
|
||||
"background": "rgba(0,0,0,0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
"root": "wl",
|
||||
"pages": [{
|
||||
"path": "login/index",
|
||||
"name": "wllogin",
|
||||
"aliasPath": "/wllogin",
|
||||
"requireAuth": false,
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
47
im-uniapp/pages/agreement/index.vue
Normal file
61
im-uniapp/pages/wxindex/index.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<view class="wx-index">
|
||||
<image class="wx-bg" src="../../static/wx/bg.jpg" mode="aspectFill"></image>
|
||||
<view class="wx-btns">
|
||||
<view class="wx-btn wx-btn-info" @click="goLogin">登录</view>
|
||||
<view class="wx-btn wx-btn-normal" @click="goRegister">注册</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
goLogin(){
|
||||
uni.navigateTo({
|
||||
url:'../../wx/login/index'
|
||||
})
|
||||
},
|
||||
goRegister(){
|
||||
uni.navigateTo({
|
||||
url:'../../wx/register/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.wx-index{
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.wx-btns{display: flex;flex-direction: row;align-items: center;justify-content: space-between;position: absolute;width: 100%;bottom: 40rpx;padding:0 34rpx;box-sizing: border-box;}
|
||||
.wx-btn{
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
border-radius: 12rpx;
|
||||
background-color: #007AFF;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.wx-btn-info{
|
||||
background-color: #05C160;
|
||||
}
|
||||
.wx-btn-normal{
|
||||
background-color: #18181A;
|
||||
}
|
||||
.wx-bg{
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
BIN
im-uniapp/static/call.mp3
Normal file
129
im-uniapp/static/customicons.css
Normal file
@@ -0,0 +1,129 @@
|
||||
@font-face {
|
||||
font-family: "customicons"; /* Project id 2878519 */
|
||||
src:url('/static/customicons.ttf') format('truetype');
|
||||
}
|
||||
|
||||
.customicons {
|
||||
font-family: "customicons" !important;
|
||||
}
|
||||
|
||||
.youxi:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.wenjian:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.zhuanfa:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "wxfont";
|
||||
src:url('/static/wx_iconfont.ttf') format('truetype');
|
||||
}
|
||||
|
||||
.wxfont{
|
||||
font-family: "wxfont" !important;
|
||||
}
|
||||
|
||||
.tupian:before {
|
||||
content: "\e626";
|
||||
}
|
||||
.caidan:before {
|
||||
content: "\e600";
|
||||
}
|
||||
.zan:before {
|
||||
content: "\e6CD";
|
||||
}
|
||||
.pinglun:before {
|
||||
content: "\e662";
|
||||
}
|
||||
.yuyin3:before {
|
||||
content: "\e629";
|
||||
}
|
||||
.shipin:before {
|
||||
content: "\e7dd";
|
||||
}
|
||||
.faxiaoxi:before {
|
||||
content: "\e61c";
|
||||
}
|
||||
.xiangji:before {
|
||||
content: "\e603";
|
||||
}
|
||||
.jiahaoyou:before {
|
||||
content: "\e611";
|
||||
}
|
||||
.xiaoxi:before {
|
||||
content: "\e69e";
|
||||
}
|
||||
.saoyisao:before {
|
||||
content: "\e60a";
|
||||
}
|
||||
.nan:before {
|
||||
content: "\e609";
|
||||
}
|
||||
.nv:before {
|
||||
content: "\e608";
|
||||
}
|
||||
.msglist:before {
|
||||
content: "\e6f4";
|
||||
}
|
||||
.gengduo:before {
|
||||
content: "\e657";
|
||||
}
|
||||
.dingwei:before {
|
||||
content: "\e7e6";
|
||||
}
|
||||
.dingwei2:before {
|
||||
content: "\e675";
|
||||
}
|
||||
.mingpian:before {
|
||||
content: "\e63c";
|
||||
}
|
||||
.shoucang:before {
|
||||
content: "\e646";
|
||||
}
|
||||
.fssb:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
.yuyin:before {
|
||||
content: "\e8c4";
|
||||
}
|
||||
.yrecord:before {
|
||||
content: "\e79d";
|
||||
}
|
||||
.yuyin2:before {
|
||||
content: "\e66c";
|
||||
}
|
||||
.jianpan:before {
|
||||
content: "\e661";
|
||||
}
|
||||
.bofang:before {
|
||||
content: "\e6a6";
|
||||
}
|
||||
.xiazai:before {
|
||||
content: "\e617";
|
||||
}
|
||||
.wxcopy:before {
|
||||
content: "\e75f";
|
||||
}
|
||||
.wxdelete:before {
|
||||
content: "\e63f";
|
||||
}
|
||||
.jia:before {
|
||||
content: "\e620";
|
||||
}
|
||||
.jian:before {
|
||||
content: "\e621";
|
||||
}
|
||||
.qunl:before {
|
||||
content: "\e612";
|
||||
}
|
||||
.yspin:before {
|
||||
content: "\e670";
|
||||
}
|
||||
.biaoqing:before {
|
||||
content: "\e60b";
|
||||
}
|
||||
BIN
im-uniapp/static/customicons.ttf
Normal file
BIN
im-uniapp/static/img/avatar/avatar1.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar10.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
im-uniapp/static/img/avatar/avatar11.jpg
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
im-uniapp/static/img/avatar/avatar12.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
im-uniapp/static/img/avatar/avatar13.jpg
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
im-uniapp/static/img/avatar/avatar14.jpg
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
im-uniapp/static/img/avatar/avatar15.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar16.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar17.jpg
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
im-uniapp/static/img/avatar/avatar18.jpg
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
im-uniapp/static/img/avatar/avatar19.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
im-uniapp/static/img/avatar/avatar2.jpg
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
im-uniapp/static/img/avatar/avatar20.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar21.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
im-uniapp/static/img/avatar/avatar22.jpg
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
im-uniapp/static/img/avatar/avatar23.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
im-uniapp/static/img/avatar/avatar24.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar25.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
im-uniapp/static/img/avatar/avatar26.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
im-uniapp/static/img/avatar/avatar27.jpg
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
im-uniapp/static/img/avatar/avatar28.jpg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
im-uniapp/static/img/avatar/avatar29.jpg
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
im-uniapp/static/img/avatar/avatar3.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
im-uniapp/static/img/avatar/avatar30.jpg
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
im-uniapp/static/img/avatar/avatar31.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar32.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
im-uniapp/static/img/avatar/avatar33.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
im-uniapp/static/img/avatar/avatar34.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar35.jpg
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
im-uniapp/static/img/avatar/avatar36.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
im-uniapp/static/img/avatar/avatar37.jpg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
im-uniapp/static/img/avatar/avatar38.jpg
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
im-uniapp/static/img/avatar/avatar39.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar4.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar40.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
im-uniapp/static/img/avatar/avatar41.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
im-uniapp/static/img/avatar/avatar42.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar43.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
im-uniapp/static/img/avatar/avatar44.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
im-uniapp/static/img/avatar/avatar45.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
im-uniapp/static/img/avatar/avatar5.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
im-uniapp/static/img/avatar/avatar6.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
im-uniapp/static/img/avatar/avatar7.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
im-uniapp/static/img/avatar/avatar8.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
im-uniapp/static/img/avatar/avatar9.jpg
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
im-uniapp/static/img/bf.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
im-uniapp/static/img/f01.png
Normal file
|
After Width: | Height: | Size: 587 B |
BIN
im-uniapp/static/img/fbg.jpg
Normal file
|
After Width: | Height: | Size: 149 KiB |